Merge "docs: Remove error in requestPermissions doc" into rvc-dev am: 05efe90a8d
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13122154
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I3325b526d894701d199f2669131adb46dc1fca42
diff --git a/Android.bp b/Android.bp
index 14a2bff..9873c61 100644
--- a/Android.bp
+++ b/Android.bp
@@ -500,7 +500,7 @@
// TODO(b/147128803) remove the below lines
"//frameworks/base/apex/blobstore/framework",
"//frameworks/base/apex/jobscheduler/framework",
- "//frameworks/base/packages/Tethering/tests/unit",
+ "//packages/modules/Connectivity/Tethering/tests/unit",
],
}
@@ -607,6 +607,7 @@
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
],
@@ -633,6 +634,7 @@
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
],
@@ -655,6 +657,7 @@
"core/java/android/annotation/RequiresPermission.java",
"core/java/android/annotation/SdkConstant.java",
"core/java/android/annotation/StringDef.java",
+ "core/java/android/annotation/SuppressLint.java",
"core/java/android/annotation/SystemApi.java",
"core/java/android/annotation/SystemService.java",
"core/java/android/annotation/TestApi.java",
@@ -748,13 +751,19 @@
name: "platformprotos",
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
+ ":libstats_internal_protos",
+ ":statsd_internal_protos",
"cmds/am/proto/instrumentation_data.proto",
"cmds/statsd/src/**/*.proto",
"core/proto/**/*.proto",
"libs/incident/proto/**/*.proto",
],
proto: {
- include_dirs: ["external/protobuf/src"],
+ include_dirs: [
+ "external/protobuf/src",
+ "frameworks/proto_logging/stats",
+ ],
type: "full",
},
errorprone: {
@@ -777,6 +786,7 @@
sdk_version: "9",
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
],
@@ -792,6 +802,7 @@
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
],
@@ -812,7 +823,9 @@
proto: {
export_proto_headers: true,
- include_dirs: ["external/protobuf/src"],
+ include_dirs: [
+ "external/protobuf/src",
+ ],
},
cflags: [
@@ -823,6 +836,7 @@
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
],
}
@@ -1177,6 +1191,7 @@
visibility: [
"//frameworks/base/wifi",
"//frameworks/base/services/net",
+ "//packages/modules/Wifi/framework",
],
}
@@ -1202,7 +1217,10 @@
"core/java/com/android/internal/util/StateMachine.java",
"core/java/com/android/internal/util/WakeupMessage.java",
],
- visibility: ["//frameworks/opt/net/wifi/service"],
+ visibility: [
+ "//frameworks/opt/net/wifi/service",
+ "//packages/modules/Wifi/service",
+ ],
}
// TODO(b/145644363): move this to under StubLibraries.bp or ApiDocs.bp
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 3eb482d..d98a665 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -154,6 +154,9 @@
module_libs = " " +
" --show-annotation android.annotation.SystemApi\\(" +
"client=android.annotation.SystemApi.Client.MODULE_LIBRARIES" +
+ "\\)" +
+ " --show-for-stub-purposes-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" +
"\\) "
droidstubs {
@@ -212,7 +215,11 @@
arg_files: [
"core/res/AndroidManifest.xml",
],
- args: metalava_framework_docs_args + " --show-annotation android.annotation.TestApi",
+ args: metalava_framework_docs_args
+ + " --show-annotation android.annotation.TestApi"
+ + " --show-for-stub-purposes-annotation android.annotation.SystemApi\\("
+ + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS"
+ + "\\)",
check_api: {
current: {
api_file: "api/test-current.txt",
@@ -231,16 +238,10 @@
}
/////////////////////////////////////////////////////////////////////
-// Following droidstubs modules are for extra APIs for modules.
-// The framework currently have two more API surfaces for modules:
-// @SystemApi(client=MODULE_APPS) and @SystemApi(client=MODULE_LIBRARIES)
+// Following droidstubs modules are for extra APIs for modules,
+// namely @SystemApi(client=MODULE_LIBRARIES) APIs.
/////////////////////////////////////////////////////////////////////
-// TODO(b/146727827) remove the *-api module when we can teach metalava
-// about the relationship among the API surfaces. Currently, these modules are only to generate
-// the API signature files and ensure that the APIs evolve in a backwards compatible manner.
-// They however are NOT used for building the API stub.
-
droidstubs {
name: "module-lib-api",
defaults: ["metalava-full-api-stubs-default"],
@@ -273,7 +274,7 @@
name: "module-lib-api-stubs-docs-non-updatable",
defaults: ["metalava-non-updatable-api-stubs-default"],
arg_files: ["core/res/AndroidManifest.xml"],
- args: metalava_framework_docs_args + module_libs,
+ args: metalava_framework_docs_args + priv_apps + module_libs,
check_api: {
current: {
api_file: "non-updatable-api/module-lib-current.txt",
@@ -286,17 +287,6 @@
},
}
-// The following droidstub module generates source files for the API stub library for
-// modules. Note that it not only includes its own APIs but also other APIs that have
-// narrower scope (all @SystemApis, not just the ones with 'client=MODULE_LIBRARIES').
-
-droidstubs {
- name: "module-lib-api-stubs-docs",
- defaults: ["metalava-non-updatable-api-stubs-default"],
- arg_files: ["core/res/AndroidManifest.xml"],
- args: metalava_framework_docs_args + priv_apps + module_libs,
-}
-
/////////////////////////////////////////////////////////////////////
// android_*_stubs_current modules are the stubs libraries compiled
// from *-api-stubs-docs
@@ -389,7 +379,7 @@
java_library_static {
name: "android_module_lib_stubs_current",
- srcs: [ ":module-lib-api-stubs-docs" ],
+ srcs: [ ":module-lib-api-stubs-docs-non-updatable" ],
defaults: ["android_defaults_stubs_current"],
libs: ["sdk_system_29_android"],
}
diff --git a/apex/Android.bp b/apex/Android.bp
index 992648b..784e3a8 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -53,6 +53,9 @@
module_libs = " " +
" --show-annotation android.annotation.SystemApi\\(" +
"client=android.annotation.SystemApi.Client.MODULE_LIBRARIES" +
+ "\\)" +
+ " --show-for-stub-purposes-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" +
"\\) "
mainline_service_stubs_args =
@@ -94,20 +97,15 @@
annotations_enabled: true,
- stubs_library_visibility: [
- "//visibility:public",
- ],
+ // Allow access to the stubs from anywhere
+ visibility: ["//visibility:public"],
+ stubs_library_visibility: ["//visibility:public"],
- // Set the visibility of the modules creating the stubs source.
- stubs_source_visibility: [
- // Ignore any visibility rules specified on the java_sdk_library when
- // setting the visibility of the stubs source modules.
- "//visibility:override",
+ // Hide impl library and stub sources
+ impl_library_visibility: [":__package__"],
+ stubs_source_visibility: ["//visibility:private"],
- // Currently, the stub source is not required for anything other than building
- // the stubs library so is private to avoid misuse.
- "//visibility:private",
- ],
+ defaults_visibility: ["//visibility:private"],
// Collates API usages from each module for further analysis.
plugins: ["java_api_finder"],
diff --git a/apex/OWNERS b/apex/OWNERS
new file mode 100644
index 0000000..97600135
--- /dev/null
+++ b/apex/OWNERS
@@ -0,0 +1,7 @@
+# Shared module build rule owners
+per-file *.bp=hansson@google.com
+per-file *.bp=jiyong@google.com
+
+# This file, and all other OWNERS files
+per-file OWNERS=dariofreni@google.com
+per-file OWNERS=hansson@google.com
diff --git a/apex/extservices/Android.bp b/apex/extservices/Android.bp
deleted file mode 100644
index 0c6c4c2..0000000
--- a/apex/extservices/Android.bp
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-apex {
- name: "com.android.extservices",
- defaults: ["com.android.extservices-defaults"],
- manifest: "apex_manifest.json",
-}
-
-apex_defaults {
- name: "com.android.extservices-defaults",
- updatable: true,
- min_sdk_version: "current",
- key: "com.android.extservices.key",
- certificate: ":com.android.extservices.certificate",
- apps: ["ExtServices"],
-}
-
-apex_key {
- name: "com.android.extservices.key",
- public_key: "com.android.extservices.avbpubkey",
- private_key: "com.android.extservices.pem",
-}
-
-android_app_certificate {
- name: "com.android.extservices.certificate",
- certificate: "com.android.extservices",
-}
diff --git a/apex/extservices/apex_manifest.json b/apex/extservices/apex_manifest.json
deleted file mode 100644
index b4acf128..0000000
--- a/apex/extservices/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.extservices",
- "version": 300000000
-}
diff --git a/apex/extservices/com.android.extservices.avbpubkey b/apex/extservices/com.android.extservices.avbpubkey
deleted file mode 100644
index f37d3e4..0000000
--- a/apex/extservices/com.android.extservices.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/extservices/com.android.extservices.pem b/apex/extservices/com.android.extservices.pem
deleted file mode 100644
index 7bfbd34..0000000
--- a/apex/extservices/com.android.extservices.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKAIBAAKCAgEAuYshVDiRkt3tmBhqcWkKOm5GcviKpLbHSPpYQDHGDwS0dqqL
-SqAd1/BgT/bVVtUkAciFApPnXn96WhNYCypptyC5FHCxM21uBCGmow+3WermD++w
-5dQk4QP2ONPIpG+KzOWBl9SiBud4SpOHDyr0JycBsrXS89Tln9kAsTDuDEFfXL/J
-8cX/S3IUwhPV0pAlgUIHdDp0DGFjZaJlEZBZ+HmImriC/AUNUMVb5lfbczXOEZPF
-0A9+JzYschfXUxn8nu1N7RN5GDbq+chszx1FMVhuFUheukkd4dLNSDl0O0RlUnD+
-C/xz1ilDzEVZhnMtMnxS9oJ8bA/HUVMfsFnaQbgGmQ0CcxFxnfbYyGXGG1H+b8vA
-MTVQi5rZXG2p+VgHIAKVrYmpETVnRPgoMqp18KuGtp5SDngi13G3YEzS7iFbqfYh
-6iW2G974nD/Dq0cSire8Oljd9PEaMCMZiP5PTFJp0G/mtw7ROoyZqsSM6rX3XVTo
-Y5dBmBMctSJ8rgDMi0ZNvRH+rq/E5+RT6yMAJ7DDbOJzBnQ3IIoGn8NzUT3P1FCB
-HYEp1U2N7QNirIQMAuVz3IlHae9N1kl3eGAO6f2CjV7vZmFpDeWw+KSYs71mRkOb
-WBgl6D9FFq4u1azrU3AwV0dj3x1eU6yVnKUy1J7ppF/mcR+VzH7ThzTdV7cCAwEA
-AQKCAgEApWFU2Mv/PYhg0bPZlLLKsiA+3RWaBo0AfpTd+oIjBpnr/OWweFjVoPcZ
-8cyShe4/RPOlUxHgJcO8m/MoA/PO/LLHJWf5GlzMthQEgs1sYVJVtBiydXitUn+E
-hUyIR8FAV7et1lZqAXtqJhbvSF7B9u/2vIMCv+GgtuTmkAmL9RKD3Jj6eG1CS84o
-oICrkx52v4rKOBgt/icEQMAKFCi1eRti3n3eCqK6JqdzbZIcAcoQnmw34mccy/im
-jx+fBuxf1oywa8NyqVmyAehazBVL6lrm7ENwY9zuLK4H2fuUFYu2QFCEsMxZt6da
-TgX2cTfSLnDQRfcyzeMWhu9vjHHabjpLNjiCKhIhGyO0rO1rtea8ajZHgM/2sxXq
-6gLynW0dlatlxmjANlN9WQPGNdzvcIFJ0TLnI4mlJnWpqCsN9iW1d4ey13WiZUVR
-DgtnR60zao+LRCCM4D3cuVLq0DjL2BlHGXnOPK/LpQG1LbI1TroZpgSEHSZlQRzT
-ql9txgNqTHxijXuPL2VhhwhW7cqDoO8sLwV3BqDMIH56U0cbUBiSA/G9fKeI/DEG
-i7LcrMgrBk+xnuAWoFHuzfBMAdD9i3kYyk+41tOmcza2TNJgxadVYp5woHFvYvS/
-GKaNiRz0XmcijO5Ir0yxgCq21BdkWzo5zVrTFABiKeR7YXiee8kCggEBAOeULWgR
-spolJJrACWJspRvKb9FGnbGiYOnCGJoAc751kuXmNxoyWnEwgcjrSEoayNPUfOtz
-IgA+twqjgl0Zec2XFPfUcgWUBrrvvUEV4NIH5ibaR7ezHGeovCWs9XoDyzHHvhDr
-c6T5kXFZ60rS5h6LGUnE1hkHFJoHuTIBbn9j7eIbri8S71i7HWQ04s4KuQ+Bwbxm
-UnkEhbc+zMWHXfXy7rx4/eEZcZwtEybIORcHXYNPGeqMfOlcEMHpKEOi+NvDA6cp
-vTaTSwJ6ZBgYh7Tw3bNgRxSknaIhcGwMD0ojStjC5xzXT1Zr2Z3GXwYvOGcq3MeZ
-z+V2cx5xuwyp7R0CggEBAM0cKKNZEZwi/1zBPUDMFB4iJoX12BxQX6e5wdlHGXgF
-XeZwCnaIxOxMDxH79M5Svmpdu/jkUijI/pRvcE1iohFyIBvTUSDmlAoy4keXqMEQ
-M2hA+TwVA3JLmMcV8HKy/MFlwwKJB1JDcoxGjnXsM5UjVTD2jilO7vlJZs3+0ws0
-R7qzRT3ED25QTpZyDYcKE2otc5bzIZG3yAaJtWd3NugWsKpxDgr2RFUGJiHBq72n
-48FkSjfgaDTn83zYcPvS0Uykb2ho8G/N+EurstL41n3nQo0I7FLbyptOopDDwsSp
-Ndejn08NVAQ+xFAafOyqHkA3Ytpl0QCZDpMBuLdvw+MCggEAOVMt1kgjPRMat4/4
-ArxANtvqyBRB7vnyIYthiaW5ARmbrntJgpuaVdCbIABWGbn9oqpD7gjHDuZ3axPE
-roUi6KiQkTSusQDOlbHI2Haw+2znJRD9ldSpoGNdh7oD3htYTk9Sll+ideEthrCq
-lRAV1NO8A83M7c8Z43Mr/dvq3XAAL+uIN7DpPL687NRGnJh87QDC039ExR5Ad3b9
-O5xhvwNO46rTtcgVnoJt7ji8IR46oMmQ8cWrGh0nLMkppWyPS98/ZT7ozryxYcCo
-TGquFTVWvBOGJO8G8l5ytNxbYI/R9Exy52nJAuyZpvu3BBHmVWt/0Y0asIOcxZmD
-owPhZQKCAQAfWAFBzReq05JQe1s/7q/YVwGqEQKgeQvVFsbvzDSxKajK0S5YJNhq
-/8iByA4GBZEBsidKhqGjh+uXhVwVB1Ca9+S+O9G3BGV1FYeMxzlLn40rjlpH+zIW
-okTLj6e5724+o61kUspioNn9Y77beGf9j3OyUsswttZAFB54tktL+AZKGqEnKjHt
-eqo3xWAZ1clXvXBfjfIAUaRok1y8XfRvDSCcO0CZHj8c+x6SpAT5q5FbeVb6KPnj
-s9p6ppzFbtb7Llm0C+1KOKCL98YRBWPJw7Bg2w86LkpM53xiQPgfk3gd5uwuaWwA
-ZhMb5qBWjjynNY+OrmZ8/+bBQk8XASZfAoIBAFkHOnZOD1JJQ0QvaJ9tuCgHi216
-I8QPMMTdm3ZEDHSYMNwl7ayeseBcmB2zaqBKYz75qcU0SK4lnZkR2wIpbsHZNSVM
-J0WpN6r9G4JdnVi11J04RsfSMjCUr/PTVMmPvw8xPHrCxkJmB+d56olSE80I1Jrx
-djCv1LtSsT10W7FIcY82/cOi4xxGLOA70lDCf+szofQgVP8WvuOA1YaFw98ca8zc
-A401CyNexk24/c3d6C19YW/MppdE0uGMxL/oHsPgwkZAf6LmvF/UF71PsBUEniLc
-YFaJl3wn1cPfBBo9L4sZzyP2qokL8YHdg+wW7b4IOsYwbeqceBvqPtcUUPs=
------END RSA PRIVATE KEY-----
diff --git a/apex/extservices/com.android.extservices.pk8 b/apex/extservices/com.android.extservices.pk8
deleted file mode 100644
index 59585a2..0000000
--- a/apex/extservices/com.android.extservices.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/extservices/com.android.extservices.x509.pem b/apex/extservices/com.android.extservices.x509.pem
deleted file mode 100644
index e0343b8..0000000
--- a/apex/extservices/com.android.extservices.x509.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGLTCCBBWgAwIBAgIUdqdMmx/5OsCP3Ew3/hcr7+1ACHEwDQYJKoZIhvcNAQEL
-BQAwgaQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMSAwHgYDVQQDDBdjb20uYW5kcm9pZC5leHRzZXJ2aWNlczEiMCAGCSqGSIb3
-DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAgFw0yMDAxMTcxMDIxMzZaGA80NzU3
-MTIxMzEwMjEzNlowgaQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
-MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
-VQQLDAdBbmRyb2lkMSAwHgYDVQQDDBdjb20uYW5kcm9pZC5leHRzZXJ2aWNlczEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCAiIwDQYJKoZIhvcN
-AQEBBQADggIPADCCAgoCggIBANKaSeLGaFRRt779vAtTfG3t2aQZrWOByUYc7yUN
-RdmJqWxU47OL5urYmanWPbz2f972Q9oi8x+8y4ny9SEY3wg0pUbzvKNTXpkxWyG1
-HE2C2zTfzuDDLpDIf2usWynt1wLVhpYC3k+7Yv2vOIK5dKkezh6PfdKmsbDae5DE
-d22tTSYZ5KwNpIWrgQle26cRG5sqhAFdkpgGMF00Huz06cjUoTjs2sNSlXTRBOTP
-CCy8UoRjBivQZkwHbddfsn+Z22ARPG8JDg/n4mEi8C0T6bJeQeirSPkBCkD6Djgq
-7RddJ2eLYZII8l8r6A6x+6cnTkXHaV5g3LUwPvi8XEn9IUuT9WJNRje/vfYLycTQ
-kP415CZMxDvsi1Ul4YsbL3enE89ryGMTpVZPogch/36DG5Sye28yISItNUy3urJa
-OXbg7mh+MwPd4bQaW4CJk+AUweKaF4aV0SZFT+nCewL4xLdGdy889KazlW98NqtK
-hOSxIg1jHkZq48ajuq2A+ns1yDKt1l0f9IYCz3mz/IXInokbkjPvHahJTJ+OMHXO
-THD8e5gBzcK841jJk+H3EsIYOHsp66uy2IgEHN+9pAS6vI0xfrXOYuKzuSL3oxcV
-FlVTimt4xokMMerdcW4KD+MC5NFEip4DUS4JKCyG0wRI3ffEs9Zcpxi3QSibrjLW
-rz+hAgMBAAGjUzBRMB0GA1UdDgQWBBTP2AhZzEUUgtAFlkaMaq+RvY06fDAfBgNV
-HSMEGDAWgBTP2AhZzEUUgtAFlkaMaq+RvY06fDAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBCwUAA4ICAQCbwtfo37j62Sudmt32PCfRN/r5ZNDNNA2JhR8uDUmX
-xXfF5YfDvSKsNLiQKcDagu6a+0C+QnzXHXCBlXZFrTJ8NAVMlmqdHGwoFoYMfJZH
-R1lCTidyFMoMLJ8GRGPJjzDkKnOeAqKMCtKvXoH2r12+JB2/ov4ooLREu/wPkEXT
-OymkyWNP5XLQTKWqfEQyXXFpuwZ+m35Wkr0Fm92mZeJpVeIZPK7M7aK3zyoj7XJP
-YLMsR/AQs8OULdpfNMddAuN3ndlYu03LZlsF6LG5bduaDDcESJ5hdJrgBa/NBKRU
-IbS+q/6WAjYKMNRT/fPGew4wUzlWKi1Ihdk79oaqKKijE1b2JSJD1/SEYiBf+JPE
-bXobUrMbBwFpdhT+YLMF9FsuPQKsUIONaWiO4QcQoY/rQwGxPP6fV8ZbBrUWJewj
-MpSdU9foZNa/TmOAgfS/JxH+nXnG4+H1m8mdNBsxvsYmF2ZuGb/jdEeA2cuHIJDZ
-FJeWwCFxzlCGZJaUsxsnZByADBuufUVaO/9gGs0YQC/JP1i9hK4DyZdKwZpXdLi2
-Nw27Qma4WEIZnMb6Rgk1nTV+7ALcOSIhGgFOOeDTuCGfnEcz2coai5fbD/K6Q7Xu
-IRNyxHQjheZPdei2x912Ex/KqKGfaFaZJxrvCSKdhzxcTFIsO4JuZs+SDpRTKcI7
-Cw==
------END CERTIFICATE-----
diff --git a/apex/extservices/testing/Android.bp b/apex/extservices/testing/Android.bp
deleted file mode 100644
index 88a4724..0000000
--- a/apex/extservices/testing/Android.bp
+++ /dev/null
@@ -1,25 +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.
-
-apex_test {
- name: "test_com.android.extservices",
- visibility: [
- "//system/apex/tests",
- ],
- defaults: ["com.android.extservices-defaults"],
- manifest: "test_manifest.json",
- file_contexts: ":com.android.extservices-file_contexts",
- // Test APEX, should never be installed
- installable: false,
-}
diff --git a/apex/extservices/testing/test_manifest.json b/apex/extservices/testing/test_manifest.json
deleted file mode 100644
index 23a50e3..0000000
--- a/apex/extservices/testing/test_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.extservices",
- "version": 2147483647
-}
diff --git a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
index d54d857..ed818f6 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
@@ -21,7 +21,6 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.content.Context;
import java.lang.annotation.Retention;
@@ -35,7 +34,6 @@
* @hide
*/
@SystemApi
-@TestApi
@SystemService(Context.POWER_WHITELIST_MANAGER)
public class PowerWhitelistManager {
private final Context mContext;
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp
index 4417b68..228e9ba 100644
--- a/apex/media/framework/Android.bp
+++ b/apex/media/framework/Android.bp
@@ -35,7 +35,6 @@
libs: [
"framework_media_annotation",
],
-
static_libs: [
"exoplayer2-extractor"
],
@@ -44,7 +43,6 @@
plugins: ["java_api_finder"],
hostdex: true, // for hiddenapi check
- visibility: ["//frameworks/av/apex:__subpackages__"],
apex_available: [
"com.android.media",
"test_com.android.media",
@@ -83,7 +81,7 @@
"java/android/media/MediaParser.java"
],
path: "java",
-}
+}
java_sdk_library {
name: "framework-media",
@@ -99,21 +97,35 @@
libs: [
"framework_media_annotation",
],
-
- // Allow access to the stubs from anywhere.
- visibility: ["//visibility:public"],
-
- // Restrict access to implementation library.
- impl_library_visibility: [
- "//visibility:override", // Ignore the visibility property.
- "//frameworks/av/apex:__subpackages__",
- ],
+ impl_library_visibility: ["//frameworks/av/apex:__subpackages__"],
}
-
java_library {
name: "framework_media_annotation",
srcs: [":framework-media-annotation-srcs"],
installable: false,
sdk_version: "core_current",
}
+
+cc_library_shared {
+ name: "libmediaparser-jni",
+ srcs: [
+ "jni/android_media_MediaParserJNI.cpp",
+ ],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ "libmediametrics",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-parameter",
+ "-Wunreachable-code",
+ "-Wunused",
+ ],
+ apex_available: [
+ "com.android.media",
+ ],
+ min_sdk_version: "29",
+}
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index e4b5d19..8bdca76 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -75,6 +75,8 @@
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.Function;
/**
* Parses media container formats and extracts contained media samples and metadata.
@@ -882,6 +884,7 @@
// Private constants.
private static final String TAG = "MediaParser";
+ private static final String JNI_LIBRARY_NAME = "mediaparser-jni";
private static final Map<String, ExtractorFactory> EXTRACTOR_FACTORIES_BY_NAME;
private static final Map<String, Class> EXPECTED_TYPE_BY_PARAMETER_NAME;
private static final String TS_MODE_SINGLE_PMT = "single_pmt";
@@ -889,6 +892,14 @@
private static final String TS_MODE_HLS = "hls";
private static final int BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY = 6;
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+ private static final String MEDIAMETRICS_ELEMENT_SEPARATOR = "|";
+ private static final int MEDIAMETRICS_MAX_STRING_SIZE = 200;
+ private static final int MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH;
+ /**
+ * Intentional error introduced to reported metrics to prevent identification of the parsed
+ * media. Note: Increasing this value may cause older hostside CTS tests to fail.
+ */
+ private static final float MEDIAMETRICS_DITHER = .02f;
@IntDef(
value = {
@@ -920,7 +931,7 @@
@NonNull @ParserName String name, @NonNull OutputConsumer outputConsumer) {
String[] nameAsArray = new String[] {name};
assertValidNames(nameAsArray);
- return new MediaParser(outputConsumer, /* sniff= */ false, name);
+ return new MediaParser(outputConsumer, /* createdByName= */ true, name);
}
/**
@@ -940,7 +951,7 @@
if (parserNames.length == 0) {
parserNames = EXTRACTOR_FACTORIES_BY_NAME.keySet().toArray(new String[0]);
}
- return new MediaParser(outputConsumer, /* sniff= */ true, parserNames);
+ return new MediaParser(outputConsumer, /* createdByName= */ false, parserNames);
}
// Misc static methods.
@@ -1052,6 +1063,14 @@
private long mPendingSeekPosition;
private long mPendingSeekTimeMicros;
private boolean mLoggedSchemeInitDataCreationException;
+ private boolean mReleased;
+
+ // MediaMetrics fields.
+ private final boolean mCreatedByName;
+ private final SparseArray<Format> mTrackFormats;
+ private String mLastObservedExceptionName;
+ private long mDurationMillis;
+ private long mResourceByteCount;
// Public methods.
@@ -1166,11 +1185,15 @@
if (mExtractorInput == null) {
// TODO: For efficiency, the same implementation should be used, by providing a
// clearBuffers() method, or similar.
+ long resourceLength = seekableInputReader.getLength();
+ if (mResourceByteCount == 0) {
+ // For resource byte count metric collection, we only take into account the length
+ // of the first provided input reader.
+ mResourceByteCount = resourceLength;
+ }
mExtractorInput =
new DefaultExtractorInput(
- mExoDataReader,
- seekableInputReader.getPosition(),
- seekableInputReader.getLength());
+ mExoDataReader, seekableInputReader.getPosition(), resourceLength);
}
mExoDataReader.mInputReader = seekableInputReader;
@@ -1195,7 +1218,10 @@
}
}
if (mExtractor == null) {
- throw UnrecognizedInputFormatException.createForExtractors(mParserNamesPool);
+ UnrecognizedInputFormatException exception =
+ UnrecognizedInputFormatException.createForExtractors(mParserNamesPool);
+ mLastObservedExceptionName = exception.getClass().getName();
+ throw exception;
}
return true;
}
@@ -1223,8 +1249,13 @@
int result;
try {
result = mExtractor.read(mExtractorInput, mPositionHolder);
- } catch (ParserException e) {
- throw new ParsingException(e);
+ } catch (Exception e) {
+ mLastObservedExceptionName = e.getClass().getName();
+ if (e instanceof ParserException) {
+ throw new ParsingException((ParserException) e);
+ } else {
+ throw e;
+ }
}
if (result == Extractor.RESULT_END_OF_INPUT) {
mExtractorInput = null;
@@ -1264,21 +1295,64 @@
* invoked.
*/
public void release() {
- // TODO: Dump media metrics here.
mExtractorInput = null;
mExtractor = null;
+ if (mReleased) {
+ // Nothing to do.
+ return;
+ }
+ mReleased = true;
+
+ String trackMimeTypes = buildMediaMetricsString(format -> format.sampleMimeType);
+ String trackCodecs = buildMediaMetricsString(format -> format.codecs);
+ int videoWidth = -1;
+ int videoHeight = -1;
+ for (int i = 0; i < mTrackFormats.size(); i++) {
+ Format format = mTrackFormats.valueAt(i);
+ if (format.width != Format.NO_VALUE && format.height != Format.NO_VALUE) {
+ videoWidth = format.width;
+ videoHeight = format.height;
+ break;
+ }
+ }
+
+ String alteredParameters =
+ String.join(
+ MEDIAMETRICS_ELEMENT_SEPARATOR,
+ mParserParameters.keySet().toArray(new String[0]));
+ alteredParameters =
+ alteredParameters.substring(
+ 0,
+ Math.min(
+ alteredParameters.length(),
+ MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH));
+
+ nativeSubmitMetrics(
+ mParserName,
+ mCreatedByName,
+ String.join(MEDIAMETRICS_ELEMENT_SEPARATOR, mParserNamesPool),
+ mLastObservedExceptionName,
+ addDither(mResourceByteCount),
+ addDither(mDurationMillis),
+ trackMimeTypes,
+ trackCodecs,
+ alteredParameters,
+ videoWidth,
+ videoHeight);
}
// Private methods.
- private MediaParser(OutputConsumer outputConsumer, boolean sniff, String... parserNamesPool) {
+ private MediaParser(
+ OutputConsumer outputConsumer, boolean createdByName, String... parserNamesPool) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
throw new UnsupportedOperationException("Android version must be R or greater.");
}
mParserParameters = new HashMap<>();
mOutputConsumer = outputConsumer;
mParserNamesPool = parserNamesPool;
- mParserName = sniff ? PARSER_NAME_UNKNOWN : parserNamesPool[0];
+ mCreatedByName = createdByName;
+ mParserName = createdByName ? parserNamesPool[0] : PARSER_NAME_UNKNOWN;
mPositionHolder = new PositionHolder();
mExoDataReader = new InputReadingDataReader();
removePendingSeek();
@@ -1286,6 +1360,24 @@
mScratchParsableByteArrayAdapter = new ParsableByteArrayAdapter();
mSchemeInitDataConstructor = getSchemeInitDataConstructor();
mMuxedCaptionFormats = new ArrayList<>();
+
+ // MediaMetrics.
+ mTrackFormats = new SparseArray<>();
+ mLastObservedExceptionName = "";
+ mDurationMillis = -1;
+ }
+
+ private String buildMediaMetricsString(Function<Format, String> formatFieldGetter) {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int i = 0; i < mTrackFormats.size(); i++) {
+ if (i > 0) {
+ stringBuilder.append(MEDIAMETRICS_ELEMENT_SEPARATOR);
+ }
+ String fieldValue = formatFieldGetter.apply(mTrackFormats.valueAt(i));
+ stringBuilder.append(fieldValue != null ? fieldValue : "");
+ }
+ return stringBuilder.substring(
+ 0, Math.min(stringBuilder.length(), MEDIAMETRICS_MAX_STRING_SIZE));
}
private void setMuxedCaptionFormats(List<MediaFormat> mediaFormats) {
@@ -1528,6 +1620,10 @@
@Override
public void seekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) {
+ long durationUs = exoplayerSeekMap.getDurationUs();
+ if (durationUs != C.TIME_UNSET) {
+ mDurationMillis = C.usToMs(durationUs);
+ }
if (mExposeChunkIndexAsMediaFormat && exoplayerSeekMap instanceof ChunkIndex) {
ChunkIndex chunkIndex = (ChunkIndex) exoplayerSeekMap;
MediaFormat mediaFormat = new MediaFormat();
@@ -1575,6 +1671,7 @@
@Override
public void format(Format format) {
+ mTrackFormats.put(mTrackIndex, format);
mOutputConsumer.onTrackDataFound(
mTrackIndex,
new TrackData(
@@ -2031,6 +2128,20 @@
return new SeekPoint(exoPlayerSeekPoint.timeUs, exoPlayerSeekPoint.position);
}
+ /**
+ * Introduces random error to the given metric value in order to prevent the identification of
+ * the parsed media.
+ */
+ private static long addDither(long value) {
+ // Generate a random in [0, 1].
+ double randomDither = ThreadLocalRandom.current().nextFloat();
+ // Clamp the random number to [0, 2 * MEDIAMETRICS_DITHER].
+ randomDither *= 2 * MEDIAMETRICS_DITHER;
+ // Translate the random number to [1 - MEDIAMETRICS_DITHER, 1 + MEDIAMETRICS_DITHER].
+ randomDither += 1 - MEDIAMETRICS_DITHER;
+ return value != -1 ? (long) (value * randomDither) : -1;
+ }
+
private static void assertValidNames(@NonNull String[] names) {
for (String name : names) {
if (!EXTRACTOR_FACTORIES_BY_NAME.containsKey(name)) {
@@ -2070,9 +2181,26 @@
}
}
+ // Native methods.
+
+ private native void nativeSubmitMetrics(
+ String parserName,
+ boolean createdByName,
+ String parserPool,
+ String lastObservedExceptionName,
+ long resourceByteCount,
+ long durationMillis,
+ String trackMimeTypes,
+ String trackCodecs,
+ String alteredParameters,
+ int videoWidth,
+ int videoHeight);
+
// Static initialization.
static {
+ System.loadLibrary(JNI_LIBRARY_NAME);
+
// Using a LinkedHashMap to keep the insertion order when iterating over the keys.
LinkedHashMap<String, ExtractorFactory> extractorFactoriesByName = new LinkedHashMap<>();
// Parsers are ordered to match ExoPlayer's DefaultExtractorsFactory extractor ordering,
@@ -2125,6 +2253,15 @@
// We do not check PARAMETER_EXPOSE_CAPTION_FORMATS here, and we do it in setParameters
// instead. Checking that the value is a List is insufficient to catch wrong parameter
// value types.
+ int sumOfParameterNameLengths =
+ expectedTypeByParameterName.keySet().stream()
+ .map(String::length)
+ .reduce(0, Integer::sum);
+ sumOfParameterNameLengths += PARAMETER_EXPOSE_CAPTION_FORMATS.length();
+ // Add space for any required separators.
+ MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH =
+ sumOfParameterNameLengths + expectedTypeByParameterName.size();
+
EXPECTED_TYPE_BY_PARAMETER_NAME = Collections.unmodifiableMap(expectedTypeByParameterName);
}
}
diff --git a/apex/media/framework/jni/android_media_MediaParserJNI.cpp b/apex/media/framework/jni/android_media_MediaParserJNI.cpp
new file mode 100644
index 0000000..7fc4628
--- /dev/null
+++ b/apex/media/framework/jni/android_media_MediaParserJNI.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <jni.h>
+#include <media/MediaMetrics.h>
+
+#define JNI_FUNCTION(RETURN_TYPE, NAME, ...) \
+ extern "C" { \
+ JNIEXPORT RETURN_TYPE Java_android_media_MediaParser_##NAME(JNIEnv* env, jobject thiz, \
+ ##__VA_ARGS__); \
+ } \
+ JNIEXPORT RETURN_TYPE Java_android_media_MediaParser_##NAME(JNIEnv* env, jobject thiz, \
+ ##__VA_ARGS__)
+
+namespace {
+
+constexpr char kMediaMetricsKey[] = "mediaparser";
+
+constexpr char kAttributeParserName[] = "android.media.mediaparser.parserName";
+constexpr char kAttributeCreatedByName[] = "android.media.mediaparser.createdByName";
+constexpr char kAttributeParserPool[] = "android.media.mediaparser.parserPool";
+constexpr char kAttributeLastException[] = "android.media.mediaparser.lastException";
+constexpr char kAttributeResourceByteCount[] = "android.media.mediaparser.resourceByteCount";
+constexpr char kAttributeDurationMillis[] = "android.media.mediaparser.durationMillis";
+constexpr char kAttributeTrackMimeTypes[] = "android.media.mediaparser.trackMimeTypes";
+constexpr char kAttributeTrackCodecs[] = "android.media.mediaparser.trackCodecs";
+constexpr char kAttributeAlteredParameters[] = "android.media.mediaparser.alteredParameters";
+constexpr char kAttributeVideoWidth[] = "android.media.mediaparser.videoWidth";
+constexpr char kAttributeVideoHeight[] = "android.media.mediaparser.videoHeight";
+
+// Util class to handle string resource management.
+class JstringHandle {
+public:
+ JstringHandle(JNIEnv* env, jstring value) : mEnv(env), mJstringValue(value) {
+ mCstringValue = env->GetStringUTFChars(value, /* isCopy= */ nullptr);
+ }
+
+ ~JstringHandle() {
+ if (mCstringValue != nullptr) {
+ mEnv->ReleaseStringUTFChars(mJstringValue, mCstringValue);
+ }
+ }
+
+ [[nodiscard]] const char* value() const {
+ return mCstringValue != nullptr ? mCstringValue : "";
+ }
+
+ JNIEnv* mEnv;
+ jstring mJstringValue;
+ const char* mCstringValue;
+};
+
+} // namespace
+
+JNI_FUNCTION(void, nativeSubmitMetrics, jstring parserNameJstring, jboolean createdByName,
+ jstring parserPoolJstring, jstring lastExceptionJstring, jlong resourceByteCount,
+ jlong durationMillis, jstring trackMimeTypesJstring, jstring trackCodecsJstring,
+ jstring alteredParameters, jint videoWidth, jint videoHeight) {
+ mediametrics_handle_t item(mediametrics_create(kMediaMetricsKey));
+ mediametrics_setCString(item, kAttributeParserName,
+ JstringHandle(env, parserNameJstring).value());
+ mediametrics_setInt32(item, kAttributeCreatedByName, createdByName ? 1 : 0);
+ mediametrics_setCString(item, kAttributeParserPool,
+ JstringHandle(env, parserPoolJstring).value());
+ mediametrics_setCString(item, kAttributeLastException,
+ JstringHandle(env, lastExceptionJstring).value());
+ mediametrics_setInt64(item, kAttributeResourceByteCount, resourceByteCount);
+ mediametrics_setInt64(item, kAttributeDurationMillis, durationMillis);
+ mediametrics_setCString(item, kAttributeTrackMimeTypes,
+ JstringHandle(env, trackMimeTypesJstring).value());
+ mediametrics_setCString(item, kAttributeTrackCodecs,
+ JstringHandle(env, trackCodecsJstring).value());
+ mediametrics_setCString(item, kAttributeAlteredParameters,
+ JstringHandle(env, alteredParameters).value());
+ mediametrics_setInt32(item, kAttributeVideoWidth, videoWidth);
+ mediametrics_setInt32(item, kAttributeVideoHeight, videoHeight);
+ mediametrics_selfRecord(item);
+ mediametrics_delete(item);
+}
diff --git a/apex/permission/Android.bp b/apex/permission/Android.bp
index 71a52bb..e30df05 100644
--- a/apex/permission/Android.bp
+++ b/apex/permission/Android.bp
@@ -21,7 +21,7 @@
apex_defaults {
name: "com.android.permission-defaults",
updatable: true,
- min_sdk_version: "R",
+ min_sdk_version: "30",
key: "com.android.permission.key",
certificate: ":com.android.permission.certificate",
java_libs: [
diff --git a/apex/permission/apex_manifest.json b/apex/permission/apex_manifest.json
index 7960598..eb2767f 100644
--- a/apex/permission/apex_manifest.json
+++ b/apex/permission/apex_manifest.json
@@ -1,4 +1,4 @@
{
"name": "com.android.permission",
- "version": 300000000
+ "version": 309999900
}
diff --git a/apex/permission/framework/Android.bp b/apex/permission/framework/Android.bp
index be553feb..c0560f6 100644
--- a/apex/permission/framework/Android.bp
+++ b/apex/permission/framework/Android.bp
@@ -25,14 +25,8 @@
name: "framework-permission",
defaults: ["framework-module-defaults"],
- // Allow access to the stubs from anywhere.
- visibility: ["//visibility:public"],
-
// Restrict access to implementation library.
- impl_library_visibility: [
- "//visibility:override", // Ignore the visibility property.
- "//frameworks/base/apex/permission:__subpackages__",
- ],
+ impl_library_visibility: ["//frameworks/base/apex/permission:__subpackages__"],
srcs: [
":framework-permission-sources",
diff --git a/apex/permission/service/Android.bp b/apex/permission/service/Android.bp
index 7f31879..b7d8433 100644
--- a/apex/permission/service/Android.bp
+++ b/apex/permission/service/Android.bp
@@ -23,15 +23,7 @@
java_sdk_library {
name: "service-permission",
defaults: ["framework-system-server-module-defaults"],
- visibility: [
- "//frameworks/base/services/core",
- "//frameworks/base/apex/permission",
- "//frameworks/base/apex/permission/testing",
- "//frameworks/base/apex/permission/tests",
- "//frameworks/base/services/tests/mockingservicestests",
- ],
impl_library_visibility: [
- "//visibility:override",
"//frameworks/base/apex/permission/tests",
"//frameworks/base/services/tests/mockingservicestests",
"//frameworks/base/services/tests/servicestests",
diff --git a/apex/statsd/.clang-format b/apex/statsd/.clang-format
deleted file mode 100644
index cead3a0..0000000
--- a/apex/statsd/.clang-format
+++ /dev/null
@@ -1,17 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: false
-AllowShortLoopsOnASingleLine: true
-BinPackArguments: true
-BinPackParameters: true
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-ContinuationIndentWidth: 8
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-AccessModifierOffset: -4
-IncludeCategories:
- - Regex: '^"Log\.h"'
- Priority: -1
diff --git a/apex/statsd/Android.bp b/apex/statsd/Android.bp
deleted file mode 100644
index e75fa88..0000000
--- a/apex/statsd/Android.bp
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-apex {
- name: "com.android.os.statsd",
- defaults: ["com.android.os.statsd-defaults"],
- manifest: "apex_manifest.json",
-}
-
-apex_defaults {
- native_shared_libs: [
- "libstats_jni",
- "libstatspull",
- "libstatssocket",
- ],
- binaries: ["statsd"],
- java_libs: [
- "framework-statsd",
- "service-statsd",
- ],
- compile_multilib: "both",
- prebuilts: ["com.android.os.statsd.init.rc"],
- name: "com.android.os.statsd-defaults",
- updatable: true,
- min_sdk_version: "R",
- key: "com.android.os.statsd.key",
- certificate: ":com.android.os.statsd.certificate",
-}
-
-apex_key {
- name: "com.android.os.statsd.key",
- public_key: "com.android.os.statsd.avbpubkey",
- private_key: "com.android.os.statsd.pem",
-}
-
-android_app_certificate {
- name: "com.android.os.statsd.certificate",
- // This will use com.android.os.statsd.x509.pem (the cert) and
- // com.android.os.statsd.pk8 (the private key)
- certificate: "com.android.os.statsd",
-}
-
-prebuilt_etc {
- name: "com.android.os.statsd.init.rc",
- src: "statsd.rc",
- filename: "init.rc",
- installable: false,
-}
-
-// JNI library for StatsLog.write
-cc_library_shared {
- name: "libstats_jni",
- srcs: ["jni/**/*.cpp"],
- header_libs: ["libnativehelper_header_only"],
- shared_libs: [
- "liblog", // Has a stable abi - should not be copied into apex.
- "libstatssocket",
- ],
- stl: "libc++_static",
- cflags: [
- "-Wall",
- "-Werror",
- "-Wextra",
- "-Wno-unused-parameter",
- ],
- apex_available: [
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
-}
diff --git a/apex/statsd/OWNERS b/apex/statsd/OWNERS
deleted file mode 100644
index bed9600..0000000
--- a/apex/statsd/OWNERS
+++ /dev/null
@@ -1,9 +0,0 @@
-jeffreyhuang@google.com
-joeo@google.com
-jtnguyen@google.com
-muhammadq@google.com
-ruchirr@google.com
-singhtejinder@google.com
-tsaichristine@google.com
-yaochen@google.com
-yro@google.com
\ No newline at end of file
diff --git a/apex/statsd/TEST_MAPPING b/apex/statsd/TEST_MAPPING
deleted file mode 100644
index 93f1087..0000000
--- a/apex/statsd/TEST_MAPPING
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "presubmit" : [
- {
- "name" : "FrameworkStatsdTest"
- },
- {
- "name" : "LibStatsPullTests"
- }
- ]
-}
diff --git a/apex/statsd/aidl/Android.bp b/apex/statsd/aidl/Android.bp
deleted file mode 100644
index 04339e6..0000000
--- a/apex/statsd/aidl/Android.bp
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-filegroup {
- name: "framework-statsd-aidl-sources",
- srcs: ["**/*.aidl"],
-}
-
-aidl_interface {
- name: "statsd-aidl",
- unstable: true,
- srcs: [
- "android/os/IPendingIntentRef.aidl",
- "android/os/IPullAtomCallback.aidl",
- "android/os/IPullAtomResultReceiver.aidl",
- "android/os/IStatsCompanionService.aidl",
- "android/os/IStatsd.aidl",
- "android/os/StatsDimensionsValueParcel.aidl",
- "android/util/StatsEventParcel.aidl",
- ],
- backend: {
- java: {
- enabled: false, // framework-statsd and service-statsd use framework-statsd-aidl-sources
- },
- cpp: {
- enabled: false,
- },
- ndk: {
- enabled: true,
- apex_available: [
- // TODO(b/145923087): Remove this once statsd binary is in apex
- "//apex_available:platform",
-
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
- },
- }
-}
diff --git a/apex/statsd/aidl/android/os/IPendingIntentRef.aidl b/apex/statsd/aidl/android/os/IPendingIntentRef.aidl
deleted file mode 100644
index 000a699..0000000
--- a/apex/statsd/aidl/android/os/IPendingIntentRef.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.os.StatsDimensionsValueParcel;
-
-/**
- * Binder interface to hold a PendingIntent for StatsCompanionService.
- * {@hide}
- */
-interface IPendingIntentRef {
-
- /**
- * Sends a broadcast to the specified PendingIntent that it should getData now.
- * This should be only called from StatsCompanionService.
- */
- oneway void sendDataBroadcast(long lastReportTimeNs);
-
- /**
- * Send a broadcast to the specified PendingIntent notifying it that the list of active configs
- * has changed. This should be only called from StatsCompanionService.
- */
- oneway void sendActiveConfigsChangedBroadcast(in long[] configIds);
-
- /**
- * Send a broadcast to the specified PendingIntent, along with the other information
- * specified. This should only be called from StatsCompanionService.
- */
- oneway void sendSubscriberBroadcast(long configUid, long configId, long subscriptionId,
- long subscriptionRuleId, in String[] cookies,
- in StatsDimensionsValueParcel dimensionsValueParcel);
-}
diff --git a/apex/statsd/aidl/android/os/IPullAtomCallback.aidl b/apex/statsd/aidl/android/os/IPullAtomCallback.aidl
deleted file mode 100644
index ff0b97b..0000000
--- a/apex/statsd/aidl/android/os/IPullAtomCallback.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.os.IPullAtomResultReceiver;
-
-/**
- * Binder interface to pull atoms for the stats service.
- * {@hide}
- */
-interface IPullAtomCallback {
- /**
- * Initiate a request for a pull for an atom.
- */
- oneway void onPullAtom(int atomTag, IPullAtomResultReceiver resultReceiver);
-
-}
diff --git a/apex/statsd/aidl/android/os/IPullAtomResultReceiver.aidl b/apex/statsd/aidl/android/os/IPullAtomResultReceiver.aidl
deleted file mode 100644
index 00d026e..0000000
--- a/apex/statsd/aidl/android/os/IPullAtomResultReceiver.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.util.StatsEventParcel;
-
-/**
- * Binder interface to pull atoms for the stats service.
- * {@hide}
- */
-interface IPullAtomResultReceiver {
-
- /**
- * Indicate that a pull request for an atom is complete.
- */
- oneway void pullFinished(int atomTag, boolean success, in StatsEventParcel[] output);
-
-}
diff --git a/apex/statsd/aidl/android/os/IStatsCompanionService.aidl b/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
deleted file mode 100644
index 5cdb324..0000000
--- a/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-/**
- * Binder interface to communicate with the Java-based statistics service helper.
- * {@hide}
- */
-interface IStatsCompanionService {
- /**
- * Tell statscompanion that stastd is up and running.
- */
- oneway void statsdReady();
-
- /**
- * Register an alarm for anomaly detection to fire at the given timestamp (ms since epoch).
- * If anomaly alarm had already been registered, it will be replaced with the new timestamp.
- * Uses AlarmManager.set API, so if the timestamp is in the past, alarm fires immediately, and
- * alarm is inexact.
- */
- oneway void setAnomalyAlarm(long timestampMs);
-
- /** Cancel any anomaly detection alarm. */
- oneway void cancelAnomalyAlarm();
-
- /**
- * Register a repeating alarm for pulling to fire at the given timestamp and every
- * intervalMs thereafter (in ms since epoch).
- * If polling alarm had already been registered, it will be replaced by new one.
- * Uses AlarmManager.setRepeating API, so if the timestamp is in past, alarm fires immediately,
- * and alarm is inexact.
- */
- oneway void setPullingAlarm(long nextPullTimeMs);
-
- /** Cancel any repeating pulling alarm. */
- oneway void cancelPullingAlarm();
-
- /**
- * Register an alarm when we want to trigger subscribers at the given
- * timestamp (in ms since epoch).
- * If an alarm had already been registered, it will be replaced by new one.
- */
- oneway void setAlarmForSubscriberTriggering(long timestampMs);
-
- /** Cancel any alarm for the purpose of subscriber triggering. */
- oneway void cancelAlarmForSubscriberTriggering();
-
- /**
- * Ask StatsCompanionService if the given permission is allowed for a particular process
- * and user ID. statsd is incapable of doing this check itself because checkCallingPermission
- * is not currently supported by libbinder_ndk.
- */
- boolean checkPermission(String permission, int pid, int uid);
-}
diff --git a/apex/statsd/aidl/android/os/IStatsManagerService.aidl b/apex/statsd/aidl/android/os/IStatsManagerService.aidl
deleted file mode 100644
index b59a97e..0000000
--- a/apex/statsd/aidl/android/os/IStatsManagerService.aidl
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.app.PendingIntent;
-import android.os.IPullAtomCallback;
-
-/**
- * Binder interface to communicate with the Java-based statistics service helper.
- * Contains parcelable objects available only in Java.
- * {@hide}
- */
-interface IStatsManagerService {
-
- /**
- * Registers the given pending intent for this config key. This intent is invoked when the
- * memory consumed by the metrics for this configuration approach the pre-defined limits. There
- * can be at most one listener per config key.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void setDataFetchOperation(long configId, in PendingIntent pendingIntent,
- in String packageName);
-
- /**
- * Removes the data fetch operation for the specified configuration.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void removeDataFetchOperation(long configId, in String packageName);
-
- /**
- * Registers the given pending intent for this packagename. This intent is invoked when the
- * active status of any of the configs sent by this package changes and will contain a list of
- * config ids that are currently active. It also returns the list of configs that are currently
- * active. There can be at most one active configs changed listener per package.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- long[] setActiveConfigsChangedOperation(in PendingIntent pendingIntent, in String packageName);
-
- /**
- * Removes the active configs changed operation for the specified package name.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void removeActiveConfigsChangedOperation(in String packageName);
-
- /**
- * Set the PendingIntent to be used when broadcasting subscriber
- * information to the given subscriberId within the given config.
- *
- * Suppose that the calling uid has added a config with key configKey, and that in this config
- * it is specified that when a particular anomaly is detected, a broadcast should be sent to
- * a BroadcastSubscriber with id subscriberId. This function links the given pendingIntent with
- * that subscriberId (for that config), so that this pendingIntent is used to send the broadcast
- * when the anomaly is detected.
- *
- * This function can only be called by the owner (uid) of the config. It must be called each
- * time statsd starts. Later calls overwrite previous calls; only one PendingIntent is stored.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void setBroadcastSubscriber(long configKey, long subscriberId, in PendingIntent pendingIntent,
- in String packageName);
-
- /**
- * Undoes setBroadcastSubscriber() for the (configKey, subscriberId) pair.
- * Any broadcasts associated with subscriberId will henceforth not be sent.
- * No-op if this (configKey, subscriberId) pair was not associated with an PendingIntent.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void unsetBroadcastSubscriber(long configKey, long subscriberId, in String packageName);
-
- /**
- * Returns the most recently registered experiment IDs.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- long[] getRegisteredExperimentIds();
-
- /**
- * Fetches metadata across statsd. Returns byte array representing wire-encoded proto.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- byte[] getMetadata(in String packageName);
-
- /**
- * Fetches data for the specified configuration key. Returns a byte array representing proto
- * wire-encoded of ConfigMetricsReportList.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- byte[] getData(in long key, in String packageName);
-
- /**
- * Sets a configuration with the specified config id and subscribes to updates for this
- * configuration id. Broadcasts will be sent if this configuration needs to be collected.
- * The configuration must be a wire-encoded StatsdConfig. The receiver for this data is
- * registered in a separate function.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void addConfiguration(in long configId, in byte[] config, in String packageName);
-
- /**
- * Removes the configuration with the matching config id. No-op if this config id does not
- * exist.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void removeConfiguration(in long configId, in String packageName);
-
- /** Tell StatsManagerService to register a puller for the given atom tag with statsd. */
- oneway void registerPullAtomCallback(int atomTag, long coolDownMillis, long timeoutMillis,
- in int[] additiveFields, IPullAtomCallback pullerCallback);
-
- /** Tell StatsManagerService to unregister the pulller for the given atom tag from statsd. */
- oneway void unregisterPullAtomCallback(int atomTag);
-}
diff --git a/apex/statsd/aidl/android/os/IStatsd.aidl b/apex/statsd/aidl/android/os/IStatsd.aidl
deleted file mode 100644
index 0d3f420..0000000
--- a/apex/statsd/aidl/android/os/IStatsd.aidl
+++ /dev/null
@@ -1,237 +0,0 @@
-/**
- * Copyright (c) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.os.IPendingIntentRef;
-import android.os.IPullAtomCallback;
-import android.os.ParcelFileDescriptor;
-
-/**
- * Binder interface to communicate with the statistics management service.
- * {@hide}
- */
-interface IStatsd {
- /**
- * Tell the stats daemon that the android system server is up and running.
- */
- oneway void systemRunning();
-
- /**
- * Tell the stats daemon that the android system has finished booting.
- */
- oneway void bootCompleted();
-
- /**
- * Tell the stats daemon that the StatsCompanionService is up and running.
- * Two-way binder call so that caller knows message received.
- */
- void statsCompanionReady();
-
- /**
- * Tells statsd that an anomaly may have occurred, so statsd can check whether this is so and
- * act accordingly.
- * Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
- */
- void informAnomalyAlarmFired();
-
- /**
- * Tells statsd that it is time to poll some stats. Statsd will be responsible for determing
- * what stats to poll and initiating the polling.
- * Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
- */
- void informPollAlarmFired();
-
- /**
- * Tells statsd that it is time to handle periodic alarms. Statsd will be responsible for
- * determing what alarm subscriber to trigger.
- * Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
- */
- void informAlarmForSubscriberTriggeringFired();
-
- /**
- * Tells statsd that the device is about to shutdown.
- */
- void informDeviceShutdown();
-
- /**
- * Inform statsd about a file descriptor for a pipe through which we will pipe version
- * and package information for each uid.
- * Versions and package information are supplied via UidData proto where info for each app
- * is captured in its own element of a repeated ApplicationInfo message.
- */
- oneway void informAllUidData(in ParcelFileDescriptor fd);
-
- /**
- * Inform statsd what the uid, version, version_string, and installer are for one app that was
- * updated.
- */
- oneway void informOnePackage(in String app, in int uid, in long version,
- in String version_string, in String installer);
-
- /**
- * Inform stats that an app was removed.
- */
- oneway void informOnePackageRemoved(in String app, in int uid);
-
- /**
- * Fetches data for the specified configuration key. Returns a byte array representing proto
- * wire-encoded of ConfigMetricsReportList.
- *
- * Requires Manifest.permission.DUMP.
- */
- byte[] getData(in long key, int callingUid);
-
- /**
- * Fetches metadata across statsd. Returns byte array representing wire-encoded proto.
- *
- * Requires Manifest.permission.DUMP.
- */
- byte[] getMetadata();
-
- /**
- * Sets a configuration with the specified config id and subscribes to updates for this
- * configuration key. Broadcasts will be sent if this configuration needs to be collected.
- * The configuration must be a wire-encoded StatsdConfig. The receiver for this data is
- * registered in a separate function.
- *
- * Requires Manifest.permission.DUMP.
- */
- void addConfiguration(in long configId, in byte[] config, in int callingUid);
-
- /**
- * Registers the given pending intent for this config key. This intent is invoked when the
- * memory consumed by the metrics for this configuration approach the pre-defined limits. There
- * can be at most one listener per config key.
- *
- * Requires Manifest.permission.DUMP.
- */
- void setDataFetchOperation(long configId, in IPendingIntentRef pendingIntentRef,
- int callingUid);
-
- /**
- * Removes the data fetch operation for the specified configuration.
- *
- * Requires Manifest.permission.DUMP.
- */
- void removeDataFetchOperation(long configId, int callingUid);
-
- /**
- * Registers the given pending intent for this packagename. This intent is invoked when the
- * active status of any of the configs sent by this package changes and will contain a list of
- * config ids that are currently active. It also returns the list of configs that are currently
- * active. There can be at most one active configs changed listener per package.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- long[] setActiveConfigsChangedOperation(in IPendingIntentRef pendingIntentRef, int callingUid);
-
- /**
- * Removes the active configs changed operation for the specified package name.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void removeActiveConfigsChangedOperation(int callingUid);
-
- /**
- * Removes the configuration with the matching config id. No-op if this config id does not
- * exist.
- *
- * Requires Manifest.permission.DUMP.
- */
- void removeConfiguration(in long configId, in int callingUid);
-
- /**
- * Set the PendingIntentRef to be used when broadcasting subscriber
- * information to the given subscriberId within the given config.
- *
- * Suppose that the calling uid has added a config with key configId, and that in this config
- * it is specified that when a particular anomaly is detected, a broadcast should be sent to
- * a BroadcastSubscriber with id subscriberId. This function links the given pendingIntent with
- * that subscriberId (for that config), so that this pendingIntent is used to send the broadcast
- * when the anomaly is detected.
- *
- * This function can only be called by the owner (uid) of the config. It must be called each
- * time statsd starts. Later calls overwrite previous calls; only one pendingIntent is stored.
- *
- * Requires Manifest.permission.DUMP.
- */
- void setBroadcastSubscriber(long configId, long subscriberId, in IPendingIntentRef pir,
- int callingUid);
-
- /**
- * Undoes setBroadcastSubscriber() for the (configId, subscriberId) pair.
- * Any broadcasts associated with subscriberId will henceforth not be sent.
- * No-op if this (configKey, subscriberId) pair was not associated with an PendingIntentRef.
- *
- * Requires Manifest.permission.DUMP.
- */
- void unsetBroadcastSubscriber(long configId, long subscriberId, int callingUid);
-
- /**
- * Tell the stats daemon that all the pullers registered during boot have been sent.
- */
- oneway void allPullersFromBootRegistered();
-
- /**
- * Registers a puller callback function that, when invoked, pulls the data
- * for the specified atom tag.
- */
- oneway void registerPullAtomCallback(int uid, int atomTag, long coolDownMillis,
- long timeoutMillis,in int[] additiveFields,
- IPullAtomCallback pullerCallback);
-
- /**
- * Registers a puller callback function that, when invoked, pulls the data
- * for the specified atom tag.
- *
- * Enforces the REGISTER_STATS_PULL_ATOM permission.
- */
- oneway void registerNativePullAtomCallback(int atomTag, long coolDownMillis, long timeoutMillis,
- in int[] additiveFields, IPullAtomCallback pullerCallback);
-
- /**
- * Unregisters any pullAtomCallback for the given uid/atom.
- */
- oneway void unregisterPullAtomCallback(int uid, int atomTag);
-
- /**
- * Unregisters any pullAtomCallback for the given atom + caller.
- *
- * Enforces the REGISTER_STATS_PULL_ATOM permission.
- */
- oneway void unregisterNativePullAtomCallback(int atomTag);
-
- /**
- * The install requires staging.
- */
- const int FLAG_REQUIRE_STAGING = 0x01;
-
- /**
- * Rollback is enabled with this install.
- */
- const int FLAG_ROLLBACK_ENABLED = 0x02;
-
- /**
- * Requires low latency monitoring.
- */
- const int FLAG_REQUIRE_LOW_LATENCY_MONITOR = 0x04;
-
- /**
- * Returns the most recently registered experiment IDs.
- */
- long[] getRegisteredExperimentIds();
-}
diff --git a/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl b/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl
deleted file mode 100644
index 05f78d0..0000000
--- a/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-package android.os;
-
-/**
- * @hide
- */
-parcelable StatsDimensionsValueParcel {
- // Field equals atomTag for top level StatsDimensionsValueParcels or
- // positions in depth (1-indexed) for lower level parcels.
- int field;
-
- // Indicator for which type of value is stored. Should be set to one
- // of the constants in StatsDimensionsValue.java.
- int valueType;
-
- String stringValue;
- int intValue;
- long longValue;
- boolean boolValue;
- float floatValue;
- StatsDimensionsValueParcel[] tupleValue;
-}
diff --git a/apex/statsd/aidl/android/util/StatsEventParcel.aidl b/apex/statsd/aidl/android/util/StatsEventParcel.aidl
deleted file mode 100644
index add8bfb..0000000
--- a/apex/statsd/aidl/android/util/StatsEventParcel.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.util;
-
-/**
- * @hide
- */
-parcelable StatsEventParcel {
- byte[] buffer;
-}
diff --git a/apex/statsd/apex_manifest.json b/apex/statsd/apex_manifest.json
deleted file mode 100644
index e2972e7..0000000
--- a/apex/statsd/apex_manifest.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "com.android.os.statsd",
- "version": 300000000
-}
-
diff --git a/apex/statsd/com.android.os.statsd.avbpubkey b/apex/statsd/com.android.os.statsd.avbpubkey
deleted file mode 100644
index d78af8b..0000000
--- a/apex/statsd/com.android.os.statsd.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/statsd/com.android.os.statsd.pem b/apex/statsd/com.android.os.statsd.pem
deleted file mode 100644
index 558e17f..0000000
--- a/apex/statsd/com.android.os.statsd.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKgIBAAKCAgEA893bbpkivKEiNgfknYBSlzC0csaKU/ddBm5Pb4ZFuab+LQSR
-9DDc5JrsmxyrsrvuwL/zAtMbkyYWzEiUxJtx/w0bw8rC90GoPRSCmxyI0ZK8FuPy
-IAQ7UeNfTWZ485mAUaTSasGIfQ3DY4F0P+aUSijeG3NUY02nALHDMqJX7lXR+mL1
-DUYDg05KB0jxQwlYqBeujTPPiAzEqm3PlBoHuan8/qgK2wdQMTVg/fieUD3lupmV
-Wj2dRZgqfBPA16ZbV4Uo0j0bZSf+fQLiXlU2VJGb5i/FQfjLqMKGABDI0MgK7Sc2
-m4ySpV4g4XKDv/vw6Dw4kwWC7mATEVAkH+q6V7uiZeN6a7w30UMtPI8fPaUvAP3L
-VBjCBIv/3m+CKkWcNxOZ3sQBQl5bS05dxcfiVsBvBLYbvQgC+Wy0Sc3b+1pXFT/E
-uAsbZ4CyVsi1+PAdx3h5e2QAyNCXgZDOcvTUyxY6JLTE0LOVHmI4fJEujBex//Oz
-PCRHvC8K+KiljyQWf/NYrLSD3QGYAjVMtQh7yu2yhzWzgBUxyhuv3rY4ATXsN3bJ
-wW4w7/L/RSLSW5+lp/NoJOD9utbsKTyGMHOY6K8JLOmhv3ORoAEmLYlFTI+FqBi9
-AH1HQEKCyh8Z/bYHLUzGWl6FqAMtcnuintv40BbKyt0/D1ItdbSNKmOZ5rkCAwEA
-AQKCAgAY7ll8mRNADYkd1Pi+UVwgMM6B3WJO6z8LZUOhtyxxqmzZ1VnGiShMBrqh
-sPCsuSHTeswxQbvT81TpVZI/91RUKtbn0VbVSFUWyX4AtY4XPtUT0gHy2/vkh0Y6
-93ruDIdd0Wfhmh+GCV4sUhO8ZKpMWpk6XTQHYuzr2UCHcKlkqElrO6qpzLqXNe3D
-iOWBYPc7WBB0RxO0aPnCIq/SCEc55/MBZdSWR80e+sILtNsagPl3djQaoanub3wI
-a0yPv2YfMHHX7H9cfBY8WYsi8bs4MhqqEcAs2m6XtitU3mJpVcooLJYcmOZ1GYZr
-BfYKLouWcnGmNi4IiLHqVzMaQDkEhAZsRaAXCkoVVrFBedLlmLPpiUIQlINF4vxe
-3IcekTKWyMzkU6h+K8T15MU5mLSqeL2Gji1JIwKJno51FZ9uc++pUJVtfYQmNny8
-8RKvQ1hv/S5yLQKgN+VkNbaWlUoMP73dtUe3m/At71/2Dj7xB0KtcgT1lEMrM1GR
-oynJAJLz/d0n5RUUREwkZZMcA4fQVC7Db6vpK69jPiQMShpZ3JKCEjfYLUuN0slt
-FPhjiR175E0vTRuLoIj4kXNwLLswH0c9zqrKM2S92SCxAV3E4JJGKhUZalvT9s1g
-LrPhMCl6CsOES98T87d3RyAIK0iVRCnRUG3bc+8rzyRd4fzkAQKCAQEA/UjmCSm3
-H46t/1w7YBZPew7SFQOAJe81iDzbonc3fNPD2R8lxtD3MwdvrQ5f9fhT4+uveWNr
-dyBX7ppnissyM3LZRN+7BdeIVVeIPVen6Ou9W2i7q18ZoQx9IpRcZEw5tGJFZaGx
-EmyPN4i1K0ccUkGbBvbXXQ/tcG3wElRpBAc5/TQ8vrpUgHll2/MbYhowx6P9uHv5
-thoyG98X+7Fbg8ikzw5GtyuedXfyX1CpJ7yUQVS2PEaOMXOkZdx2bbWRAYYCpsqB
-dMmjs2PsFhZHu6CpLhlocHbfUiRztCUCaMZJPQXFSVmy8QDMvZEdVLvad9Poi8ny
-lmHVRgxaNbAtIQKCAQEA9nscqRaaO7hIX9bOUxcDbI0486Ws4H0hAFApIN+6/LP4
-hkxey3xWArTYWrvSG1d5GkJAdn99ayWzo2PevmJlrhIJiO1QqYBAk+87cnhwSCmB
-kb0sGkNWcc/xNRy7eqdhyCmVhaUnIbORee+cD6qiu/l2BAclTf2ZARFOGXjhQkvt
-cDbc/9ZR467ceXbiTIU34Be4xnNAY1mo59jvwl9eqxgpefYTqPhcZ7OmlDli77Hd
-XuRfuxLZCscv7A9M5Enc2zwOEP5VwRNwYzYtMm2Yh9CQZxNWC7JVh1Gw5MPFzsGl
-sgEdb4WGneN6PPLQHK7NF0f7wYSNnF0i3XSME9MumQKCAQEA0qMbWydr+TyJC0LC
-xigHtUkgAQXGPsXuePxTk4sdhBwAVcKHgg4qZi+a+gpoV4BLE9LfPU4nAwzM08to
-rI5Lk2nBsnt1Z2hVItQGoy0QoK3b7fbti5ktETf3oRhMtcSGgLLxD5ImVjId8Isq
-T3F15hpVOLdzZxtl1Qg4jKXSJ91yplYY5mzC9Yz/3qkQbsdlJcIFsLS5eG3UmkUw
-Bsr6VmA4X1F6Eb6eqwYzdHz6D+fOS36NhxcODaYkY+myO46xptixv8/NVTiTgQ5q
-OfwRb8Iur/3FUzIoioFyD7Bvjn7ITY1NArEsFS0bF9Nk1yDakKiUThyGN/Xojbac
-FuYKwQKCAQEAxOWJ+qU8phJLdowBHC0ZJiEWasRhep9auoZOpJ01IWOfV6EwZLs5
-dkYDQ1Agwoi5DDn6hu7HQM3IV/CS4mF2OnzcMw7ozc7PR53nTkVZ5LuLbuHAlmZO
-avKjDDucpJmLqjtV34IT5X8t6kt3zqgQAbuBBCy1Jz07ebfaPMzsnWpMDcU1/AW4
-OvrX0wweMOSGwzQP/i/ZMsRQAo2w0gQfeuv9Thk+kU99ebXwjx3co//hCEnFE4s1
-6L8/0AJU+VTr4hJyZi7WUDt4HzkLF+qm22/Hux+eMA/Q9R1UAxtFLCpTdAQiAJGY
-/Q3X+1I434DgAwYU3f1Gpq9cB65vq/KamQKCAQEAjIub5wde/ttHlLALvnOXrbqe
-nUIfWHExMzhul/rkr8fFEJwij2nZUuN2EWUGzBWQQoNXw5QKHLZyPsyFUOa/P2BS
-osnffAa+sumL4k36E71xFdTVV5ExyTXZVB49sPmUpivP9gEucFFqDHKjGsF45dBF
-+DZdykLUIv+/jQUzXGkZ5Wv/r52YUNho4EZdwnlJ2so7cxnsYnjW+c1nlp17tkq5
-DfwktkeD9iFzlaZ66vLoO44luaBm+lC3xM2sHinOTwbk0gvhJAIoLfkOYhpmGc8A
-4W/E1OHfVz6xqVDsMBFhRbQpHNkf8XZNqkIoqHVMTaMOJJlM+lb0+A9B8Bm/XA==
------END RSA PRIVATE KEY-----
diff --git a/apex/statsd/com.android.os.statsd.pk8 b/apex/statsd/com.android.os.statsd.pk8
deleted file mode 100644
index 49910f8..0000000
--- a/apex/statsd/com.android.os.statsd.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/statsd/com.android.os.statsd.x509.pem b/apex/statsd/com.android.os.statsd.x509.pem
deleted file mode 100644
index e7b16b2..0000000
--- a/apex/statsd/com.android.os.statsd.x509.pem
+++ /dev/null
@@ -1,30 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFDTCCAvWgAwIBAgIUCnta1LAl5fMMLLQx//4zWz9A2A8wDQYJKoZIhvcNAQEL
-BQAwFTETMBEGA1UECgwKR29vZ2xlIExMQzAgFw0xOTA4MTIyMjM5MzBaGA80NzU3
-MDcwODIyMzkzMFowFTETMBEGA1UECgwKR29vZ2xlIExMQzCCAiIwDQYJKoZIhvcN
-AQEBBQADggIPADCCAgoCggIBAOranWZ19jkXCF9WIlXv01tUUvLKMHWKV7X9Earw
-cL7/aax0pFbNJutgyBUiOszbR+0T7quZxz6jACu+6y7iaMJnvMluZsfTi+p2UvQt
-y6Ql7ZUOQ7bVluCFIW5hZ+8d9RrLmZdvX1r4YfF6HufDBkAbj+os+y6407OezJAV
-8EATpemc9gsCC4RJZpwzTs1RUXMD4UoNrLZAE8+7iaJZeBxmz0MAPj92pYc9M7/d
-xInzYvOR08/uEpHt8jlMdVgSQS/FaRlIOIqcGBk3cjkjDlpVATQ4Hyjy+IPQPjTD
-bJUmDJiYeBCyY/pYZQvTQjl8s+fvykTsF9Lfb+E+PhZ0+N8pRi7sUSpisZHSiqaN
-W3oxYWc0YQSuzygHHog8HH/azHX5L805g/+Rwfb/cUF9eJgjq0vrkFnsz4UKgKNV
-hHL90mfqpbc2UvJ8VY8BvIjbsHQ77LrBKlqI9VMPorttpTOuwHHJPKsyN972F0Ul
-lRB6CwFE8csVGWXoNaDZWBv7xTDdbdirmlKDNueg9pw6ksYV2Is9Dv8PxmsZvb+4
-oftC/hb4X1Pudn01PPs9Tx44CwHuVLENUwlDEVzG5zNetsv9kAuCYt3VRVF+NYqj
-NAfLbxCKLe25wGzJrZUEJ1YrYIjpUbfwnttEad/9Pu13DAS7HZwn5vwqEKB/1LlT
-NSUXAgMBAAGjUzBRMB0GA1UdDgQWBBSKElkhJSbzgh8+iysye8SrkmJ62DAfBgNV
-HSMEGDAWgBSKElkhJSbzgh8+iysye8SrkmJ62DAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBCwUAA4ICAQANFGnc2wJBrFbh2nzhl06g4TjPKGRCw365vZ1A3T9O
-jXP0lToHDxB33TpKk6d7zszR1uPphQQxgzhSVZB/jx8q4kWSSoKoF9Dlx7h8rAt+
-2TM5DaBvxrwu5mqOALwQuF81wap1Pl2L2fFHvygCm8b+Ci4iS5vcr0axNnp1rK1b
-vUtRWY4mfxTjJYcgeCVUGskqTb+cCxQZ6Icno6VTKajT1FybRmD3KZJaUuLbNEN+
-IE4nGTMG2WZ5Hl2vR8JJp1sYYn8T3ElMAb0MSNFkqsfI+tToEwGsuJDgYEdtEnzf
-lTycQvn5NhrIZRRN3pqSyWpAU7p9mmyTK0PHMz2D/Rtfb7lE692vXzxCmZND51mc
-YXCCoanV6eZZ7Sbqzh60+5QV38hgFBst5l8CcFaWWSFK9nBWdzS5lhs9lmQ4aiYd
-IE0qsNZgMob+TTP1VW39hu4EDjNmOrKfimM9J2tcPZ5QP01DgETPvAsB7vn2Xz9J
-HGt5ntiSV4W2izDP8viQ1M5NvfdBaUhcnNsE6/sxfU0USRs2hrEp1oiqrv4p6V0P
-qOt7C2/YtJzkrxfsHZAxBUSRHa7LwtzgeiJDUivHn94VnAzSAH8MLx6CzDPQ8HWN
-NiZFxTKfMVyjEmbQ2PalHWB8pWtpdEh7X4rzaqhnLBTis3pGssASgo3ArLIYleAU
-+g==
------END CERTIFICATE-----
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
deleted file mode 100644
index d19faa97..0000000
--- a/apex/statsd/framework/Android.bp
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- default_visibility: [ ":__pkg__" ]
-}
-
-genrule {
- name: "statslog-statsd-java-gen",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --java $(out) --module statsd" +
- " --javaPackage com.android.internal.statsd --javaClass StatsdStatsLog",
- out: ["com/android/internal/statsd/StatsdStatsLog.java"],
-}
-
-java_library_static {
- name: "statslog-statsd",
- srcs: [
- ":statslog-statsd-java-gen",
- ],
- visibility: [
- "//cts/hostsidetests/statsd/apps:__subpackages__",
- ]
-}
-
-filegroup {
- name: "framework-statsd-sources",
- srcs: [
- "java/**/*.java",
- ":framework-statsd-aidl-sources",
- ":statslog-statsd-java-gen",
- ],
- visibility: [
- "//frameworks/base", // For the "global" stubs.
- "//frameworks/base/apex/statsd:__subpackages__",
- ],
-}
-java_sdk_library {
- name: "framework-statsd",
- defaults: ["framework-module-defaults"],
- installable: true,
-
- srcs: [
- ":framework-statsd-sources",
- ],
-
- permitted_packages: [
- "android.app",
- "android.os",
- "android.util",
- // From :statslog-statsd-java-gen
- "com.android.internal.statsd",
- ],
-
- api_packages: [
- "android.app",
- "android.os",
- "android.util",
- ],
-
- hostdex: true, // for hiddenapi check
-
- visibility: [
- "//frameworks/base", // Framework
- "//frameworks/base/apex/statsd:__subpackages__", // statsd apex
- "//frameworks/base/packages/Tethering", // Tethering
- "//frameworks/opt/net/wifi/service", // wifi service
- "//packages/providers/MediaProvider", // MediaProvider apk
- ],
-
- // Restrict access to implementation library.
- impl_library_visibility: [
- "//visibility:override", // Ignore the visibility property.
- "//frameworks/base/apex/statsd:__subpackages__", // statsd apex
- ],
-
- apex_available: [
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
-}
diff --git a/apex/statsd/framework/api/current.txt b/apex/statsd/framework/api/current.txt
deleted file mode 100644
index a655693..0000000
--- a/apex/statsd/framework/api/current.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-// Signature format: 2.0
-package android.util {
-
- public final class StatsLog {
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public static boolean logBinaryPushStateChanged(@NonNull String, long, int, int, @NonNull long[]);
- method public static boolean logEvent(int);
- method public static boolean logStart(int);
- method public static boolean logStop(int);
- }
-
-}
-
diff --git a/apex/statsd/framework/api/module-lib-current.txt b/apex/statsd/framework/api/module-lib-current.txt
deleted file mode 100644
index 8b6e217..0000000
--- a/apex/statsd/framework/api/module-lib-current.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-// Signature format: 2.0
-package android.os {
-
- public class StatsFrameworkInitializer {
- method public static void registerServiceWrappers();
- method public static void setStatsServiceManager(@NonNull android.os.StatsServiceManager);
- }
-
-}
-
diff --git a/apex/statsd/framework/api/module-lib-removed.txt b/apex/statsd/framework/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apex/statsd/framework/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/statsd/framework/api/removed.txt b/apex/statsd/framework/api/removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apex/statsd/framework/api/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/statsd/framework/api/system-current.txt b/apex/statsd/framework/api/system-current.txt
deleted file mode 100644
index 3ea5724..0000000
--- a/apex/statsd/framework/api/system-current.txt
+++ /dev/null
@@ -1,111 +0,0 @@
-// Signature format: 2.0
-package android.app {
-
- public final class StatsManager {
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void addConfig(long, byte[]) throws android.app.StatsManager.StatsUnavailableException;
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean addConfiguration(long, byte[]);
- method @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM) public void clearPullAtomCallback(int);
- method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getData(long);
- method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getMetadata();
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] getRegisteredExperimentIds() throws android.app.StatsManager.StatsUnavailableException;
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getReports(long) throws android.app.StatsManager.StatsUnavailableException;
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean removeConfiguration(long);
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setBroadcastSubscriber(android.app.PendingIntent, long, long) throws android.app.StatsManager.StatsUnavailableException;
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setDataFetchOperation(long, android.app.PendingIntent);
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setFetchReportsOperation(android.app.PendingIntent, long) throws android.app.StatsManager.StatsUnavailableException;
- method @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM) public void setPullAtomCallback(int, @Nullable android.app.StatsManager.PullAtomMetadata, @NonNull java.util.concurrent.Executor, @NonNull android.app.StatsManager.StatsPullAtomCallback);
- field public static final String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
- field public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS = "android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
- field public static final String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES = "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
- field public static final String EXTRA_STATS_CONFIG_KEY = "android.app.extra.STATS_CONFIG_KEY";
- field public static final String EXTRA_STATS_CONFIG_UID = "android.app.extra.STATS_CONFIG_UID";
- field public static final String EXTRA_STATS_DIMENSIONS_VALUE = "android.app.extra.STATS_DIMENSIONS_VALUE";
- field public static final String EXTRA_STATS_SUBSCRIPTION_ID = "android.app.extra.STATS_SUBSCRIPTION_ID";
- field public static final String EXTRA_STATS_SUBSCRIPTION_RULE_ID = "android.app.extra.STATS_SUBSCRIPTION_RULE_ID";
- field public static final int PULL_SKIP = 1; // 0x1
- field public static final int PULL_SUCCESS = 0; // 0x0
- }
-
- public static class StatsManager.PullAtomMetadata {
- method @Nullable public int[] getAdditiveFields();
- method public long getCoolDownMillis();
- method public long getTimeoutMillis();
- }
-
- public static class StatsManager.PullAtomMetadata.Builder {
- ctor public StatsManager.PullAtomMetadata.Builder();
- method @NonNull public android.app.StatsManager.PullAtomMetadata build();
- method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setAdditiveFields(@NonNull int[]);
- method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setCoolDownMillis(long);
- method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setTimeoutMillis(long);
- }
-
- public static interface StatsManager.StatsPullAtomCallback {
- method public int onPullAtom(int, @NonNull java.util.List<android.util.StatsEvent>);
- }
-
- public static class StatsManager.StatsUnavailableException extends android.util.AndroidException {
- ctor public StatsManager.StatsUnavailableException(String);
- ctor public StatsManager.StatsUnavailableException(String, Throwable);
- }
-
-}
-
-package android.os {
-
- public final class StatsDimensionsValue implements android.os.Parcelable {
- method public int describeContents();
- method public boolean getBooleanValue();
- method public int getField();
- method public float getFloatValue();
- method public int getIntValue();
- method public long getLongValue();
- method public String getStringValue();
- method public java.util.List<android.os.StatsDimensionsValue> getTupleValueList();
- method public int getValueType();
- method public boolean isValueType(int);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int BOOLEAN_VALUE_TYPE = 5; // 0x5
- field @NonNull public static final android.os.Parcelable.Creator<android.os.StatsDimensionsValue> CREATOR;
- field public static final int FLOAT_VALUE_TYPE = 6; // 0x6
- field public static final int INT_VALUE_TYPE = 3; // 0x3
- field public static final int LONG_VALUE_TYPE = 4; // 0x4
- field public static final int STRING_VALUE_TYPE = 2; // 0x2
- field public static final int TUPLE_VALUE_TYPE = 7; // 0x7
- }
-
-}
-
-package android.util {
-
- public final class StatsEvent {
- method @NonNull public static android.util.StatsEvent.Builder newBuilder();
- }
-
- public static final class StatsEvent.Builder {
- method @NonNull public android.util.StatsEvent.Builder addBooleanAnnotation(byte, boolean);
- method @NonNull public android.util.StatsEvent.Builder addIntAnnotation(byte, int);
- method @NonNull public android.util.StatsEvent build();
- method @NonNull public android.util.StatsEvent.Builder setAtomId(int);
- method @NonNull public android.util.StatsEvent.Builder usePooledBuffer();
- method @NonNull public android.util.StatsEvent.Builder writeAttributionChain(@NonNull int[], @NonNull String[]);
- method @NonNull public android.util.StatsEvent.Builder writeBoolean(boolean);
- method @NonNull public android.util.StatsEvent.Builder writeByteArray(@NonNull byte[]);
- method @NonNull public android.util.StatsEvent.Builder writeFloat(float);
- method @NonNull public android.util.StatsEvent.Builder writeInt(int);
- method @NonNull public android.util.StatsEvent.Builder writeKeyValuePairs(@Nullable android.util.SparseIntArray, @Nullable android.util.SparseLongArray, @Nullable android.util.SparseArray<java.lang.String>, @Nullable android.util.SparseArray<java.lang.Float>);
- method @NonNull public android.util.StatsEvent.Builder writeLong(long);
- method @NonNull public android.util.StatsEvent.Builder writeString(@NonNull String);
- }
-
- public final class StatsLog {
- method public static void write(@NonNull android.util.StatsEvent);
- method public static void writeRaw(@NonNull byte[], int);
- }
-
-}
-
diff --git a/apex/statsd/framework/api/system-removed.txt b/apex/statsd/framework/api/system-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apex/statsd/framework/api/system-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/statsd/framework/java/android/app/StatsManager.java b/apex/statsd/framework/java/android/app/StatsManager.java
deleted file mode 100644
index a7d2057..0000000
--- a/apex/statsd/framework/java/android/app/StatsManager.java
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.app;
-
-import static android.Manifest.permission.DUMP;
-import static android.Manifest.permission.PACKAGE_USAGE_STATS;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.Binder;
-import android.os.IPullAtomCallback;
-import android.os.IPullAtomResultReceiver;
-import android.os.IStatsManagerService;
-import android.os.RemoteException;
-import android.os.StatsFrameworkInitializer;
-import android.util.AndroidException;
-import android.util.Log;
-import android.util.StatsEvent;
-import android.util.StatsEventParcel;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * API for statsd clients to send configurations and retrieve data.
- *
- * @hide
- */
-@SystemApi
-public final class StatsManager {
- private static final String TAG = "StatsManager";
- private static final boolean DEBUG = false;
-
- private static final Object sLock = new Object();
- private final Context mContext;
-
- @GuardedBy("sLock")
- private IStatsManagerService mStatsManagerService;
-
- /**
- * Long extra of uid that added the relevant stats config.
- */
- public static final String EXTRA_STATS_CONFIG_UID = "android.app.extra.STATS_CONFIG_UID";
- /**
- * Long extra of the relevant stats config's configKey.
- */
- public static final String EXTRA_STATS_CONFIG_KEY = "android.app.extra.STATS_CONFIG_KEY";
- /**
- * Long extra of the relevant statsd_config.proto's Subscription.id.
- */
- public static final String EXTRA_STATS_SUBSCRIPTION_ID =
- "android.app.extra.STATS_SUBSCRIPTION_ID";
- /**
- * Long extra of the relevant statsd_config.proto's Subscription.rule_id.
- */
- public static final String EXTRA_STATS_SUBSCRIPTION_RULE_ID =
- "android.app.extra.STATS_SUBSCRIPTION_RULE_ID";
- /**
- * List<String> of the relevant statsd_config.proto's BroadcastSubscriberDetails.cookie.
- * Obtain using {@link android.content.Intent#getStringArrayListExtra(String)}.
- */
- public static final String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES =
- "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
- /**
- * Extra of a {@link android.os.StatsDimensionsValue} representing sliced dimension value
- * information.
- */
- public static final String EXTRA_STATS_DIMENSIONS_VALUE =
- "android.app.extra.STATS_DIMENSIONS_VALUE";
- /**
- * Long array extra of the active configs for the uid that added those configs.
- */
- public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS =
- "android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
-
- /**
- * Broadcast Action: Statsd has started.
- * Configurations and PendingIntents can now be sent to it.
- */
- public static final String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
-
- // Pull atom callback return codes.
- /**
- * Value indicating that this pull was successful and that the result should be used.
- *
- **/
- public static final int PULL_SUCCESS = 0;
-
- /**
- * Value indicating that this pull was unsuccessful and that the result should not be used.
- **/
- public static final int PULL_SKIP = 1;
-
- /**
- * @hide
- **/
- @VisibleForTesting public static final long DEFAULT_COOL_DOWN_MILLIS = 1_000L; // 1 second.
-
- /**
- * @hide
- **/
- @VisibleForTesting public static final long DEFAULT_TIMEOUT_MILLIS = 2_000L; // 2 seconds.
-
- /**
- * Constructor for StatsManagerClient.
- *
- * @hide
- */
- public StatsManager(Context context) {
- mContext = context;
- }
-
- /**
- * Adds the given configuration and associates it with the given configKey. If a config with the
- * given configKey already exists for the caller's uid, it is replaced with the new one.
- *
- * @param configKey An arbitrary integer that allows clients to track the configuration.
- * @param config Wire-encoded StatsdConfig proto that specifies metrics (and all
- * dependencies eg, conditions and matchers).
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- * @throws IllegalArgumentException if config is not a wire-encoded StatsdConfig proto
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public void addConfig(long configKey, byte[] config) throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- // can throw IllegalArgumentException
- service.addConfiguration(configKey, config, mContext.getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when adding configuration");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to addConfig in statsmanager");
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #addConfig(long, byte[])}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public boolean addConfiguration(long configKey, byte[] config) {
- try {
- addConfig(configKey, config);
- return true;
- } catch (StatsUnavailableException | IllegalArgumentException e) {
- return false;
- }
- }
-
- /**
- * Remove a configuration from logging.
- *
- * @param configKey Configuration key to remove.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public void removeConfig(long configKey) throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- service.removeConfiguration(configKey, mContext.getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when removing configuration");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to removeConfig in statsmanager");
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #removeConfig(long)}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public boolean removeConfiguration(long configKey) {
- try {
- removeConfig(configKey);
- return true;
- } catch (StatsUnavailableException e) {
- return false;
- }
- }
-
- /**
- * Set the PendingIntent to be used when broadcasting subscriber information to the given
- * subscriberId within the given config.
- * <p>
- * Suppose that the calling uid has added a config with key configKey, and that in this config
- * it is specified that when a particular anomaly is detected, a broadcast should be sent to
- * a BroadcastSubscriber with id subscriberId. This function links the given pendingIntent with
- * that subscriberId (for that config), so that this pendingIntent is used to send the broadcast
- * when the anomaly is detected.
- * <p>
- * When statsd sends the broadcast, the PendingIntent will used to send an intent with
- * information of
- * {@link #EXTRA_STATS_CONFIG_UID},
- * {@link #EXTRA_STATS_CONFIG_KEY},
- * {@link #EXTRA_STATS_SUBSCRIPTION_ID},
- * {@link #EXTRA_STATS_SUBSCRIPTION_RULE_ID},
- * {@link #EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES}, and
- * {@link #EXTRA_STATS_DIMENSIONS_VALUE}.
- * <p>
- * This function can only be called by the owner (uid) of the config. It must be called each
- * time statsd starts. The config must have been added first (via {@link #addConfig}).
- *
- * @param pendingIntent the PendingIntent to use when broadcasting info to the subscriber
- * associated with the given subscriberId. May be null, in which case
- * it undoes any previous setting of this subscriberId.
- * @param configKey The integer naming the config to which this subscriber is attached.
- * @param subscriberId ID of the subscriber, as used in the config.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public void setBroadcastSubscriber(
- PendingIntent pendingIntent, long configKey, long subscriberId)
- throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- if (pendingIntent != null) {
- service.setBroadcastSubscriber(configKey, subscriberId, pendingIntent,
- mContext.getOpPackageName());
- } else {
- service.unsetBroadcastSubscriber(configKey, subscriberId,
- mContext.getOpPackageName());
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when adding broadcast subscriber",
- e);
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #setBroadcastSubscriber(PendingIntent, long, long)}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public boolean setBroadcastSubscriber(
- long configKey, long subscriberId, PendingIntent pendingIntent) {
- try {
- setBroadcastSubscriber(pendingIntent, configKey, subscriberId);
- return true;
- } catch (StatsUnavailableException e) {
- return false;
- }
- }
-
- /**
- * Registers the operation that is called to retrieve the metrics data. This must be called
- * each time statsd starts. The config must have been added first (via {@link #addConfig},
- * although addConfig could have been called on a previous boot). This operation allows
- * statsd to send metrics data whenever statsd determines that the metrics in memory are
- * approaching the memory limits. The fetch operation should call {@link #getReports} to fetch
- * the data, which also deletes the retrieved metrics from statsd's memory.
- *
- * @param pendingIntent the PendingIntent to use when broadcasting info to the subscriber
- * associated with the given subscriberId. May be null, in which case
- * it removes any associated pending intent with this configKey.
- * @param configKey The integer naming the config to which this operation is attached.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public void setFetchReportsOperation(PendingIntent pendingIntent, long configKey)
- throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- if (pendingIntent == null) {
- service.removeDataFetchOperation(configKey, mContext.getOpPackageName());
- } else {
- service.setDataFetchOperation(configKey, pendingIntent,
- mContext.getOpPackageName());
- }
-
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when registering data listener.");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- /**
- * Registers the operation that is called whenever there is a change in which configs are
- * active. This must be called each time statsd starts. This operation allows
- * statsd to inform clients that they should pull data of the configs that are currently
- * active. The activeConfigsChangedOperation should set periodic alarms to pull data of configs
- * that are active and stop pulling data of configs that are no longer active.
- *
- * @param pendingIntent the PendingIntent to use when broadcasting info to the subscriber
- * associated with the given subscriberId. May be null, in which case
- * it removes any associated pending intent for this client.
- * @return A list of configs that are currently active for this client. If the pendingIntent is
- * null, this will be an empty list.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public @NonNull long[] setActiveConfigsChangedOperation(@Nullable PendingIntent pendingIntent)
- throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- if (pendingIntent == null) {
- service.removeActiveConfigsChangedOperation(mContext.getOpPackageName());
- return new long[0];
- } else {
- return service.setActiveConfigsChangedOperation(pendingIntent,
- mContext.getOpPackageName());
- }
-
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager "
- + "when registering active configs listener.");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #setFetchReportsOperation(PendingIntent, long)}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public boolean setDataFetchOperation(long configKey, PendingIntent pendingIntent) {
- try {
- setFetchReportsOperation(pendingIntent, configKey);
- return true;
- } catch (StatsUnavailableException e) {
- return false;
- }
- }
-
- /**
- * Request the data collected for the given configKey.
- * This getter is destructive - it also clears the retrieved metrics from statsd's memory.
- *
- * @param configKey Configuration key to retrieve data from.
- * @return Serialized ConfigMetricsReportList proto.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public byte[] getReports(long configKey) throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- return service.getData(configKey, mContext.getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when getting data");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to getReports in statsmanager");
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #getReports(long)}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public @Nullable byte[] getData(long configKey) {
- try {
- return getReports(configKey);
- } catch (StatsUnavailableException e) {
- return null;
- }
- }
-
- /**
- * Clients can request metadata for statsd. Will contain stats across all configurations but not
- * the actual metrics themselves (metrics must be collected via {@link #getReports(long)}.
- * This getter is not destructive and will not reset any metrics/counters.
- *
- * @return Serialized StatsdStatsReport proto.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public byte[] getStatsMetadata() throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- return service.getMetadata(mContext.getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when getting metadata");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to getStatsMetadata in statsmanager");
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #getStatsMetadata()}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public @Nullable byte[] getMetadata() {
- try {
- return getStatsMetadata();
- } catch (StatsUnavailableException e) {
- return null;
- }
- }
-
- /**
- * Returns the experiments IDs registered with statsd, or an empty array if there aren't any.
- *
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
- public long[] getRegisteredExperimentIds()
- throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- return service.getRegisteredExperimentIds();
- } catch (RemoteException e) {
- if (DEBUG) {
- Log.d(TAG,
- "Failed to connect to StatsManagerService when getting "
- + "registered experiment IDs");
- }
- throw new StatsUnavailableException("could not connect", e);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to getRegisteredExperimentIds in statsmanager");
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- /**
- * Sets a callback for an atom when that atom is to be pulled. The stats service will
- * invoke pullData in the callback when the stats service determines that this atom needs to be
- * pulled. This method should not be called by third-party apps.
- *
- * @param atomTag The tag of the atom for this puller callback.
- * @param metadata Optional metadata specifying the timeout, cool down time, and
- * additive fields for mapping isolated to host uids.
- * @param executor The executor in which to run the callback.
- * @param callback The callback to be invoked when the stats service pulls the atom.
- *
- */
- @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM)
- public void setPullAtomCallback(int atomTag, @Nullable PullAtomMetadata metadata,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull StatsPullAtomCallback callback) {
- long coolDownMillis =
- metadata == null ? DEFAULT_COOL_DOWN_MILLIS : metadata.mCoolDownMillis;
- long timeoutMillis = metadata == null ? DEFAULT_TIMEOUT_MILLIS : metadata.mTimeoutMillis;
- int[] additiveFields = metadata == null ? new int[0] : metadata.mAdditiveFields;
- if (additiveFields == null) {
- additiveFields = new int[0];
- }
-
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- PullAtomCallbackInternal rec =
- new PullAtomCallbackInternal(atomTag, callback, executor);
- service.registerPullAtomCallback(
- atomTag, coolDownMillis, timeoutMillis, additiveFields, rec);
- } catch (RemoteException e) {
- throw new RuntimeException("Unable to register pull callback", e);
- }
- }
- }
-
- /**
- * Clears a callback for an atom when that atom is to be pulled. Note that any ongoing
- * pulls will still occur. This method should not be called by third-party apps.
- *
- * @param atomTag The tag of the atom of which to unregister
- *
- */
- @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM)
- public void clearPullAtomCallback(int atomTag) {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- service.unregisterPullAtomCallback(atomTag);
- } catch (RemoteException e) {
- throw new RuntimeException("Unable to unregister pull atom callback");
- }
- }
- }
-
- private static class PullAtomCallbackInternal extends IPullAtomCallback.Stub {
- public final int mAtomId;
- public final StatsPullAtomCallback mCallback;
- public final Executor mExecutor;
-
- PullAtomCallbackInternal(int atomId, StatsPullAtomCallback callback, Executor executor) {
- mAtomId = atomId;
- mCallback = callback;
- mExecutor = executor;
- }
-
- @Override
- public void onPullAtom(int atomTag, IPullAtomResultReceiver resultReceiver) {
- long token = Binder.clearCallingIdentity();
- try {
- mExecutor.execute(() -> {
- List<StatsEvent> data = new ArrayList<>();
- int successInt = mCallback.onPullAtom(atomTag, data);
- boolean success = successInt == PULL_SUCCESS;
- StatsEventParcel[] parcels = new StatsEventParcel[data.size()];
- for (int i = 0; i < data.size(); i++) {
- parcels[i] = new StatsEventParcel();
- parcels[i].buffer = data.get(i).getBytes();
- }
- try {
- resultReceiver.pullFinished(atomTag, success, parcels);
- } catch (RemoteException e) {
- Log.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId
- + " due to TransactionTooLarge. Calling pullFinish with no data");
- StatsEventParcel[] emptyData = new StatsEventParcel[0];
- try {
- resultReceiver.pullFinished(atomTag, /*success=*/false, emptyData);
- } catch (RemoteException nestedException) {
- Log.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId
- + " with empty payload");
- }
- }
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- }
-
- /**
- * Metadata required for registering a StatsPullAtomCallback.
- * All fields are optional, and defaults will be used for fields that are unspecified.
- *
- */
- public static class PullAtomMetadata {
- private final long mCoolDownMillis;
- private final long mTimeoutMillis;
- private final int[] mAdditiveFields;
-
- // Private Constructor for builder
- private PullAtomMetadata(long coolDownMillis, long timeoutMillis, int[] additiveFields) {
- mCoolDownMillis = coolDownMillis;
- mTimeoutMillis = timeoutMillis;
- mAdditiveFields = additiveFields;
- }
-
- /**
- * Builder for PullAtomMetadata.
- */
- public static class Builder {
- private long mCoolDownMillis;
- private long mTimeoutMillis;
- private int[] mAdditiveFields;
-
- /**
- * Returns a new PullAtomMetadata.Builder object for constructing PullAtomMetadata for
- * StatsManager#registerPullAtomCallback
- */
- public Builder() {
- mCoolDownMillis = DEFAULT_COOL_DOWN_MILLIS;
- mTimeoutMillis = DEFAULT_TIMEOUT_MILLIS;
- mAdditiveFields = null;
- }
-
- /**
- * Set the cool down time of the pull in milliseconds. If two successive pulls are
- * issued within the cool down, a cached version of the first pull will be used for the
- * second pull. The minimum allowed cool down is 1 second.
- */
- @NonNull
- public Builder setCoolDownMillis(long coolDownMillis) {
- mCoolDownMillis = coolDownMillis;
- return this;
- }
-
- /**
- * Set the maximum time the pull can take in milliseconds. The maximum allowed timeout
- * is 10 seconds.
- */
- @NonNull
- public Builder setTimeoutMillis(long timeoutMillis) {
- mTimeoutMillis = timeoutMillis;
- return this;
- }
-
- /**
- * Set the additive fields of this pulled atom.
- *
- * This is only applicable for atoms which have a uid field. When tasks are run in
- * isolated processes, the data will be attributed to the host uid. Additive fields
- * will be combined when the non-additive fields are the same.
- */
- @NonNull
- public Builder setAdditiveFields(@NonNull int[] additiveFields) {
- mAdditiveFields = additiveFields;
- return this;
- }
-
- /**
- * Builds and returns a PullAtomMetadata object with the values set in the builder and
- * defaults for unset fields.
- */
- @NonNull
- public PullAtomMetadata build() {
- return new PullAtomMetadata(mCoolDownMillis, mTimeoutMillis, mAdditiveFields);
- }
- }
-
- /**
- * Return the cool down time of this pull in milliseconds.
- */
- public long getCoolDownMillis() {
- return mCoolDownMillis;
- }
-
- /**
- * Return the maximum amount of time this pull can take in milliseconds.
- */
- public long getTimeoutMillis() {
- return mTimeoutMillis;
- }
-
- /**
- * Return the additive fields of this pulled atom.
- *
- * This is only applicable for atoms that have a uid field. When tasks are run in
- * isolated processes, the data will be attributed to the host uid. Additive fields
- * will be combined when the non-additive fields are the same.
- */
- @Nullable
- public int[] getAdditiveFields() {
- return mAdditiveFields;
- }
- }
-
- /**
- * Callback interface for pulling atoms requested by the stats service.
- *
- */
- public interface StatsPullAtomCallback {
- /**
- * Pull data for the specified atom tag, filling in the provided list of StatsEvent data.
- * @return {@link #PULL_SUCCESS} if the pull was successful, or {@link #PULL_SKIP} if not.
- */
- int onPullAtom(int atomTag, @NonNull List<StatsEvent> data);
- }
-
- @GuardedBy("sLock")
- private IStatsManagerService getIStatsManagerServiceLocked() {
- if (mStatsManagerService != null) {
- return mStatsManagerService;
- }
- mStatsManagerService = IStatsManagerService.Stub.asInterface(
- StatsFrameworkInitializer
- .getStatsServiceManager()
- .getStatsManagerServiceRegisterer()
- .get());
- return mStatsManagerService;
- }
-
- /**
- * Exception thrown when communication with the stats service fails (eg if it is not available).
- * This might be thrown early during boot before the stats service has started or if it crashed.
- */
- public static class StatsUnavailableException extends AndroidException {
- public StatsUnavailableException(String reason) {
- super("Failed to connect to statsd: " + reason);
- }
-
- public StatsUnavailableException(String reason, Throwable e) {
- super("Failed to connect to statsd: " + reason, e);
- }
- }
-}
diff --git a/apex/statsd/framework/java/android/os/StatsDimensionsValue.java b/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
deleted file mode 100644
index 7d9349c..0000000
--- a/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.os;
-
-import android.annotation.SystemApi;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Container for statsd dimension value information, corresponding to a
- * stats_log.proto's DimensionValue.
- *
- * This consists of a field (an int representing a statsd atom field)
- * and a value (which may be one of a number of types).
- *
- * <p>
- * Only a single value is held, and it is necessarily one of the following types:
- * {@link String}, int, long, boolean, float,
- * or tuple (i.e. {@link List} of {@code StatsDimensionsValue}).
- *
- * The type of value held can be retrieved using {@link #getValueType()}, which returns one of the
- * following ints, depending on the type of value:
- * <ul>
- * <li>{@link #STRING_VALUE_TYPE}</li>
- * <li>{@link #INT_VALUE_TYPE}</li>
- * <li>{@link #LONG_VALUE_TYPE}</li>
- * <li>{@link #BOOLEAN_VALUE_TYPE}</li>
- * <li>{@link #FLOAT_VALUE_TYPE}</li>
- * <li>{@link #TUPLE_VALUE_TYPE}</li>
- * </ul>
- * Alternatively, this can be determined using {@link #isValueType(int)} with one of these constants
- * as a parameter.
- * The value itself can be retrieved using the correct get...Value() function for its type.
- *
- * <p>
- * The field is always an int, and always exists; it can be obtained using {@link #getField()}.
- *
- *
- * @hide
- */
-@SystemApi
-public final class StatsDimensionsValue implements Parcelable {
- private static final String TAG = "StatsDimensionsValue";
-
- // Values of the value type correspond to stats_log.proto's DimensionValue fields.
- // Keep constants in sync with frameworks/base/cmds/statsd/src/HashableDimensionKey.cpp.
- /** Indicates that this holds a String. */
- public static final int STRING_VALUE_TYPE = 2;
- /** Indicates that this holds an int. */
- public static final int INT_VALUE_TYPE = 3;
- /** Indicates that this holds a long. */
- public static final int LONG_VALUE_TYPE = 4;
- /** Indicates that this holds a boolean. */
- public static final int BOOLEAN_VALUE_TYPE = 5;
- /** Indicates that this holds a float. */
- public static final int FLOAT_VALUE_TYPE = 6;
- /** Indicates that this holds a List of StatsDimensionsValues. */
- public static final int TUPLE_VALUE_TYPE = 7;
-
- private final StatsDimensionsValueParcel mInner;
-
- /**
- * Creates a {@code StatsDimensionValue} from a parcel.
- *
- * @hide
- */
- public StatsDimensionsValue(Parcel in) {
- mInner = StatsDimensionsValueParcel.CREATOR.createFromParcel(in);
- }
-
- /**
- * Creates a {@code StatsDimensionsValue} from a StatsDimensionsValueParcel
- *
- * @hide
- */
- public StatsDimensionsValue(StatsDimensionsValueParcel parcel) {
- mInner = parcel;
- }
-
- /**
- * Return the field, i.e. the tag of a statsd atom.
- *
- * @return the field
- */
- public int getField() {
- return mInner.field;
- }
-
- /**
- * Retrieve the String held, if any.
- *
- * @return the {@link String} held if {@link #getValueType()} == {@link #STRING_VALUE_TYPE},
- * null otherwise
- */
- public String getStringValue() {
- if (mInner.valueType == STRING_VALUE_TYPE) {
- return mInner.stringValue;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not string.");
- return null;
- }
- }
-
- /**
- * Retrieve the int held, if any.
- *
- * @return the int held if {@link #getValueType()} == {@link #INT_VALUE_TYPE}, 0 otherwise
- */
- public int getIntValue() {
- if (mInner.valueType == INT_VALUE_TYPE) {
- return mInner.intValue;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not int.");
- return 0;
- }
- }
-
- /**
- * Retrieve the long held, if any.
- *
- * @return the long held if {@link #getValueType()} == {@link #LONG_VALUE_TYPE}, 0 otherwise
- */
- public long getLongValue() {
- if (mInner.valueType == LONG_VALUE_TYPE) {
- return mInner.longValue;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not long.");
- return 0;
- }
- }
-
- /**
- * Retrieve the boolean held, if any.
- *
- * @return the boolean held if {@link #getValueType()} == {@link #BOOLEAN_VALUE_TYPE},
- * false otherwise
- */
- public boolean getBooleanValue() {
- if (mInner.valueType == BOOLEAN_VALUE_TYPE) {
- return mInner.boolValue;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not boolean.");
- return false;
- }
- }
-
- /**
- * Retrieve the float held, if any.
- *
- * @return the float held if {@link #getValueType()} == {@link #FLOAT_VALUE_TYPE}, 0 otherwise
- */
- public float getFloatValue() {
- if (mInner.valueType == FLOAT_VALUE_TYPE) {
- return mInner.floatValue;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not float.");
- return 0;
- }
- }
-
- /**
- * Retrieve the tuple, in the form of a {@link List} of {@link StatsDimensionsValue}, held,
- * if any.
- *
- * @return the {@link List} of {@link StatsDimensionsValue} held
- * if {@link #getValueType()} == {@link #TUPLE_VALUE_TYPE},
- * null otherwise
- */
- public List<StatsDimensionsValue> getTupleValueList() {
- if (mInner.valueType == TUPLE_VALUE_TYPE) {
- int length = (mInner.tupleValue == null) ? 0 : mInner.tupleValue.length;
- List<StatsDimensionsValue> tupleValues = new ArrayList<>(length);
- for (int i = 0; i < length; i++) {
- tupleValues.add(new StatsDimensionsValue(mInner.tupleValue[i]));
- }
- return tupleValues;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not tuple.");
- return null;
- }
- }
-
- /**
- * Returns the constant representing the type of value stored, namely one of
- * <ul>
- * <li>{@link #STRING_VALUE_TYPE}</li>
- * <li>{@link #INT_VALUE_TYPE}</li>
- * <li>{@link #LONG_VALUE_TYPE}</li>
- * <li>{@link #BOOLEAN_VALUE_TYPE}</li>
- * <li>{@link #FLOAT_VALUE_TYPE}</li>
- * <li>{@link #TUPLE_VALUE_TYPE}</li>
- * </ul>
- *
- * @return the constant representing the type of value stored
- */
- public int getValueType() {
- return mInner.valueType;
- }
-
- /**
- * Returns whether the type of value stored is equal to the given type.
- *
- * @param valueType int representing the type of value stored, as used in {@link #getValueType}
- * @return true if {@link #getValueType()} is equal to {@code valueType}.
- */
- public boolean isValueType(int valueType) {
- return mInner.valueType == valueType;
- }
-
- /**
- * Returns a String representing the information in this StatsDimensionValue.
- * No guarantees are made about the format of this String.
- *
- * @return String representation
- *
- * @hide
- */
- // Follows the format of statsd's dimension.h toString.
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(mInner.field);
- sb.append(":");
- switch (mInner.valueType) {
- case STRING_VALUE_TYPE:
- sb.append(mInner.stringValue);
- break;
- case INT_VALUE_TYPE:
- sb.append(String.valueOf(mInner.intValue));
- break;
- case LONG_VALUE_TYPE:
- sb.append(String.valueOf(mInner.longValue));
- break;
- case BOOLEAN_VALUE_TYPE:
- sb.append(String.valueOf(mInner.boolValue));
- break;
- case FLOAT_VALUE_TYPE:
- sb.append(String.valueOf(mInner.floatValue));
- break;
- case TUPLE_VALUE_TYPE:
- sb.append("{");
- int length = (mInner.tupleValue == null) ? 0 : mInner.tupleValue.length;
- for (int i = 0; i < length; i++) {
- StatsDimensionsValue child = new StatsDimensionsValue(mInner.tupleValue[i]);
- sb.append(child.toString());
- sb.append("|");
- }
- sb.append("}");
- break;
- default:
- Log.w(TAG, "Incorrect value type");
- break;
- }
- return sb.toString();
- }
-
- /**
- * Parcelable Creator for StatsDimensionsValue.
- */
- public static final @android.annotation.NonNull
- Parcelable.Creator<StatsDimensionsValue> CREATOR = new
- Parcelable.Creator<StatsDimensionsValue>() {
- public StatsDimensionsValue createFromParcel(Parcel in) {
- return new StatsDimensionsValue(in);
- }
-
- public StatsDimensionsValue[] newArray(int size) {
- return new StatsDimensionsValue[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- mInner.writeToParcel(out, flags);
- }
-
- /**
- * Returns a string representation of the type of value stored.
- */
- private String getValueTypeAsString() {
- switch (mInner.valueType) {
- case STRING_VALUE_TYPE:
- return "string";
- case INT_VALUE_TYPE:
- return "int";
- case LONG_VALUE_TYPE:
- return "long";
- case BOOLEAN_VALUE_TYPE:
- return "boolean";
- case FLOAT_VALUE_TYPE:
- return "float";
- case TUPLE_VALUE_TYPE:
- return "tuple";
- default:
- return "unknown";
- }
- }
-}
diff --git a/apex/statsd/framework/java/android/os/StatsFrameworkInitializer.java b/apex/statsd/framework/java/android/os/StatsFrameworkInitializer.java
deleted file mode 100644
index 8dc9123..0000000
--- a/apex/statsd/framework/java/android/os/StatsFrameworkInitializer.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.os;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.annotation.SystemApi.Client;
-import android.app.StatsManager;
-import android.app.SystemServiceRegistry;
-import android.content.Context;
-
-/**
- * Class for performing registration for all stats services
- *
- * @hide
- */
-@SystemApi(client = Client.MODULE_LIBRARIES)
-public class StatsFrameworkInitializer {
- private StatsFrameworkInitializer() {
- }
-
- private static volatile StatsServiceManager sStatsServiceManager;
-
- /**
- * Sets an instance of {@link StatsServiceManager} that allows
- * the statsd mainline module to register/obtain stats binder services. This is called
- * by the platform during the system initialization.
- *
- * @param statsServiceManager instance of {@link StatsServiceManager} that allows
- * the statsd mainline module to register/obtain statsd binder services.
- */
- public static void setStatsServiceManager(
- @NonNull StatsServiceManager statsServiceManager) {
- if (sStatsServiceManager != null) {
- throw new IllegalStateException("setStatsServiceManager called twice!");
- }
-
- if (statsServiceManager == null) {
- throw new NullPointerException("statsServiceManager is null");
- }
-
- sStatsServiceManager = statsServiceManager;
- }
-
- /** @hide */
- public static StatsServiceManager getStatsServiceManager() {
- return sStatsServiceManager;
- }
-
- /**
- * Called by {@link SystemServiceRegistry}'s static initializer and registers all statsd
- * services to {@link Context}, so that {@link Context#getSystemService} can return them.
- *
- * @throws IllegalStateException if this is called from anywhere besides
- * {@link SystemServiceRegistry}
- */
- public static void registerServiceWrappers() {
- SystemServiceRegistry.registerContextAwareService(
- Context.STATS_MANAGER,
- StatsManager.class,
- context -> new StatsManager(context)
- );
- }
-}
diff --git a/apex/statsd/framework/java/android/util/StatsEvent.java b/apex/statsd/framework/java/android/util/StatsEvent.java
deleted file mode 100644
index 8be5c63..0000000
--- a/apex/statsd/framework/java/android/util/StatsEvent.java
+++ /dev/null
@@ -1,879 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.SystemClock;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Arrays;
-
-/**
- * StatsEvent builds and stores the buffer sent over the statsd socket.
- * This class defines and encapsulates the socket protocol.
- *
- * <p>Usage:</p>
- * <pre>
- * // Pushed event
- * StatsEvent statsEvent = StatsEvent.newBuilder()
- * .setAtomId(atomId)
- * .writeBoolean(false)
- * .writeString("annotated String field")
- * .addBooleanAnnotation(annotationId, true)
- * .usePooledBuffer()
- * .build();
- * StatsLog.write(statsEvent);
- *
- * // Pulled event
- * StatsEvent statsEvent = StatsEvent.newBuilder()
- * .setAtomId(atomId)
- * .writeBoolean(false)
- * .writeString("annotated String field")
- * .addBooleanAnnotation(annotationId, true)
- * .build();
- * </pre>
- * @hide
- **/
-@SystemApi
-public final class StatsEvent {
- // Type Ids.
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_INT = 0x00;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_LONG = 0x01;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_STRING = 0x02;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_LIST = 0x03;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_FLOAT = 0x04;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_BOOLEAN = 0x05;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_BYTE_ARRAY = 0x06;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_OBJECT = 0x07;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_KEY_VALUE_PAIRS = 0x08;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_ATTRIBUTION_CHAIN = 0x09;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_ERRORS = 0x0F;
-
- // Error flags.
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_NO_TIMESTAMP = 0x1;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_NO_ATOM_ID = 0x2;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_OVERFLOW = 0x4;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_ATTRIBUTION_CHAIN_TOO_LONG = 0x8;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_TOO_MANY_KEY_VALUE_PAIRS = 0x10;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD = 0x20;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_INVALID_ANNOTATION_ID = 0x40;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_ANNOTATION_ID_TOO_LARGE = 0x80;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_TOO_MANY_ANNOTATIONS = 0x100;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_TOO_MANY_FIELDS = 0x200;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL = 0x1000;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_ATOM_ID_INVALID_POSITION = 0x2000;
-
- // Size limits.
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int MAX_ANNOTATION_COUNT = 15;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int MAX_ATTRIBUTION_NODES = 127;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int MAX_NUM_ELEMENTS = 127;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int MAX_KEY_VALUE_PAIRS = 127;
-
- private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;
-
- // Max payload size is 4 bytes less as 4 bytes are reserved for statsEventTag.
- // See android_util_StatsLog.cpp.
- private static final int MAX_PUSH_PAYLOAD_SIZE = LOGGER_ENTRY_MAX_PAYLOAD - 4;
-
- private static final int MAX_PULL_PAYLOAD_SIZE = 50 * 1024; // 50 KB
-
- private final int mAtomId;
- private final byte[] mPayload;
- private Buffer mBuffer;
- private final int mNumBytes;
-
- private StatsEvent(final int atomId, @Nullable final Buffer buffer,
- @NonNull final byte[] payload, final int numBytes) {
- mAtomId = atomId;
- mBuffer = buffer;
- mPayload = payload;
- mNumBytes = numBytes;
- }
-
- /**
- * Returns a new StatsEvent.Builder for building StatsEvent object.
- **/
- @NonNull
- public static StatsEvent.Builder newBuilder() {
- return new StatsEvent.Builder(Buffer.obtain());
- }
-
- /**
- * Get the atom Id of the atom encoded in this StatsEvent object.
- *
- * @hide
- **/
- public int getAtomId() {
- return mAtomId;
- }
-
- /**
- * Get the byte array that contains the encoded payload that can be sent to statsd.
- *
- * @hide
- **/
- @NonNull
- public byte[] getBytes() {
- return mPayload;
- }
-
- /**
- * Get the number of bytes used to encode the StatsEvent payload.
- *
- * @hide
- **/
- public int getNumBytes() {
- return mNumBytes;
- }
-
- /**
- * Recycle resources used by this StatsEvent object.
- * No actions should be taken on this StatsEvent after release() is called.
- *
- * @hide
- **/
- public void release() {
- if (mBuffer != null) {
- mBuffer.release();
- mBuffer = null;
- }
- }
-
- /**
- * Builder for constructing a StatsEvent object.
- *
- * <p>This class defines and encapsulates the socket encoding for the buffer.
- * The write methods must be called in the same order as the order of fields in the
- * atom definition.</p>
- *
- * <p>setAtomId() can be called anytime before build().</p>
- *
- * <p>Example:</p>
- * <pre>
- * // Atom definition.
- * message MyAtom {
- * optional int32 field1 = 1;
- * optional int64 field2 = 2;
- * optional string field3 = 3 [(annotation1) = true];
- * }
- *
- * // StatsEvent construction for pushed event.
- * StatsEvent.newBuilder()
- * StatsEvent statsEvent = StatsEvent.newBuilder()
- * .setAtomId(atomId)
- * .writeInt(3) // field1
- * .writeLong(8L) // field2
- * .writeString("foo") // field 3
- * .addBooleanAnnotation(annotation1Id, true)
- * .usePooledBuffer()
- * .build();
- *
- * // StatsEvent construction for pulled event.
- * StatsEvent.newBuilder()
- * StatsEvent statsEvent = StatsEvent.newBuilder()
- * .setAtomId(atomId)
- * .writeInt(3) // field1
- * .writeLong(8L) // field2
- * .writeString("foo") // field 3
- * .addBooleanAnnotation(annotation1Id, true)
- * .build();
- * </pre>
- **/
- public static final class Builder {
- // Fixed positions.
- private static final int POS_NUM_ELEMENTS = 1;
- private static final int POS_TIMESTAMP_NS = POS_NUM_ELEMENTS + Byte.BYTES;
- private static final int POS_ATOM_ID = POS_TIMESTAMP_NS + Byte.BYTES + Long.BYTES;
-
- private final Buffer mBuffer;
- private long mTimestampNs;
- private int mAtomId;
- private byte mCurrentAnnotationCount;
- private int mPos;
- private int mPosLastField;
- private byte mLastType;
- private int mNumElements;
- private int mErrorMask;
- private boolean mUsePooledBuffer = false;
-
- private Builder(final Buffer buffer) {
- mBuffer = buffer;
- mCurrentAnnotationCount = 0;
- mAtomId = 0;
- mTimestampNs = SystemClock.elapsedRealtimeNanos();
- mNumElements = 0;
-
- // Set mPos to 0 for writing TYPE_OBJECT at 0th position.
- mPos = 0;
- writeTypeId(TYPE_OBJECT);
-
- // Write timestamp.
- mPos = POS_TIMESTAMP_NS;
- writeLong(mTimestampNs);
- }
-
- /**
- * Sets the atom id for this StatsEvent.
- *
- * This should be called immediately after StatsEvent.newBuilder()
- * and should only be called once.
- * Not calling setAtomId will result in ERROR_NO_ATOM_ID.
- * Calling setAtomId out of order will result in ERROR_ATOM_ID_INVALID_POSITION.
- **/
- @NonNull
- public Builder setAtomId(final int atomId) {
- if (0 == mAtomId) {
- mAtomId = atomId;
-
- if (1 == mNumElements) { // Only timestamp is written so far.
- writeInt(atomId);
- } else {
- // setAtomId called out of order.
- mErrorMask |= ERROR_ATOM_ID_INVALID_POSITION;
- }
- }
-
- return this;
- }
-
- /**
- * Write a boolean field to this StatsEvent.
- **/
- @NonNull
- public Builder writeBoolean(final boolean value) {
- // Write boolean typeId byte followed by boolean byte representation.
- writeTypeId(TYPE_BOOLEAN);
- mPos += mBuffer.putBoolean(mPos, value);
- mNumElements++;
- return this;
- }
-
- /**
- * Write an integer field to this StatsEvent.
- **/
- @NonNull
- public Builder writeInt(final int value) {
- // Write integer typeId byte followed by 4-byte representation of value.
- writeTypeId(TYPE_INT);
- mPos += mBuffer.putInt(mPos, value);
- mNumElements++;
- return this;
- }
-
- /**
- * Write a long field to this StatsEvent.
- **/
- @NonNull
- public Builder writeLong(final long value) {
- // Write long typeId byte followed by 8-byte representation of value.
- writeTypeId(TYPE_LONG);
- mPos += mBuffer.putLong(mPos, value);
- mNumElements++;
- return this;
- }
-
- /**
- * Write a float field to this StatsEvent.
- **/
- @NonNull
- public Builder writeFloat(final float value) {
- // Write float typeId byte followed by 4-byte representation of value.
- writeTypeId(TYPE_FLOAT);
- mPos += mBuffer.putFloat(mPos, value);
- mNumElements++;
- return this;
- }
-
- /**
- * Write a String field to this StatsEvent.
- **/
- @NonNull
- public Builder writeString(@NonNull final String value) {
- // Write String typeId byte, followed by 4-byte representation of number of bytes
- // in the UTF-8 encoding, followed by the actual UTF-8 byte encoding of value.
- final byte[] valueBytes = stringToBytes(value);
- writeByteArray(valueBytes, TYPE_STRING);
- return this;
- }
-
- /**
- * Write a byte array field to this StatsEvent.
- **/
- @NonNull
- public Builder writeByteArray(@NonNull final byte[] value) {
- // Write byte array typeId byte, followed by 4-byte representation of number of bytes
- // in value, followed by the actual byte array.
- writeByteArray(value, TYPE_BYTE_ARRAY);
- return this;
- }
-
- private void writeByteArray(@NonNull final byte[] value, final byte typeId) {
- writeTypeId(typeId);
- final int numBytes = value.length;
- mPos += mBuffer.putInt(mPos, numBytes);
- mPos += mBuffer.putByteArray(mPos, value);
- mNumElements++;
- }
-
- /**
- * Write an attribution chain field to this StatsEvent.
- *
- * The sizes of uids and tags must be equal. The AttributionNode at position i is
- * made up of uids[i] and tags[i].
- *
- * @param uids array of uids in the attribution nodes.
- * @param tags array of tags in the attribution nodes.
- **/
- @NonNull
- public Builder writeAttributionChain(
- @NonNull final int[] uids, @NonNull final String[] tags) {
- final byte numUids = (byte) uids.length;
- final byte numTags = (byte) tags.length;
-
- if (numUids != numTags) {
- mErrorMask |= ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL;
- } else if (numUids > MAX_ATTRIBUTION_NODES) {
- mErrorMask |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG;
- } else {
- // Write attribution chain typeId byte, followed by 1-byte representation of
- // number of attribution nodes, followed by encoding of each attribution node.
- writeTypeId(TYPE_ATTRIBUTION_CHAIN);
- mPos += mBuffer.putByte(mPos, numUids);
- for (int i = 0; i < numUids; i++) {
- // Each uid is encoded as 4-byte representation of its int value.
- mPos += mBuffer.putInt(mPos, uids[i]);
-
- // Each tag is encoded as 4-byte representation of number of bytes in its
- // UTF-8 encoding, followed by the actual UTF-8 bytes.
- final byte[] tagBytes = stringToBytes(tags[i]);
- mPos += mBuffer.putInt(mPos, tagBytes.length);
- mPos += mBuffer.putByteArray(mPos, tagBytes);
- }
- mNumElements++;
- }
- return this;
- }
-
- /**
- * Write KeyValuePairsAtom entries to this StatsEvent.
- *
- * @param intMap Integer key-value pairs.
- * @param longMap Long key-value pairs.
- * @param stringMap String key-value pairs.
- * @param floatMap Float key-value pairs.
- **/
- @NonNull
- public Builder writeKeyValuePairs(
- @Nullable final SparseIntArray intMap,
- @Nullable final SparseLongArray longMap,
- @Nullable final SparseArray<String> stringMap,
- @Nullable final SparseArray<Float> floatMap) {
- final int intMapSize = null == intMap ? 0 : intMap.size();
- final int longMapSize = null == longMap ? 0 : longMap.size();
- final int stringMapSize = null == stringMap ? 0 : stringMap.size();
- final int floatMapSize = null == floatMap ? 0 : floatMap.size();
- final int totalCount = intMapSize + longMapSize + stringMapSize + floatMapSize;
-
- if (totalCount > MAX_KEY_VALUE_PAIRS) {
- mErrorMask |= ERROR_TOO_MANY_KEY_VALUE_PAIRS;
- } else {
- writeTypeId(TYPE_KEY_VALUE_PAIRS);
- mPos += mBuffer.putByte(mPos, (byte) totalCount);
-
- for (int i = 0; i < intMapSize; i++) {
- final int key = intMap.keyAt(i);
- final int value = intMap.valueAt(i);
- mPos += mBuffer.putInt(mPos, key);
- writeTypeId(TYPE_INT);
- mPos += mBuffer.putInt(mPos, value);
- }
-
- for (int i = 0; i < longMapSize; i++) {
- final int key = longMap.keyAt(i);
- final long value = longMap.valueAt(i);
- mPos += mBuffer.putInt(mPos, key);
- writeTypeId(TYPE_LONG);
- mPos += mBuffer.putLong(mPos, value);
- }
-
- for (int i = 0; i < stringMapSize; i++) {
- final int key = stringMap.keyAt(i);
- final String value = stringMap.valueAt(i);
- mPos += mBuffer.putInt(mPos, key);
- writeTypeId(TYPE_STRING);
- final byte[] valueBytes = stringToBytes(value);
- mPos += mBuffer.putInt(mPos, valueBytes.length);
- mPos += mBuffer.putByteArray(mPos, valueBytes);
- }
-
- for (int i = 0; i < floatMapSize; i++) {
- final int key = floatMap.keyAt(i);
- final float value = floatMap.valueAt(i);
- mPos += mBuffer.putInt(mPos, key);
- writeTypeId(TYPE_FLOAT);
- mPos += mBuffer.putFloat(mPos, value);
- }
-
- mNumElements++;
- }
-
- return this;
- }
-
- /**
- * Write a boolean annotation for the last field written.
- **/
- @NonNull
- public Builder addBooleanAnnotation(
- final byte annotationId, final boolean value) {
- // Ensure there's a field written to annotate.
- if (mNumElements < 2) {
- mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
- } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) {
- mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS;
- } else {
- mPos += mBuffer.putByte(mPos, annotationId);
- mPos += mBuffer.putByte(mPos, TYPE_BOOLEAN);
- mPos += mBuffer.putBoolean(mPos, value);
- mCurrentAnnotationCount++;
- writeAnnotationCount();
- }
-
- return this;
- }
-
- /**
- * Write an integer annotation for the last field written.
- **/
- @NonNull
- public Builder addIntAnnotation(final byte annotationId, final int value) {
- if (mNumElements < 2) {
- mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
- } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) {
- mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS;
- } else {
- mPos += mBuffer.putByte(mPos, annotationId);
- mPos += mBuffer.putByte(mPos, TYPE_INT);
- mPos += mBuffer.putInt(mPos, value);
- mCurrentAnnotationCount++;
- writeAnnotationCount();
- }
-
- return this;
- }
-
- /**
- * Indicates to reuse Buffer's byte array as the underlying payload in StatsEvent.
- * This should be called for pushed events to reduce memory allocations and garbage
- * collections.
- **/
- @NonNull
- public Builder usePooledBuffer() {
- mUsePooledBuffer = true;
- mBuffer.setMaxSize(MAX_PUSH_PAYLOAD_SIZE, mPos);
- return this;
- }
-
- /**
- * Builds a StatsEvent object with values entered in this Builder.
- **/
- @NonNull
- public StatsEvent build() {
- if (0L == mTimestampNs) {
- mErrorMask |= ERROR_NO_TIMESTAMP;
- }
- if (0 == mAtomId) {
- mErrorMask |= ERROR_NO_ATOM_ID;
- }
- if (mBuffer.hasOverflowed()) {
- mErrorMask |= ERROR_OVERFLOW;
- }
- if (mNumElements > MAX_NUM_ELEMENTS) {
- mErrorMask |= ERROR_TOO_MANY_FIELDS;
- }
-
- if (0 == mErrorMask) {
- mBuffer.putByte(POS_NUM_ELEMENTS, (byte) mNumElements);
- } else {
- // Write atom id and error mask. Overwrite any annotations for atom Id.
- mPos = POS_ATOM_ID;
- mPos += mBuffer.putByte(mPos, TYPE_INT);
- mPos += mBuffer.putInt(mPos, mAtomId);
- mPos += mBuffer.putByte(mPos, TYPE_ERRORS);
- mPos += mBuffer.putInt(mPos, mErrorMask);
- mBuffer.putByte(POS_NUM_ELEMENTS, (byte) 3);
- }
-
- final int size = mPos;
-
- if (mUsePooledBuffer) {
- return new StatsEvent(mAtomId, mBuffer, mBuffer.getBytes(), size);
- } else {
- // Create a copy of the buffer with the required number of bytes.
- final byte[] payload = new byte[size];
- System.arraycopy(mBuffer.getBytes(), 0, payload, 0, size);
-
- // Return Buffer instance to the pool.
- mBuffer.release();
-
- return new StatsEvent(mAtomId, null, payload, size);
- }
- }
-
- private void writeTypeId(final byte typeId) {
- mPosLastField = mPos;
- mLastType = typeId;
- mCurrentAnnotationCount = 0;
- final byte encodedId = (byte) (typeId & 0x0F);
- mPos += mBuffer.putByte(mPos, encodedId);
- }
-
- private void writeAnnotationCount() {
- // Use first 4 bits for annotation count and last 4 bits for typeId.
- final byte encodedId = (byte) ((mCurrentAnnotationCount << 4) | (mLastType & 0x0F));
- mBuffer.putByte(mPosLastField, encodedId);
- }
-
- @NonNull
- private static byte[] stringToBytes(@Nullable final String value) {
- return (null == value ? "" : value).getBytes(UTF_8);
- }
- }
-
- private static final class Buffer {
- private static Object sLock = new Object();
-
- @GuardedBy("sLock")
- private static Buffer sPool;
-
- private byte[] mBytes = new byte[MAX_PUSH_PAYLOAD_SIZE];
- private boolean mOverflow = false;
- private int mMaxSize = MAX_PULL_PAYLOAD_SIZE;
-
- @NonNull
- private static Buffer obtain() {
- final Buffer buffer;
- synchronized (sLock) {
- buffer = null == sPool ? new Buffer() : sPool;
- sPool = null;
- }
- buffer.reset();
- return buffer;
- }
-
- private Buffer() {
- }
-
- @NonNull
- private byte[] getBytes() {
- return mBytes;
- }
-
- private void release() {
- // Recycle this Buffer if its size is MAX_PUSH_PAYLOAD_SIZE or under.
- if (mBytes.length <= MAX_PUSH_PAYLOAD_SIZE) {
- synchronized (sLock) {
- if (null == sPool) {
- sPool = this;
- }
- }
- }
- }
-
- private void reset() {
- mOverflow = false;
- mMaxSize = MAX_PULL_PAYLOAD_SIZE;
- }
-
- private void setMaxSize(final int maxSize, final int numBytesWritten) {
- mMaxSize = maxSize;
- if (numBytesWritten > maxSize) {
- mOverflow = true;
- }
- }
-
- private boolean hasOverflowed() {
- return mOverflow;
- }
-
- /**
- * Checks for available space in the byte array.
- *
- * @param index starting position in the buffer to start the check.
- * @param numBytes number of bytes to check from index.
- * @return true if space is available, false otherwise.
- **/
- private boolean hasEnoughSpace(final int index, final int numBytes) {
- final int totalBytesNeeded = index + numBytes;
-
- if (totalBytesNeeded > mMaxSize) {
- mOverflow = true;
- return false;
- }
-
- // Expand buffer if needed.
- if (mBytes.length < mMaxSize && totalBytesNeeded > mBytes.length) {
- int newSize = mBytes.length;
- do {
- newSize *= 2;
- } while (newSize <= totalBytesNeeded);
-
- if (newSize > mMaxSize) {
- newSize = mMaxSize;
- }
-
- mBytes = Arrays.copyOf(mBytes, newSize);
- }
-
- return true;
- }
-
- /**
- * Writes a byte into the buffer.
- *
- * @param index position in the buffer where the byte is written.
- * @param value the byte to write.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putByte(final int index, final byte value) {
- if (hasEnoughSpace(index, Byte.BYTES)) {
- mBytes[index] = (byte) (value);
- return Byte.BYTES;
- }
- return 0;
- }
-
- /**
- * Writes a boolean into the buffer.
- *
- * @param index position in the buffer where the boolean is written.
- * @param value the boolean to write.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putBoolean(final int index, final boolean value) {
- return putByte(index, (byte) (value ? 1 : 0));
- }
-
- /**
- * Writes an integer into the buffer.
- *
- * @param index position in the buffer where the integer is written.
- * @param value the integer to write.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putInt(final int index, final int value) {
- if (hasEnoughSpace(index, Integer.BYTES)) {
- // Use little endian byte order.
- mBytes[index] = (byte) (value);
- mBytes[index + 1] = (byte) (value >> 8);
- mBytes[index + 2] = (byte) (value >> 16);
- mBytes[index + 3] = (byte) (value >> 24);
- return Integer.BYTES;
- }
- return 0;
- }
-
- /**
- * Writes a long into the buffer.
- *
- * @param index position in the buffer where the long is written.
- * @param value the long to write.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putLong(final int index, final long value) {
- if (hasEnoughSpace(index, Long.BYTES)) {
- // Use little endian byte order.
- mBytes[index] = (byte) (value);
- mBytes[index + 1] = (byte) (value >> 8);
- mBytes[index + 2] = (byte) (value >> 16);
- mBytes[index + 3] = (byte) (value >> 24);
- mBytes[index + 4] = (byte) (value >> 32);
- mBytes[index + 5] = (byte) (value >> 40);
- mBytes[index + 6] = (byte) (value >> 48);
- mBytes[index + 7] = (byte) (value >> 56);
- return Long.BYTES;
- }
- return 0;
- }
-
- /**
- * Writes a float into the buffer.
- *
- * @param index position in the buffer where the float is written.
- * @param value the float to write.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putFloat(final int index, final float value) {
- return putInt(index, Float.floatToIntBits(value));
- }
-
- /**
- * Copies a byte array into the buffer.
- *
- * @param index position in the buffer where the byte array is copied.
- * @param value the byte array to copy.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putByteArray(final int index, @NonNull final byte[] value) {
- final int numBytes = value.length;
- if (hasEnoughSpace(index, numBytes)) {
- System.arraycopy(value, 0, mBytes, index, numBytes);
- return numBytes;
- }
- return 0;
- }
- }
-}
diff --git a/apex/statsd/framework/java/android/util/StatsLog.java b/apex/statsd/framework/java/android/util/StatsLog.java
deleted file mode 100644
index 0a9f4eb..0000000
--- a/apex/statsd/framework/java/android/util/StatsLog.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import static android.Manifest.permission.DUMP;
-import static android.Manifest.permission.PACKAGE_USAGE_STATS;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.IStatsd;
-import android.os.Process;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.statsd.StatsdStatsLog;
-
-/**
- * StatsLog provides an API for developers to send events to statsd. The events can be used to
- * define custom metrics inside statsd.
- */
-public final class StatsLog {
-
- // Load JNI library
- static {
- System.loadLibrary("stats_jni");
- }
- private static final String TAG = "StatsLog";
- private static final boolean DEBUG = false;
- private static final int EXPERIMENT_IDS_FIELD_ID = 1;
-
- private StatsLog() {
- }
-
- /**
- * Logs a start event.
- *
- * @param label developer-chosen label.
- * @return True if the log request was sent to statsd.
- */
- public static boolean logStart(int label) {
- int callingUid = Process.myUid();
- StatsdStatsLog.write(
- StatsdStatsLog.APP_BREADCRUMB_REPORTED,
- callingUid,
- label,
- StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__START);
- return true;
- }
-
- /**
- * Logs a stop event.
- *
- * @param label developer-chosen label.
- * @return True if the log request was sent to statsd.
- */
- public static boolean logStop(int label) {
- int callingUid = Process.myUid();
- StatsdStatsLog.write(
- StatsdStatsLog.APP_BREADCRUMB_REPORTED,
- callingUid,
- label,
- StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP);
- return true;
- }
-
- /**
- * Logs an event that does not represent a start or stop boundary.
- *
- * @param label developer-chosen label.
- * @return True if the log request was sent to statsd.
- */
- public static boolean logEvent(int label) {
- int callingUid = Process.myUid();
- StatsdStatsLog.write(
- StatsdStatsLog.APP_BREADCRUMB_REPORTED,
- callingUid,
- label,
- StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED);
- return true;
- }
-
- /**
- * Logs an event for binary push for module updates.
- *
- * @param trainName name of install train.
- * @param trainVersionCode version code of the train.
- * @param options optional flags about this install.
- * The last 3 bits indicate options:
- * 0x01: FLAG_REQUIRE_STAGING
- * 0x02: FLAG_ROLLBACK_ENABLED
- * 0x04: FLAG_REQUIRE_LOW_LATENCY_MONITOR
- * @param state current install state. Defined as State enums in
- * BinaryPushStateChanged atom in
- * frameworks/base/cmds/statsd/src/atoms.proto
- * @param experimentIds experiment ids.
- * @return True if the log request was sent to statsd.
- */
- @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
- public static boolean logBinaryPushStateChanged(@NonNull String trainName,
- long trainVersionCode, int options, int state,
- @NonNull long[] experimentIds) {
- ProtoOutputStream proto = new ProtoOutputStream();
- for (long id : experimentIds) {
- proto.write(
- ProtoOutputStream.FIELD_TYPE_INT64
- | ProtoOutputStream.FIELD_COUNT_REPEATED
- | EXPERIMENT_IDS_FIELD_ID,
- id);
- }
- StatsdStatsLog.write(StatsdStatsLog.BINARY_PUSH_STATE_CHANGED,
- trainName,
- trainVersionCode,
- (options & IStatsd.FLAG_REQUIRE_STAGING) > 0,
- (options & IStatsd.FLAG_ROLLBACK_ENABLED) > 0,
- (options & IStatsd.FLAG_REQUIRE_LOW_LATENCY_MONITOR) > 0,
- state,
- proto.getBytes(),
- 0,
- 0,
- false);
- return true;
- }
-
- /**
- * Write an event to stats log using the raw format.
- *
- * @param buffer The encoded buffer of data to write.
- * @param size The number of bytes from the buffer to write.
- * @hide
- */
- // TODO(b/144935988): Mark deprecated.
- @SystemApi
- public static void writeRaw(@NonNull byte[] buffer, int size) {
- // TODO(b/144935988): make this no-op once clients have migrated to StatsEvent.
- writeImpl(buffer, size, 0);
- }
-
- /**
- * Write an event to stats log using the raw format.
- *
- * @param buffer The encoded buffer of data to write.
- * @param size The number of bytes from the buffer to write.
- * @param atomId The id of the atom to which the event belongs.
- */
- private static native void writeImpl(@NonNull byte[] buffer, int size, int atomId);
-
- /**
- * Write an event to stats log using the raw format encapsulated in StatsEvent.
- * After writing to stats log, release() is called on the StatsEvent object.
- * No further action should be taken on the StatsEvent object following this call.
- *
- * @param statsEvent The StatsEvent object containing the encoded buffer of data to write.
- * @hide
- */
- @SystemApi
- public static void write(@NonNull final StatsEvent statsEvent) {
- writeImpl(statsEvent.getBytes(), statsEvent.getNumBytes(), statsEvent.getAtomId());
- statsEvent.release();
- }
-
- private static void enforceDumpCallingPermission(Context context) {
- context.enforceCallingPermission(android.Manifest.permission.DUMP, "Need DUMP permission.");
- }
-
- private static void enforcesageStatsCallingPermission(Context context) {
- context.enforceCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS,
- "Need PACKAGE_USAGE_STATS permission.");
- }
-}
diff --git a/apex/statsd/framework/test/Android.bp b/apex/statsd/framework/test/Android.bp
deleted file mode 100644
index b113d59..0000000
--- a/apex/statsd/framework/test/Android.bp
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test {
- name: "FrameworkStatsdTest",
- platform_apis: true,
- srcs: [
- // TODO(b/147705194): Use framework-statsd as a lib dependency instead.
- ":framework-statsd-sources",
- "**/*.java",
- ],
- manifest: "AndroidManifest.xml",
- static_libs: [
- "androidx.test.rules",
- "truth-prebuilt",
- ],
- libs: [
- "android.test.runner.stubs",
- "android.test.base.stubs",
- ],
- test_suites: [
- "device-tests",
- "mts",
- ],
-}
\ No newline at end of file
diff --git a/apex/statsd/framework/test/AndroidManifest.xml b/apex/statsd/framework/test/AndroidManifest.xml
deleted file mode 100644
index 8f89d23..0000000
--- a/apex/statsd/framework/test/AndroidManifest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.os.statsd.framework.test"
- >
-
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.os.statsd.framework.test"
- android:label="Framework Statsd Tests" />
-
-</manifest>
diff --git a/apex/statsd/framework/test/AndroidTest.xml b/apex/statsd/framework/test/AndroidTest.xml
deleted file mode 100644
index fb51915..0000000
--- a/apex/statsd/framework/test/AndroidTest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Runs Tests for Statsd.">
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
- <option name="test-file-name" value="FrameworkStatsdTest.apk" />
- <option name="install-arg" value="-g" />
- </target_preparer>
-
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="mts" />
- <option name="test-tag" value="FrameworkStatsdTest" />
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="com.android.os.statsd.framework.test" />
- <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
- <option name="hidden-api-checks" value="false"/>
- </test>
-
- <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
- <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
- </object>
-</configuration>
\ No newline at end of file
diff --git a/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java b/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java
deleted file mode 100644
index fd386bd..0000000
--- a/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.StatsManager.PullAtomMetadata;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class PullAtomMetadataTest {
-
- @Test
- public void testEmpty() {
- PullAtomMetadata metadata = new PullAtomMetadata.Builder().build();
- assertThat(metadata.getTimeoutMillis()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_MILLIS);
- assertThat(metadata.getCoolDownMillis()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_MILLIS);
- assertThat(metadata.getAdditiveFields()).isNull();
- }
-
- @Test
- public void testSetTimeoutMillis() {
- long timeoutMillis = 500L;
- PullAtomMetadata metadata =
- new PullAtomMetadata.Builder().setTimeoutMillis(timeoutMillis).build();
- assertThat(metadata.getTimeoutMillis()).isEqualTo(timeoutMillis);
- assertThat(metadata.getCoolDownMillis()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_MILLIS);
- assertThat(metadata.getAdditiveFields()).isNull();
- }
-
- @Test
- public void testSetCoolDownMillis() {
- long coolDownMillis = 10_000L;
- PullAtomMetadata metadata =
- new PullAtomMetadata.Builder().setCoolDownMillis(coolDownMillis).build();
- assertThat(metadata.getTimeoutMillis()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_MILLIS);
- assertThat(metadata.getCoolDownMillis()).isEqualTo(coolDownMillis);
- assertThat(metadata.getAdditiveFields()).isNull();
- }
-
- @Test
- public void testSetAdditiveFields() {
- int[] fields = {2, 4, 6};
- PullAtomMetadata metadata =
- new PullAtomMetadata.Builder().setAdditiveFields(fields).build();
- assertThat(metadata.getTimeoutMillis()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_MILLIS);
- assertThat(metadata.getCoolDownMillis()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_MILLIS);
- assertThat(metadata.getAdditiveFields()).isEqualTo(fields);
- }
-
- @Test
- public void testSetAllElements() {
- long timeoutMillis = 300L;
- long coolDownMillis = 9572L;
- int[] fields = {3, 2};
- PullAtomMetadata metadata = new PullAtomMetadata.Builder()
- .setTimeoutMillis(timeoutMillis)
- .setCoolDownMillis(coolDownMillis)
- .setAdditiveFields(fields)
- .build();
- assertThat(metadata.getTimeoutMillis()).isEqualTo(timeoutMillis);
- assertThat(metadata.getCoolDownMillis()).isEqualTo(coolDownMillis);
- assertThat(metadata.getAdditiveFields()).isEqualTo(fields);
- }
-}
diff --git a/apex/statsd/framework/test/src/android/os/StatsDimensionsValueTest.java b/apex/statsd/framework/test/src/android/os/StatsDimensionsValueTest.java
deleted file mode 100644
index db25911..0000000
--- a/apex/statsd/framework/test/src/android/os/StatsDimensionsValueTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.List;
-
-@RunWith(JUnit4.class)
-public final class StatsDimensionsValueTest {
-
- @Test
- public void testConversionFromStructuredParcel() {
- int tupleField = 100; // atom id
- String stringValue = "Hello";
- int intValue = 123;
- long longValue = 123456789L;
- float floatValue = 1.1f;
- boolean boolValue = true;
-
- // Construct structured parcel
- StatsDimensionsValueParcel sdvp = new StatsDimensionsValueParcel();
- sdvp.field = tupleField;
- sdvp.valueType = StatsDimensionsValue.TUPLE_VALUE_TYPE;
- sdvp.tupleValue = new StatsDimensionsValueParcel[5];
-
- for (int i = 0; i < 5; i++) {
- sdvp.tupleValue[i] = new StatsDimensionsValueParcel();
- sdvp.tupleValue[i].field = i + 1;
- }
-
- sdvp.tupleValue[0].valueType = StatsDimensionsValue.STRING_VALUE_TYPE;
- sdvp.tupleValue[1].valueType = StatsDimensionsValue.INT_VALUE_TYPE;
- sdvp.tupleValue[2].valueType = StatsDimensionsValue.LONG_VALUE_TYPE;
- sdvp.tupleValue[3].valueType = StatsDimensionsValue.FLOAT_VALUE_TYPE;
- sdvp.tupleValue[4].valueType = StatsDimensionsValue.BOOLEAN_VALUE_TYPE;
-
- sdvp.tupleValue[0].stringValue = stringValue;
- sdvp.tupleValue[1].intValue = intValue;
- sdvp.tupleValue[2].longValue = longValue;
- sdvp.tupleValue[3].floatValue = floatValue;
- sdvp.tupleValue[4].boolValue = boolValue;
-
- // Convert to StatsDimensionsValue and check result
- StatsDimensionsValue sdv = new StatsDimensionsValue(sdvp);
-
- assertThat(sdv.getField()).isEqualTo(tupleField);
- assertThat(sdv.getValueType()).isEqualTo(StatsDimensionsValue.TUPLE_VALUE_TYPE);
- List<StatsDimensionsValue> sdvChildren = sdv.getTupleValueList();
- assertThat(sdvChildren.size()).isEqualTo(5);
-
- for (int i = 0; i < 5; i++) {
- assertThat(sdvChildren.get(i).getField()).isEqualTo(i + 1);
- }
-
- assertThat(sdvChildren.get(0).getValueType())
- .isEqualTo(StatsDimensionsValue.STRING_VALUE_TYPE);
- assertThat(sdvChildren.get(1).getValueType())
- .isEqualTo(StatsDimensionsValue.INT_VALUE_TYPE);
- assertThat(sdvChildren.get(2).getValueType())
- .isEqualTo(StatsDimensionsValue.LONG_VALUE_TYPE);
- assertThat(sdvChildren.get(3).getValueType())
- .isEqualTo(StatsDimensionsValue.FLOAT_VALUE_TYPE);
- assertThat(sdvChildren.get(4).getValueType())
- .isEqualTo(StatsDimensionsValue.BOOLEAN_VALUE_TYPE);
-
- assertThat(sdvChildren.get(0).getStringValue()).isEqualTo(stringValue);
- assertThat(sdvChildren.get(1).getIntValue()).isEqualTo(intValue);
- assertThat(sdvChildren.get(2).getLongValue()).isEqualTo(longValue);
- assertThat(sdvChildren.get(3).getFloatValue()).isEqualTo(floatValue);
- assertThat(sdvChildren.get(4).getBooleanValue()).isEqualTo(boolValue);
-
- // Ensure that StatsDimensionsValue and StatsDimensionsValueParcel are
- // parceled equivalently
- Parcel sdvpParcel = Parcel.obtain();
- Parcel sdvParcel = Parcel.obtain();
- sdvp.writeToParcel(sdvpParcel, 0);
- sdv.writeToParcel(sdvParcel, 0);
- assertThat(sdvpParcel.dataSize()).isEqualTo(sdvParcel.dataSize());
- }
-
- @Test
- public void testNullTupleArray() {
- int tupleField = 100; // atom id
-
- StatsDimensionsValueParcel parcel = new StatsDimensionsValueParcel();
- parcel.field = tupleField;
- parcel.valueType = StatsDimensionsValue.TUPLE_VALUE_TYPE;
- parcel.tupleValue = null;
-
- StatsDimensionsValue sdv = new StatsDimensionsValue(parcel);
- assertThat(sdv.getField()).isEqualTo(tupleField);
- assertThat(sdv.getValueType()).isEqualTo(StatsDimensionsValue.TUPLE_VALUE_TYPE);
- List<StatsDimensionsValue> sdvChildren = sdv.getTupleValueList();
- assertThat(sdvChildren.size()).isEqualTo(0);
- }
-}
diff --git a/apex/statsd/framework/test/src/android/util/StatsEventTest.java b/apex/statsd/framework/test/src/android/util/StatsEventTest.java
deleted file mode 100644
index 8d26369..0000000
--- a/apex/statsd/framework/test/src/android/util/StatsEventTest.java
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.os.SystemClock;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.common.collect.Range;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Random;
-
-/**
- * Internal tests for {@link StatsEvent}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class StatsEventTest {
-
- @Test
- public void testNoFields() {
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder().usePooledBuffer().build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- final int expectedAtomId = 0;
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("Third element is not errors type")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ERRORS);
-
- final int errorMask = buffer.getInt();
-
- assertWithMessage("ERROR_NO_ATOM_ID should be the only error in the error mask")
- .that(errorMask).isEqualTo(StatsEvent.ERROR_NO_ATOM_ID);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testOnlyAtomId() {
- final int expectedAtomId = 109;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(2);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testIntBooleanIntInt() {
- final int expectedAtomId = 109;
- final int field1 = 1;
- final boolean field2 = true;
- final int field3 = 3;
- final int field4 = 4;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeInt(field1)
- .writeBoolean(field2)
- .writeInt(field3)
- .writeInt(field4)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(6);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("First field is not Int")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect field 1")
- .that(buffer.getInt()).isEqualTo(field1);
-
- assertWithMessage("Second field is not Boolean")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN);
-
- assertWithMessage("Incorrect field 2")
- .that(buffer.get()).isEqualTo(1);
-
- assertWithMessage("Third field is not Int")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect field 3")
- .that(buffer.getInt()).isEqualTo(field3);
-
- assertWithMessage("Fourth field is not Int")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect field 4")
- .that(buffer.getInt()).isEqualTo(field4);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testStringFloatByteArray() {
- final int expectedAtomId = 109;
- final String field1 = "Str 1";
- final float field2 = 9.334f;
- final byte[] field3 = new byte[] { 56, 23, 89, -120 };
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeString(field1)
- .writeFloat(field2)
- .writeByteArray(field3)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(5);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("First field is not String")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_STRING);
-
- final String field1Actual = getStringFromByteBuffer(buffer);
- assertWithMessage("Incorrect field 1")
- .that(field1Actual).isEqualTo(field1);
-
- assertWithMessage("Second field is not Float")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_FLOAT);
-
- assertWithMessage("Incorrect field 2")
- .that(buffer.getFloat()).isEqualTo(field2);
-
- assertWithMessage("Third field is not byte array")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BYTE_ARRAY);
-
- final byte[] field3Actual = getByteArrayFromByteBuffer(buffer);
- assertWithMessage("Incorrect field 3")
- .that(field3Actual).isEqualTo(field3);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testAttributionChainLong() {
- final int expectedAtomId = 109;
- final int[] uids = new int[] { 1, 2, 3, 4, 5 };
- final String[] tags = new String[] { "1", "2", "3", "4", "5" };
- final long field2 = -230909823L;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeAttributionChain(uids, tags)
- .writeLong(field2)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(4);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("First field is not Attribution Chain")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ATTRIBUTION_CHAIN);
-
- assertWithMessage("Incorrect number of attribution nodes")
- .that(buffer.get()).isEqualTo((byte) uids.length);
-
- for (int i = 0; i < tags.length; i++) {
- assertWithMessage("Incorrect uid in Attribution Chain")
- .that(buffer.getInt()).isEqualTo(uids[i]);
-
- final String tag = getStringFromByteBuffer(buffer);
- assertWithMessage("Incorrect tag in Attribution Chain")
- .that(tag).isEqualTo(tags[i]);
- }
-
- assertWithMessage("Second field is not Long")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect field 2")
- .that(buffer.getLong()).isEqualTo(field2);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testKeyValuePairs() {
- final int expectedAtomId = 109;
- final SparseIntArray intMap = new SparseIntArray();
- final SparseLongArray longMap = new SparseLongArray();
- final SparseArray<String> stringMap = new SparseArray<>();
- final SparseArray<Float> floatMap = new SparseArray<>();
- intMap.put(1, -1);
- intMap.put(2, -2);
- stringMap.put(3, "abc");
- stringMap.put(4, "2h");
- floatMap.put(9, -234.344f);
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeKeyValuePairs(intMap, longMap, stringMap, floatMap)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("First field is not KeyValuePairs")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_KEY_VALUE_PAIRS);
-
- assertWithMessage("Incorrect number of key value pairs")
- .that(buffer.get()).isEqualTo(
- (byte) (intMap.size() + longMap.size() + stringMap.size()
- + floatMap.size()));
-
- for (int i = 0; i < intMap.size(); i++) {
- assertWithMessage("Incorrect key in intMap")
- .that(buffer.getInt()).isEqualTo(intMap.keyAt(i));
- assertWithMessage("The type id of the value should be TYPE_INT in intMap")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("Incorrect value in intMap")
- .that(buffer.getInt()).isEqualTo(intMap.valueAt(i));
- }
-
- for (int i = 0; i < longMap.size(); i++) {
- assertWithMessage("Incorrect key in longMap")
- .that(buffer.getInt()).isEqualTo(longMap.keyAt(i));
- assertWithMessage("The type id of the value should be TYPE_LONG in longMap")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
- assertWithMessage("Incorrect value in longMap")
- .that(buffer.getLong()).isEqualTo(longMap.valueAt(i));
- }
-
- for (int i = 0; i < stringMap.size(); i++) {
- assertWithMessage("Incorrect key in stringMap")
- .that(buffer.getInt()).isEqualTo(stringMap.keyAt(i));
- assertWithMessage("The type id of the value should be TYPE_STRING in stringMap")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_STRING);
- final String value = getStringFromByteBuffer(buffer);
- assertWithMessage("Incorrect value in stringMap")
- .that(value).isEqualTo(stringMap.valueAt(i));
- }
-
- for (int i = 0; i < floatMap.size(); i++) {
- assertWithMessage("Incorrect key in floatMap")
- .that(buffer.getInt()).isEqualTo(floatMap.keyAt(i));
- assertWithMessage("The type id of the value should be TYPE_FLOAT in floatMap")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_FLOAT);
- assertWithMessage("Incorrect value in floatMap")
- .that(buffer.getFloat()).isEqualTo(floatMap.valueAt(i));
- }
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testSingleAnnotations() {
- final int expectedAtomId = 109;
- final int field1 = 1;
- final byte field1AnnotationId = 45;
- final boolean field1AnnotationValue = false;
- final boolean field2 = true;
- final byte field2AnnotationId = 1;
- final int field2AnnotationValue = 23;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeInt(field1)
- .addBooleanAnnotation(field1AnnotationId, field1AnnotationValue)
- .writeBoolean(field2)
- .addIntAnnotation(field2AnnotationId, field2AnnotationValue)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(4);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- final byte field1Header = buffer.get();
- final int field1AnnotationValueCount = field1Header >> 4;
- final byte field1Type = (byte) (field1Header & 0x0F);
- assertWithMessage("First field is not Int")
- .that(field1Type).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("First field annotation count is wrong")
- .that(field1AnnotationValueCount).isEqualTo(1);
- assertWithMessage("Incorrect field 1")
- .that(buffer.getInt()).isEqualTo(field1);
- assertWithMessage("First field's annotation id is wrong")
- .that(buffer.get()).isEqualTo(field1AnnotationId);
- assertWithMessage("First field's annotation type is wrong")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN);
- assertWithMessage("First field's annotation value is wrong")
- .that(buffer.get()).isEqualTo(field1AnnotationValue ? 1 : 0);
-
- final byte field2Header = buffer.get();
- final int field2AnnotationValueCount = field2Header >> 4;
- final byte field2Type = (byte) (field2Header & 0x0F);
- assertWithMessage("Second field is not boolean")
- .that(field2Type).isEqualTo(StatsEvent.TYPE_BOOLEAN);
- assertWithMessage("Second field annotation count is wrong")
- .that(field2AnnotationValueCount).isEqualTo(1);
- assertWithMessage("Incorrect field 2")
- .that(buffer.get()).isEqualTo(field2 ? 1 : 0);
- assertWithMessage("Second field's annotation id is wrong")
- .that(buffer.get()).isEqualTo(field2AnnotationId);
- assertWithMessage("Second field's annotation type is wrong")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("Second field's annotation value is wrong")
- .that(buffer.getInt()).isEqualTo(field2AnnotationValue);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testAtomIdAnnotations() {
- final int expectedAtomId = 109;
- final byte atomAnnotationId = 84;
- final int atomAnnotationValue = 9;
- final int field1 = 1;
- final byte field1AnnotationId = 45;
- final boolean field1AnnotationValue = false;
- final boolean field2 = true;
- final byte field2AnnotationId = 1;
- final int field2AnnotationValue = 23;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .addIntAnnotation(atomAnnotationId, atomAnnotationValue)
- .writeInt(field1)
- .addBooleanAnnotation(field1AnnotationId, field1AnnotationValue)
- .writeBoolean(field2)
- .addIntAnnotation(field2AnnotationId, field2AnnotationValue)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(4);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- final byte atomIdHeader = buffer.get();
- final int atomIdAnnotationValueCount = atomIdHeader >> 4;
- final byte atomIdValueType = (byte) (atomIdHeader & 0x0F);
- assertWithMessage("Second element is not atom id")
- .that(atomIdValueType).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("Atom id annotation count is wrong")
- .that(atomIdAnnotationValueCount).isEqualTo(1);
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
- assertWithMessage("Atom id's annotation id is wrong")
- .that(buffer.get()).isEqualTo(atomAnnotationId);
- assertWithMessage("Atom id's annotation type is wrong")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("Atom id's annotation value is wrong")
- .that(buffer.getInt()).isEqualTo(atomAnnotationValue);
-
- final byte field1Header = buffer.get();
- final int field1AnnotationValueCount = field1Header >> 4;
- final byte field1Type = (byte) (field1Header & 0x0F);
- assertWithMessage("First field is not Int")
- .that(field1Type).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("First field annotation count is wrong")
- .that(field1AnnotationValueCount).isEqualTo(1);
- assertWithMessage("Incorrect field 1")
- .that(buffer.getInt()).isEqualTo(field1);
- assertWithMessage("First field's annotation id is wrong")
- .that(buffer.get()).isEqualTo(field1AnnotationId);
- assertWithMessage("First field's annotation type is wrong")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN);
- assertWithMessage("First field's annotation value is wrong")
- .that(buffer.get()).isEqualTo(field1AnnotationValue ? 1 : 0);
-
- final byte field2Header = buffer.get();
- final int field2AnnotationValueCount = field2Header >> 4;
- final byte field2Type = (byte) (field2Header & 0x0F);
- assertWithMessage("Second field is not boolean")
- .that(field2Type).isEqualTo(StatsEvent.TYPE_BOOLEAN);
- assertWithMessage("Second field annotation count is wrong")
- .that(field2AnnotationValueCount).isEqualTo(1);
- assertWithMessage("Incorrect field 2")
- .that(buffer.get()).isEqualTo(field2 ? 1 : 0);
- assertWithMessage("Second field's annotation id is wrong")
- .that(buffer.get()).isEqualTo(field2AnnotationId);
- assertWithMessage("Second field's annotation type is wrong")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("Second field's annotation value is wrong")
- .that(buffer.getInt()).isEqualTo(field2AnnotationValue);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testSetAtomIdNotCalledImmediately() {
- final int expectedAtomId = 109;
- final int field1 = 25;
- final boolean field2 = true;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .writeInt(field1)
- .setAtomId(expectedAtomId)
- .writeBoolean(field2)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("Third element is not errors type")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ERRORS);
-
- final int errorMask = buffer.getInt();
-
- assertWithMessage("ERROR_ATOM_ID_INVALID_POSITION should be the only error in the mask")
- .that(errorMask).isEqualTo(StatsEvent.ERROR_ATOM_ID_INVALID_POSITION);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testLargePulledEvent() {
- final int expectedAtomId = 10_020;
- byte[] field1 = new byte[10 * 1024];
- new Random().nextBytes(field1);
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent =
- StatsEvent.newBuilder().setAtomId(expectedAtomId).writeByteArray(field1).build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get())
- .isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong())
- .isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id").that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("Third element is not byte array")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_BYTE_ARRAY);
-
- final byte[] field1Actual = getByteArrayFromByteBuffer(buffer);
- assertWithMessage("Incorrect field 1").that(field1Actual).isEqualTo(field1);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testPulledEventOverflow() {
- final int expectedAtomId = 10_020;
- byte[] field1 = new byte[50 * 1024];
- new Random().nextBytes(field1);
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent =
- StatsEvent.newBuilder().setAtomId(expectedAtomId).writeByteArray(field1).build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get())
- .isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong())
- .isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id").that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("Third element is not errors type")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_ERRORS);
-
- final int errorMask = buffer.getInt();
-
- assertWithMessage("ERROR_OVERFLOW should be the only error in the error mask")
- .that(errorMask)
- .isEqualTo(StatsEvent.ERROR_OVERFLOW);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testPushedEventOverflow() {
- final int expectedAtomId = 10_020;
- byte[] field1 = new byte[10 * 1024];
- new Random().nextBytes(field1);
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeByteArray(field1)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get())
- .isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong())
- .isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id").that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("Third element is not errors type")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_ERRORS);
-
- final int errorMask = buffer.getInt();
-
- assertWithMessage("ERROR_OVERFLOW should be the only error in the error mask")
- .that(errorMask)
- .isEqualTo(StatsEvent.ERROR_OVERFLOW);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- private static byte[] getByteArrayFromByteBuffer(final ByteBuffer buffer) {
- final int numBytes = buffer.getInt();
- byte[] bytes = new byte[numBytes];
- buffer.get(bytes);
- return bytes;
- }
-
- private static String getStringFromByteBuffer(final ByteBuffer buffer) {
- final byte[] bytes = getByteArrayFromByteBuffer(buffer);
- return new String(bytes, UTF_8);
- }
-}
diff --git a/apex/statsd/jni/android_util_StatsLog.cpp b/apex/statsd/jni/android_util_StatsLog.cpp
deleted file mode 100644
index 71ce949..0000000
--- a/apex/statsd/jni/android_util_StatsLog.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_NAMESPACE "StatsLog.tag."
-#define LOG_TAG "StatsLog_println"
-
-#include <jni.h>
-#include <log/log.h>
-#include <nativehelper/scoped_local_ref.h>
-#include "stats_buffer_writer.h"
-
-namespace android {
-
-static void android_util_StatsLog_write(JNIEnv* env, jobject clazz, jbyteArray buf, jint size,
- jint atomId) {
- if (buf == NULL) {
- return;
- }
- jint actualSize = env->GetArrayLength(buf);
- if (actualSize < size) {
- return;
- }
-
- jbyte* bufferArray = env->GetByteArrayElements(buf, NULL);
- if (bufferArray == NULL) {
- return;
- }
-
- write_buffer_to_statsd((void*) bufferArray, size, atomId);
-
- env->ReleaseByteArrayElements(buf, bufferArray, 0);
-}
-
-/*
- * JNI registration.
- */
-static const JNINativeMethod gMethods[] = {
- /* name, signature, funcPtr */
- { "writeImpl", "([BII)V", (void*) android_util_StatsLog_write },
-};
-
-int register_android_util_StatsLog(JNIEnv* env)
-{
- static const char* kStatsLogClass = "android/util/StatsLog";
-
- ScopedLocalRef<jclass> cls(env, env->FindClass(kStatsLogClass));
- if (cls.get() == nullptr) {
- ALOGE("jni statsd registration failure, class not found '%s'", kStatsLogClass);
- return JNI_ERR;
- }
-
- const jint count = sizeof(gMethods) / sizeof(gMethods[0]);
- int status = env->RegisterNatives(cls.get(), gMethods, count);
- if (status < 0) {
- ALOGE("jni statsd registration failure, status: %d", status);
- return JNI_ERR;
- }
- return JNI_VERSION_1_4;
-}
-
-}; // namespace android
-
-/*
- * JNI Initialization
- */
-jint JNI_OnLoad(JavaVM* jvm, void* reserved) {
- JNIEnv* e;
-
- ALOGV("statsd : loading JNI\n");
- // Check JNI version
- if (jvm->GetEnv((void**)&e, JNI_VERSION_1_4)) {
- ALOGE("JNI version mismatch error");
- return JNI_ERR;
- }
-
- return android::register_android_util_StatsLog(e);
-}
diff --git a/apex/statsd/service/Android.bp b/apex/statsd/service/Android.bp
deleted file mode 100644
index df0ccfc..0000000
--- a/apex/statsd/service/Android.bp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-filegroup {
- name: "service-statsd-sources",
- srcs: [
- "java/**/*.java",
- ],
-}
-
-java_library {
- name: "service-statsd",
- srcs: [ ":service-statsd-sources" ],
- sdk_version: "system_server_current",
- libs: [
- "framework-annotations-lib",
- "framework-statsd",
- ],
- plugins: ["java_api_finder"],
- apex_available: [
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
-}
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java
deleted file mode 100644
index dc477a5..0000000
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.stats;
-
-import android.app.PendingIntent;
-import android.app.StatsManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.IPendingIntentRef;
-import android.os.Process;
-import android.os.StatsDimensionsValue;
-import android.os.StatsDimensionsValueParcel;
-import android.util.Log;
-
-import com.android.server.SystemService;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * @hide
- */
-public class StatsCompanion {
- private static final String TAG = "StatsCompanion";
- private static final boolean DEBUG = false;
-
- private static final int AID_STATSD = 1066;
-
- private static final String STATS_COMPANION_SERVICE = "statscompanion";
- private static final String STATS_MANAGER_SERVICE = "statsmanager";
-
- static void enforceStatsdCallingUid() {
- if (Binder.getCallingPid() == Process.myPid()) {
- return;
- }
- if (Binder.getCallingUid() != AID_STATSD) {
- throw new SecurityException("Not allowed to access StatsCompanion");
- }
- }
-
- /**
- * Lifecycle class for both {@link StatsCompanionService} and {@link StatsManagerService}.
- */
- public static final class Lifecycle extends SystemService {
- private StatsCompanionService mStatsCompanionService;
- private StatsManagerService mStatsManagerService;
-
- public Lifecycle(Context context) {
- super(context);
- }
-
- @Override
- public void onStart() {
- mStatsCompanionService = new StatsCompanionService(getContext());
- mStatsManagerService = new StatsManagerService(getContext());
- mStatsCompanionService.setStatsManagerService(mStatsManagerService);
- mStatsManagerService.setStatsCompanionService(mStatsCompanionService);
-
- try {
- publishBinderService(STATS_COMPANION_SERVICE, mStatsCompanionService);
- if (DEBUG) Log.d(TAG, "Published " + STATS_COMPANION_SERVICE);
- publishBinderService(STATS_MANAGER_SERVICE, mStatsManagerService);
- if (DEBUG) Log.d(TAG, "Published " + STATS_MANAGER_SERVICE);
- } catch (Exception e) {
- Log.e(TAG, "Failed to publishBinderService", e);
- }
- }
-
- @Override
- public void onBootPhase(int phase) {
- super.onBootPhase(phase);
- if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
- mStatsCompanionService.systemReady();
- }
- if (phase == PHASE_BOOT_COMPLETED) {
- mStatsCompanionService.bootCompleted();
- }
- }
- }
-
- /**
- * Wrapper for {@link PendingIntent}. Allows Statsd to send PendingIntents.
- */
- public static class PendingIntentRef extends IPendingIntentRef.Stub {
-
- private static final String TAG = "PendingIntentRef";
-
- /**
- * The last report time is provided with each intent registered to
- * StatsManager#setFetchReportsOperation. This allows easy de-duping in the receiver if
- * statsd is requesting the client to retrieve the same statsd data. The last report time
- * corresponds to the last_report_elapsed_nanos that will provided in the current
- * ConfigMetricsReport, and this timestamp also corresponds to the
- * current_report_elapsed_nanos of the most recently obtained ConfigMetricsReport.
- */
- private static final String EXTRA_LAST_REPORT_TIME = "android.app.extra.LAST_REPORT_TIME";
- private static final int CODE_DATA_BROADCAST = 1;
- private static final int CODE_ACTIVE_CONFIGS_BROADCAST = 1;
- private static final int CODE_SUBSCRIBER_BROADCAST = 1;
-
- private final PendingIntent mPendingIntent;
- private final Context mContext;
-
- public PendingIntentRef(PendingIntent pendingIntent, Context context) {
- mPendingIntent = pendingIntent;
- mContext = context;
- }
-
- @Override
- public void sendDataBroadcast(long lastReportTimeNs) {
- enforceStatsdCallingUid();
- Intent intent = new Intent();
- intent.putExtra(EXTRA_LAST_REPORT_TIME, lastReportTimeNs);
- try {
- mPendingIntent.send(mContext, CODE_DATA_BROADCAST, intent, null, null);
- } catch (PendingIntent.CanceledException e) {
- Log.w(TAG, "Unable to send PendingIntent");
- }
- }
-
- @Override
- public void sendActiveConfigsChangedBroadcast(long[] configIds) {
- enforceStatsdCallingUid();
- Intent intent = new Intent();
- intent.putExtra(StatsManager.EXTRA_STATS_ACTIVE_CONFIG_KEYS, configIds);
- try {
- mPendingIntent.send(mContext, CODE_ACTIVE_CONFIGS_BROADCAST, intent, null, null);
- if (DEBUG) {
- Log.d(TAG, "Sent broadcast with config ids " + Arrays.toString(configIds));
- }
- } catch (PendingIntent.CanceledException e) {
- Log.w(TAG, "Unable to send active configs changed broadcast using PendingIntent");
- }
- }
-
- @Override
- public void sendSubscriberBroadcast(long configUid, long configId, long subscriptionId,
- long subscriptionRuleId, String[] cookies,
- StatsDimensionsValueParcel dimensionsValueParcel) {
- enforceStatsdCallingUid();
- StatsDimensionsValue dimensionsValue = new StatsDimensionsValue(dimensionsValueParcel);
- Intent intent =
- new Intent()
- .putExtra(StatsManager.EXTRA_STATS_CONFIG_UID, configUid)
- .putExtra(StatsManager.EXTRA_STATS_CONFIG_KEY, configId)
- .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID, subscriptionId)
- .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_RULE_ID,
- subscriptionRuleId)
- .putExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, dimensionsValue);
-
- ArrayList<String> cookieList = new ArrayList<>(cookies.length);
- cookieList.addAll(Arrays.asList(cookies));
- intent.putStringArrayListExtra(
- StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES, cookieList);
-
- if (DEBUG) {
- Log.d(TAG,
- String.format(
- "Statsd sendSubscriberBroadcast with params {%d %d %d %d %s %s}",
- configUid, configId, subscriptionId, subscriptionRuleId,
- Arrays.toString(cookies),
- dimensionsValue));
- }
- try {
- mPendingIntent.send(mContext, CODE_SUBSCRIBER_BROADCAST, intent, null, null);
- } catch (PendingIntent.CanceledException e) {
- Log.w(TAG,
- "Unable to send using PendingIntent from uid " + configUid
- + "; presumably it had been cancelled.");
- }
- }
- }
-}
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
deleted file mode 100644
index cbc8ed6..0000000
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.stats;
-
-import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
-
-import android.app.AlarmManager;
-import android.app.AlarmManager.OnAlarmListener;
-import android.app.StatsManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.IStatsCompanionService;
-import android.os.IStatsd;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.StatsFrameworkInitializer;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Helper service for statsd (the native stats management service in cmds/statsd/).
- * Used for registering and receiving alarms on behalf of statsd.
- *
- * @hide
- */
-public class StatsCompanionService extends IStatsCompanionService.Stub {
-
- private static final long MILLIS_IN_A_DAY = TimeUnit.DAYS.toMillis(1);
-
- public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
- public static final String CONFIG_DIR = "/data/misc/stats-service";
-
- static final String TAG = "StatsCompanionService";
- static final boolean DEBUG = false;
- /**
- * Hard coded field ids of frameworks/base/cmds/statsd/src/uid_data.proto
- * to be used in ProtoOutputStream.
- */
- private static final int APPLICATION_INFO_FIELD_ID = 1;
- private static final int UID_FIELD_ID = 1;
- private static final int VERSION_FIELD_ID = 2;
- private static final int VERSION_STRING_FIELD_ID = 3;
- private static final int PACKAGE_NAME_FIELD_ID = 4;
- private static final int INSTALLER_FIELD_ID = 5;
-
- public static final int DEATH_THRESHOLD = 10;
-
- static final class CompanionHandler extends Handler {
- CompanionHandler(Looper looper) {
- super(looper);
- }
- }
-
- private final Context mContext;
- private final AlarmManager mAlarmManager;
- @GuardedBy("sStatsdLock")
- private static IStatsd sStatsd;
- private static final Object sStatsdLock = new Object();
-
- private final OnAlarmListener mAnomalyAlarmListener;
- private final OnAlarmListener mPullingAlarmListener;
- private final OnAlarmListener mPeriodicAlarmListener;
-
- private StatsManagerService mStatsManagerService;
-
- @GuardedBy("sStatsdLock")
- private final HashSet<Long> mDeathTimeMillis = new HashSet<>();
- @GuardedBy("sStatsdLock")
- private final HashMap<Long, String> mDeletedFiles = new HashMap<>();
- private final CompanionHandler mHandler;
-
- // Flag that is set when PHASE_BOOT_COMPLETED is triggered in the StatsCompanion lifecycle.
- private AtomicBoolean mBootCompleted = new AtomicBoolean(false);
-
- public StatsCompanionService(Context context) {
- super();
- mContext = context;
- mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
- if (DEBUG) Log.d(TAG, "Registered receiver for ACTION_PACKAGE_REPLACED and ADDED.");
- HandlerThread handlerThread = new HandlerThread(TAG);
- handlerThread.start();
- mHandler = new CompanionHandler(handlerThread.getLooper());
-
- mAnomalyAlarmListener = new AnomalyAlarmListener(context);
- mPullingAlarmListener = new PullingAlarmListener(context);
- mPeriodicAlarmListener = new PeriodicAlarmListener(context);
- }
-
- private final static int[] toIntArray(List<Integer> list) {
- int[] ret = new int[list.size()];
- for (int i = 0; i < ret.length; i++) {
- ret[i] = list.get(i);
- }
- return ret;
- }
-
- private final static long[] toLongArray(List<Long> list) {
- long[] ret = new long[list.size()];
- for (int i = 0; i < ret.length; i++) {
- ret[i] = list.get(i);
- }
- return ret;
- }
-
- /**
- * Non-blocking call to retrieve a reference to statsd
- *
- * @return IStatsd object if statsd is ready, null otherwise.
- */
- private static IStatsd getStatsdNonblocking() {
- synchronized (sStatsdLock) {
- return sStatsd;
- }
- }
-
- private static void informAllUids(Context context) {
- ParcelFileDescriptor[] fds;
- try {
- fds = ParcelFileDescriptor.createPipe();
- } catch (IOException e) {
- Log.e(TAG, "Failed to create a pipe to send uid map data.", e);
- return;
- }
- HandlerThread backgroundThread = new HandlerThread(
- "statsCompanionService.bg", THREAD_PRIORITY_BACKGROUND);
- backgroundThread.start();
- Handler handler = new Handler(backgroundThread.getLooper());
- handler.post(() -> {
- UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
- PackageManager pm = context.getPackageManager();
- final List<UserHandle> users = um.getUserHandles(true);
- if (DEBUG) {
- Log.d(TAG, "Iterating over " + users.size() + " userHandles.");
- }
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- return;
- }
- try {
- statsd.informAllUidData(fds[0]);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to send uid map to statsd");
- }
- try {
- fds[0].close();
- } catch (IOException e) {
- Log.e(TAG, "Failed to close the read side of the pipe.", e);
- }
- final ParcelFileDescriptor writeFd = fds[1];
- FileOutputStream fout = new ParcelFileDescriptor.AutoCloseOutputStream(writeFd);
- try {
- ProtoOutputStream output = new ProtoOutputStream(fout);
- int numRecords = 0;
- // Add in all the apps for every user/profile.
- for (UserHandle userHandle : users) {
- List<PackageInfo> pi =
- pm.getInstalledPackagesAsUser(PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_ANY_USER
- | PackageManager.MATCH_APEX,
- userHandle.getIdentifier());
- for (int j = 0; j < pi.size(); j++) {
- if (pi.get(j).applicationInfo != null) {
- String installer;
- try {
- installer = pm.getInstallerPackageName(pi.get(j).packageName);
- } catch (IllegalArgumentException e) {
- installer = "";
- }
- long applicationInfoToken =
- output.start(ProtoOutputStream.FIELD_TYPE_MESSAGE
- | ProtoOutputStream.FIELD_COUNT_REPEATED
- | APPLICATION_INFO_FIELD_ID);
- output.write(ProtoOutputStream.FIELD_TYPE_INT32
- | ProtoOutputStream.FIELD_COUNT_SINGLE | UID_FIELD_ID,
- pi.get(j).applicationInfo.uid);
- output.write(ProtoOutputStream.FIELD_TYPE_INT64
- | ProtoOutputStream.FIELD_COUNT_SINGLE
- | VERSION_FIELD_ID, pi.get(j).getLongVersionCode());
- output.write(ProtoOutputStream.FIELD_TYPE_STRING
- | ProtoOutputStream.FIELD_COUNT_SINGLE
- | VERSION_STRING_FIELD_ID,
- pi.get(j).versionName);
- output.write(ProtoOutputStream.FIELD_TYPE_STRING
- | ProtoOutputStream.FIELD_COUNT_SINGLE
- | PACKAGE_NAME_FIELD_ID, pi.get(j).packageName);
- output.write(ProtoOutputStream.FIELD_TYPE_STRING
- | ProtoOutputStream.FIELD_COUNT_SINGLE
- | INSTALLER_FIELD_ID,
- installer == null ? "" : installer);
- numRecords++;
- output.end(applicationInfoToken);
- }
- }
- }
- output.flush();
- if (DEBUG) {
- Log.d(TAG, "Sent data for " + numRecords + " apps");
- }
- } finally {
- FileUtils.closeQuietly(fout);
- backgroundThread.quit();
- backgroundThread.interrupt();
- }
- });
- }
-
- private static class WakelockThread extends Thread {
- private final PowerManager.WakeLock mWl;
- private final Runnable mRunnable;
-
- WakelockThread(Context context, String wakelockName, Runnable runnable) {
- PowerManager powerManager = (PowerManager)
- context.getSystemService(Context.POWER_SERVICE);
- mWl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, wakelockName);
- mRunnable = runnable;
- }
- @Override
- public void run() {
- try {
- mRunnable.run();
- } finally {
- mWl.release();
- }
- }
- @Override
- public void start() {
- mWl.acquire();
- super.start();
- }
- }
-
- private final static class AppUpdateReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- /**
- * App updates actually consist of REMOVE, ADD, and then REPLACE broadcasts. To avoid
- * waste, we ignore the REMOVE and ADD broadcasts that contain the replacing flag.
- * If we can't find the value for EXTRA_REPLACING, we default to false.
- */
- if (!intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)
- && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
- return; // Keep only replacing or normal add and remove.
- }
- if (DEBUG) Log.d(TAG, "StatsCompanionService noticed an app was updated.");
- synchronized (sStatsdLock) {
- if (sStatsd == null) {
- Log.w(TAG, "Could not access statsd to inform it of an app update");
- return;
- }
- try {
- if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
- Bundle b = intent.getExtras();
- int uid = b.getInt(Intent.EXTRA_UID);
- boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
- if (!replacing) {
- // Don't bother sending an update if we're right about to get another
- // intent for the new version that's added.
- String app = intent.getData().getSchemeSpecificPart();
- sStatsd.informOnePackageRemoved(app, uid);
- }
- } else {
- PackageManager pm = context.getPackageManager();
- Bundle b = intent.getExtras();
- int uid = b.getInt(Intent.EXTRA_UID);
- String app = intent.getData().getSchemeSpecificPart();
- PackageInfo pi = pm.getPackageInfo(app, PackageManager.MATCH_ANY_USER);
- String installer;
- try {
- installer = pm.getInstallerPackageName(app);
- } catch (IllegalArgumentException e) {
- installer = "";
- }
- sStatsd.informOnePackage(
- app,
- uid,
- pi.getLongVersionCode(),
- pi.versionName == null ? "" : pi.versionName,
- installer == null ? "" : installer);
- }
- } catch (Exception e) {
- Log.w(TAG, "Failed to inform statsd of an app update", e);
- }
- }
- }
- }
-
- private static final class UserUpdateReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- // Pull the latest state of UID->app name, version mapping.
- // Needed since the new user basically has a version of every app.
- informAllUids(context);
- }
- }
-
- public static final class AnomalyAlarmListener implements OnAlarmListener {
- private final Context mContext;
-
- AnomalyAlarmListener(Context context) {
- mContext = context;
- }
-
- @Override
- public void onAlarm() {
- if (DEBUG) {
- Log.i(TAG, "StatsCompanionService believes an anomaly has occurred at time "
- + System.currentTimeMillis() + "ms.");
- }
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- Log.w(TAG, "Could not access statsd to inform it of anomaly alarm firing");
- return;
- }
-
- // Wakelock needs to be retained while calling statsd.
- Thread thread = new WakelockThread(mContext,
- AnomalyAlarmListener.class.getCanonicalName(), new Runnable() {
- @Override
- public void run() {
- try {
- statsd.informAnomalyAlarmFired();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to inform statsd of anomaly alarm firing", e);
- }
- }
- });
- thread.start();
- }
- }
-
- public final static class PullingAlarmListener implements OnAlarmListener {
- private final Context mContext;
-
- PullingAlarmListener(Context context) {
- mContext = context;
- }
-
- @Override
- public void onAlarm() {
- if (DEBUG) {
- Log.d(TAG, "Time to poll something.");
- }
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- Log.w(TAG, "Could not access statsd to inform it of pulling alarm firing.");
- return;
- }
-
- // Wakelock needs to be retained while calling statsd.
- Thread thread = new WakelockThread(mContext,
- PullingAlarmListener.class.getCanonicalName(), new Runnable() {
- @Override
- public void run() {
- try {
- statsd.informPollAlarmFired();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to inform statsd of pulling alarm firing.", e);
- }
- }
- });
- thread.start();
- }
- }
-
- public final static class PeriodicAlarmListener implements OnAlarmListener {
- private final Context mContext;
-
- PeriodicAlarmListener(Context context) {
- mContext = context;
- }
-
- @Override
- public void onAlarm() {
- if (DEBUG) {
- Log.d(TAG, "Time to trigger periodic alarm.");
- }
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- Log.w(TAG, "Could not access statsd to inform it of periodic alarm firing.");
- return;
- }
-
- // Wakelock needs to be retained while calling statsd.
- Thread thread = new WakelockThread(mContext,
- PeriodicAlarmListener.class.getCanonicalName(), new Runnable() {
- @Override
- public void run() {
- try {
- statsd.informAlarmForSubscriberTriggeringFired();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to inform statsd of periodic alarm firing.", e);
- }
- }
- });
- thread.start();
- }
- }
-
- public final static class ShutdownEventReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- /**
- * Skip immediately if intent is not relevant to device shutdown.
- */
- if (!intent.getAction().equals(Intent.ACTION_REBOOT)
- && !(intent.getAction().equals(Intent.ACTION_SHUTDOWN)
- && (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0)) {
- return;
- }
-
- if (DEBUG) {
- Log.i(TAG, "StatsCompanionService noticed a shutdown.");
- }
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- Log.w(TAG, "Could not access statsd to inform it of a shutdown event.");
- return;
- }
- try {
- // two way binder call
- statsd.informDeviceShutdown();
- } catch (Exception e) {
- Log.w(TAG, "Failed to inform statsd of a shutdown event.", e);
- }
- }
- }
-
- @Override // Binder call
- public void setAnomalyAlarm(long timestampMs) {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) Log.d(TAG, "Setting anomaly alarm for " + timestampMs);
- final long callingToken = Binder.clearCallingIdentity();
- try {
- // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
- // only fire when it awakens.
- // AlarmManager will automatically cancel any previous mAnomalyAlarmListener alarm.
- mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".anomaly",
- mAnomalyAlarmListener, mHandler);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void cancelAnomalyAlarm() {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) Log.d(TAG, "Cancelling anomaly alarm");
- final long callingToken = Binder.clearCallingIdentity();
- try {
- mAlarmManager.cancel(mAnomalyAlarmListener);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void setAlarmForSubscriberTriggering(long timestampMs) {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) {
- Log.d(TAG,
- "Setting periodic alarm in about " + (timestampMs
- - SystemClock.elapsedRealtime()));
- }
- final long callingToken = Binder.clearCallingIdentity();
- try {
- // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
- // only fire when it awakens.
- mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".periodic",
- mPeriodicAlarmListener, mHandler);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void cancelAlarmForSubscriberTriggering() {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) {
- Log.d(TAG, "Cancelling periodic alarm");
- }
- final long callingToken = Binder.clearCallingIdentity();
- try {
- mAlarmManager.cancel(mPeriodicAlarmListener);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void setPullingAlarm(long nextPullTimeMs) {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) {
- Log.d(TAG, "Setting pulling alarm in about "
- + (nextPullTimeMs - SystemClock.elapsedRealtime()));
- }
- final long callingToken = Binder.clearCallingIdentity();
- try {
- // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
- // only fire when it awakens.
- mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, nextPullTimeMs, TAG + ".pull",
- mPullingAlarmListener, mHandler);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void cancelPullingAlarm() {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) {
- Log.d(TAG, "Cancelling pulling alarm");
- }
- final long callingToken = Binder.clearCallingIdentity();
- try {
- mAlarmManager.cancel(mPullingAlarmListener);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void statsdReady() {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) {
- Log.d(TAG, "learned that statsdReady");
- }
- sayHiToStatsd(); // tell statsd that we're ready too and link to it
-
- final Intent intent = new Intent(StatsManager.ACTION_STATSD_STARTED);
- // Retrieve list of broadcast receivers for this broadcast & send them directed broadcasts
- // to wake them up (if they're in background).
- List<ResolveInfo> resolveInfos =
- mContext.getPackageManager().queryBroadcastReceiversAsUser(
- intent, 0, UserHandle.SYSTEM);
- if (resolveInfos == null || resolveInfos.isEmpty()) {
- return; // No need to send broadcast.
- }
-
- for (ResolveInfo resolveInfo : resolveInfos) {
- Intent intentToSend = new Intent(intent);
- intentToSend.setComponent(new ComponentName(
- resolveInfo.activityInfo.applicationInfo.packageName,
- resolveInfo.activityInfo.name));
- mContext.sendBroadcastAsUser(intentToSend, UserHandle.SYSTEM,
- android.Manifest.permission.DUMP);
- }
- }
-
- @Override // Binder call
- public boolean checkPermission(String permission, int pid, int uid) {
- StatsCompanion.enforceStatsdCallingUid();
- return mContext.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED;
- }
-
- // Statsd related code
-
- /**
- * Fetches the statsd IBinder service. This is a blocking call that always refetches statsd
- * instead of returning the cached sStatsd.
- * Note: This should only be called from {@link #sayHiToStatsd()}. All other clients should use
- * the cached sStatsd via {@link #getStatsdNonblocking()}.
- */
- private IStatsd fetchStatsdServiceLocked() {
- sStatsd = IStatsd.Stub.asInterface(StatsFrameworkInitializer
- .getStatsServiceManager()
- .getStatsdServiceRegisterer()
- .get());
- return sStatsd;
- }
-
- private void registerStatsdDeathRecipient(IStatsd statsd, List<BroadcastReceiver> receivers) {
- StatsdDeathRecipient deathRecipient = new StatsdDeathRecipient(statsd, receivers);
-
- try {
- statsd.asBinder().linkToDeath(deathRecipient, /*flags=*/0);
- } catch (RemoteException e) {
- Log.e(TAG, "linkToDeath (StatsdDeathRecipient) failed");
- // Statsd has already died. Unregister receivers ourselves.
- for (BroadcastReceiver receiver : receivers) {
- mContext.unregisterReceiver(receiver);
- }
- synchronized (sStatsdLock) {
- if (statsd == sStatsd) {
- statsdNotReadyLocked();
- }
- }
- }
- }
-
- /**
- * Now that the android system is ready, StatsCompanion is ready too, so inform statsd.
- */
- void systemReady() {
- if (DEBUG) Log.d(TAG, "Learned that systemReady");
- sayHiToStatsd();
- }
-
- void setStatsManagerService(StatsManagerService statsManagerService) {
- mStatsManagerService = statsManagerService;
- }
-
- /**
- * Tells statsd that statscompanion is ready. If the binder call returns, link to
- * statsd.
- */
- private void sayHiToStatsd() {
- IStatsd statsd;
- synchronized (sStatsdLock) {
- if (sStatsd != null && sStatsd.asBinder().isBinderAlive()) {
- Log.e(TAG, "statsd has already been fetched before",
- new IllegalStateException("IStatsd object should be null or dead"));
- return;
- }
- statsd = fetchStatsdServiceLocked();
- }
-
- if (statsd == null) {
- Log.i(TAG, "Could not yet find statsd to tell it that StatsCompanion is alive.");
- return;
- }
-
- // Cleann up from previous statsd - cancel any alarms that had been set. Do this here
- // instead of in binder death because statsd can come back and set different alarms, or not
- // want to set an alarm when it had been set. This guarantees that when we get a new statsd,
- // we cancel any alarms before it is able to set them.
- cancelAnomalyAlarm();
- cancelPullingAlarm();
- cancelAlarmForSubscriberTriggering();
-
- if (DEBUG) Log.d(TAG, "Saying hi to statsd");
- mStatsManagerService.statsdReady(statsd);
- try {
- statsd.statsCompanionReady();
-
- BroadcastReceiver appUpdateReceiver = new AppUpdateReceiver();
- BroadcastReceiver userUpdateReceiver = new UserUpdateReceiver();
- BroadcastReceiver shutdownEventReceiver = new ShutdownEventReceiver();
-
- // Setup broadcast receiver for updates.
- IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REPLACED);
- filter.addAction(Intent.ACTION_PACKAGE_ADDED);
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addDataScheme("package");
- mContext.registerReceiverForAllUsers(appUpdateReceiver, filter, null, null);
-
- // Setup receiver for user initialize (which happens once for a new user)
- // and if a user is removed.
- filter = new IntentFilter(Intent.ACTION_USER_INITIALIZE);
- filter.addAction(Intent.ACTION_USER_REMOVED);
- mContext.registerReceiverForAllUsers(userUpdateReceiver, filter, null, null);
-
- // Setup receiver for device reboots or shutdowns.
- filter = new IntentFilter(Intent.ACTION_REBOOT);
- filter.addAction(Intent.ACTION_SHUTDOWN);
- mContext.registerReceiverForAllUsers(shutdownEventReceiver, filter, null, null);
-
- // Register death recipient.
- List<BroadcastReceiver> broadcastReceivers =
- List.of(appUpdateReceiver, userUpdateReceiver, shutdownEventReceiver);
- registerStatsdDeathRecipient(statsd, broadcastReceivers);
-
- // Tell statsd that boot has completed. The signal may have already been sent, but since
- // the signal-receiving function is idempotent, that's ok.
- if (mBootCompleted.get()) {
- statsd.bootCompleted();
- }
-
- // Pull the latest state of UID->app name, version mapping when statsd starts.
- informAllUids(mContext);
-
- Log.i(TAG, "Told statsd that StatsCompanionService is alive.");
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to inform statsd that statscompanion is ready", e);
- }
- }
-
- private class StatsdDeathRecipient implements IBinder.DeathRecipient {
-
- private final IStatsd mStatsd;
- private final List<BroadcastReceiver> mReceiversToUnregister;
-
- StatsdDeathRecipient(IStatsd statsd, List<BroadcastReceiver> receivers) {
- mStatsd = statsd;
- mReceiversToUnregister = receivers;
- }
-
- // It is possible for binderDied to be called after a restarted statsd calls statsdReady,
- // but that's alright because the code does not assume an ordering of the two calls.
- @Override
- public void binderDied() {
- Log.i(TAG, "Statsd is dead - erase all my knowledge, except pullers");
- synchronized (sStatsdLock) {
- long now = SystemClock.elapsedRealtime();
- for (Long timeMillis : mDeathTimeMillis) {
- long ageMillis = now - timeMillis;
- if (ageMillis > MILLIS_IN_A_DAY) {
- mDeathTimeMillis.remove(timeMillis);
- }
- }
- for (Long timeMillis : mDeletedFiles.keySet()) {
- long ageMillis = now - timeMillis;
- if (ageMillis > MILLIS_IN_A_DAY * 7) {
- mDeletedFiles.remove(timeMillis);
- }
- }
- mDeathTimeMillis.add(now);
- if (mDeathTimeMillis.size() >= DEATH_THRESHOLD) {
- mDeathTimeMillis.clear();
- File[] configs = new File(CONFIG_DIR).listFiles();
- if (configs != null && configs.length > 0) {
- String fileName = configs[0].getName();
- if (configs[0].delete()) {
- mDeletedFiles.put(now, fileName);
- }
- }
- }
-
- // Unregister receivers on death because receivers can only be unregistered once.
- // Otherwise, an IllegalArgumentException is thrown.
- for (BroadcastReceiver receiver: mReceiversToUnregister) {
- mContext.unregisterReceiver(receiver);
- }
-
- // It's possible for statsd to have restarted and called statsdReady, causing a new
- // sStatsd binder object to be fetched, before the binderDied callback runs. Only
- // call #statsdNotReadyLocked if that hasn't happened yet.
- if (mStatsd == sStatsd) {
- statsdNotReadyLocked();
- }
- }
- }
- }
-
- private void statsdNotReadyLocked() {
- sStatsd = null;
- mStatsManagerService.statsdNotReady();
- }
-
- void bootCompleted() {
- mBootCompleted.set(true);
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- // Statsd is not yet ready.
- // Delay the boot completed ping to {@link #sayHiToStatsd()}
- return;
- }
- try {
- statsd.bootCompleted();
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to notify statsd that boot completed");
- }
- }
-
- @Override
- protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- return;
- }
-
- synchronized (sStatsdLock) {
- writer.println("Number of configuration files deleted: " + mDeletedFiles.size());
- if (mDeletedFiles.size() > 0) {
- writer.println(" timestamp, deleted file name");
- }
- long lastBootMillis =
- SystemClock.currentThreadTimeMillis() - SystemClock.elapsedRealtime();
- for (Long elapsedMillis : mDeletedFiles.keySet()) {
- long deletionMillis = lastBootMillis + elapsedMillis;
- writer.println(" " + deletionMillis + ", " + mDeletedFiles.get(elapsedMillis));
- }
- }
- }
-}
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java b/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java
deleted file mode 100644
index 97846f2..0000000
--- a/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.stats;
-
-import static com.android.server.stats.StatsCompanion.PendingIntentRef;
-
-import android.Manifest;
-import android.annotation.Nullable;
-import android.app.AppOpsManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.Binder;
-import android.os.IPullAtomCallback;
-import android.os.IStatsManagerService;
-import android.os.IStatsd;
-import android.os.Process;
-import android.os.RemoteException;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Service for {@link android.app.StatsManager}.
- *
- * @hide
- */
-public class StatsManagerService extends IStatsManagerService.Stub {
-
- private static final String TAG = "StatsManagerService";
- private static final boolean DEBUG = false;
-
- private static final int STATSD_TIMEOUT_MILLIS = 5000;
-
- private static final String USAGE_STATS_PERMISSION_OPS = "android:get_usage_stats";
-
- @GuardedBy("mLock")
- private IStatsd mStatsd;
- private final Object mLock = new Object();
-
- private StatsCompanionService mStatsCompanionService;
- private Context mContext;
-
- @GuardedBy("mLock")
- private ArrayMap<ConfigKey, PendingIntentRef> mDataFetchPirMap = new ArrayMap<>();
- @GuardedBy("mLock")
- private ArrayMap<Integer, PendingIntentRef> mActiveConfigsPirMap = new ArrayMap<>();
- @GuardedBy("mLock")
- private ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> mBroadcastSubscriberPirMap =
- new ArrayMap<>();
-
- public StatsManagerService(Context context) {
- super();
- mContext = context;
- }
-
- private static class ConfigKey {
- private final int mUid;
- private final long mConfigId;
-
- ConfigKey(int uid, long configId) {
- mUid = uid;
- mConfigId = configId;
- }
-
- public int getUid() {
- return mUid;
- }
-
- public long getConfigId() {
- return mConfigId;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mUid, mConfigId);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof ConfigKey) {
- ConfigKey other = (ConfigKey) obj;
- return this.mUid == other.getUid() && this.mConfigId == other.getConfigId();
- }
- return false;
- }
- }
-
- private static class PullerKey {
- private final int mUid;
- private final int mAtomTag;
-
- PullerKey(int uid, int atom) {
- mUid = uid;
- mAtomTag = atom;
- }
-
- public int getUid() {
- return mUid;
- }
-
- public int getAtom() {
- return mAtomTag;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mUid, mAtomTag);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof PullerKey) {
- PullerKey other = (PullerKey) obj;
- return this.mUid == other.getUid() && this.mAtomTag == other.getAtom();
- }
- return false;
- }
- }
-
- private static class PullerValue {
- private final long mCoolDownMillis;
- private final long mTimeoutMillis;
- private final int[] mAdditiveFields;
- private final IPullAtomCallback mCallback;
-
- PullerValue(long coolDownMillis, long timeoutMillis, int[] additiveFields,
- IPullAtomCallback callback) {
- mCoolDownMillis = coolDownMillis;
- mTimeoutMillis = timeoutMillis;
- mAdditiveFields = additiveFields;
- mCallback = callback;
- }
-
- public long getCoolDownMillis() {
- return mCoolDownMillis;
- }
-
- public long getTimeoutMillis() {
- return mTimeoutMillis;
- }
-
- public int[] getAdditiveFields() {
- return mAdditiveFields;
- }
-
- public IPullAtomCallback getCallback() {
- return mCallback;
- }
- }
-
- private final ArrayMap<PullerKey, PullerValue> mPullers = new ArrayMap<>();
-
- @Override
- public void registerPullAtomCallback(int atomTag, long coolDownMillis, long timeoutMillis,
- int[] additiveFields, IPullAtomCallback pullerCallback) {
- enforceRegisterStatsPullAtomPermission();
- if (pullerCallback == null) {
- Log.w(TAG, "Puller callback is null for atom " + atomTag);
- return;
- }
- int callingUid = Binder.getCallingUid();
- PullerKey key = new PullerKey(callingUid, atomTag);
- PullerValue val =
- new PullerValue(coolDownMillis, timeoutMillis, additiveFields, pullerCallback);
-
- // Always cache the puller in StatsManagerService. If statsd is down, we will register the
- // puller when statsd comes back up.
- synchronized (mLock) {
- mPullers.put(key, val);
- }
-
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- return;
- }
-
- final long token = Binder.clearCallingIdentity();
- try {
- statsd.registerPullAtomCallback(callingUid, atomTag, coolDownMillis, timeoutMillis,
- additiveFields, pullerCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to access statsd to register puller for atom " + atomTag);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void unregisterPullAtomCallback(int atomTag) {
- enforceRegisterStatsPullAtomPermission();
- int callingUid = Binder.getCallingUid();
- PullerKey key = new PullerKey(callingUid, atomTag);
-
- // Always remove the puller from StatsManagerService even if statsd is down. When statsd
- // comes back up, we will not re-register the removed puller.
- synchronized (mLock) {
- mPullers.remove(key);
- }
-
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- return;
- }
-
- final long token = Binder.clearCallingIdentity();
- try {
- statsd.unregisterPullAtomCallback(callingUid, atomTag);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to access statsd to unregister puller for atom " + atomTag);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void setDataFetchOperation(long configId, PendingIntent pendingIntent,
- String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- PendingIntentRef pir = new PendingIntentRef(pendingIntent, mContext);
- ConfigKey key = new ConfigKey(callingUid, configId);
- // We add the PIR to a map so we can reregister if statsd is unavailable.
- synchronized (mLock) {
- mDataFetchPirMap.put(key, pir);
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- statsd.setDataFetchOperation(configId, pir, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to setDataFetchOperation with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void removeDataFetchOperation(long configId, String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- ConfigKey key = new ConfigKey(callingUid, configId);
- synchronized (mLock) {
- mDataFetchPirMap.remove(key);
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- statsd.removeDataFetchOperation(configId, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to removeDataFetchOperation with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public long[] setActiveConfigsChangedOperation(PendingIntent pendingIntent,
- String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- PendingIntentRef pir = new PendingIntentRef(pendingIntent, mContext);
- // We add the PIR to a map so we can reregister if statsd is unavailable.
- synchronized (mLock) {
- mActiveConfigsPirMap.put(callingUid, pir);
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- return statsd.setActiveConfigsChangedOperation(pir, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to setActiveConfigsChangedOperation with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- return new long[] {};
- }
-
- @Override
- public void removeActiveConfigsChangedOperation(String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- synchronized (mLock) {
- mActiveConfigsPirMap.remove(callingUid);
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- statsd.removeActiveConfigsChangedOperation(callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to removeActiveConfigsChangedOperation with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void setBroadcastSubscriber(long configId, long subscriberId,
- PendingIntent pendingIntent, String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- PendingIntentRef pir = new PendingIntentRef(pendingIntent, mContext);
- ConfigKey key = new ConfigKey(callingUid, configId);
- // We add the PIR to a map so we can reregister if statsd is unavailable.
- synchronized (mLock) {
- ArrayMap<Long, PendingIntentRef> innerMap = mBroadcastSubscriberPirMap
- .getOrDefault(key, new ArrayMap<>());
- innerMap.put(subscriberId, pir);
- mBroadcastSubscriberPirMap.put(key, innerMap);
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- statsd.setBroadcastSubscriber(
- configId, subscriberId, pir, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to setBroadcastSubscriber with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void unsetBroadcastSubscriber(long configId, long subscriberId, String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- ConfigKey key = new ConfigKey(callingUid, configId);
- synchronized (mLock) {
- ArrayMap<Long, PendingIntentRef> innerMap = mBroadcastSubscriberPirMap
- .getOrDefault(key, new ArrayMap<>());
- innerMap.remove(subscriberId);
- if (innerMap.isEmpty()) {
- mBroadcastSubscriberPirMap.remove(key);
- }
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- statsd.unsetBroadcastSubscriber(configId, subscriberId, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to unsetBroadcastSubscriber with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public long[] getRegisteredExperimentIds() throws IllegalStateException {
- enforceDumpAndUsageStatsPermission(null);
- final long token = Binder.clearCallingIdentity();
- try {
- IStatsd statsd = waitForStatsd();
- if (statsd != null) {
- return statsd.getRegisteredExperimentIds();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to getRegisteredExperimentIds with statsd");
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- throw new IllegalStateException("Failed to connect to statsd to registerExperimentIds");
- }
-
- @Override
- public byte[] getMetadata(String packageName) throws IllegalStateException {
- enforceDumpAndUsageStatsPermission(packageName);
- final long token = Binder.clearCallingIdentity();
- try {
- IStatsd statsd = waitForStatsd();
- if (statsd != null) {
- return statsd.getMetadata();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to getMetadata with statsd");
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- throw new IllegalStateException("Failed to connect to statsd to getMetadata");
- }
-
- @Override
- public byte[] getData(long key, String packageName) throws IllegalStateException {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- IStatsd statsd = waitForStatsd();
- if (statsd != null) {
- return statsd.getData(key, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to getData with statsd");
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- throw new IllegalStateException("Failed to connect to statsd to getData");
- }
-
- @Override
- public void addConfiguration(long configId, byte[] config, String packageName)
- throws IllegalStateException {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- IStatsd statsd = waitForStatsd();
- if (statsd != null) {
- statsd.addConfiguration(configId, config, callingUid);
- return;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to addConfiguration with statsd");
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- throw new IllegalStateException("Failed to connect to statsd to addConfig");
- }
-
- @Override
- public void removeConfiguration(long configId, String packageName)
- throws IllegalStateException {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- IStatsd statsd = waitForStatsd();
- if (statsd != null) {
- statsd.removeConfiguration(configId, callingUid);
- return;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to removeConfiguration with statsd");
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- throw new IllegalStateException("Failed to connect to statsd to removeConfig");
- }
-
- void setStatsCompanionService(StatsCompanionService statsCompanionService) {
- mStatsCompanionService = statsCompanionService;
- }
-
- /**
- * Checks that the caller has both DUMP and PACKAGE_USAGE_STATS permissions. Also checks that
- * the caller has USAGE_STATS_PERMISSION_OPS for the specified packageName if it is not null.
- *
- * @param packageName The packageName to check USAGE_STATS_PERMISSION_OPS.
- */
- private void enforceDumpAndUsageStatsPermission(@Nullable String packageName) {
- int callingUid = Binder.getCallingUid();
- int callingPid = Binder.getCallingPid();
-
- if (callingPid == Process.myPid()) {
- return;
- }
-
- mContext.enforceCallingPermission(Manifest.permission.DUMP, null);
- mContext.enforceCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS, null);
-
- if (packageName == null) {
- return;
- }
- AppOpsManager appOpsManager = (AppOpsManager) mContext
- .getSystemService(Context.APP_OPS_SERVICE);
- switch (appOpsManager.noteOp(USAGE_STATS_PERMISSION_OPS,
- Binder.getCallingUid(), packageName, null, null)) {
- case AppOpsManager.MODE_ALLOWED:
- case AppOpsManager.MODE_DEFAULT:
- break;
- default:
- throw new SecurityException(
- String.format("UID %d / PID %d lacks app-op %s",
- callingUid, callingPid, USAGE_STATS_PERMISSION_OPS)
- );
- }
- }
-
- private void enforceRegisterStatsPullAtomPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.REGISTER_STATS_PULL_ATOM,
- "Need REGISTER_STATS_PULL_ATOM permission.");
- }
-
-
- /**
- * Clients should call this if blocking until statsd to be ready is desired
- *
- * @return IStatsd object if statsd becomes ready within the timeout, null otherwise.
- */
- private IStatsd waitForStatsd() {
- synchronized (mLock) {
- if (mStatsd == null) {
- try {
- mLock.wait(STATSD_TIMEOUT_MILLIS);
- } catch (InterruptedException e) {
- Log.e(TAG, "wait for statsd interrupted");
- }
- }
- return mStatsd;
- }
- }
-
- /**
- * Clients should call this to receive a reference to statsd.
- *
- * @return IStatsd object if statsd is ready, null otherwise.
- */
- private IStatsd getStatsdNonblocking() {
- synchronized (mLock) {
- return mStatsd;
- }
- }
-
- /**
- * Called from {@link StatsCompanionService}.
- *
- * Tells StatsManagerService that Statsd is ready and updates
- * Statsd with the contents of our local cache.
- */
- void statsdReady(IStatsd statsd) {
- synchronized (mLock) {
- mStatsd = statsd;
- mLock.notify();
- }
- sayHiToStatsd(statsd);
- }
-
- /**
- * Called from {@link StatsCompanionService}.
- *
- * Tells StatsManagerService that Statsd is no longer ready
- * and we should no longer make binder calls with statsd.
- */
- void statsdNotReady() {
- synchronized (mLock) {
- mStatsd = null;
- }
- }
-
- private void sayHiToStatsd(IStatsd statsd) {
- if (statsd == null) {
- return;
- }
-
- final long token = Binder.clearCallingIdentity();
- try {
- registerAllPullers(statsd);
- registerAllDataFetchOperations(statsd);
- registerAllActiveConfigsChangedOperations(statsd);
- registerAllBroadcastSubscribers(statsd);
- } catch (RemoteException e) {
- Log.e(TAG, "StatsManager failed to (re-)register data with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- // Pre-condition: the Binder calling identity has already been cleared
- private void registerAllPullers(IStatsd statsd) throws RemoteException {
- // Since we do not want to make an IPC with the lock held, we first create a copy of the
- // data with the lock held before iterating through the map.
- ArrayMap<PullerKey, PullerValue> pullersCopy;
- synchronized (mLock) {
- pullersCopy = new ArrayMap<>(mPullers);
- }
-
- for (Map.Entry<PullerKey, PullerValue> entry : pullersCopy.entrySet()) {
- PullerKey key = entry.getKey();
- PullerValue value = entry.getValue();
- statsd.registerPullAtomCallback(key.getUid(), key.getAtom(), value.getCoolDownMillis(),
- value.getTimeoutMillis(), value.getAdditiveFields(), value.getCallback());
- }
- statsd.allPullersFromBootRegistered();
- }
-
- // Pre-condition: the Binder calling identity has already been cleared
- private void registerAllDataFetchOperations(IStatsd statsd) throws RemoteException {
- // Since we do not want to make an IPC with the lock held, we first create a copy of the
- // data with the lock held before iterating through the map.
- ArrayMap<ConfigKey, PendingIntentRef> dataFetchCopy;
- synchronized (mLock) {
- dataFetchCopy = new ArrayMap<>(mDataFetchPirMap);
- }
-
- for (Map.Entry<ConfigKey, PendingIntentRef> entry : dataFetchCopy.entrySet()) {
- ConfigKey key = entry.getKey();
- statsd.setDataFetchOperation(key.getConfigId(), entry.getValue(), key.getUid());
- }
- }
-
- // Pre-condition: the Binder calling identity has already been cleared
- private void registerAllActiveConfigsChangedOperations(IStatsd statsd) throws RemoteException {
- // Since we do not want to make an IPC with the lock held, we first create a copy of the
- // data with the lock held before iterating through the map.
- ArrayMap<Integer, PendingIntentRef> activeConfigsChangedCopy;
- synchronized (mLock) {
- activeConfigsChangedCopy = new ArrayMap<>(mActiveConfigsPirMap);
- }
-
- for (Map.Entry<Integer, PendingIntentRef> entry : activeConfigsChangedCopy.entrySet()) {
- statsd.setActiveConfigsChangedOperation(entry.getValue(), entry.getKey());
- }
- }
-
- // Pre-condition: the Binder calling identity has already been cleared
- private void registerAllBroadcastSubscribers(IStatsd statsd) throws RemoteException {
- // Since we do not want to make an IPC with the lock held, we first create a deep copy of
- // the data with the lock held before iterating through the map.
- ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> broadcastSubscriberCopy =
- new ArrayMap<>();
- synchronized (mLock) {
- for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry :
- mBroadcastSubscriberPirMap.entrySet()) {
- broadcastSubscriberCopy.put(entry.getKey(), new ArrayMap(entry.getValue()));
- }
- }
-
- for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry :
- mBroadcastSubscriberPirMap.entrySet()) {
- ConfigKey configKey = entry.getKey();
- for (Map.Entry<Long, PendingIntentRef> subscriberEntry : entry.getValue().entrySet()) {
- statsd.setBroadcastSubscriber(configKey.getConfigId(), subscriberEntry.getKey(),
- subscriberEntry.getValue(), configKey.getUid());
- }
- }
- }
-}
diff --git a/apex/statsd/statsd.rc b/apex/statsd/statsd.rc
deleted file mode 100644
index 605da2a..0000000
--- a/apex/statsd/statsd.rc
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-service statsd /apex/com.android.os.statsd/bin/statsd
- class main
- socket statsdw dgram+passcred 0222 statsd statsd
- user statsd
- group statsd log
- writepid /dev/cpuset/system-background/tasks
diff --git a/apex/statsd/testing/Android.bp b/apex/statsd/testing/Android.bp
deleted file mode 100644
index a9cd0cc..0000000
--- a/apex/statsd/testing/Android.bp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-apex_test {
- name: "test_com.android.os.statsd",
- visibility: [
- "//system/apex/tests",
- ],
- defaults: ["com.android.os.statsd-defaults"],
- manifest: "test_manifest.json",
- file_contexts: ":com.android.os.statsd-file_contexts",
- // Test APEX, should never be installed
- installable: false,
-}
diff --git a/apex/statsd/testing/test_manifest.json b/apex/statsd/testing/test_manifest.json
deleted file mode 100644
index 57343d3e..0000000
--- a/apex/statsd/testing/test_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.os.statsd",
- "version": 2147483647
-}
diff --git a/apex/statsd/tests/libstatspull/Android.bp b/apex/statsd/tests/libstatspull/Android.bp
deleted file mode 100644
index 05b3e04..0000000
--- a/apex/statsd/tests/libstatspull/Android.bp
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test {
- name: "LibStatsPullTests",
- static_libs: [
- "androidx.test.rules",
- "platformprotoslite",
- "statsdprotolite",
- "truth-prebuilt",
- ],
- libs: [
- "android.test.runner.stubs",
- "android.test.base.stubs",
- ],
- jni_libs: [
- "libstatspull_testhelper",
- ],
- srcs: [
- "src/**/*.java",
- "protos/**/*.proto",
- ],
- test_suites: [
- "device-tests",
- "mts",
- ],
- platform_apis: true,
- privileged: true,
- certificate: "platform",
- compile_multilib: "both",
-}
-
-cc_library_shared {
- name: "libstatspull_testhelper",
- srcs: ["jni/stats_pull_helper.cpp"],
- cflags: [
- "-Wall",
- "-Werror",
- ],
- shared_libs: [
- "libbinder_ndk",
- "statsd-aidl-ndk_platform",
- ],
- static_libs: [
- "libstatspull_private",
- "libstatssocket_private",
- "libutils",
- "libcutils",
- ],
-}
diff --git a/apex/statsd/tests/libstatspull/AndroidManifest.xml b/apex/statsd/tests/libstatspull/AndroidManifest.xml
deleted file mode 100644
index 0c669b0..0000000
--- a/apex/statsd/tests/libstatspull/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.internal.os.statsd.libstats" >
-
-
- <uses-permission android:name="android.permission.DUMP" />
- <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
- <uses-permission android:name="android.permission.REGISTER_STATS_PULL_ATOM" />
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.internal.os.statsd.libstats"
- android:label="Tests for libstatspull">
- </instrumentation>
-</manifest>
-
diff --git a/apex/statsd/tests/libstatspull/jni/stats_pull_helper.cpp b/apex/statsd/tests/libstatspull/jni/stats_pull_helper.cpp
deleted file mode 100644
index 166592d..0000000
--- a/apex/statsd/tests/libstatspull/jni/stats_pull_helper.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <jni.h>
-#include <log/log.h>
-#include <stats_event.h>
-#include <stats_pull_atom_callback.h>
-
-#include <chrono>
-#include <thread>
-
-using std::this_thread::sleep_for;
-
-namespace {
-static int32_t sAtomTag;
-static int32_t sPullReturnVal;
-static int64_t sLatencyMillis;
-static int32_t sAtomsPerPull;
-static int32_t sNumPulls = 0;
-
-static AStatsManager_PullAtomCallbackReturn pullAtomCallback(int32_t atomTag, AStatsEventList* data,
- void* /*cookie*/) {
- sNumPulls++;
- sleep_for(std::chrono::milliseconds(sLatencyMillis));
- for (int i = 0; i < sAtomsPerPull; i++) {
- AStatsEvent* event = AStatsEventList_addStatsEvent(data);
- AStatsEvent_setAtomId(event, atomTag);
- AStatsEvent_writeInt64(event, (int64_t) sNumPulls);
- AStatsEvent_build(event);
- }
- return sPullReturnVal;
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_internal_os_statsd_libstats_LibStatsPullTests_setStatsPuller(
- JNIEnv* /*env*/, jobject /* this */, jint atomTag, jlong timeoutMillis,
- jlong coolDownMillis, jint pullRetVal, jlong latencyMillis, int atomsPerPull) {
- sAtomTag = atomTag;
- sPullReturnVal = pullRetVal;
- sLatencyMillis = latencyMillis;
- sAtomsPerPull = atomsPerPull;
- sNumPulls = 0;
- AStatsManager_PullAtomMetadata* metadata = AStatsManager_PullAtomMetadata_obtain();
- AStatsManager_PullAtomMetadata_setCoolDownMillis(metadata, coolDownMillis);
- AStatsManager_PullAtomMetadata_setTimeoutMillis(metadata, timeoutMillis);
-
- AStatsManager_setPullAtomCallback(sAtomTag, metadata, &pullAtomCallback, nullptr);
- AStatsManager_PullAtomMetadata_release(metadata);
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_internal_os_statsd_libstats_LibStatsPullTests_clearStatsPuller(JNIEnv* /*env*/,
- jobject /* this */,
- jint /*atomTag*/) {
- AStatsManager_clearPullAtomCallback(sAtomTag);
-}
-} // namespace
diff --git a/apex/statsd/tests/libstatspull/protos/test_atoms.proto b/apex/statsd/tests/libstatspull/protos/test_atoms.proto
deleted file mode 100644
index 56c1b53..0000000
--- a/apex/statsd/tests/libstatspull/protos/test_atoms.proto
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-syntax = "proto2";
-
-package com.android.internal.os.statsd.protos;
-
-option java_package = "com.android.internal.os.statsd.protos";
-option java_outer_classname = "TestAtoms";
-
-message PullCallbackAtomWrapper {
- optional PullCallbackAtom pull_callback_atom = 150030;
-}
-
-message PullCallbackAtom {
- optional int64 long_val = 1;
-}
-
-
-
diff --git a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/LibStatsPullTests.java b/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/LibStatsPullTests.java
deleted file mode 100644
index 6108a32..0000000
--- a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/LibStatsPullTests.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.os.statsd.libstats;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.StatsManager;
-import android.content.Context;
-import android.util.Log;
-import android.util.StatsLog;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.PullAtomPackages;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.internal.os.statsd.protos.TestAtoms;
-import com.android.os.AtomsProto.Atom;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-/**
- * Test puller registration.
- */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class LibStatsPullTests {
- private static final String LOG_TAG = LibStatsPullTests.class.getSimpleName();
- private static final int SHORT_SLEEP_MILLIS = 250;
- private static final int LONG_SLEEP_MILLIS = 1_000;
- private Context mContext;
- private static final int PULL_ATOM_TAG = 150030;
- private static final int APP_BREADCRUMB_LABEL = 3;
- private static int sPullReturnValue;
- private static long sConfigId;
- private static long sPullLatencyMillis;
- private static long sPullTimeoutMillis;
- private static long sCoolDownMillis;
- private static int sAtomsPerPull;
-
- static {
- System.loadLibrary("statspull_testhelper");
- }
-
- /**
- * Setup the tests. Initialize shared data.
- */
- @Before
- public void setup() {
- mContext = InstrumentationRegistry.getTargetContext();
- assertThat(InstrumentationRegistry.getInstrumentation()).isNotNull();
- sPullReturnValue = StatsManager.PULL_SUCCESS;
- sPullLatencyMillis = 0;
- sPullTimeoutMillis = 10_000L;
- sCoolDownMillis = 1_000L;
- sAtomsPerPull = 1;
- }
-
- /**
- * Teardown the tests.
- */
- @After
- public void tearDown() throws Exception {
- clearStatsPuller(PULL_ATOM_TAG);
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- statsManager.removeConfig(sConfigId);
- }
-
- /**
- * Tests adding a puller callback and that pulls complete successfully.
- */
- @Test
- public void testPullAtomCallbackRegistration() throws Exception {
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- // Upload a config that captures that pulled atom.
- createAndAddConfigToStatsd(statsManager);
-
- // Add the puller.
- setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
- sPullLatencyMillis, sAtomsPerPull);
- Thread.sleep(SHORT_SLEEP_MILLIS);
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- // Let the current bucket finish.
- Thread.sleep(LONG_SLEEP_MILLIS);
- List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
- clearStatsPuller(PULL_ATOM_TAG);
- assertThat(data.size()).isEqualTo(1);
- TestAtoms.PullCallbackAtomWrapper atomWrapper = null;
- try {
- atomWrapper = TestAtoms.PullCallbackAtomWrapper.parser()
- .parseFrom(data.get(0).toByteArray());
- } catch (Exception e) {
- Log.e(LOG_TAG, "Failed to parse primitive atoms");
- }
- assertThat(atomWrapper).isNotNull();
- assertThat(atomWrapper.hasPullCallbackAtom()).isTrue();
- TestAtoms.PullCallbackAtom atom =
- atomWrapper.getPullCallbackAtom();
- assertThat(atom.getLongVal()).isEqualTo(1);
- }
-
- /**
- * Tests that a failed pull is skipped.
- */
- @Test
- public void testPullAtomCallbackFailure() throws Exception {
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- createAndAddConfigToStatsd(statsManager);
- sPullReturnValue = StatsManager.PULL_SKIP;
- // Add the puller.
- setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
- sPullLatencyMillis, sAtomsPerPull);
- Thread.sleep(SHORT_SLEEP_MILLIS);
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- // Let the current bucket finish.
- Thread.sleep(LONG_SLEEP_MILLIS);
- List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
- clearStatsPuller(PULL_ATOM_TAG);
- assertThat(data.size()).isEqualTo(0);
- }
-
- /**
- * Tests that a pull that times out is skipped.
- */
- @Test
- public void testPullAtomCallbackTimeout() throws Exception {
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- createAndAddConfigToStatsd(statsManager);
- // The puller will sleep for 1.5 sec.
- sPullLatencyMillis = 1_500;
- // 1 second timeout
- sPullTimeoutMillis = 1_000;
-
- // Add the puller.
- setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
- sPullLatencyMillis, sAtomsPerPull);
- Thread.sleep(SHORT_SLEEP_MILLIS);
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- // Let the current bucket finish and the pull timeout.
- Thread.sleep(sPullLatencyMillis * 2);
- List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
- clearStatsPuller(PULL_ATOM_TAG);
- assertThat(data.size()).isEqualTo(0);
- }
-
- /**
- * Tests that 2 pulls in quick succession use the cache instead of pulling again.
- */
- @Test
- public void testPullAtomCallbackCache() throws Exception {
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- createAndAddConfigToStatsd(statsManager);
-
- // Set the cooldown to 10 seconds
- sCoolDownMillis = 10_000L;
- // Add the puller.
- setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
- sPullLatencyMillis, sAtomsPerPull);
-
- Thread.sleep(SHORT_SLEEP_MILLIS);
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- // Pull from cache.
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- Thread.sleep(LONG_SLEEP_MILLIS);
- List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
- clearStatsPuller(PULL_ATOM_TAG);
- assertThat(data.size()).isEqualTo(2);
- for (int i = 0; i < data.size(); i++) {
- TestAtoms.PullCallbackAtomWrapper atomWrapper = null;
- try {
- atomWrapper = TestAtoms.PullCallbackAtomWrapper.parser()
- .parseFrom(data.get(i).toByteArray());
- } catch (Exception e) {
- Log.e(LOG_TAG, "Failed to parse primitive atoms");
- }
- assertThat(atomWrapper).isNotNull();
- assertThat(atomWrapper.hasPullCallbackAtom()).isTrue();
- TestAtoms.PullCallbackAtom atom =
- atomWrapper.getPullCallbackAtom();
- assertThat(atom.getLongVal()).isEqualTo(1);
- }
- }
-
- /**
- * Tests that a pull that returns 1000 stats events works properly.
- */
- @Test
- public void testPullAtomCallbackStress() throws Exception {
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- // Upload a config that captures that pulled atom.
- createAndAddConfigToStatsd(statsManager);
- sAtomsPerPull = 1000;
- // Add the puller.
- setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
- sPullLatencyMillis, sAtomsPerPull);
-
- Thread.sleep(SHORT_SLEEP_MILLIS);
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- // Let the current bucket finish.
- Thread.sleep(LONG_SLEEP_MILLIS);
- List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
- clearStatsPuller(PULL_ATOM_TAG);
- assertThat(data.size()).isEqualTo(sAtomsPerPull);
-
- for (int i = 0; i < data.size(); i++) {
- TestAtoms.PullCallbackAtomWrapper atomWrapper = null;
- try {
- atomWrapper = TestAtoms.PullCallbackAtomWrapper.parser()
- .parseFrom(data.get(i).toByteArray());
- } catch (Exception e) {
- Log.e(LOG_TAG, "Failed to parse primitive atoms");
- }
- assertThat(atomWrapper).isNotNull();
- assertThat(atomWrapper.hasPullCallbackAtom()).isTrue();
- TestAtoms.PullCallbackAtom atom =
- atomWrapper.getPullCallbackAtom();
- assertThat(atom.getLongVal()).isEqualTo(1);
- }
- }
-
- private void createAndAddConfigToStatsd(StatsManager statsManager) throws Exception {
- sConfigId = System.currentTimeMillis();
- long triggerMatcherId = sConfigId + 10;
- long pullerMatcherId = sConfigId + 11;
- long metricId = sConfigId + 100;
- StatsdConfig config = StatsConfigUtils.getSimpleTestConfig(sConfigId)
- .addAtomMatcher(
- StatsConfigUtils.getAppBreadcrumbMatcher(triggerMatcherId,
- APP_BREADCRUMB_LABEL))
- .addAtomMatcher(AtomMatcher.newBuilder()
- .setId(pullerMatcherId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(PULL_ATOM_TAG))
- )
- .addGaugeMetric(GaugeMetric.newBuilder()
- .setId(metricId)
- .setWhat(pullerMatcherId)
- .setTriggerEvent(triggerMatcherId)
- .setGaugeFieldsFilter(FieldFilter.newBuilder().setIncludeAll(true))
- .setBucket(TimeUnit.CTS)
- .setSamplingType(GaugeMetric.SamplingType.FIRST_N_SAMPLES)
- .setMaxNumGaugeAtomsPerBucket(1000)
- )
- .addPullAtomPackages(PullAtomPackages.newBuilder()
- .setAtomId(PULL_ATOM_TAG)
- .addPackages(LibStatsPullTests.class.getPackage().getName()))
- .build();
- statsManager.addConfig(sConfigId, config.toByteArray());
- assertThat(StatsConfigUtils.verifyValidConfigExists(statsManager, sConfigId)).isTrue();
- }
-
- private native void setStatsPuller(int atomTag, long timeoutMillis, long coolDownMillis,
- int pullReturnVal, long latencyMillis, int atomPerPull);
-
- private native void clearStatsPuller(int atomTag);
-}
-
diff --git a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/StatsConfigUtils.java b/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/StatsConfigUtils.java
deleted file mode 100644
index b5afb94..0000000
--- a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/StatsConfigUtils.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.os.statsd.libstats;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.StatsManager;
-import android.util.Log;
-
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.GaugeBucketInfo;
-import com.android.os.StatsLog.GaugeMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.os.StatsLog.StatsdStatsReport;
-import com.android.os.StatsLog.StatsdStatsReport.ConfigStats;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Util class for constructing statsd configs.
- */
-public class StatsConfigUtils {
- public static final String TAG = "statsd.StatsConfigUtils";
- public static final int SHORT_WAIT = 2_000; // 2 seconds.
-
- /**
- * @return An empty StatsdConfig in serialized proto format.
- */
- public static StatsdConfig.Builder getSimpleTestConfig(long configId) {
- return StatsdConfig.newBuilder().setId(configId)
- .addAllowedLogSource(StatsConfigUtils.class.getPackage().getName());
- }
-
-
- public static boolean verifyValidConfigExists(StatsManager statsManager, long configId) {
- StatsdStatsReport report = null;
- try {
- report = StatsdStatsReport.parser().parseFrom(statsManager.getStatsMetadata());
- } catch (Exception e) {
- Log.e(TAG, "getMetadata failed", e);
- }
- assertThat(report).isNotNull();
- boolean foundConfig = false;
- for (ConfigStats configStats : report.getConfigStatsList()) {
- if (configStats.getId() == configId && configStats.getIsValid()
- && configStats.getDeletionTimeSec() == 0) {
- foundConfig = true;
- }
- }
- return foundConfig;
- }
-
- public static AtomMatcher getAppBreadcrumbMatcher(long id, int label) {
- return AtomMatcher.newBuilder()
- .setId(id)
- .setSimpleAtomMatcher(
- SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
- .setEqInt(label)
- )
- )
- .build();
- }
-
- public static ConfigMetricsReport getConfigMetricsReport(StatsManager statsManager,
- long configId) {
- ConfigMetricsReportList reportList = null;
- try {
- reportList = ConfigMetricsReportList.parser()
- .parseFrom(statsManager.getReports(configId));
- } catch (Exception e) {
- Log.e(TAG, "getData failed", e);
- }
- assertThat(reportList).isNotNull();
- assertThat(reportList.getReportsCount()).isEqualTo(1);
- ConfigMetricsReport report = reportList.getReports(0);
- assertThat(report.getDumpReportReason())
- .isEqualTo(ConfigMetricsReport.DumpReportReason.GET_DATA_CALLED);
- return report;
-
- }
- public static List<Atom> getGaugeMetricDataList(ConfigMetricsReport report) {
- List<Atom> data = new ArrayList<>();
- for (StatsLogReport metric : report.getMetricsList()) {
- for (GaugeMetricData gaugeMetricData : metric.getGaugeMetrics().getDataList()) {
- for (GaugeBucketInfo bucketInfo : gaugeMetricData.getBucketInfoList()) {
- for (Atom atom : bucketInfo.getAtomList()) {
- data.add(atom);
- }
- }
- }
- }
- return data;
- }
-
- public static List<Atom> getGaugeMetricDataList(StatsManager statsManager, long configId) {
- ConfigMetricsReport report = getConfigMetricsReport(statsManager, configId);
- return getGaugeMetricDataList(report);
- }
-}
-
diff --git a/api/current.txt b/api/current.txt
index 952ccda..a586dd2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3712,7 +3712,7 @@
ctor public ActionBar.LayoutParams(int);
ctor public ActionBar.LayoutParams(android.app.ActionBar.LayoutParams);
ctor public ActionBar.LayoutParams(android.view.ViewGroup.LayoutParams);
- field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=0xffffffff, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.NO_GRAVITY, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.TOP, to="TOP"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.BOTTOM, to="BOTTOM"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.LEFT, to="LEFT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.RIGHT, to="RIGHT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.START, to="START"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.END, to="END"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_VERTICAL, to="CENTER_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_VERTICAL, to="FILL_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_HORIZONTAL, to="CENTER_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_HORIZONTAL, to="FILL_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL, to="FILL")}) public int gravity;
+ field public int gravity;
}
public static interface ActionBar.OnMenuVisibilityListener {
@@ -10092,7 +10092,7 @@
method public final <T> T getSystemService(@NonNull Class<T>);
method @Nullable public abstract String getSystemServiceName(@NonNull Class<?>);
method @NonNull public final CharSequence getText(@StringRes int);
- method @android.view.ViewDebug.ExportedProperty(deepExport=true) public abstract android.content.res.Resources.Theme getTheme();
+ method public abstract android.content.res.Resources.Theme getTheme();
method @Deprecated public abstract android.graphics.drawable.Drawable getWallpaper();
method @Deprecated public abstract int getWallpaperDesiredMinimumHeight();
method @Deprecated public abstract int getWallpaperDesiredMinimumWidth();
@@ -53838,13 +53838,13 @@
method @Nullable public CharSequence getAccessibilityPaneTitle();
method @IdRes public int getAccessibilityTraversalAfter();
method @IdRes public int getAccessibilityTraversalBefore();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getAlpha();
+ method public float getAlpha();
method public android.view.animation.Animation getAnimation();
method @Nullable public android.graphics.Matrix getAnimationMatrix();
method public android.os.IBinder getApplicationWindowToken();
method @NonNull public int[] getAttributeResolutionStack(@AttrRes int);
method @NonNull public java.util.Map<java.lang.Integer,java.lang.Integer> getAttributeSourceResourceMap();
- method @android.view.ViewDebug.ExportedProperty @Nullable public String[] getAutofillHints();
+ method @Nullable public String[] getAutofillHints();
method public final android.view.autofill.AutofillId getAutofillId();
method public int getAutofillType();
method @Nullable public android.view.autofill.AutofillValue getAutofillValue();
@@ -53852,8 +53852,8 @@
method @Nullable public android.graphics.BlendMode getBackgroundTintBlendMode();
method @Nullable public android.content.res.ColorStateList getBackgroundTintList();
method @Nullable public android.graphics.PorterDuff.Mode getBackgroundTintMode();
- method @android.view.ViewDebug.ExportedProperty(category="layout") public int getBaseline();
- method @android.view.ViewDebug.CapturedViewProperty public final int getBottom();
+ method public int getBaseline();
+ method public final int getBottom();
method protected float getBottomFadingEdgeStrength();
method protected int getBottomPaddingOffset();
method public float getCameraDistance();
@@ -53861,10 +53861,10 @@
method public boolean getClipBounds(android.graphics.Rect);
method public final boolean getClipToOutline();
method @Nullable public final android.view.contentcapture.ContentCaptureSession getContentCaptureSession();
- method @android.view.ViewDebug.ExportedProperty(category="accessibility") public CharSequence getContentDescription();
- method @android.view.ViewDebug.CapturedViewProperty public final android.content.Context getContext();
+ method public CharSequence getContentDescription();
+ method public final android.content.Context getContext();
method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean getDefaultFocusHighlightEnabled();
+ method public final boolean getDefaultFocusHighlightEnabled();
method public static int getDefaultSize(int, int);
method public android.view.Display getDisplay();
method public final int[] getDrawableState();
@@ -53874,11 +53874,11 @@
method @Deprecated public int getDrawingCacheQuality();
method public void getDrawingRect(android.graphics.Rect);
method public long getDrawingTime();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getElevation();
+ method public float getElevation();
method @StyleRes public int getExplicitStyle();
- method @android.view.ViewDebug.ExportedProperty public boolean getFilterTouchesWhenObscured();
- method @android.view.ViewDebug.ExportedProperty public boolean getFitsSystemWindows();
- method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.NOT_FOCUSABLE, to="NOT_FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE, to="FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE_AUTO, to="FOCUSABLE_AUTO")}, category="focus") public int getFocusable();
+ method public boolean getFilterTouchesWhenObscured();
+ method public boolean getFitsSystemWindows();
+ method public int getFocusable();
method public java.util.ArrayList<android.view.View> getFocusables(int);
method public void getFocusedRect(android.graphics.Rect);
method public android.graphics.drawable.Drawable getForeground();
@@ -53890,23 +53890,23 @@
method public final boolean getGlobalVisibleRect(android.graphics.Rect);
method public android.os.Handler getHandler();
method public final boolean getHasOverlappingRendering();
- method @android.view.ViewDebug.ExportedProperty(category="layout") public final int getHeight();
+ method public final int getHeight();
method public void getHitRect(android.graphics.Rect);
method public int getHorizontalFadingEdgeLength();
method protected int getHorizontalScrollbarHeight();
method @Nullable public android.graphics.drawable.Drawable getHorizontalScrollbarThumbDrawable();
method @Nullable public android.graphics.drawable.Drawable getHorizontalScrollbarTrackDrawable();
- method @android.view.ViewDebug.CapturedViewProperty @IdRes public int getId();
- method @android.view.ViewDebug.ExportedProperty(category="accessibility", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS, to="noHideDescendants")}) public int getImportantForAccessibility();
- method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForAutofill();
- method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForContentCapture();
+ method @IdRes public int getId();
+ method public int getImportantForAccessibility();
+ method public int getImportantForAutofill();
+ method public int getImportantForContentCapture();
method public boolean getKeepScreenOn();
method public android.view.KeyEvent.DispatcherState getKeyDispatcherState();
- method @android.view.ViewDebug.ExportedProperty(category="accessibility") @IdRes public int getLabelFor();
+ method @IdRes public int getLabelFor();
method public int getLayerType();
- method @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.LAYOUT_DIRECTION_LTR, to="RESOLVED_DIRECTION_LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.LAYOUT_DIRECTION_RTL, to="RESOLVED_DIRECTION_RTL")}) public int getLayoutDirection();
- method @android.view.ViewDebug.ExportedProperty(deepExport=true, prefix="layout_") public android.view.ViewGroup.LayoutParams getLayoutParams();
- method @android.view.ViewDebug.CapturedViewProperty public final int getLeft();
+ method public int getLayoutDirection();
+ method public android.view.ViewGroup.LayoutParams getLayoutParams();
+ method public final int getLeft();
method protected float getLeftFadingEdgeStrength();
method protected int getLeftPaddingOffset();
method public final boolean getLocalVisibleRect(android.graphics.Rect);
@@ -53915,10 +53915,10 @@
method public void getLocationOnScreen(@Size(2) int[]);
method public android.graphics.Matrix getMatrix();
method public final int getMeasuredHeight();
- method @android.view.ViewDebug.ExportedProperty(category="measurement", flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.View.MEASURED_STATE_MASK, equals=android.view.View.MEASURED_STATE_TOO_SMALL, name="MEASURED_STATE_TOO_SMALL")}) public final int getMeasuredHeightAndState();
+ method public final int getMeasuredHeightAndState();
method public final int getMeasuredState();
method public final int getMeasuredWidth();
- method @android.view.ViewDebug.ExportedProperty(category="measurement", flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.View.MEASURED_STATE_MASK, equals=android.view.View.MEASURED_STATE_TOO_SMALL, name="MEASURED_STATE_TOO_SMALL")}) public final int getMeasuredWidthAndState();
+ method public final int getMeasuredWidthAndState();
method public int getMinimumHeight();
method public int getMinimumWidth();
method @IdRes public int getNextClusterForwardId();
@@ -53941,51 +53941,51 @@
method public int getPaddingTop();
method public final android.view.ViewParent getParent();
method public android.view.ViewParent getParentForAccessibility();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getPivotX();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getPivotY();
+ method public float getPivotX();
+ method public float getPivotY();
method public android.view.PointerIcon getPointerIcon();
method public android.content.res.Resources getResources();
method public final boolean getRevealOnFocusHint();
- method @android.view.ViewDebug.CapturedViewProperty public final int getRight();
+ method public final int getRight();
method protected float getRightFadingEdgeStrength();
method protected int getRightPaddingOffset();
method public android.view.View getRootView();
method public android.view.WindowInsets getRootWindowInsets();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotation();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotationX();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotationY();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getScaleX();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getScaleY();
+ method public float getRotation();
+ method public float getRotationX();
+ method public float getRotationY();
+ method public float getScaleX();
+ method public float getScaleY();
method public int getScrollBarDefaultDelayBeforeFade();
method public int getScrollBarFadeDuration();
method public int getScrollBarSize();
- method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_INSIDE_OVERLAY, to="INSIDE_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_INSIDE_INSET, to="INSIDE_INSET"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_OUTSIDE_OVERLAY, to="OUTSIDE_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_OUTSIDE_INSET, to="OUTSIDE_INSET")}) public int getScrollBarStyle();
+ method public int getScrollBarStyle();
method public int getScrollIndicators();
method public final int getScrollX();
method public final int getScrollY();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") @ColorInt public int getSolidColor();
+ method @ColorInt public int getSolidColor();
method @LayoutRes public int getSourceLayoutResId();
- method @android.view.ViewDebug.ExportedProperty(category="accessibility") @Nullable public final CharSequence getStateDescription();
+ method @Nullable public final CharSequence getStateDescription();
method public android.animation.StateListAnimator getStateListAnimator();
method protected int getSuggestedMinimumHeight();
method protected int getSuggestedMinimumWidth();
method @NonNull public java.util.List<android.graphics.Rect> getSystemGestureExclusionRects();
method @Deprecated public int getSystemUiVisibility();
- method @android.view.ViewDebug.ExportedProperty public Object getTag();
+ method public Object getTag();
method public Object getTag(int);
- method @android.view.ViewDebug.ExportedProperty(category="text", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_INHERIT, to="INHERIT"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_GRAVITY, to="GRAVITY"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_TEXT_START, to="TEXT_START"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_TEXT_END, to="TEXT_END"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_VIEW_START, to="VIEW_START"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_VIEW_END, to="VIEW_END")}) public int getTextAlignment();
- method @android.view.ViewDebug.ExportedProperty(category="text", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_INHERIT, to="INHERIT"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG, to="FIRST_STRONG"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_ANY_RTL, to="ANY_RTL"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_LTR, to="LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_RTL, to="RTL"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_LOCALE, to="LOCALE"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG_LTR, to="FIRST_STRONG_LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG_RTL, to="FIRST_STRONG_RTL")}) public int getTextDirection();
+ method public int getTextAlignment();
+ method public int getTextDirection();
method @Nullable public CharSequence getTooltipText();
- method @android.view.ViewDebug.CapturedViewProperty public final int getTop();
+ method public final int getTop();
method protected float getTopFadingEdgeStrength();
method protected int getTopPaddingOffset();
method public android.view.TouchDelegate getTouchDelegate();
method public java.util.ArrayList<android.view.View> getTouchables();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTransitionAlpha();
- method @android.view.ViewDebug.ExportedProperty public String getTransitionName();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationX();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationY();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationZ();
+ method public float getTransitionAlpha();
+ method public String getTransitionName();
+ method public float getTranslationX();
+ method public float getTranslationY();
+ method public float getTranslationZ();
method public long getUniqueDrawingId();
method public int getVerticalFadingEdgeLength();
method public int getVerticalScrollbarPosition();
@@ -53993,8 +53993,8 @@
method @Nullable public android.graphics.drawable.Drawable getVerticalScrollbarTrackDrawable();
method public int getVerticalScrollbarWidth();
method public android.view.ViewTreeObserver getViewTreeObserver();
- method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.VISIBLE, to="VISIBLE"), @android.view.ViewDebug.IntToString(from=android.view.View.INVISIBLE, to="INVISIBLE"), @android.view.ViewDebug.IntToString(from=android.view.View.GONE, to="GONE")}) public int getVisibility();
- method @android.view.ViewDebug.ExportedProperty(category="layout") public final int getWidth();
+ method public int getVisibility();
+ method public final int getWidth();
method protected int getWindowAttachCount();
method public android.view.WindowId getWindowId();
method @Nullable public android.view.WindowInsetsController getWindowInsetsController();
@@ -54002,18 +54002,18 @@
method public android.os.IBinder getWindowToken();
method public int getWindowVisibility();
method public void getWindowVisibleDisplayFrame(android.graphics.Rect);
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getX();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getY();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getZ();
+ method public float getX();
+ method public float getY();
+ method public float getZ();
method public boolean hasExplicitFocusable();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean hasFocus();
+ method public boolean hasFocus();
method public boolean hasFocusable();
method public boolean hasNestedScrollingParent();
method public boolean hasOnClickListeners();
method public boolean hasOnLongClickListeners();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean hasOverlappingRendering();
+ method public boolean hasOverlappingRendering();
method public boolean hasPointerCapture();
- method @android.view.ViewDebug.ExportedProperty(category="layout") public boolean hasTransientState();
+ method public boolean hasTransientState();
method public boolean hasWindowFocus();
method public static android.view.View inflate(android.content.Context, @LayoutRes int, android.view.ViewGroup);
method @Deprecated public void invalidate(android.graphics.Rect);
@@ -54023,50 +54023,50 @@
method public void invalidateOutline();
method public boolean isAccessibilityFocused();
method public boolean isAccessibilityHeading();
- method @android.view.ViewDebug.ExportedProperty public boolean isActivated();
+ method public boolean isActivated();
method public boolean isAttachedToWindow();
- method @android.view.ViewDebug.ExportedProperty public boolean isClickable();
+ method public boolean isClickable();
method public boolean isContextClickable();
method public boolean isDirty();
- method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isDrawingCacheEnabled();
+ method @Deprecated public boolean isDrawingCacheEnabled();
method public boolean isDuplicateParentStateEnabled();
- method @android.view.ViewDebug.ExportedProperty public boolean isEnabled();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusable();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusableInTouchMode();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean isFocused();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusedByDefault();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isForceDarkAllowed();
- method @android.view.ViewDebug.ExportedProperty public boolean isHapticFeedbackEnabled();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isHardwareAccelerated();
+ method public boolean isEnabled();
+ method public final boolean isFocusable();
+ method public final boolean isFocusableInTouchMode();
+ method public boolean isFocused();
+ method public final boolean isFocusedByDefault();
+ method public boolean isForceDarkAllowed();
+ method public boolean isHapticFeedbackEnabled();
+ method public boolean isHardwareAccelerated();
method public boolean isHorizontalFadingEdgeEnabled();
method public boolean isHorizontalScrollBarEnabled();
- method @android.view.ViewDebug.ExportedProperty public boolean isHovered();
+ method public boolean isHovered();
method public boolean isImportantForAccessibility();
method public final boolean isImportantForAutofill();
method public final boolean isImportantForContentCapture();
method public boolean isInEditMode();
method public boolean isInLayout();
- method @android.view.ViewDebug.ExportedProperty public boolean isInTouchMode();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isKeyboardNavigationCluster();
+ method public boolean isInTouchMode();
+ method public final boolean isKeyboardNavigationCluster();
method public boolean isLaidOut();
method public boolean isLayoutDirectionResolved();
method public boolean isLayoutRequested();
method public boolean isLongClickable();
method public boolean isNestedScrollingEnabled();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isOpaque();
+ method public boolean isOpaque();
method protected boolean isPaddingOffsetRequired();
method public boolean isPaddingRelative();
method public boolean isPivotSet();
- method @android.view.ViewDebug.ExportedProperty public boolean isPressed();
+ method public boolean isPressed();
method public boolean isSaveEnabled();
method public boolean isSaveFromParentEnabled();
method public boolean isScreenReaderFocusable();
method public boolean isScrollContainer();
method public boolean isScrollbarFadingEnabled();
- method @android.view.ViewDebug.ExportedProperty public boolean isSelected();
+ method public boolean isSelected();
method public final boolean isShowingLayoutBounds();
method public boolean isShown();
- method @android.view.ViewDebug.ExportedProperty public boolean isSoundEffectsEnabled();
+ method public boolean isSoundEffectsEnabled();
method public final boolean isTemporarilyDetached();
method public boolean isTextAlignmentResolved();
method public boolean isTextDirectionResolved();
@@ -54357,8 +54357,8 @@
method public void unscheduleDrawable(android.graphics.drawable.Drawable);
method public final void updateDragShadow(android.view.View.DragShadowBuilder);
method @CallSuper protected boolean verifyDrawable(@NonNull android.graphics.drawable.Drawable);
- method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean willNotCacheDrawing();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean willNotDraw();
+ method @Deprecated public boolean willNotCacheDrawing();
+ method public boolean willNotDraw();
field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
@@ -54799,9 +54799,9 @@
method public static int getChildMeasureSpec(int, int, int);
method protected boolean getChildStaticTransformation(android.view.View, android.view.animation.Transformation);
method public boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point);
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean getClipChildren();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean getClipToPadding();
- method @android.view.ViewDebug.ExportedProperty(category="focus", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_BEFORE_DESCENDANTS, to="FOCUS_BEFORE_DESCENDANTS"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_AFTER_DESCENDANTS, to="FOCUS_AFTER_DESCENDANTS"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_BLOCK_DESCENDANTS, to="FOCUS_BLOCK_DESCENDANTS")}) public int getDescendantFocusability();
+ method public boolean getClipChildren();
+ method public boolean getClipToPadding();
+ method public int getDescendantFocusability();
method public android.view.View getFocusedChild();
method public android.view.animation.LayoutAnimationController getLayoutAnimation();
method public android.view.animation.Animation.AnimationListener getLayoutAnimationListener();
@@ -54809,14 +54809,14 @@
method public android.animation.LayoutTransition getLayoutTransition();
method public int getNestedScrollAxes();
method public android.view.ViewGroupOverlay getOverlay();
- method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_NO_CACHE, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_ANIMATION_CACHE, to="ANIMATION"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_SCROLLING_CACHE, to="SCROLLING"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_ALL_CACHES, to="ALL")}) public int getPersistentDrawingCache();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean getTouchscreenBlocksFocus();
+ method @Deprecated public int getPersistentDrawingCache();
+ method public boolean getTouchscreenBlocksFocus();
method public int indexOfChild(android.view.View);
method @Deprecated public final void invalidateChild(android.view.View, android.graphics.Rect);
method @Deprecated public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
method @Deprecated public boolean isAlwaysDrawnWithCacheEnabled();
method @Deprecated public boolean isAnimationCacheEnabled();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") protected boolean isChildrenDrawingOrderEnabled();
+ method protected boolean isChildrenDrawingOrderEnabled();
method @Deprecated protected boolean isChildrenDrawnWithCacheEnabled();
method public boolean isLayoutSuppressed();
method public boolean isMotionEventSplittingEnabled();
@@ -54907,9 +54907,9 @@
field @Deprecated public static final int FILL_PARENT = -1; // 0xffffffff
field public static final int MATCH_PARENT = -1; // 0xffffffff
field public static final int WRAP_CONTENT = -2; // 0xfffffffe
- field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.MATCH_PARENT, to="MATCH_PARENT"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.WRAP_CONTENT, to="WRAP_CONTENT")}) public int height;
+ field public int height;
field public android.view.animation.LayoutAnimationController.AnimationParameters layoutAnimationParameters;
- field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.MATCH_PARENT, to="MATCH_PARENT"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.WRAP_CONTENT, to="WRAP_CONTENT")}) public int width;
+ field public int width;
}
public static class ViewGroup.MarginLayoutParams extends android.view.ViewGroup.LayoutParams {
@@ -54925,10 +54925,10 @@
method public void setMarginEnd(int);
method public void setMarginStart(int);
method public void setMargins(int, int, int, int);
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int bottomMargin;
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int leftMargin;
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int rightMargin;
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int topMargin;
+ field public int bottomMargin;
+ field public int leftMargin;
+ field public int rightMargin;
+ field public int topMargin;
}
public static interface ViewGroup.OnHierarchyChangeListener {
@@ -55725,11 +55725,11 @@
field public float alpha;
field public float buttonBrightness;
field public float dimAmount;
- field @android.view.ViewDebug.ExportedProperty(flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, name="ALLOW_LOCK_WHILE_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND, equals=android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND, name="DIM_BEHIND"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND, equals=android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND, name="BLUR_BEHIND"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, name="NOT_FOCUSABLE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, name="NOT_TOUCHABLE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, name="NOT_TOUCH_MODAL"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, equals=android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, name="TOUCHABLE_WHEN_WAKING"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, name="KEEP_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, name="LAYOUT_IN_SCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, name="LAYOUT_NO_LIMITS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN, name="FULLSCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, name="FORCE_NOT_FULLSCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DITHER, equals=android.view.WindowManager.LayoutParams.FLAG_DITHER, name="DITHER"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SECURE, equals=android.view.WindowManager.LayoutParams.FLAG_SECURE, name="SECURE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SCALED, equals=android.view.WindowManager.LayoutParams.FLAG_SCALED, name="SCALED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES, equals=android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES, name="IGNORE_CHEEK_PRESSES"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR, name="LAYOUT_INSET_DECOR"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, equals=android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, name="ALT_FOCUSABLE_IM"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, equals=android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, name="WATCH_OUTSIDE_TOUCH"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, equals=android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, name="SHOW_WHEN_LOCKED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER, equals=android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER, name="SHOW_WALLPAPER"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, name="TURN_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, equals=android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, name="DISMISS_KEYGUARD"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, equals=android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, name="SPLIT_TOUCH"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, equals=android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, name="HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN, name="LOCAL_FOCUS_MODE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, equals=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, name="TRANSLUCENT_STATUS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, equals=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, name="TRANSLUCENT_NAVIGATION"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE, equals=android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE, name="LOCAL_FOCUS_MODE"), @android.view.ViewDebug.FlagToString(mask=0x20000000, equals=0x20000000, name="FLAG_SLIPPERY"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR, name="FLAG_LAYOUT_ATTACHED_IN_DECOR"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, equals=android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, name="DRAWS_SYSTEM_BAR_BACKGROUNDS")}, formatToHexString=true) public int flags;
+ field public int flags;
field public int format;
field public int gravity;
field public float horizontalMargin;
- field @android.view.ViewDebug.ExportedProperty public float horizontalWeight;
+ field public float horizontalWeight;
field public int layoutInDisplayCutoutMode;
field @Deprecated public int memoryType;
field public String packageName;
@@ -55742,12 +55742,12 @@
field public int softInputMode;
field @Deprecated public int systemUiVisibility;
field public android.os.IBinder token;
- field @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION, to="BASE_APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION, to="APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING, to="APPLICATION_STARTING"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION, to="DRAWN_APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, to="APPLICATION_PANEL"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA, to="APPLICATION_MEDIA"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL, to="APPLICATION_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=0x3ed, to="APPLICATION_ABOVE_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG, to="APPLICATION_ATTACHED_DIALOG"), @android.view.ViewDebug.IntToString(from=0x3ec, to="APPLICATION_MEDIA_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR, to="STATUS_BAR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR, to="SEARCH_BAR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PHONE, to="PHONE"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, to="SYSTEM_ALERT"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_TOAST, to="TOAST"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, to="SYSTEM_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE, to="PRIORITY_PHONE"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG, to="SYSTEM_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, to="KEYGUARD_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, to="SYSTEM_ERROR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD, to="INPUT_METHOD"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG, to="INPUT_METHOD_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_WALLPAPER, to="WALLPAPER"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, to="STATUS_BAR_PANEL"), @android.view.ViewDebug.IntToString(from=0x7df, to="SECURE_SYSTEM_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7e0, to="DRAG"), @android.view.ViewDebug.IntToString(from=0x7e1, to="STATUS_BAR_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=0x7e2, to="POINTER"), @android.view.ViewDebug.IntToString(from=0x7e3, to="NAVIGATION_BAR"), @android.view.ViewDebug.IntToString(from=0x7e4, to="VOLUME_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7e5, to="BOOT_PROGRESS"), @android.view.ViewDebug.IntToString(from=0x7e6, to="INPUT_CONSUMER"), @android.view.ViewDebug.IntToString(from=0x7e8, to="NAVIGATION_BAR_PANEL"), @android.view.ViewDebug.IntToString(from=0x7ea, to="DISPLAY_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7eb, to="MAGNIFICATION_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7f5, to="PRESENTATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION, to="PRIVATE_PRESENTATION"), @android.view.ViewDebug.IntToString(from=0x7ef, to="VOICE_INTERACTION"), @android.view.ViewDebug.IntToString(from=0x7f1, to="VOICE_INTERACTION_STARTING"), @android.view.ViewDebug.IntToString(from=0x7f2, to="DOCK_DIVIDER"), @android.view.ViewDebug.IntToString(from=0x7f3, to="QS_DIALOG"), @android.view.ViewDebug.IntToString(from=0x7f4, to="SCREENSHOT"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, to="APPLICATION_OVERLAY")}) public int type;
+ field public int type;
field public float verticalMargin;
- field @android.view.ViewDebug.ExportedProperty public float verticalWeight;
+ field public float verticalWeight;
field public int windowAnimations;
- field @android.view.ViewDebug.ExportedProperty public int x;
- field @android.view.ViewDebug.ExportedProperty public int y;
+ field public int x;
+ field public int y;
}
public final class WindowMetrics {
@@ -58484,21 +58484,21 @@
method public void flingScroll(int, int);
method @Deprecated public void freeMemory();
method @Nullable public android.net.http.SslCertificate getCertificate();
- method @android.view.ViewDebug.ExportedProperty(category="webview") public int getContentHeight();
+ method public int getContentHeight();
method @Nullable public static android.content.pm.PackageInfo getCurrentWebViewPackage();
method @Nullable public android.graphics.Bitmap getFavicon();
method @NonNull public android.webkit.WebView.HitTestResult getHitTestResult();
method @Deprecated @Nullable public String[] getHttpAuthUsernamePassword(String, String);
- method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getOriginalUrl();
+ method @Nullable public String getOriginalUrl();
method public int getProgress();
method public boolean getRendererPriorityWaivedWhenNotVisible();
method public int getRendererRequestedPriority();
method @NonNull public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
- method @Deprecated @android.view.ViewDebug.ExportedProperty(category="webview") public float getScale();
+ method @Deprecated public float getScale();
method @NonNull public android.webkit.WebSettings getSettings();
method @NonNull public android.view.textclassifier.TextClassifier getTextClassifier();
- method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getTitle();
- method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getUrl();
+ method @Nullable public String getTitle();
+ method @Nullable public String getUrl();
method @Nullable public android.webkit.WebChromeClient getWebChromeClient();
method @NonNull public static ClassLoader getWebViewClassLoader();
method @NonNull public android.webkit.WebViewClient getWebViewClient();
@@ -58700,7 +58700,7 @@
method public void fling(int);
method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
method @ColorInt public int getBottomEdgeEffectColor();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") @ColorInt public int getCacheColorHint();
+ method @ColorInt public int getCacheColorHint();
method public int getCheckedItemCount();
method public long[] getCheckedItemIds();
method public int getCheckedItemPosition();
@@ -58710,7 +58710,7 @@
method public int getListPaddingLeft();
method public int getListPaddingRight();
method public int getListPaddingTop();
- method @android.view.ViewDebug.ExportedProperty public android.view.View getSelectedView();
+ method public android.view.View getSelectedView();
method public android.graphics.drawable.Drawable getSelector();
method public CharSequence getTextFilter();
method @ColorInt public int getTopEdgeEffectColor();
@@ -58720,13 +58720,13 @@
method public void invalidateViews();
method public boolean isDrawSelectorOnTop();
method public boolean isFastScrollAlwaysVisible();
- method @android.view.ViewDebug.ExportedProperty public boolean isFastScrollEnabled();
+ method public boolean isFastScrollEnabled();
method protected boolean isInFilterMode();
method public boolean isItemChecked(int);
- method @android.view.ViewDebug.ExportedProperty public boolean isScrollingCacheEnabled();
- method @android.view.ViewDebug.ExportedProperty public boolean isSmoothScrollbarEnabled();
- method @android.view.ViewDebug.ExportedProperty public boolean isStackFromBottom();
- method @android.view.ViewDebug.ExportedProperty public boolean isTextFilterEnabled();
+ method public boolean isScrollingCacheEnabled();
+ method public boolean isSmoothScrollbarEnabled();
+ method public boolean isStackFromBottom();
+ method public boolean isTextFilterEnabled();
method protected void layoutChildren();
method public void onFilterComplete(int);
method public void onGlobalLayout();
@@ -58923,7 +58923,7 @@
ctor public AdapterView(android.content.Context, android.util.AttributeSet, int);
ctor public AdapterView(android.content.Context, android.util.AttributeSet, int, int);
method public abstract T getAdapter();
- method @android.view.ViewDebug.CapturedViewProperty public int getCount();
+ method public int getCount();
method public android.view.View getEmptyView();
method public int getFirstVisiblePosition();
method public Object getItemAtPosition(int);
@@ -58934,8 +58934,8 @@
method @Nullable public final android.widget.AdapterView.OnItemSelectedListener getOnItemSelectedListener();
method public int getPositionForView(android.view.View);
method public Object getSelectedItem();
- method @android.view.ViewDebug.CapturedViewProperty public long getSelectedItemId();
- method @android.view.ViewDebug.CapturedViewProperty public int getSelectedItemPosition();
+ method public long getSelectedItemId();
+ method public int getSelectedItemPosition();
method public abstract android.view.View getSelectedView();
method public boolean performItemClick(android.view.View, int, long);
method public abstract void setAdapter(T);
@@ -59236,7 +59236,7 @@
method @Nullable public android.graphics.BlendMode getCheckMarkTintBlendMode();
method @Nullable public android.content.res.ColorStateList getCheckMarkTintList();
method @Nullable public android.graphics.PorterDuff.Mode getCheckMarkTintMode();
- method @android.view.ViewDebug.ExportedProperty public boolean isChecked();
+ method public boolean isChecked();
method public void setCheckMarkDrawable(@DrawableRes int);
method public void setCheckMarkDrawable(@Nullable android.graphics.drawable.Drawable);
method public void setCheckMarkTintBlendMode(@Nullable android.graphics.BlendMode);
@@ -59277,7 +59277,7 @@
method @Nullable public android.graphics.BlendMode getButtonTintBlendMode();
method @Nullable public android.content.res.ColorStateList getButtonTintList();
method @Nullable public android.graphics.PorterDuff.Mode getButtonTintMode();
- method @android.view.ViewDebug.ExportedProperty public boolean isChecked();
+ method public boolean isChecked();
method public void setButtonDrawable(@DrawableRes int);
method public void setButtonDrawable(@Nullable android.graphics.drawable.Drawable);
method public void setButtonTintBlendMode(@Nullable android.graphics.BlendMode);
@@ -59666,7 +59666,7 @@
method public int getColumnWidth();
method public int getGravity();
method public int getHorizontalSpacing();
- method @android.view.ViewDebug.ExportedProperty public int getNumColumns();
+ method public int getNumColumns();
method public int getRequestedColumnWidth();
method public int getRequestedHorizontalSpacing();
method public int getStretchMode();
@@ -59857,8 +59857,8 @@
ctor public LinearLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
ctor public LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams);
method public String debug(String);
- field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=0xffffffff, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.NO_GRAVITY, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.TOP, to="TOP"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.BOTTOM, to="BOTTOM"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.LEFT, to="LEFT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.RIGHT, to="RIGHT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.START, to="START"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.END, to="END"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_VERTICAL, to="CENTER_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_VERTICAL, to="FILL_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_HORIZONTAL, to="CENTER_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_HORIZONTAL, to="FILL_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL, to="FILL")}) public int gravity;
- field @android.view.ViewDebug.ExportedProperty(category="layout") public float weight;
+ field public int gravity;
+ field public float weight;
}
public interface ListAdapter extends android.widget.Adapter {
@@ -60247,13 +60247,13 @@
method @Nullable public android.content.res.ColorStateList getIndeterminateTintList();
method @Nullable public android.graphics.PorterDuff.Mode getIndeterminateTintMode();
method public android.view.animation.Interpolator getInterpolator();
- method @android.view.ViewDebug.ExportedProperty(category="progress") public int getMax();
+ method public int getMax();
method @Px public int getMaxHeight();
method @Px public int getMaxWidth();
- method @android.view.ViewDebug.ExportedProperty(category="progress") public int getMin();
+ method public int getMin();
method @Px public int getMinHeight();
method @Px public int getMinWidth();
- method @android.view.ViewDebug.ExportedProperty(category="progress") public int getProgress();
+ method public int getProgress();
method @Nullable public android.graphics.BlendMode getProgressBackgroundTintBlendMode();
method @Nullable public android.content.res.ColorStateList getProgressBackgroundTintList();
method @Nullable public android.graphics.PorterDuff.Mode getProgressBackgroundTintMode();
@@ -60261,14 +60261,14 @@
method @Nullable public android.graphics.BlendMode getProgressTintBlendMode();
method @Nullable public android.content.res.ColorStateList getProgressTintList();
method @Nullable public android.graphics.PorterDuff.Mode getProgressTintMode();
- method @android.view.ViewDebug.ExportedProperty(category="progress") public int getSecondaryProgress();
+ method public int getSecondaryProgress();
method @Nullable public android.graphics.BlendMode getSecondaryProgressTintBlendMode();
method @Nullable public android.content.res.ColorStateList getSecondaryProgressTintList();
method @Nullable public android.graphics.PorterDuff.Mode getSecondaryProgressTintMode();
method public final void incrementProgressBy(int);
method public final void incrementSecondaryProgressBy(int);
method public boolean isAnimating();
- method @android.view.ViewDebug.ExportedProperty(category="progress") public boolean isIndeterminate();
+ method public boolean isIndeterminate();
method public void onRestoreInstanceState(android.os.Parcelable);
method public android.os.Parcelable onSaveInstanceState();
method public void setIndeterminate(boolean);
@@ -60419,7 +60419,7 @@
method public int getRule(int);
method public int[] getRules();
method public void removeRule(int);
- field @android.view.ViewDebug.ExportedProperty(category="layout") public boolean alignWithParent;
+ field public boolean alignWithParent;
}
public class RemoteViews implements android.view.LayoutInflater.Filter android.os.Parcelable {
@@ -60978,8 +60978,8 @@
ctor public TableRow.LayoutParams(int);
ctor public TableRow.LayoutParams(android.view.ViewGroup.LayoutParams);
ctor public TableRow.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int column;
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int span;
+ field public int column;
+ field public int span;
}
@android.widget.RemoteViews.RemoteView public class TextClock extends android.widget.TextView {
@@ -60987,8 +60987,8 @@
ctor public TextClock(android.content.Context, android.util.AttributeSet);
ctor public TextClock(android.content.Context, android.util.AttributeSet, int);
ctor public TextClock(android.content.Context, android.util.AttributeSet, int, int);
- method @android.view.ViewDebug.ExportedProperty public CharSequence getFormat12Hour();
- method @android.view.ViewDebug.ExportedProperty public CharSequence getFormat24Hour();
+ method public CharSequence getFormat12Hour();
+ method public CharSequence getFormat24Hour();
method public String getTimeZone();
method public boolean is24HourModeEnabled();
method public void refreshTime();
@@ -61047,7 +61047,7 @@
method protected boolean getDefaultEditable();
method protected android.text.method.MovementMethod getDefaultMovementMethod();
method public android.text.Editable getEditableText();
- method @android.view.ViewDebug.ExportedProperty public android.text.TextUtils.TruncateAt getEllipsize();
+ method public android.text.TextUtils.TruncateAt getEllipsize();
method public CharSequence getError();
method public int getExtendedPaddingBottom();
method public int getExtendedPaddingTop();
@@ -61058,7 +61058,7 @@
method public boolean getFreezesText();
method public int getGravity();
method @ColorInt public int getHighlightColor();
- method @android.view.ViewDebug.CapturedViewProperty public CharSequence getHint();
+ method public CharSequence getHint();
method public final android.content.res.ColorStateList getHintTextColors();
method public int getHyphenationFrequency();
method public int getImeActionId();
@@ -61094,14 +61094,14 @@
method public android.text.TextPaint getPaint();
method public int getPaintFlags();
method public String getPrivateImeOptions();
- method @android.view.ViewDebug.ExportedProperty(category="text") public int getSelectionEnd();
- method @android.view.ViewDebug.ExportedProperty(category="text") public int getSelectionStart();
+ method public int getSelectionEnd();
+ method public int getSelectionStart();
method @ColorInt public int getShadowColor();
method public float getShadowDx();
method public float getShadowDy();
method public float getShadowRadius();
method public final boolean getShowSoftInputOnFocus();
- method @android.view.ViewDebug.CapturedViewProperty public CharSequence getText();
+ method public CharSequence getText();
method @NonNull public android.view.textclassifier.TextClassifier getTextClassifier();
method public final android.content.res.ColorStateList getTextColors();
method @Nullable public android.graphics.drawable.Drawable getTextCursorDrawable();
@@ -61113,7 +61113,7 @@
method @Nullable public android.graphics.drawable.Drawable getTextSelectHandle();
method @Nullable public android.graphics.drawable.Drawable getTextSelectHandleLeft();
method @Nullable public android.graphics.drawable.Drawable getTextSelectHandleRight();
- method @android.view.ViewDebug.ExportedProperty(category="text") public float getTextSize();
+ method public float getTextSize();
method public int getTextSizeUnit();
method public int getTotalPaddingBottom();
method public int getTotalPaddingEnd();
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
index 67afc32..6f5ac7c 100644
--- a/api/module-lib-current.txt
+++ b/api/module-lib-current.txt
@@ -1,24 +1,6 @@
// Signature format: 2.0
package android.net {
- public final class TetheredClient implements android.os.Parcelable {
- ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int);
- method public int describeContents();
- method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses();
- method @NonNull public android.net.MacAddress getMacAddress();
- method public int getTetheringType();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR;
- }
-
- public static final class TetheredClient.AddressInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.net.LinkAddress getAddress();
- method @Nullable public String getHostname();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
- }
-
public final class TetheringConstants {
field public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
field public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
@@ -38,69 +20,15 @@
method @NonNull public String[] getTetheringErroredIfaces();
method public boolean isTetheringSupported();
method public boolean isTetheringSupported(@NonNull String);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
method public void requestLatestTetheringEntitlementResult(int, @NonNull android.os.ResultReceiver, boolean);
method @Deprecated public int setUsbTethering(boolean);
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
+ method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
method @Deprecated public int tether(@NonNull String);
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
method @Deprecated public int untether(@NonNull String);
- field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
- field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
- field public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
- field public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
- field public static final String EXTRA_ERRORED_TETHER = "erroredArray";
- field public static final int TETHERING_BLUETOOTH = 2; // 0x2
- field public static final int TETHERING_ETHERNET = 5; // 0x5
- field public static final int TETHERING_INVALID = -1; // 0xffffffff
- field public static final int TETHERING_NCM = 4; // 0x4
- field public static final int TETHERING_USB = 1; // 0x1
- field public static final int TETHERING_WIFI = 0; // 0x0
- field public static final int TETHERING_WIFI_P2P = 3; // 0x3
- field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
- field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9
- field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8
- field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
- field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
- field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5
- field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
- field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
- field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
- field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb
- field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
- field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
- field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
- field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
- field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10
- field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
- field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
- field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
- field public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; // 0x1
- field public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; // 0x0
- }
-
- public static interface TetheringManager.OnTetheringEntitlementResultListener {
- method public void onTetheringEntitlementResult(int);
- }
-
- public static interface TetheringManager.StartTetheringCallback {
- method public default void onTetheringFailed(int);
- method public default void onTetheringStarted();
}
public static interface TetheringManager.TetheringEventCallback {
- method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
- method public default void onError(@NonNull String, int);
- method public default void onOffloadStatusChanged(int);
method public default void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
- method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
- method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
- method public default void onTetheringSupported(boolean);
- method public default void onUpstreamChanged(@Nullable android.net.Network);
}
public static class TetheringManager.TetheringInterfaceRegexps {
@@ -109,22 +37,6 @@
method @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
}
- public static class TetheringManager.TetheringRequest {
- method @Nullable public android.net.LinkAddress getClientStaticIpv4Address();
- method @Nullable public android.net.LinkAddress getLocalIpv4Address();
- method public boolean getShouldShowEntitlementUi();
- method public int getTetheringType();
- method public boolean isExemptFromEntitlementCheck();
- }
-
- public static class TetheringManager.TetheringRequest.Builder {
- ctor public TetheringManager.TetheringRequest.Builder(int);
- method @NonNull public android.net.TetheringManager.TetheringRequest build();
- method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
- method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean);
- method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress);
- }
-
}
package android.os {
diff --git a/api/test-current.txt b/api/test-current.txt
index 3838bad5..818a333 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -72,18 +72,11 @@
}
public class ActivityManager {
- method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int);
method public void alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName);
- method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public void forceStopPackage(String);
- method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getPackageImportance(String);
method public long getTotalRam();
- method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
method public static boolean isHighEndGfx();
- method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public void killProcessesWhenImperceptible(@NonNull int[], @NonNull String);
- method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
method public static void resumeAppSwitches() throws android.os.RemoteException;
method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int);
- method @RequiresPermission("android.permission.MANAGE_USERS") public boolean switchUser(@NonNull android.os.UserHandle);
field public static final int PROCESS_CAPABILITY_ALL = 7; // 0x7
field public static final int PROCESS_CAPABILITY_ALL_EXPLICIT = 1; // 0x1
field public static final int PROCESS_CAPABILITY_ALL_IMPLICIT = 6; // 0x6
@@ -93,10 +86,6 @@
field public static final int PROCESS_CAPABILITY_NONE = 0; // 0x0
}
- public static interface ActivityManager.OnUidImportanceListener {
- method public void onUidImportance(int, int);
- }
-
public static class ActivityManager.RunningAppProcessInfo implements android.os.Parcelable {
field public static final int IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170; // 0xaa
}
@@ -183,15 +172,10 @@
public class AppOpsManager {
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void addHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOps);
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void clearHistory();
- method @Nullable @RequiresPermission("android.permission.GET_APP_OPS_STATS") public android.app.RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage();
- method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void getHistoricalOpsFromDiskRaw(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
method public static int getNumOps();
- method public static String[] getOpStrs();
- method @NonNull @RequiresPermission("android.permission.GET_APP_OPS_STATS") public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
method public boolean isOperationActive(int, int, String);
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void offsetHistory(long);
- method public static int opToDefaultMode(@NonNull String);
method public static String opToPermission(int);
method public static int permissionToOpCode(String);
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void rebootHistory(long);
@@ -199,8 +183,6 @@
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void resetHistoryParameters();
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void setHistoryParameters(int, long, int);
method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(int, int, String, int);
- method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(@NonNull String, int, @Nullable String, int);
- method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setUidMode(@NonNull String, int, int);
method public static int strOpToOp(@NonNull String);
field public static final int HISTORICAL_MODE_DISABLED = 0; // 0x0
field public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1; // 0x1
@@ -208,224 +190,18 @@
field public static final String KEY_BG_STATE_SETTLE_TIME = "bg_state_settle_time";
field public static final String KEY_FG_SERVICE_STATE_SETTLE_TIME = "fg_service_state_settle_time";
field public static final String KEY_TOP_STATE_SETTLE_TIME = "top_state_settle_time";
- field public static final String OPSTR_ACCEPT_HANDOVER = "android:accept_handover";
- field public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
- field public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
- field public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
- field public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
- field public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME = "android:audio_accessibility_volume";
- field public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
- field public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
- field public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
- field public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
- field public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME = "android:audio_notification_volume";
- field public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
- field public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
- field public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE = "android:bind_accessibility_service";
- field public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
- field public static final String OPSTR_GET_ACCOUNTS = "android:get_accounts";
- field public static final String OPSTR_GPS = "android:gps";
- field public static final String OPSTR_INSTANT_APP_START_FOREGROUND = "android:instant_app_start_foreground";
- field public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
- field public static final String OPSTR_MANAGE_EXTERNAL_STORAGE = "android:manage_external_storage";
- field public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
- field public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
- field public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
- field public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
- field public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
- field public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
- field public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
- field public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
- field public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
- field public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
- field public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
- field public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST = "android:receive_emergency_broadcast";
- field public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
- field public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
- field public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
- field public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
- field public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
- field public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
- field public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
- field public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
- field public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
- field public static final String OPSTR_VIBRATE = "android:vibrate";
- field public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
- field public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
- field public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
- field public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
- field public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
- field public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
- field public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
- field public static final String OPSTR_WRITE_SMS = "android:write_sms";
- field public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
field public static final int OP_COARSE_LOCATION = 0; // 0x0
- field public static final int OP_FLAGS_ALL = 31; // 0x1f
- field public static final int OP_FLAG_SELF = 1; // 0x1
- field public static final int OP_FLAG_TRUSTED_PROXIED = 8; // 0x8
- field public static final int OP_FLAG_TRUSTED_PROXY = 2; // 0x2
- field public static final int OP_FLAG_UNTRUSTED_PROXIED = 16; // 0x10
- field public static final int OP_FLAG_UNTRUSTED_PROXY = 4; // 0x4
field public static final int OP_RECORD_AUDIO = 27; // 0x1b
field public static final int OP_START_FOREGROUND = 76; // 0x4c
field public static final int OP_SYSTEM_ALERT_WINDOW = 24; // 0x18
- field public static final int UID_STATE_BACKGROUND = 600; // 0x258
- field public static final int UID_STATE_CACHED = 700; // 0x2bc
- field public static final int UID_STATE_FOREGROUND = 500; // 0x1f4
- field public static final int UID_STATE_FOREGROUND_SERVICE = 400; // 0x190
- field @Deprecated public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300; // 0x12c
- field public static final int UID_STATE_PERSISTENT = 100; // 0x64
- field public static final int UID_STATE_TOP = 200; // 0xc8
- }
-
- public static final class AppOpsManager.AttributedHistoricalOps implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String);
- method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(@IntRange(from=0) int);
- method @IntRange(from=0) public int getOpCount();
- method @Nullable public String getTag();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.AttributedHistoricalOps> CREATOR;
- }
-
- public static final class AppOpsManager.AttributedOpEntry implements android.os.Parcelable {
- method public int describeContents();
- method public long getLastAccessBackgroundTime(int);
- method public long getLastAccessForegroundTime(int);
- method public long getLastAccessTime(int);
- method public long getLastAccessTime(int, int, int);
- method public long getLastBackgroundDuration(int);
- method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastBackgroundProxyInfo(int);
- method public long getLastDuration(int);
- method public long getLastDuration(int, int, int);
- method public long getLastForegroundDuration(int);
- method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastForegroundProxyInfo(int);
- method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int);
- method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int, int, int);
- method public long getLastRejectBackgroundTime(int);
- method public long getLastRejectForegroundTime(int);
- method public long getLastRejectTime(int);
- method public long getLastRejectTime(int, int, int);
- method public boolean isRunning();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.AttributedOpEntry> CREATOR;
- }
-
- public static final class AppOpsManager.HistoricalOp implements android.os.Parcelable {
- method public int describeContents();
- method public long getAccessCount(int, int, int);
- method public long getAccessDuration(int, int, int);
- method public long getBackgroundAccessCount(int);
- method public long getBackgroundAccessDuration(int);
- method public long getBackgroundRejectCount(int);
- method public long getForegroundAccessCount(int);
- method public long getForegroundAccessDuration(int);
- method public long getForegroundRejectCount(int);
- method @NonNull public String getOpName();
- method public long getRejectCount(int, int, int);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOp> CREATOR;
}
public static final class AppOpsManager.HistoricalOps implements android.os.Parcelable {
ctor public AppOpsManager.HistoricalOps(long, long);
- method public int describeContents();
- method public long getBeginTimeMillis();
- method public long getEndTimeMillis();
- method @IntRange(from=0) public int getUidCount();
- method @Nullable public android.app.AppOpsManager.HistoricalUidOps getUidOps(int);
- method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(@IntRange(from=0) int);
method public void increaseAccessCount(int, int, @NonNull String, @Nullable String, int, int, long);
method public void increaseAccessDuration(int, int, @NonNull String, @Nullable String, int, int, long);
method public void increaseRejectCount(int, int, @NonNull String, @Nullable String, int, int, long);
method public void offsetBeginAndEndTime(long);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOps> CREATOR;
- }
-
- public static final class AppOpsManager.HistoricalOpsRequest {
- }
-
- public static final class AppOpsManager.HistoricalOpsRequest.Builder {
- ctor public AppOpsManager.HistoricalOpsRequest.Builder(long, long);
- method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest build();
- method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setAttributionTag(@Nullable String);
- method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setFlags(int);
- method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setOpNames(@Nullable java.util.List<java.lang.String>);
- method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setPackageName(@Nullable String);
- method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setUid(int);
- }
-
- public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public android.app.AppOpsManager.AttributedHistoricalOps getAttributedOps(@NonNull String);
- method @NonNull public android.app.AppOpsManager.AttributedHistoricalOps getAttributedOpsAt(@IntRange(from=0) int);
- method @IntRange(from=0) public int getAttributedOpsCount();
- method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String);
- method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(@IntRange(from=0) int);
- method @IntRange(from=0) public int getOpCount();
- method @NonNull public String getPackageName();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalPackageOps> CREATOR;
- }
-
- public static final class AppOpsManager.HistoricalUidOps implements android.os.Parcelable {
- method public int describeContents();
- method @IntRange(from=0) public int getPackageCount();
- method @Nullable public android.app.AppOpsManager.HistoricalPackageOps getPackageOps(@NonNull String);
- method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(@IntRange(from=0) int);
- method public int getUid();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalUidOps> CREATOR;
- }
-
- public static final class AppOpsManager.OpEntry implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public java.util.Map<java.lang.String,android.app.AppOpsManager.AttributedOpEntry> getAttributedOpEntries();
- method @Deprecated public long getDuration();
- method public long getLastAccessBackgroundTime(int);
- method public long getLastAccessForegroundTime(int);
- method public long getLastAccessTime(int);
- method public long getLastAccessTime(int, int, int);
- method public long getLastBackgroundDuration(int);
- method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastBackgroundProxyInfo(int);
- method public long getLastDuration(int);
- method public long getLastDuration(int, int, int);
- method public long getLastForegroundDuration(int);
- method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastForegroundProxyInfo(int);
- method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int);
- method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int, int, int);
- method public long getLastRejectBackgroundTime(int);
- method public long getLastRejectForegroundTime(int);
- method public long getLastRejectTime(int);
- method public long getLastRejectTime(int, int, int);
- method public int getMode();
- method @NonNull public String getOpStr();
- method @Deprecated @Nullable public String getProxyPackageName();
- method @Deprecated @Nullable public String getProxyPackageName(int, int);
- method @Deprecated public int getProxyUid();
- method @Deprecated public int getProxyUid(int, int);
- method public boolean isRunning();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.OpEntry> CREATOR;
- }
-
- public static final class AppOpsManager.OpEventProxyInfo implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public String getAttributionTag();
- method @Nullable public String getPackageName();
- method @IntRange(from=0) public int getUid();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.OpEventProxyInfo> CREATOR;
- }
-
- public static final class AppOpsManager.PackageOps implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public java.util.List<android.app.AppOpsManager.OpEntry> getOps();
- method @NonNull public String getPackageName();
- method public int getUid();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.PackageOps> CREATOR;
}
public class DownloadManager {
@@ -433,10 +209,10 @@
}
public class DreamManager {
- method @RequiresPermission("android.permission.READ_DREAM_STATE") public boolean isDreaming();
- method @RequiresPermission("android.permission.WRITE_DREAM_STATE") public void setActiveDream(@NonNull android.content.ComponentName);
- method @RequiresPermission("android.permission.WRITE_DREAM_STATE") public void startDream(@NonNull android.content.ComponentName);
- method @RequiresPermission("android.permission.WRITE_DREAM_STATE") public void stopDream();
+ method @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE) public boolean isDreaming();
+ method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void setActiveDream(@NonNull android.content.ComponentName);
+ method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void startDream(@NonNull android.content.ComponentName);
+ method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void stopDream();
}
public final class NotificationChannel implements android.os.Parcelable {
@@ -445,14 +221,12 @@
method public boolean isImportanceLockedByCriticalDeviceFunction();
method public boolean isImportanceLockedByOEM();
method public void lockFields(int);
- method public void setBlockable(boolean);
method public void setDeleted(boolean);
method public void setFgServiceShown(boolean);
method public void setImportanceLockedByCriticalDeviceFunction(boolean);
method public void setImportanceLockedByOEM(boolean);
method public void setImportantConversation(boolean);
method public void setOriginalImportance(int);
- field public static final int USER_LOCKED_SOUND = 32; // 0x20
}
public final class NotificationChannelGroup implements android.os.Parcelable {
@@ -464,12 +238,8 @@
public class NotificationManager {
method public void allowAssistantAdjustment(String);
method public void disallowAssistantAdjustment(String);
- method @NonNull public java.util.List<java.lang.String> getAllowedAssistantAdjustments();
- method @Nullable public android.content.ComponentName getAllowedNotificationAssistant();
method public android.content.ComponentName getEffectsSuppressor();
- method public boolean isNotificationAssistantAccessGranted(@NonNull android.content.ComponentName);
method public boolean matchesCallFilter(android.os.Bundle);
- method public void setNotificationAssistantAccessGranted(@Nullable android.content.ComponentName, boolean);
}
public final class PictureInPictureParams implements android.os.Parcelable {
@@ -478,36 +248,12 @@
method public android.graphics.Rect getSourceRectHint();
}
- public final class RuntimeAppOpAccessMessage implements android.os.Parcelable {
- ctor public RuntimeAppOpAccessMessage(@IntRange(from=0L) int, @IntRange(from=0L) int, @NonNull String, @Nullable String, @NonNull String, int);
- method public int describeContents();
- method @Nullable public String getAttributionTag();
- method @NonNull public String getMessage();
- method @NonNull public String getOp();
- method @NonNull public String getPackageName();
- method public int getSamplingStrategy();
- method @IntRange(from=0L) public int getUid();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.RuntimeAppOpAccessMessage> CREATOR;
- }
-
public class StatusBarManager {
method public void collapsePanels();
method public void expandNotificationsPanel();
- method @NonNull @RequiresPermission(android.Manifest.permission.STATUS_BAR) public android.app.StatusBarManager.DisableInfo getDisableInfo();
- method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setDisabledForSetup(boolean);
method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setDisabledForSimNetworkLock(boolean);
}
- public static final class StatusBarManager.DisableInfo {
- method public boolean areAllComponentsEnabled();
- method public boolean isNavigateToHomeDisabled();
- method public boolean isNotificationPeekingDisabled();
- method public boolean isRecentsDisabled();
- method public boolean isSearchDisabled();
- method public boolean isStatusBarExpansionDisabled();
- }
-
public class TaskInfo {
method @NonNull public android.content.res.Configuration getConfiguration();
method @NonNull public android.window.WindowContainerToken getToken();
@@ -526,14 +272,12 @@
}
public class UiModeManager {
- method @RequiresPermission("android.permission.ENTER_CAR_MODE_PRIORITIZED") public void enableCarMode(@IntRange(from=0) int, int);
method public boolean isNightModeLocked();
method public boolean isUiModeLocked();
}
public class WallpaperManager {
method @Nullable public android.graphics.Bitmap getBitmap();
- method @RequiresPermission("android.permission.SET_WALLPAPER_COMPONENT") public boolean setWallpaperComponent(android.content.ComponentName);
method public boolean shouldEnableWideColorGamut();
method @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public boolean wallpaperSupportsWcg(int);
}
@@ -576,18 +320,13 @@
package android.app.admin {
public class DevicePolicyManager {
- method @Nullable public CharSequence getDeviceOwnerOrganizationName();
method public long getLastBugReportRequestTime();
method public long getLastNetworkLogRetrievalTime();
method public long getLastSecurityLogRetrievalTime();
method public java.util.List<java.lang.String> getOwnerInstalledCaCerts(@NonNull android.os.UserHandle);
method public boolean isCurrentInputMethodSetByOwner();
- method public boolean isDeviceManaged();
method public boolean isFactoryResetProtectionPolicySupported();
- field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED";
- field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
field public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED = "android.app.action.DATA_SHARING_RESTRICTION_APPLIED";
- field public static final String EXTRA_RESTRICTION = "android.app.extra.RESTRICTION";
}
public static final class SecurityLog.SecurityEvent implements android.os.Parcelable {
@@ -596,26 +335,6 @@
}
-package android.app.assist {
-
- public static class AssistStructure.ViewNode {
- ctor public AssistStructure.ViewNode();
- }
-
-}
-
-package android.app.backup {
-
- public class BackupManager {
- method @RequiresPermission("android.permission.BACKUP") public android.content.Intent getConfigurationIntent(String);
- method @RequiresPermission("android.permission.BACKUP") public android.content.Intent getDataManagementIntent(String);
- method @Nullable @RequiresPermission("android.permission.BACKUP") public CharSequence getDataManagementIntentLabel(@NonNull String);
- method @Deprecated @Nullable @RequiresPermission("android.permission.BACKUP") public String getDataManagementLabel(@NonNull String);
- method @RequiresPermission("android.permission.BACKUP") public String getDestinationString(String);
- }
-
-}
-
package android.app.blob {
public class BlobStoreManager {
@@ -638,121 +357,17 @@
package android.app.prediction {
- public final class AppPredictionContext implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public android.os.Bundle getExtras();
- method @NonNull public String getPackageName();
- method @IntRange(from=0) public int getPredictedTargetCount();
- method @NonNull public String getUiSurface();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.prediction.AppPredictionContext> CREATOR;
- }
-
- public static final class AppPredictionContext.Builder {
- ctor public AppPredictionContext.Builder(@NonNull android.content.Context);
- method @NonNull public android.app.prediction.AppPredictionContext build();
- method @NonNull public android.app.prediction.AppPredictionContext.Builder setExtras(@Nullable android.os.Bundle);
- method @NonNull public android.app.prediction.AppPredictionContext.Builder setPredictedTargetCount(@IntRange(from=0) int);
- method @NonNull public android.app.prediction.AppPredictionContext.Builder setUiSurface(@NonNull String);
- }
-
- public final class AppPredictionManager {
- method @NonNull public android.app.prediction.AppPredictor createAppPredictionSession(@NonNull android.app.prediction.AppPredictionContext);
- }
-
- public final class AppPredictionSessionId implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.prediction.AppPredictionSessionId> CREATOR;
- }
-
public final class AppPredictor {
- method public void destroy();
method public android.app.prediction.AppPredictionSessionId getSessionId();
- method public void notifyAppTargetEvent(@NonNull android.app.prediction.AppTargetEvent);
- method public void notifyLaunchLocationShown(@NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>);
- method public void registerPredictionUpdates(@NonNull java.util.concurrent.Executor, @NonNull android.app.prediction.AppPredictor.Callback);
- method public void requestPredictionUpdate();
- method @Nullable public void sortTargets(@NonNull java.util.List<android.app.prediction.AppTarget>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.app.prediction.AppTarget>>);
- method public void unregisterPredictionUpdates(@NonNull android.app.prediction.AppPredictor.Callback);
- }
-
- public static interface AppPredictor.Callback {
- method public void onTargetsAvailable(@NonNull java.util.List<android.app.prediction.AppTarget>);
- }
-
- public final class AppTarget implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public String getClassName();
- method @NonNull public android.app.prediction.AppTargetId getId();
- method @NonNull public String getPackageName();
- method @IntRange(from=0) public int getRank();
- method @Nullable public android.content.pm.ShortcutInfo getShortcutInfo();
- method @NonNull public android.os.UserHandle getUser();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.prediction.AppTarget> CREATOR;
- }
-
- public static final class AppTarget.Builder {
- ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId, @NonNull String, @NonNull android.os.UserHandle);
- ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId, @NonNull android.content.pm.ShortcutInfo);
- method @NonNull public android.app.prediction.AppTarget build();
- method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String);
- method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int);
- }
-
- public final class AppTargetEvent implements android.os.Parcelable {
- method public int describeContents();
- method public int getAction();
- method @Nullable public String getLaunchLocation();
- method @Nullable public android.app.prediction.AppTarget getTarget();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int ACTION_DISMISS = 2; // 0x2
- field public static final int ACTION_LAUNCH = 1; // 0x1
- field public static final int ACTION_PIN = 3; // 0x3
- field public static final int ACTION_UNPIN = 4; // 0x4
- field @NonNull public static final android.os.Parcelable.Creator<android.app.prediction.AppTargetEvent> CREATOR;
- }
-
- public static final class AppTargetEvent.Builder {
- ctor public AppTargetEvent.Builder(@Nullable android.app.prediction.AppTarget, int);
- method @NonNull public android.app.prediction.AppTargetEvent build();
- method @NonNull public android.app.prediction.AppTargetEvent.Builder setLaunchLocation(@Nullable String);
- }
-
- public final class AppTargetId implements android.os.Parcelable {
- ctor public AppTargetId(@NonNull String);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.prediction.AppTargetId> CREATOR;
}
}
package android.app.role {
- public interface OnRoleHoldersChangedListener {
- method public void onRoleHoldersChanged(@NonNull String, @NonNull android.os.UserHandle);
- }
-
public class RoleControllerManager {
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void isApplicationVisibleForRole(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void isRoleVisible(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- }
-
- public final class RoleManager {
- method @RequiresPermission("android.permission.OBSERVE_ROLE_HOLDERS") public void addOnRoleHoldersChangedListenerAsUser(@NonNull java.util.concurrent.Executor, @NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle);
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean addRoleHolderFromController(@NonNull String, @NonNull String);
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void clearRoleHoldersAsUser(@NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- method @NonNull @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public java.util.List<java.lang.String> getHeldRolesFromController(@NonNull String);
- method @NonNull @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public java.util.List<java.lang.String> getRoleHolders(@NonNull String);
- method @NonNull @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public java.util.List<java.lang.String> getRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle);
- method @RequiresPermission("android.permission.OBSERVE_ROLE_HOLDERS") public void removeOnRoleHoldersChangedListenerAsUser(@NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle);
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void removeRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean removeRoleHolderFromController(@NonNull String, @NonNull String);
- method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public void setRoleNamesFromController(@NonNull java.util.List<java.lang.String>);
- field public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1; // 0x1
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void isApplicationVisibleForRole(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void isRoleVisible(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
}
}
@@ -785,23 +400,8 @@
}
-package android.companion {
-
- public final class CompanionDeviceManager {
- method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociatedForWifiConnection(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle);
- }
-
-}
-
package android.content {
- public class ApexEnvironment {
- method @NonNull public static android.content.ApexEnvironment getApexEnvironment(@NonNull String);
- method @NonNull public java.io.File getCredentialProtectedDataDirForUser(@NonNull android.os.UserHandle);
- method @NonNull public java.io.File getDeviceProtectedDataDir();
- method @NonNull public java.io.File getDeviceProtectedDataDirForUser(@NonNull android.os.UserHandle);
- }
-
public final class AutofillOptions implements android.os.Parcelable {
ctor public AutofillOptions(int, boolean);
method public int describeContents();
@@ -837,36 +437,21 @@
method @NonNull public static android.os.UserHandle getUserHandleFromUri(@NonNull android.net.Uri);
}
- public class ContentProviderClient implements java.lang.AutoCloseable {
- method @RequiresPermission(android.Manifest.permission.REMOVE_TASKS) public void setDetectNotResponding(long);
- }
-
public abstract class ContentResolver {
- method @NonNull public static android.net.Uri decodeFromFile(@NonNull java.io.File);
- method @NonNull public static java.io.File encodeToFile(@NonNull android.net.Uri);
method public static String[] getSyncAdapterPackagesForAuthorityAsUser(String, int);
}
public abstract class Context {
- method @NonNull public android.content.Context createContextAsUser(@NonNull android.os.UserHandle, int);
- method @NonNull public android.content.Context createPackageContextAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public java.io.File getCrateDir(@NonNull String);
method public abstract int getDisplayId();
method public android.os.UserHandle getUser();
method public int getUserId();
method public void setAutofillOptions(@Nullable android.content.AutofillOptions);
method public void setContentCaptureOptions(@Nullable android.content.ContentCaptureOptions);
- method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.os.UserHandle);
- field public static final String APP_INTEGRITY_SERVICE = "app_integrity";
- field public static final String BUGREPORT_SERVICE = "bugreport";
field public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "content_capture";
field public static final String DEVICE_IDLE_CONTROLLER = "deviceidle";
field public static final String DREAM_SERVICE = "dream";
- field public static final String ETHERNET_SERVICE = "ethernet";
- field public static final String PERMISSION_SERVICE = "permission";
field public static final String POWER_WHITELIST_MANAGER = "power_whitelist";
- field public static final String ROLLBACK_SERVICE = "rollback";
- field public static final String STATUS_BAR_SERVICE = "statusbar";
field public static final String TEST_NETWORK_SERVICE = "test_network";
}
@@ -874,75 +459,13 @@
method public int getDisplayId();
}
- public class Intent implements java.lang.Cloneable android.os.Parcelable {
- field @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public static final String ACTION_MANAGE_DEFAULT_APP = "android.intent.action.MANAGE_DEFAULT_APP";
- field public static final String ACTION_ROLLBACK_COMMITTED = "android.intent.action.ROLLBACK_COMMITTED";
- field public static final String EXTRA_ORIGINATING_UID = "android.intent.extra.ORIGINATING_UID";
- field public static final String EXTRA_ROLE_NAME = "android.intent.extra.ROLE_NAME";
- }
-
}
package android.content.integrity {
public class AppIntegrityManager {
method @NonNull public android.content.integrity.RuleSet getCurrentRuleSet();
- method @NonNull public String getCurrentRuleSetProvider();
- method @NonNull public String getCurrentRuleSetVersion();
method @NonNull public java.util.List<java.lang.String> getWhitelistedRuleProviders();
- method public void updateRuleSet(@NonNull android.content.integrity.RuleSet, @NonNull android.content.IntentSender);
- field public static final String EXTRA_STATUS = "android.content.integrity.extra.STATUS";
- field public static final int STATUS_FAILURE = 1; // 0x1
- field public static final int STATUS_SUCCESS = 0; // 0x0
- }
-
- public abstract class IntegrityFormula {
- method @NonNull public static android.content.integrity.IntegrityFormula all(@NonNull android.content.integrity.IntegrityFormula...);
- method @NonNull public static android.content.integrity.IntegrityFormula any(@NonNull android.content.integrity.IntegrityFormula...);
- method @NonNull public static android.content.integrity.IntegrityFormula not(@NonNull android.content.integrity.IntegrityFormula);
- }
-
- public static final class IntegrityFormula.Application {
- method @NonNull public static android.content.integrity.IntegrityFormula certificatesContain(@NonNull String);
- method @NonNull public static android.content.integrity.IntegrityFormula isPreInstalled();
- method @NonNull public static android.content.integrity.IntegrityFormula packageNameEquals(@NonNull String);
- method @NonNull public static android.content.integrity.IntegrityFormula versionCodeEquals(@NonNull long);
- method @NonNull public static android.content.integrity.IntegrityFormula versionCodeGreaterThan(@NonNull long);
- method @NonNull public static android.content.integrity.IntegrityFormula versionCodeGreaterThanOrEqualTo(@NonNull long);
- }
-
- public static final class IntegrityFormula.Installer {
- method @NonNull public static android.content.integrity.IntegrityFormula certificatesContain(@NonNull String);
- method @NonNull public static android.content.integrity.IntegrityFormula notAllowedByManifest();
- method @NonNull public static android.content.integrity.IntegrityFormula packageNameEquals(@NonNull String);
- }
-
- public static final class IntegrityFormula.SourceStamp {
- method @NonNull public static android.content.integrity.IntegrityFormula notTrusted();
- method @NonNull public static android.content.integrity.IntegrityFormula stampCertificateHashEquals(@NonNull String);
- }
-
- public final class Rule implements android.os.Parcelable {
- ctor public Rule(@NonNull android.content.integrity.IntegrityFormula, int);
- method public int describeContents();
- method public int getEffect();
- method @NonNull public android.content.integrity.IntegrityFormula getFormula();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.content.integrity.Rule> CREATOR;
- field public static final int DENY = 0; // 0x0
- field public static final int FORCE_ALLOW = 1; // 0x1
- }
-
- public class RuleSet {
- method @NonNull public java.util.List<android.content.integrity.Rule> getRules();
- method @NonNull public String getVersion();
- }
-
- public static class RuleSet.Builder {
- ctor public RuleSet.Builder();
- method @NonNull public android.content.integrity.RuleSet.Builder addRules(@NonNull java.util.List<android.content.integrity.Rule>);
- method @NonNull public android.content.integrity.RuleSet build();
- method @NonNull public android.content.integrity.RuleSet.Builder setVersion(@NonNull String);
}
}
@@ -965,84 +488,31 @@
ctor public LauncherApps(android.content.Context);
}
- public static class PackageInstaller.SessionInfo implements android.os.Parcelable {
- method public int getAutoRevokePermissionsMode();
- method public int getRollbackDataPolicy();
- method @NonNull public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions();
- }
-
public static class PackageInstaller.SessionParams implements android.os.Parcelable {
- method public void setEnableRollback(boolean);
- method public void setEnableRollback(boolean, int);
- method @RequiresPermission("android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS") public void setGrantedRuntimePermissions(String[]);
- method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex();
method public void setInstallerPackageName(@Nullable String);
- method public void setRequestDowngrade(boolean);
- method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
}
public abstract class PackageManager {
- method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
- method public abstract boolean arePermissionsIndividuallyControlled();
method @Nullable public String getContentCaptureServicePackageName();
- method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int);
method @Nullable public String getDefaultTextClassifierPackageName();
- method @Nullable public String getIncidentReportApproverPackageName();
method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle);
method @NonNull public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int);
- method @NonNull @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int);
method @Nullable public abstract String[] getNamesForUids(int[]);
method @NonNull public abstract String getPermissionControllerPackageName();
- method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS", "android.permission.GET_RUNTIME_PERMISSIONS"}) public abstract int getPermissionFlags(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
method @NonNull public abstract String getServicesSystemSharedLibraryPackageName();
method @NonNull public abstract String getSharedSystemSharedLibraryPackageName();
method @Nullable public String getSystemTextClassifierPackageName();
method @Nullable public String getWellbeingPackageName();
- method @RequiresPermission("android.permission.GRANT_RUNTIME_PERMISSIONS") public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
- method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
- method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
- method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull String);
- method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS"}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, int, int, @NonNull android.os.UserHandle);
field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage";
field public static final String FEATURE_FILE_BASED_ENCRYPTION = "android.software.file_based_encryption";
- field public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 16384; // 0x4000
- field public static final int FLAG_PERMISSION_GRANTED_BY_ROLE = 32768; // 0x8000
- field public static final int FLAG_PERMISSION_ONE_TIME = 65536; // 0x10000
- field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4
- field public static final int FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT = 2048; // 0x800
- field public static final int FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT = 4096; // 0x1000
- field public static final int FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT = 8192; // 0x2000
- field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40
- field public static final int FLAG_PERMISSION_REVOKED_COMPAT = 8; // 0x8
- field @Deprecated public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8
field public static final int FLAG_PERMISSION_REVOKE_WHEN_REQUESTED = 128; // 0x80
- field public static final int FLAG_PERMISSION_SYSTEM_FIXED = 16; // 0x10
- field public static final int FLAG_PERMISSION_USER_FIXED = 2; // 0x2
- field public static final int FLAG_PERMISSION_USER_SET = 1; // 0x1
- field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000
field public static final int MATCH_KNOWN_PACKAGES = 4202496; // 0x402000
- field public static final int MODULE_APEX_NAME = 1; // 0x1
field public static final String SYSTEM_SHARED_LIBRARY_SERVICES = "android.ext.services";
field public static final String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared";
}
- public static interface PackageManager.OnPermissionsChangedListener {
- method public void onPermissionsChanged(int);
- }
-
public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
- field public static final int FLAG_REMOVED = 2; // 0x2
- field public static final int PROTECTION_FLAG_APP_PREDICTOR = 2097152; // 0x200000
- field public static final int PROTECTION_FLAG_COMPANION = 8388608; // 0x800000
- field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000
- field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000
- field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000
- field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000
- field public static final int PROTECTION_FLAG_RETAIL_DEMO = 16777216; // 0x1000000
- field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000
field public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 32768; // 0x8000
- field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000
- field @Nullable public final String backgroundPermission;
}
public final class ProviderInfoList implements android.os.Parcelable {
@@ -1081,40 +551,11 @@
package android.content.rollback {
- public final class PackageRollbackInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public String getPackageName();
- method @NonNull public android.content.pm.VersionedPackage getVersionRolledBackFrom();
- method @NonNull public android.content.pm.VersionedPackage getVersionRolledBackTo();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.content.rollback.PackageRollbackInfo> CREATOR;
- }
-
- public final class RollbackInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public java.util.List<android.content.pm.VersionedPackage> getCausePackages();
- method public int getCommittedSessionId();
- method @NonNull public java.util.List<android.content.rollback.PackageRollbackInfo> getPackages();
- method public int getRollbackId();
- method public boolean isStaged();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.content.rollback.RollbackInfo> CREATOR;
- }
-
public final class RollbackManager {
method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void blockRollbackManager(long);
- method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public void commitRollback(int, @NonNull java.util.List<android.content.pm.VersionedPackage>, @NonNull android.content.IntentSender);
method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void expireRollbackForPackage(@NonNull String);
- method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks();
- method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public java.util.List<android.content.rollback.RollbackInfo> getRecentlyCommittedRollbacks();
method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void reloadPersistedData();
- field public static final String EXTRA_STATUS = "android.content.rollback.extra.STATUS";
- field public static final String EXTRA_STATUS_MESSAGE = "android.content.rollback.extra.STATUS_MESSAGE";
field public static final String PROPERTY_ROLLBACK_LIFETIME_MILLIS = "rollback_lifetime_in_millis";
- field public static final int STATUS_FAILURE = 1; // 0x1
- field public static final int STATUS_FAILURE_INSTALL = 3; // 0x3
- field public static final int STATUS_FAILURE_ROLLBACK_UNAVAILABLE = 2; // 0x2
- field public static final int STATUS_SUCCESS = 0; // 0x0
}
}
@@ -1201,13 +642,6 @@
package android.hardware.camera2 {
- public abstract class CameraDevice implements java.lang.AutoCloseable {
- method @Deprecated public abstract void createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, @NonNull java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, @NonNull android.hardware.camera2.CameraCaptureSession.StateCallback, @Nullable android.os.Handler) throws android.hardware.camera2.CameraAccessException;
- field public static final int SESSION_OPERATION_MODE_CONSTRAINED_HIGH_SPEED = 1; // 0x1
- field public static final int SESSION_OPERATION_MODE_NORMAL = 0; // 0x0
- field public static final int SESSION_OPERATION_MODE_VENDOR_START = 32768; // 0x8000
- }
-
public final class CameraManager {
method public String[] getCameraIdListNoLazy() throws android.hardware.camera2.CameraAccessException;
}
@@ -1216,15 +650,6 @@
package android.hardware.display {
- public final class AmbientBrightnessDayStats implements android.os.Parcelable {
- method public int describeContents();
- method public float[] getBucketBoundaries();
- method public java.time.LocalDate getLocalDate();
- method public float[] getStats();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.AmbientBrightnessDayStats> CREATOR;
- }
-
public class AmbientDisplayConfiguration {
ctor public AmbientDisplayConfiguration(android.content.Context);
method public boolean alwaysOnAvailable();
@@ -1232,167 +657,14 @@
method public boolean alwaysOnEnabled(int);
}
- public final class BrightnessChangeEvent implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessChangeEvent> CREATOR;
- field public final float batteryLevel;
- field public final float brightness;
- field public final long colorSampleDuration;
- field public final int colorTemperature;
- field @Nullable public final long[] colorValueBuckets;
- field public final boolean isDefaultBrightnessConfig;
- field public final boolean isUserSetBrightness;
- field public final float lastBrightness;
- field public final long[] luxTimestamps;
- field public final float[] luxValues;
- field public final boolean nightMode;
- field public final String packageName;
- field public final float powerBrightnessFactor;
- field public final long timeStamp;
- }
-
- public final class BrightnessConfiguration implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByCategory(int);
- method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByPackageName(@NonNull String);
- method public android.util.Pair<float[],float[]> getCurve();
- method public float getShortTermModelLowerLuxMultiplier();
- method public long getShortTermModelTimeoutMillis();
- method public float getShortTermModelUpperLuxMultiplier();
- method public boolean shouldCollectColorSamples();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessConfiguration> CREATOR;
- field public static final long SHORT_TERM_TIMEOUT_UNSET = -1L; // 0xffffffffffffffffL
- }
-
- public static class BrightnessConfiguration.Builder {
- ctor public BrightnessConfiguration.Builder(float[], float[]);
- method @NonNull public android.hardware.display.BrightnessConfiguration.Builder addCorrectionByCategory(int, @NonNull android.hardware.display.BrightnessCorrection);
- method @NonNull public android.hardware.display.BrightnessConfiguration.Builder addCorrectionByPackageName(@NonNull String, @NonNull android.hardware.display.BrightnessCorrection);
- method @NonNull public android.hardware.display.BrightnessConfiguration build();
- method public int getMaxCorrectionsByCategory();
- method public int getMaxCorrectionsByPackageName();
- method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setDescription(@Nullable String);
- method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setShortTermModelLowerLuxMultiplier(@FloatRange(from=0.0f) float);
- method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setShortTermModelTimeoutMillis(long);
- method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setShortTermModelUpperLuxMultiplier(@FloatRange(from=0.0f) float);
- method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setShouldCollectColorSamples(boolean);
- }
-
- public final class BrightnessCorrection implements android.os.Parcelable {
- method @FloatRange(from=0.0) public float apply(@FloatRange(from=0.0) float);
- method @NonNull public static android.hardware.display.BrightnessCorrection createScaleAndTranslateLog(float, float);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessCorrection> CREATOR;
- }
-
public final class DisplayManager {
- method @RequiresPermission("android.permission.ACCESS_AMBIENT_LIGHT_STATS") public java.util.List<android.hardware.display.AmbientBrightnessDayStats> getAmbientBrightnessStats();
- method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getBrightnessConfiguration();
- method @RequiresPermission(android.Manifest.permission.BRIGHTNESS_SLIDER_USAGE) public java.util.List<android.hardware.display.BrightnessChangeEvent> getBrightnessEvents();
- method @Nullable @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getDefaultBrightnessConfiguration();
- method public android.graphics.Point getStableDisplaySize();
method public boolean isMinimalPostProcessingRequested(int);
- method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration);
}
}
package android.hardware.hdmi {
- public final class HdmiControlManager {
- method @Nullable public android.hardware.hdmi.HdmiSwitchClient getSwitchClient();
- method @RequiresPermission("android.permission.HDMI_CEC") public void setStandbyMode(boolean);
- field public static final String ACTION_OSD_MESSAGE = "android.hardware.hdmi.action.OSD_MESSAGE";
- field public static final int AVR_VOLUME_MUTED = 101; // 0x65
- field public static final int CLEAR_TIMER_STATUS_CEC_DISABLE = 162; // 0xa2
- field public static final int CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION = 160; // 0xa0
- field public static final int CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE = 161; // 0xa1
- field public static final int CLEAR_TIMER_STATUS_TIMER_CLEARED = 128; // 0x80
- field public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_INFO_AVAILABLE = 2; // 0x2
- field public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_MATCHING = 1; // 0x1
- field public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_RECORDING = 0; // 0x0
- field public static final int CONTROL_STATE_CHANGED_REASON_SETTING = 1; // 0x1
- field public static final int CONTROL_STATE_CHANGED_REASON_STANDBY = 3; // 0x3
- field public static final int CONTROL_STATE_CHANGED_REASON_START = 0; // 0x0
- field public static final int CONTROL_STATE_CHANGED_REASON_WAKEUP = 2; // 0x2
- field public static final int DEVICE_EVENT_ADD_DEVICE = 1; // 0x1
- field public static final int DEVICE_EVENT_REMOVE_DEVICE = 2; // 0x2
- field public static final int DEVICE_EVENT_UPDATE_DEVICE = 3; // 0x3
- field public static final String EXTRA_MESSAGE_EXTRA_PARAM1 = "android.hardware.hdmi.extra.MESSAGE_EXTRA_PARAM1";
- field public static final String EXTRA_MESSAGE_ID = "android.hardware.hdmi.extra.MESSAGE_ID";
- field public static final int ONE_TOUCH_RECORD_ALREADY_RECORDING = 18; // 0x12
- field public static final int ONE_TOUCH_RECORD_CEC_DISABLED = 51; // 0x33
- field public static final int ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION = 49; // 0x31
- field public static final int ONE_TOUCH_RECORD_DISALLOW_TO_COPY = 13; // 0xd
- field public static final int ONE_TOUCH_RECORD_DISALLOW_TO_FUTHER_COPIES = 14; // 0xe
- field public static final int ONE_TOUCH_RECORD_FAIL_TO_RECORD_DISPLAYED_SCREEN = 50; // 0x32
- field public static final int ONE_TOUCH_RECORD_INVALID_EXTERNAL_PHYSICAL_ADDRESS = 10; // 0xa
- field public static final int ONE_TOUCH_RECORD_INVALID_EXTERNAL_PLUG_NUMBER = 9; // 0x9
- field public static final int ONE_TOUCH_RECORD_MEDIA_PROBLEM = 21; // 0x15
- field public static final int ONE_TOUCH_RECORD_MEDIA_PROTECTED = 19; // 0x13
- field public static final int ONE_TOUCH_RECORD_NOT_ENOUGH_SPACE = 22; // 0x16
- field public static final int ONE_TOUCH_RECORD_NO_MEDIA = 16; // 0x10
- field public static final int ONE_TOUCH_RECORD_NO_OR_INSUFFICIENT_CA_ENTITLEMENTS = 12; // 0xc
- field public static final int ONE_TOUCH_RECORD_NO_SOURCE_SIGNAL = 20; // 0x14
- field public static final int ONE_TOUCH_RECORD_OTHER_REASON = 31; // 0x1f
- field public static final int ONE_TOUCH_RECORD_PARENT_LOCK_ON = 23; // 0x17
- field public static final int ONE_TOUCH_RECORD_PLAYING = 17; // 0x11
- field public static final int ONE_TOUCH_RECORD_PREVIOUS_RECORDING_IN_PROGRESS = 48; // 0x30
- field public static final int ONE_TOUCH_RECORD_RECORDING_ALREADY_TERMINATED = 27; // 0x1b
- field public static final int ONE_TOUCH_RECORD_RECORDING_ANALOGUE_SERVICE = 3; // 0x3
- field public static final int ONE_TOUCH_RECORD_RECORDING_CURRENTLY_SELECTED_SOURCE = 1; // 0x1
- field public static final int ONE_TOUCH_RECORD_RECORDING_DIGITAL_SERVICE = 2; // 0x2
- field public static final int ONE_TOUCH_RECORD_RECORDING_EXTERNAL_INPUT = 4; // 0x4
- field public static final int ONE_TOUCH_RECORD_RECORDING_TERMINATED_NORMALLY = 26; // 0x1a
- field public static final int ONE_TOUCH_RECORD_UNABLE_ANALOGUE_SERVICE = 6; // 0x6
- field public static final int ONE_TOUCH_RECORD_UNABLE_DIGITAL_SERVICE = 5; // 0x5
- field public static final int ONE_TOUCH_RECORD_UNABLE_SELECTED_SERVICE = 7; // 0x7
- field public static final int ONE_TOUCH_RECORD_UNSUPPORTED_CA = 11; // 0xb
- field public static final int OSD_MESSAGE_ARC_CONNECTED_INVALID_PORT = 1; // 0x1
- field public static final int OSD_MESSAGE_AVR_VOLUME_CHANGED = 2; // 0x2
- field public static final int POWER_STATUS_ON = 0; // 0x0
- field public static final int POWER_STATUS_STANDBY = 1; // 0x1
- field public static final int POWER_STATUS_TRANSIENT_TO_ON = 2; // 0x2
- field public static final int POWER_STATUS_TRANSIENT_TO_STANDBY = 3; // 0x3
- field public static final int POWER_STATUS_UNKNOWN = -1; // 0xffffffff
- field @Deprecated public static final int RESULT_ALREADY_IN_PROGRESS = 4; // 0x4
- field public static final int RESULT_COMMUNICATION_FAILED = 7; // 0x7
- field public static final int RESULT_EXCEPTION = 5; // 0x5
- field public static final int RESULT_INCORRECT_MODE = 6; // 0x6
- field public static final int RESULT_SOURCE_NOT_AVAILABLE = 2; // 0x2
- field public static final int RESULT_SUCCESS = 0; // 0x0
- field public static final int RESULT_TARGET_NOT_AVAILABLE = 3; // 0x3
- field public static final int RESULT_TIMEOUT = 1; // 0x1
- field public static final int TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED = 3; // 0x3
- field public static final int TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION = 1; // 0x1
- field public static final int TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE = 2; // 0x2
- field public static final int TIMER_RECORDING_RESULT_EXTRA_NO_ERROR = 0; // 0x0
- field public static final int TIMER_RECORDING_TYPE_ANALOGUE = 2; // 0x2
- field public static final int TIMER_RECORDING_TYPE_DIGITAL = 1; // 0x1
- field public static final int TIMER_RECORDING_TYPE_EXTERNAL = 3; // 0x3
- field public static final int TIMER_STATUS_MEDIA_INFO_NOT_PRESENT = 2; // 0x2
- field public static final int TIMER_STATUS_MEDIA_INFO_PRESENT_NOT_PROTECTED = 0; // 0x0
- field public static final int TIMER_STATUS_MEDIA_INFO_PRESENT_PROTECTED = 1; // 0x1
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_CA_NOT_SUPPORTED = 6; // 0x6
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_CLOCK_FAILURE = 10; // 0xa
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_DATE_OUT_OF_RANGE = 2; // 0x2
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_DUPLICATED = 14; // 0xe
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PHYSICAL_NUMBER = 5; // 0x5
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PLUG_NUMBER = 4; // 0x4
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_SEQUENCE = 3; // 0x3
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_NO_CA_ENTITLEMENTS = 7; // 0x7
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_NO_FREE_TIME = 1; // 0x1
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_PARENTAL_LOCK_ON = 9; // 0x9
- field public static final int TIMER_STATUS_NOT_PROGRAMMED_UNSUPPORTED_RESOLUTION = 8; // 0x8
- field public static final int TIMER_STATUS_PROGRAMMED_INFO_ENOUGH_SPACE = 8; // 0x8
- field public static final int TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE = 11; // 0xb
- field public static final int TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE = 9; // 0x9
- field public static final int TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO = 10; // 0xa
- }
-
public final class HdmiControlServiceWrapper {
ctor public HdmiControlServiceWrapper();
method @NonNull public android.hardware.hdmi.HdmiControlManager createHdmiControlManager();
@@ -1401,68 +673,12 @@
field public static final int DEVICE_PURE_CEC_SWITCH = 6; // 0x6
}
- public final class HdmiPortInfo implements android.os.Parcelable {
- ctor public HdmiPortInfo(int, int, int, boolean, boolean, boolean);
- method public int describeContents();
- method public int getAddress();
- method public int getId();
- method public int getType();
- method public boolean isArcSupported();
- method public boolean isCecSupported();
- method public boolean isMhlSupported();
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.hdmi.HdmiPortInfo> CREATOR;
- field public static final int PORT_INPUT = 0; // 0x0
- field public static final int PORT_OUTPUT = 1; // 0x1
- }
-
- public class HdmiSwitchClient {
- method public int getDeviceType();
- method @NonNull public java.util.List<android.hardware.hdmi.HdmiPortInfo> getPortInfo();
- method public void sendKeyEvent(int, boolean);
- method public void sendVendorCommand(int, byte[], boolean);
- }
-
}
package android.hardware.lights {
- public final class Light implements android.os.Parcelable {
- method public int describeContents();
- method public int getId();
- method public int getOrdinal();
- method public int getType();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.lights.Light> CREATOR;
- }
-
- public final class LightState implements android.os.Parcelable {
- ctor public LightState(@ColorInt int);
- method public int describeContents();
- method @ColorInt public int getColor();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.lights.LightState> CREATOR;
- }
-
public final class LightsManager {
method @NonNull @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_LIGHTS) public android.hardware.lights.LightState getLightState(@NonNull android.hardware.lights.Light);
- method @NonNull @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_LIGHTS) public java.util.List<android.hardware.lights.Light> getLights();
- method @NonNull @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_LIGHTS) public android.hardware.lights.LightsManager.LightsSession openSession();
- field public static final int LIGHT_TYPE_MICROPHONE = 8; // 0x8
- }
-
- public final class LightsManager.LightsSession implements java.lang.AutoCloseable {
- method @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_LIGHTS) public void close();
- method @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_LIGHTS) public void requestLights(@NonNull android.hardware.lights.LightsRequest);
- }
-
- public final class LightsRequest {
- }
-
- public static final class LightsRequest.Builder {
- ctor public LightsRequest.Builder();
- method @NonNull public android.hardware.lights.LightsRequest build();
- method @NonNull public android.hardware.lights.LightsRequest.Builder clearLight(@NonNull android.hardware.lights.Light);
- method @NonNull public android.hardware.lights.LightsRequest.Builder setLight(@NonNull android.hardware.lights.Light, @NonNull android.hardware.lights.LightState);
}
}
@@ -1493,84 +709,16 @@
field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.KeyphraseMetadata> CREATOR;
}
- public class SoundTrigger {
- field public static final int RECOGNITION_MODE_GENERIC = 8; // 0x8
- field public static final int RECOGNITION_MODE_USER_AUTHENTICATION = 4; // 0x4
- field public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 2; // 0x2
- field public static final int RECOGNITION_MODE_VOICE_TRIGGER = 1; // 0x1
- field public static final int STATUS_OK = 0; // 0x0
- }
-
- public static final class SoundTrigger.Keyphrase implements android.os.Parcelable {
- ctor public SoundTrigger.Keyphrase(int, int, @NonNull java.util.Locale, @NonNull String, @Nullable int[]);
- method public int getId();
- method @NonNull public java.util.Locale getLocale();
- method public int getRecognitionModes();
- method @NonNull public String getText();
- method @NonNull public int[] getUsers();
- method @NonNull public static android.hardware.soundtrigger.SoundTrigger.Keyphrase readFromParcel(@NonNull android.os.Parcel);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.Keyphrase> CREATOR;
- }
-
- public static final class SoundTrigger.KeyphraseSoundModel extends android.hardware.soundtrigger.SoundTrigger.SoundModel implements android.os.Parcelable {
- ctor public SoundTrigger.KeyphraseSoundModel(@NonNull java.util.UUID, @NonNull java.util.UUID, @Nullable byte[], @Nullable android.hardware.soundtrigger.SoundTrigger.Keyphrase[], int);
- ctor public SoundTrigger.KeyphraseSoundModel(@NonNull java.util.UUID, @NonNull java.util.UUID, @Nullable byte[], @Nullable android.hardware.soundtrigger.SoundTrigger.Keyphrase[]);
- method @NonNull public android.hardware.soundtrigger.SoundTrigger.Keyphrase[] getKeyphrases();
- method @NonNull public static android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel readFromParcel(@NonNull android.os.Parcel);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel> CREATOR;
- }
-
public static final class SoundTrigger.ModelParamRange implements android.os.Parcelable {
ctor public SoundTrigger.ModelParamRange(int, int);
- method public int getEnd();
- method public int getStart();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.ModelParamRange> CREATOR;
}
public static final class SoundTrigger.ModuleProperties implements android.os.Parcelable {
ctor public SoundTrigger.ModuleProperties(int, @NonNull String, @NonNull String, @NonNull String, int, @NonNull String, int, int, int, int, boolean, int, boolean, int, boolean, int);
- method public int describeContents();
- method public int getAudioCapabilities();
- method @NonNull public String getDescription();
- method public int getId();
- method @NonNull public String getImplementor();
- method public int getMaxBufferMillis();
- method public int getMaxKeyphrases();
- method public int getMaxSoundModels();
- method public int getMaxUsers();
- method public int getPowerConsumptionMw();
- method public int getRecognitionModes();
- method @NonNull public String getSupportedModelArch();
- method @NonNull public java.util.UUID getUuid();
- method public int getVersion();
- method public boolean isCaptureTransitionSupported();
- method public boolean isConcurrentCaptureSupported();
- method public boolean isTriggerReturnedInEvent();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int AUDIO_CAPABILITY_ECHO_CANCELLATION = 1; // 0x1
- field public static final int AUDIO_CAPABILITY_NOISE_SUPPRESSION = 2; // 0x2
- field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.ModuleProperties> CREATOR;
}
public static class SoundTrigger.RecognitionEvent {
ctor public SoundTrigger.RecognitionEvent(int, int, boolean, int, int, int, boolean, @NonNull android.media.AudioFormat, @Nullable byte[]);
- method @Nullable public android.media.AudioFormat getCaptureFormat();
- method public int getCaptureSession();
- method public byte[] getData();
- method public boolean isCaptureAvailable();
- }
-
- public static class SoundTrigger.SoundModel {
- method @NonNull public byte[] getData();
- method public int getType();
- method @NonNull public java.util.UUID getUuid();
- method @NonNull public java.util.UUID getVendorUuid();
- method public int getVersion();
- field public static final int TYPE_GENERIC_SOUND = 1; // 0x1
- field public static final int TYPE_KEYPHRASE = 0; // 0x0
}
}
@@ -1669,71 +817,18 @@
method public void setType(int);
}
- public class Location implements android.os.Parcelable {
- method public void makeComplete();
- field @Deprecated public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
- }
-
public class LocationManager {
method @NonNull public String[] getBackgroundThrottlingWhitelist();
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void getCurrentLocation(@NonNull android.location.LocationRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.location.Location>);
method @NonNull public String[] getIgnoreSettingsWhitelist();
- method @Nullable @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public java.util.List<java.lang.String> getProviderPackages(@NonNull String);
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public java.util.List<java.lang.String> getProviderPackages(@NonNull String);
method @NonNull public java.util.List<android.location.LocationRequest> getTestProviderCurrentRequests(String);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
field public static final String FUSED_PROVIDER = "fused";
}
- public final class LocationRequest implements android.os.Parcelable {
- method @NonNull public static android.location.LocationRequest create();
- method public int describeContents();
- method @Deprecated public long getExpireAt();
- method public long getExpireIn();
- method public long getFastestInterval();
- method public long getInterval();
- method public int getNumUpdates();
- method public int getQuality();
- method public boolean isLocationSettingsIgnored();
- method public boolean isLowPowerMode();
- method @Deprecated @NonNull public android.location.LocationRequest setExpireAt(long);
- method @NonNull public android.location.LocationRequest setExpireIn(long);
- method @NonNull public android.location.LocationRequest setFastestInterval(long);
- method @NonNull public android.location.LocationRequest setInterval(long);
- method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.location.LocationRequest setLocationSettingsIgnored(boolean);
- method @NonNull public android.location.LocationRequest setLowPowerMode(boolean);
- method @NonNull public android.location.LocationRequest setNumUpdates(int);
- method @NonNull public android.location.LocationRequest setProvider(@NonNull String);
- method @NonNull public android.location.LocationRequest setQuality(int);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int ACCURACY_BLOCK = 102; // 0x66
- field public static final int ACCURACY_CITY = 104; // 0x68
- field public static final int ACCURACY_FINE = 100; // 0x64
- field @NonNull public static final android.os.Parcelable.Creator<android.location.LocationRequest> CREATOR;
- field public static final int POWER_HIGH = 203; // 0xcb
- field public static final int POWER_LOW = 201; // 0xc9
- field public static final int POWER_NONE = 200; // 0xc8
- }
-
}
package android.media {
- public final class AudioFocusInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.media.AudioAttributes getAttributes();
- method @NonNull public String getClientId();
- method public int getClientUid();
- method public int getFlags();
- method public int getGainRequest();
- method public int getLossReceived();
- method @NonNull public String getPackageName();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioFocusInfo> CREATOR;
- }
-
public final class AudioFocusRequest {
method @Nullable public android.media.AudioManager.OnAudioFocusChangeListener getOnAudioFocusChangeListener();
}
@@ -1746,13 +841,7 @@
}
public class AudioManager {
- method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method public boolean hasRegisteredDynamicPolicy();
- method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
- method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
- method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
- method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy);
- field public static final int SUCCESS = 0; // 0x0
}
public static final class AudioRecord.MetricsConstants {
@@ -1853,90 +942,8 @@
package android.media.audiopolicy {
- public class AudioMix {
- method public int getMixState();
- field public static final int MIX_STATE_DISABLED = -1; // 0xffffffff
- field public static final int MIX_STATE_IDLE = 0; // 0x0
- field public static final int MIX_STATE_MIXING = 1; // 0x1
- field public static final int ROUTE_FLAG_LOOP_BACK = 2; // 0x2
- field public static final int ROUTE_FLAG_RENDER = 1; // 0x1
- }
-
- public static class AudioMix.Builder {
- ctor public AudioMix.Builder(android.media.audiopolicy.AudioMixingRule) throws java.lang.IllegalArgumentException;
- method public android.media.audiopolicy.AudioMix build() throws java.lang.IllegalArgumentException;
- method public android.media.audiopolicy.AudioMix.Builder setDevice(@NonNull android.media.AudioDeviceInfo) throws java.lang.IllegalArgumentException;
- method public android.media.audiopolicy.AudioMix.Builder setFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException;
- method public android.media.audiopolicy.AudioMix.Builder setRouteFlags(int) throws java.lang.IllegalArgumentException;
- }
-
- public class AudioMixingRule {
- field public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 2; // 0x2
- field public static final int RULE_MATCH_ATTRIBUTE_USAGE = 1; // 0x1
- field public static final int RULE_MATCH_UID = 4; // 0x4
- field public static final int RULE_MATCH_USERID = 8; // 0x8
- }
-
- public static class AudioMixingRule.Builder {
- ctor public AudioMixingRule.Builder();
- method public android.media.audiopolicy.AudioMixingRule.Builder addMixRule(int, Object) throws java.lang.IllegalArgumentException;
- method public android.media.audiopolicy.AudioMixingRule.Builder addRule(android.media.AudioAttributes, int) throws java.lang.IllegalArgumentException;
- method @NonNull public android.media.audiopolicy.AudioMixingRule.Builder allowPrivilegedPlaybackCapture(boolean);
- method public android.media.audiopolicy.AudioMixingRule build();
- method public android.media.audiopolicy.AudioMixingRule.Builder excludeMixRule(int, Object) throws java.lang.IllegalArgumentException;
- method public android.media.audiopolicy.AudioMixingRule.Builder excludeRule(android.media.AudioAttributes, int) throws java.lang.IllegalArgumentException;
- }
-
- public class AudioPolicy {
- method public int attachMixes(@NonNull java.util.List<android.media.audiopolicy.AudioMix>);
- method public android.media.AudioRecord createAudioRecordSink(android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
- method public android.media.AudioTrack createAudioTrackSource(android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
- method public int detachMixes(@NonNull java.util.List<android.media.audiopolicy.AudioMix>);
- method public int getFocusDuckingBehavior();
- method public int getStatus();
- method public boolean removeUidDeviceAffinity(int);
- method public boolean removeUserIdDeviceAffinity(int);
- method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
- method public void setRegistration(String);
- method public boolean setUidDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>);
- method public boolean setUserIdDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>);
- method public String toLogFriendlyString();
- field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0
- field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0
- field public static final int FOCUS_POLICY_DUCKING_IN_POLICY = 1; // 0x1
- field public static final int POLICY_STATUS_REGISTERED = 2; // 0x2
- field public static final int POLICY_STATUS_UNREGISTERED = 1; // 0x1
- }
-
- public abstract static class AudioPolicy.AudioPolicyFocusListener {
- ctor public AudioPolicy.AudioPolicyFocusListener();
- method public void onAudioFocusAbandon(android.media.AudioFocusInfo);
- method public void onAudioFocusGrant(android.media.AudioFocusInfo, int);
- method public void onAudioFocusLoss(android.media.AudioFocusInfo, boolean);
- method public void onAudioFocusRequest(android.media.AudioFocusInfo, int);
- }
-
- public abstract static class AudioPolicy.AudioPolicyStatusListener {
- ctor public AudioPolicy.AudioPolicyStatusListener();
- method public void onMixStateUpdate(android.media.audiopolicy.AudioMix);
- method public void onStatusChange();
- }
-
- public abstract static class AudioPolicy.AudioPolicyVolumeCallback {
- ctor public AudioPolicy.AudioPolicyVolumeCallback();
- method public void onVolumeAdjustment(int);
- }
-
public static class AudioPolicy.Builder {
- ctor public AudioPolicy.Builder(android.content.Context);
- method @NonNull public android.media.audiopolicy.AudioPolicy.Builder addMix(@NonNull android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
- method @NonNull public android.media.audiopolicy.AudioPolicy build();
- method public void setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener);
- method public void setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener);
- method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setAudioPolicyVolumeCallback(@NonNull android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback);
- method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean);
method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsTestFocusPolicy(boolean);
- method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setLooper(@NonNull android.os.Looper) throws java.lang.IllegalArgumentException;
}
}
@@ -1950,232 +957,27 @@
}
-package android.metrics {
-
- public class LogMaker {
- ctor public LogMaker(int);
- ctor public LogMaker(Object[]);
- method public android.metrics.LogMaker addTaggedData(int, Object);
- method public android.metrics.LogMaker clearCategory();
- method public android.metrics.LogMaker clearPackageName();
- method public android.metrics.LogMaker clearSubtype();
- method public android.metrics.LogMaker clearTaggedData(int);
- method public android.metrics.LogMaker clearType();
- method public void deserialize(Object[]);
- method public int getCategory();
- method public long getCounterBucket();
- method public String getCounterName();
- method public int getCounterValue();
- method public String getPackageName();
- method public int getProcessId();
- method public int getSubtype();
- method public Object getTaggedData(int);
- method public long getTimestamp();
- method public int getType();
- method public int getUid();
- method public boolean isLongCounterBucket();
- method public boolean isSubsetOf(android.metrics.LogMaker);
- method public boolean isValidValue(Object);
- method public Object[] serialize();
- method public android.metrics.LogMaker setCategory(int);
- method public android.metrics.LogMaker setPackageName(String);
- method public android.metrics.LogMaker setSubtype(int);
- method public android.metrics.LogMaker setType(int);
- }
-
- public class MetricsReader {
- ctor public MetricsReader();
- method public void checkpoint();
- method public boolean hasNext();
- method public android.metrics.LogMaker next();
- method public void read(long);
- method public void reset();
- }
-
-}
-
package android.net {
- public class CaptivePortal implements android.os.Parcelable {
- method public void logEvent(int, @NonNull String);
- method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void reevaluateNetwork();
- method public void useNetwork();
- field public static final int APP_REQUEST_REEVALUATION_REQUIRED = 100; // 0x64
- field public static final int APP_RETURN_DISMISSED = 0; // 0x0
- field public static final int APP_RETURN_UNWANTED = 1; // 0x1
- field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2
- }
-
- public final class CaptivePortalData implements android.os.Parcelable {
- method public int describeContents();
- method public long getByteLimit();
- method public long getExpiryTimeMillis();
- method public long getRefreshTimeMillis();
- method @Nullable public android.net.Uri getUserPortalUrl();
- method @Nullable public android.net.Uri getVenueInfoUrl();
- method public boolean isCaptive();
- method public boolean isSessionExtendable();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortalData> CREATOR;
- }
-
- public static class CaptivePortalData.Builder {
- ctor public CaptivePortalData.Builder();
- ctor public CaptivePortalData.Builder(@Nullable android.net.CaptivePortalData);
- method @NonNull public android.net.CaptivePortalData build();
- method @NonNull public android.net.CaptivePortalData.Builder setBytesRemaining(long);
- method @NonNull public android.net.CaptivePortalData.Builder setCaptive(boolean);
- method @NonNull public android.net.CaptivePortalData.Builder setExpiryTime(long);
- method @NonNull public android.net.CaptivePortalData.Builder setRefreshTime(long);
- method @NonNull public android.net.CaptivePortalData.Builder setSessionExtendable(boolean);
- method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri);
- method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri);
- }
-
public class ConnectivityManager {
method @RequiresPermission(anyOf={"android.permission.MANAGE_TEST_NETWORKS", android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
- method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
- field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
- field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
}
public class EthernetManager {
- method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback);
method public void setIncludeTestInterfaces(boolean);
}
- public static interface EthernetManager.TetheredInterfaceCallback {
- method public void onAvailable(@NonNull String);
- method public void onUnavailable();
- }
-
- public static class EthernetManager.TetheredInterfaceRequest {
- method public void release();
- }
-
- public final class IpPrefix implements android.os.Parcelable {
- ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
- ctor public IpPrefix(@NonNull String);
- }
-
public final class IpSecManager {
field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
}
- public class LinkAddress implements android.os.Parcelable {
- ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int);
- ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int, long, long);
- ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
- ctor public LinkAddress(@NonNull String);
- ctor public LinkAddress(@NonNull String, int, int);
- method public long getDeprecationTime();
- method public long getExpirationTime();
- method public boolean isGlobalPreferred();
- method public boolean isIpv4();
- method public boolean isIpv6();
- method public boolean isSameAddressAs(@Nullable android.net.LinkAddress);
- }
-
- public final class LinkProperties implements android.os.Parcelable {
- ctor public LinkProperties(@Nullable android.net.LinkProperties);
- ctor public LinkProperties(@Nullable android.net.LinkProperties, boolean);
- method public boolean addDnsServer(@NonNull java.net.InetAddress);
- method public boolean addLinkAddress(@NonNull android.net.LinkAddress);
- method @Nullable public android.net.Uri getCaptivePortalApiUrl();
- method @Nullable public android.net.CaptivePortalData getCaptivePortalData();
- method @NonNull public java.util.List<java.net.InetAddress> getPcscfServers();
- method @Nullable public String getTcpBufferSizes();
- method @NonNull public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers();
- method public boolean hasGlobalIpv6Address();
- method public boolean hasIpv4Address();
- method public boolean hasIpv6DefaultRoute();
- method public boolean isIpv4Provisioned();
- method public boolean isIpv6Provisioned();
- method public boolean isProvisioned();
- method public boolean isReachable(@NonNull java.net.InetAddress);
- method public boolean removeDnsServer(@NonNull java.net.InetAddress);
- method public boolean removeLinkAddress(@NonNull android.net.LinkAddress);
- method public boolean removeRoute(@NonNull android.net.RouteInfo);
- method public void setCaptivePortalApiUrl(@Nullable android.net.Uri);
- method public void setCaptivePortalData(@Nullable android.net.CaptivePortalData);
- method public void setPcscfServers(@NonNull java.util.Collection<java.net.InetAddress>);
- method public void setPrivateDnsServerName(@Nullable String);
- method public void setTcpBufferSizes(@Nullable String);
- method public void setUsePrivateDns(boolean);
- method public void setValidatedPrivateDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
- }
-
- public class Network implements android.os.Parcelable {
- ctor public Network(@NonNull android.net.Network);
- method public int getNetId();
- method @NonNull public android.net.Network getPrivateDnsBypassingCopy();
- }
-
public final class NetworkCapabilities implements android.os.Parcelable {
- method @NonNull public int[] getAdministratorUids();
method public int[] getCapabilities();
- method @Nullable public String getSsid();
- method @NonNull public int[] getTransportTypes();
- method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
field public static final int TRANSPORT_TEST = 7; // 0x7
}
- public static final class NetworkCapabilities.Builder {
- ctor public NetworkCapabilities.Builder();
- ctor public NetworkCapabilities.Builder(@NonNull android.net.NetworkCapabilities);
- method @NonNull public android.net.NetworkCapabilities.Builder addCapability(int);
- method @NonNull public android.net.NetworkCapabilities.Builder addTransportType(int);
- method @NonNull public android.net.NetworkCapabilities build();
- method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int);
- method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int);
- method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]);
- method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int);
- method @NonNull public android.net.NetworkCapabilities.Builder setLinkUpstreamBandwidthKbps(int);
- method @NonNull public android.net.NetworkCapabilities.Builder setNetworkSpecifier(@Nullable android.net.NetworkSpecifier);
- method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setOwnerUid(int);
- method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String);
- method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setRequestorUid(int);
- method @NonNull @RequiresPermission("android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP") public android.net.NetworkCapabilities.Builder setSignalStrength(int);
- method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
- method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
- }
-
public class NetworkStack {
- method @Nullable public static android.os.IBinder getService();
method public static void setServiceForTest(@Nullable android.os.IBinder);
- field public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK";
- }
-
- public final class RouteInfo implements android.os.Parcelable {
- ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int);
- method public int getType();
- field public static final int RTN_THROW = 9; // 0x9
- field public static final int RTN_UNICAST = 1; // 0x1
- field public static final int RTN_UNREACHABLE = 7; // 0x7
- }
-
- public final class StaticIpConfiguration implements android.os.Parcelable {
- ctor public StaticIpConfiguration();
- ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
- method public void addDnsServer(@NonNull java.net.InetAddress);
- method public void clear();
- method public int describeContents();
- method @NonNull public java.util.List<java.net.InetAddress> getDnsServers();
- method @Nullable public String getDomains();
- method @Nullable public java.net.InetAddress getGateway();
- method @Nullable public android.net.LinkAddress getIpAddress();
- method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.StaticIpConfiguration> CREATOR;
- }
-
- public static final class StaticIpConfiguration.Builder {
- ctor public StaticIpConfiguration.Builder();
- method @NonNull public android.net.StaticIpConfiguration build();
- method @NonNull public android.net.StaticIpConfiguration.Builder setDnsServers(@NonNull Iterable<java.net.InetAddress>);
- method @NonNull public android.net.StaticIpConfiguration.Builder setDomains(@Nullable String);
- method @NonNull public android.net.StaticIpConfiguration.Builder setGateway(@Nullable java.net.InetAddress);
- method @NonNull public android.net.StaticIpConfiguration.Builder setIpAddress(@Nullable android.net.LinkAddress);
}
public final class TestNetworkInterface implements android.os.Parcelable {
@@ -2194,100 +996,6 @@
method public void teardownTestNetwork(@NonNull android.net.Network);
}
- public final class TetheredClient implements android.os.Parcelable {
- ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int);
- method public int describeContents();
- method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses();
- method @NonNull public android.net.MacAddress getMacAddress();
- method public int getTetheringType();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR;
- }
-
- public static final class TetheredClient.AddressInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.net.LinkAddress getAddress();
- method @Nullable public String getHostname();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
- }
-
- public class TetheringManager {
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
- field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
- field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
- field public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
- field public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
- field public static final String EXTRA_ERRORED_TETHER = "erroredArray";
- field public static final int TETHERING_BLUETOOTH = 2; // 0x2
- field public static final int TETHERING_ETHERNET = 5; // 0x5
- field public static final int TETHERING_INVALID = -1; // 0xffffffff
- field public static final int TETHERING_NCM = 4; // 0x4
- field public static final int TETHERING_USB = 1; // 0x1
- field public static final int TETHERING_WIFI = 0; // 0x0
- field public static final int TETHERING_WIFI_P2P = 3; // 0x3
- field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
- field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9
- field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8
- field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
- field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
- field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5
- field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
- field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
- field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
- field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb
- field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
- field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
- field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
- field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
- field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10
- field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
- field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
- field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
- field public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; // 0x1
- field public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; // 0x0
- }
-
- public static interface TetheringManager.OnTetheringEntitlementResultListener {
- method public void onTetheringEntitlementResult(int);
- }
-
- public static interface TetheringManager.StartTetheringCallback {
- method public default void onTetheringFailed(int);
- method public default void onTetheringStarted();
- }
-
- public static interface TetheringManager.TetheringEventCallback {
- method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
- method public default void onError(@NonNull String, int);
- method public default void onOffloadStatusChanged(int);
- method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
- method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
- method public default void onTetheringSupported(boolean);
- method public default void onUpstreamChanged(@Nullable android.net.Network);
- }
-
- public static class TetheringManager.TetheringRequest {
- method @Nullable public android.net.LinkAddress getClientStaticIpv4Address();
- method @Nullable public android.net.LinkAddress getLocalIpv4Address();
- method public boolean getShouldShowEntitlementUi();
- method public int getTetheringType();
- method public boolean isExemptFromEntitlementCheck();
- }
-
- public static class TetheringManager.TetheringRequest.Builder {
- ctor public TetheringManager.TetheringRequest.Builder(int);
- method @NonNull public android.net.TetheringManager.TetheringRequest build();
- method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
- method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean);
- method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress);
- }
-
public class TrafficStats {
method public static long getLoopbackRxBytes();
method public static long getLoopbackRxPackets();
@@ -2297,228 +1005,8 @@
}
-package android.net.apf {
-
- public final class ApfCapabilities implements android.os.Parcelable {
- ctor public ApfCapabilities(int, int, int);
- method public int describeContents();
- method public static boolean getApfDrop8023Frames();
- method @NonNull public static int[] getApfEtherTypeBlackList();
- method public boolean hasDataAccess();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.apf.ApfCapabilities> CREATOR;
- field public final int apfPacketFormat;
- field public final int apfVersionSupported;
- field public final int maximumApfProgramSize;
- }
-
-}
-
-package android.net.metrics {
-
- public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event {
- }
-
- public static final class ApfProgramEvent.Builder {
- ctor public ApfProgramEvent.Builder();
- method @NonNull public android.net.metrics.ApfProgramEvent build();
- method @NonNull public android.net.metrics.ApfProgramEvent.Builder setActualLifetime(long);
- method @NonNull public android.net.metrics.ApfProgramEvent.Builder setCurrentRas(int);
- method @NonNull public android.net.metrics.ApfProgramEvent.Builder setFilteredRas(int);
- method @NonNull public android.net.metrics.ApfProgramEvent.Builder setFlags(boolean, boolean);
- method @NonNull public android.net.metrics.ApfProgramEvent.Builder setLifetime(long);
- method @NonNull public android.net.metrics.ApfProgramEvent.Builder setProgramLength(int);
- }
-
- public final class ApfStats implements android.net.metrics.IpConnectivityLog.Event {
- }
-
- public static final class ApfStats.Builder {
- ctor public ApfStats.Builder();
- method @NonNull public android.net.metrics.ApfStats build();
- method @NonNull public android.net.metrics.ApfStats.Builder setDroppedRas(int);
- method @NonNull public android.net.metrics.ApfStats.Builder setDurationMs(long);
- method @NonNull public android.net.metrics.ApfStats.Builder setMatchingRas(int);
- method @NonNull public android.net.metrics.ApfStats.Builder setMaxProgramSize(int);
- method @NonNull public android.net.metrics.ApfStats.Builder setParseErrors(int);
- method @NonNull public android.net.metrics.ApfStats.Builder setProgramUpdates(int);
- method @NonNull public android.net.metrics.ApfStats.Builder setProgramUpdatesAll(int);
- method @NonNull public android.net.metrics.ApfStats.Builder setProgramUpdatesAllowingMulticast(int);
- method @NonNull public android.net.metrics.ApfStats.Builder setReceivedRas(int);
- method @NonNull public android.net.metrics.ApfStats.Builder setZeroLifetimeRas(int);
- }
-
- public final class DhcpClientEvent implements android.net.metrics.IpConnectivityLog.Event {
- }
-
- public static final class DhcpClientEvent.Builder {
- ctor public DhcpClientEvent.Builder();
- method @NonNull public android.net.metrics.DhcpClientEvent build();
- method @NonNull public android.net.metrics.DhcpClientEvent.Builder setDurationMs(int);
- method @NonNull public android.net.metrics.DhcpClientEvent.Builder setMsg(String);
- }
-
- public final class DhcpErrorEvent implements android.net.metrics.IpConnectivityLog.Event {
- ctor public DhcpErrorEvent(int);
- method public static int errorCodeWithOption(int, int);
- field public static final int BOOTP_TOO_SHORT = 67174400; // 0x4010000
- field public static final int BUFFER_UNDERFLOW = 83951616; // 0x5010000
- field public static final int DHCP_BAD_MAGIC_COOKIE = 67239936; // 0x4020000
- field public static final int DHCP_ERROR = 4; // 0x4
- field public static final int DHCP_INVALID_OPTION_LENGTH = 67305472; // 0x4030000
- field public static final int DHCP_NO_COOKIE = 67502080; // 0x4060000
- field public static final int DHCP_NO_MSG_TYPE = 67371008; // 0x4040000
- field public static final int DHCP_UNKNOWN_MSG_TYPE = 67436544; // 0x4050000
- field public static final int L2_ERROR = 1; // 0x1
- field public static final int L2_TOO_SHORT = 16842752; // 0x1010000
- field public static final int L2_WRONG_ETH_TYPE = 16908288; // 0x1020000
- field public static final int L3_ERROR = 2; // 0x2
- field public static final int L3_INVALID_IP = 33751040; // 0x2030000
- field public static final int L3_NOT_IPV4 = 33685504; // 0x2020000
- field public static final int L3_TOO_SHORT = 33619968; // 0x2010000
- field public static final int L4_ERROR = 3; // 0x3
- field public static final int L4_NOT_UDP = 50397184; // 0x3010000
- field public static final int L4_WRONG_PORT = 50462720; // 0x3020000
- field public static final int MISC_ERROR = 5; // 0x5
- field public static final int PARSING_ERROR = 84082688; // 0x5030000
- field public static final int RECEIVE_ERROR = 84017152; // 0x5020000
- }
-
- public class IpConnectivityLog {
- ctor public IpConnectivityLog();
- method public boolean log(long, @NonNull android.net.metrics.IpConnectivityLog.Event);
- method public boolean log(@NonNull String, @NonNull android.net.metrics.IpConnectivityLog.Event);
- method public boolean log(@NonNull android.net.Network, @NonNull int[], @NonNull android.net.metrics.IpConnectivityLog.Event);
- method public boolean log(int, @NonNull int[], @NonNull android.net.metrics.IpConnectivityLog.Event);
- method public boolean log(@NonNull android.net.metrics.IpConnectivityLog.Event);
- }
-
- public static interface IpConnectivityLog.Event extends android.os.Parcelable {
- }
-
- public final class IpManagerEvent implements android.net.metrics.IpConnectivityLog.Event {
- ctor public IpManagerEvent(int, long);
- field public static final int COMPLETE_LIFECYCLE = 3; // 0x3
- field public static final int ERROR_INTERFACE_NOT_FOUND = 8; // 0x8
- field public static final int ERROR_INVALID_PROVISIONING = 7; // 0x7
- field public static final int ERROR_STARTING_IPREACHABILITYMONITOR = 6; // 0x6
- field public static final int ERROR_STARTING_IPV4 = 4; // 0x4
- field public static final int ERROR_STARTING_IPV6 = 5; // 0x5
- field public static final int PROVISIONING_FAIL = 2; // 0x2
- field public static final int PROVISIONING_OK = 1; // 0x1
- }
-
- public final class IpReachabilityEvent implements android.net.metrics.IpConnectivityLog.Event {
- ctor public IpReachabilityEvent(int);
- field public static final int NUD_FAILED = 512; // 0x200
- field public static final int NUD_FAILED_ORGANIC = 1024; // 0x400
- field public static final int PROBE = 256; // 0x100
- field public static final int PROVISIONING_LOST = 768; // 0x300
- field public static final int PROVISIONING_LOST_ORGANIC = 1280; // 0x500
- }
-
- public final class NetworkEvent implements android.net.metrics.IpConnectivityLog.Event {
- ctor public NetworkEvent(int, long);
- ctor public NetworkEvent(int);
- field public static final int NETWORK_CAPTIVE_PORTAL_FOUND = 4; // 0x4
- field public static final int NETWORK_CONNECTED = 1; // 0x1
- field public static final int NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND = 12; // 0xc
- field public static final int NETWORK_DISCONNECTED = 7; // 0x7
- field public static final int NETWORK_FIRST_VALIDATION_PORTAL_FOUND = 10; // 0xa
- field public static final int NETWORK_FIRST_VALIDATION_SUCCESS = 8; // 0x8
- field public static final int NETWORK_LINGER = 5; // 0x5
- field public static final int NETWORK_PARTIAL_CONNECTIVITY = 13; // 0xd
- field public static final int NETWORK_REVALIDATION_PORTAL_FOUND = 11; // 0xb
- field public static final int NETWORK_REVALIDATION_SUCCESS = 9; // 0x9
- field public static final int NETWORK_UNLINGER = 6; // 0x6
- field public static final int NETWORK_VALIDATED = 2; // 0x2
- field public static final int NETWORK_VALIDATION_FAILED = 3; // 0x3
- }
-
- public final class RaEvent implements android.net.metrics.IpConnectivityLog.Event {
- }
-
- public static final class RaEvent.Builder {
- ctor public RaEvent.Builder();
- method @NonNull public android.net.metrics.RaEvent build();
- method @NonNull public android.net.metrics.RaEvent.Builder updateDnsslLifetime(long);
- method @NonNull public android.net.metrics.RaEvent.Builder updatePrefixPreferredLifetime(long);
- method @NonNull public android.net.metrics.RaEvent.Builder updatePrefixValidLifetime(long);
- method @NonNull public android.net.metrics.RaEvent.Builder updateRdnssLifetime(long);
- method @NonNull public android.net.metrics.RaEvent.Builder updateRouteInfoLifetime(long);
- method @NonNull public android.net.metrics.RaEvent.Builder updateRouterLifetime(long);
- }
-
- public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event {
- method @NonNull public static String getProbeName(int);
- field public static final int DNS_FAILURE = 0; // 0x0
- field public static final int DNS_SUCCESS = 1; // 0x1
- field public static final int PROBE_DNS = 0; // 0x0
- field public static final int PROBE_FALLBACK = 4; // 0x4
- field public static final int PROBE_HTTP = 1; // 0x1
- field public static final int PROBE_HTTPS = 2; // 0x2
- field public static final int PROBE_PAC = 3; // 0x3
- field public static final int PROBE_PRIVDNS = 5; // 0x5
- }
-
- public static final class ValidationProbeEvent.Builder {
- ctor public ValidationProbeEvent.Builder();
- method @NonNull public android.net.metrics.ValidationProbeEvent build();
- method @NonNull public android.net.metrics.ValidationProbeEvent.Builder setDurationMs(long);
- method @NonNull public android.net.metrics.ValidationProbeEvent.Builder setProbeType(int, boolean);
- method @NonNull public android.net.metrics.ValidationProbeEvent.Builder setReturnCode(int);
- }
-
-}
-
-package android.net.util {
-
- public final class SocketUtils {
- method public static void bindSocketToInterface(@NonNull java.io.FileDescriptor, @NonNull String) throws android.system.ErrnoException;
- method public static void closeSocket(@Nullable java.io.FileDescriptor) throws java.io.IOException;
- method @NonNull public static java.net.SocketAddress makeNetlinkSocketAddress(int, int);
- method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int);
- method @Deprecated @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
- method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int, @NonNull byte[]);
- }
-
-}
-
package android.os {
- public class BatteryManager {
- method @RequiresPermission("android.permission.POWER_SAVER") public boolean setChargingStateUpdateDelayMillis(int);
- }
-
- public final class BugreportManager {
- method @RequiresPermission(android.Manifest.permission.DUMP) public void cancelBugreport();
- method @RequiresPermission(android.Manifest.permission.DUMP) public void requestBugreport(@NonNull android.os.BugreportParams, @Nullable CharSequence, @Nullable CharSequence);
- method @RequiresPermission(android.Manifest.permission.DUMP) public void startBugreport(@NonNull android.os.ParcelFileDescriptor, @Nullable android.os.ParcelFileDescriptor, @NonNull android.os.BugreportParams, @NonNull java.util.concurrent.Executor, @NonNull android.os.BugreportManager.BugreportCallback);
- }
-
- public abstract static class BugreportManager.BugreportCallback {
- ctor public BugreportManager.BugreportCallback();
- method public void onError(int);
- method public void onFinished();
- method public void onProgress(@FloatRange(from=0.0f, to=100.0f) float);
- field public static final int BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS = 5; // 0x5
- field public static final int BUGREPORT_ERROR_INVALID_INPUT = 1; // 0x1
- field public static final int BUGREPORT_ERROR_RUNTIME = 2; // 0x2
- field public static final int BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT = 4; // 0x4
- field public static final int BUGREPORT_ERROR_USER_DENIED_CONSENT = 3; // 0x3
- }
-
- public final class BugreportParams {
- ctor public BugreportParams(int);
- method public int getMode();
- field public static final int BUGREPORT_MODE_FULL = 0; // 0x0
- field public static final int BUGREPORT_MODE_INTERACTIVE = 1; // 0x1
- field public static final int BUGREPORT_MODE_REMOTE = 2; // 0x2
- field public static final int BUGREPORT_MODE_TELEPHONY = 4; // 0x4
- field public static final int BUGREPORT_MODE_WEAR = 3; // 0x3
- field public static final int BUGREPORT_MODE_WIFI = 5; // 0x5
- }
-
public class Build {
method public static boolean is64BitAbi(String);
field public static final boolean IS_EMULATOR;
@@ -2537,11 +1025,6 @@
public class Environment {
method public static java.io.File buildPath(java.io.File, java.lang.String...);
- method @NonNull public static java.io.File getOdmDirectory();
- method @NonNull public static java.io.File getOemDirectory();
- method @NonNull public static java.io.File getProductDirectory();
- method @NonNull public static java.io.File getSystemExtDirectory();
- method @NonNull public static java.io.File getVendorDirectory();
}
public final class FileUtils {
@@ -2550,228 +1033,11 @@
method @NonNull public static byte[] digest(@NonNull java.io.InputStream, @NonNull String) throws java.io.IOException, java.security.NoSuchAlgorithmException;
}
- public class HidlMemory implements java.io.Closeable {
- ctor public HidlMemory(@NonNull String, @IntRange(from=0) long, @Nullable android.os.NativeHandle);
- method public void close() throws java.io.IOException;
- method @NonNull public android.os.HidlMemory dup() throws java.io.IOException;
- method protected void finalize();
- method @Nullable public android.os.NativeHandle getHandle();
- method @NonNull public String getName();
- method public long getSize();
- method @Nullable public android.os.NativeHandle releaseHandle();
- }
-
- public abstract class HwBinder implements android.os.IHwBinder {
- ctor public HwBinder();
- method public static final void configureRpcThreadpool(long, boolean);
- method public static void enableInstrumentation();
- method public static final android.os.IHwBinder getService(String, String) throws java.util.NoSuchElementException, android.os.RemoteException;
- method public static final android.os.IHwBinder getService(String, String, boolean) throws java.util.NoSuchElementException, android.os.RemoteException;
- method public static final void joinRpcThreadpool();
- method public abstract void onTransact(int, android.os.HwParcel, android.os.HwParcel, int) throws android.os.RemoteException;
- method public final void registerService(String) throws android.os.RemoteException;
- method public final void transact(int, android.os.HwParcel, android.os.HwParcel, int) throws android.os.RemoteException;
- }
-
- public class HwBlob {
- ctor public HwBlob(int);
- method public final void copyToBoolArray(long, boolean[], int);
- method public final void copyToDoubleArray(long, double[], int);
- method public final void copyToFloatArray(long, float[], int);
- method public final void copyToInt16Array(long, short[], int);
- method public final void copyToInt32Array(long, int[], int);
- method public final void copyToInt64Array(long, long[], int);
- method public final void copyToInt8Array(long, byte[], int);
- method public final boolean getBool(long);
- method public final double getDouble(long);
- method public final long getFieldHandle(long);
- method public final float getFloat(long);
- method public final short getInt16(long);
- method public final int getInt32(long);
- method public final long getInt64(long);
- method public final byte getInt8(long);
- method public final String getString(long);
- method public final long handle();
- method public final void putBlob(long, android.os.HwBlob);
- method public final void putBool(long, boolean);
- method public final void putBoolArray(long, boolean[]);
- method public final void putDouble(long, double);
- method public final void putDoubleArray(long, double[]);
- method public final void putFloat(long, float);
- method public final void putFloatArray(long, float[]);
- method public final void putHidlMemory(long, @NonNull android.os.HidlMemory);
- method public final void putInt16(long, short);
- method public final void putInt16Array(long, short[]);
- method public final void putInt32(long, int);
- method public final void putInt32Array(long, int[]);
- method public final void putInt64(long, long);
- method public final void putInt64Array(long, long[]);
- method public final void putInt8(long, byte);
- method public final void putInt8Array(long, byte[]);
- method public final void putNativeHandle(long, @Nullable android.os.NativeHandle);
- method public final void putString(long, String);
- method public static Boolean[] wrapArray(@NonNull boolean[]);
- method public static Long[] wrapArray(@NonNull long[]);
- method public static Byte[] wrapArray(@NonNull byte[]);
- method public static Short[] wrapArray(@NonNull short[]);
- method public static Integer[] wrapArray(@NonNull int[]);
- method public static Float[] wrapArray(@NonNull float[]);
- method public static Double[] wrapArray(@NonNull double[]);
- }
-
- public class HwParcel {
- ctor public HwParcel();
- method public final void enforceInterface(String);
- method public final boolean readBool();
- method public final java.util.ArrayList<java.lang.Boolean> readBoolVector();
- method public final android.os.HwBlob readBuffer(long);
- method public final double readDouble();
- method public final java.util.ArrayList<java.lang.Double> readDoubleVector();
- method public final android.os.HwBlob readEmbeddedBuffer(long, long, long, boolean);
- method @NonNull @Nullable public final android.os.HidlMemory readEmbeddedHidlMemory(long, long, long);
- method @Nullable public final android.os.NativeHandle readEmbeddedNativeHandle(long, long);
- method public final float readFloat();
- method public final java.util.ArrayList<java.lang.Float> readFloatVector();
- method @NonNull public final android.os.HidlMemory readHidlMemory();
- method public final short readInt16();
- method public final java.util.ArrayList<java.lang.Short> readInt16Vector();
- method public final int readInt32();
- method public final java.util.ArrayList<java.lang.Integer> readInt32Vector();
- method public final long readInt64();
- method public final java.util.ArrayList<java.lang.Long> readInt64Vector();
- method public final byte readInt8();
- method public final java.util.ArrayList<java.lang.Byte> readInt8Vector();
- method @Nullable public final android.os.NativeHandle readNativeHandle();
- method @NonNull public final java.util.ArrayList<android.os.NativeHandle> readNativeHandleVector();
- method public final String readString();
- method public final java.util.ArrayList<java.lang.String> readStringVector();
- method public final android.os.IHwBinder readStrongBinder();
- method public final void release();
- method public final void releaseTemporaryStorage();
- method public final void send();
- method public final void verifySuccess();
- method public final void writeBool(boolean);
- method public final void writeBoolVector(java.util.ArrayList<java.lang.Boolean>);
- method public final void writeBuffer(android.os.HwBlob);
- method public final void writeDouble(double);
- method public final void writeDoubleVector(java.util.ArrayList<java.lang.Double>);
- method public final void writeFloat(float);
- method public final void writeFloatVector(java.util.ArrayList<java.lang.Float>);
- method public final void writeHidlMemory(@NonNull android.os.HidlMemory);
- method public final void writeInt16(short);
- method public final void writeInt16Vector(java.util.ArrayList<java.lang.Short>);
- method public final void writeInt32(int);
- method public final void writeInt32Vector(java.util.ArrayList<java.lang.Integer>);
- method public final void writeInt64(long);
- method public final void writeInt64Vector(java.util.ArrayList<java.lang.Long>);
- method public final void writeInt8(byte);
- method public final void writeInt8Vector(java.util.ArrayList<java.lang.Byte>);
- method public final void writeInterfaceToken(String);
- method public final void writeNativeHandle(@Nullable android.os.NativeHandle);
- method public final void writeNativeHandleVector(@NonNull java.util.ArrayList<android.os.NativeHandle>);
- method public final void writeStatus(int);
- method public final void writeString(String);
- method public final void writeStringVector(java.util.ArrayList<java.lang.String>);
- method public final void writeStrongBinder(android.os.IHwBinder);
- field public static final int STATUS_SUCCESS = 0; // 0x0
- }
-
- public interface IHwBinder {
- method public boolean linkToDeath(android.os.IHwBinder.DeathRecipient, long);
- method public android.os.IHwInterface queryLocalInterface(String);
- method public void transact(int, android.os.HwParcel, android.os.HwParcel, int) throws android.os.RemoteException;
- method public boolean unlinkToDeath(android.os.IHwBinder.DeathRecipient);
- }
-
- public static interface IHwBinder.DeathRecipient {
- method public void serviceDied(long);
- }
-
- public interface IHwInterface {
- method public android.os.IHwBinder asBinder();
- }
-
- public class IncidentManager {
- method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public void approveReport(android.net.Uri);
- method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void cancelAuthorization(android.os.IncidentManager.AuthListener);
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void deleteIncidentReports(android.net.Uri);
- method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public void denyReport(android.net.Uri);
- method @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public android.os.IncidentManager.IncidentReport getIncidentReport(android.net.Uri);
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public java.util.List<android.net.Uri> getIncidentReportList(String);
- method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public java.util.List<android.os.IncidentManager.PendingReport> getPendingReports();
- method public void registerSection(int, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.IncidentManager.DumpCallback);
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void reportIncident(android.os.IncidentReportArgs);
- method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener);
- method public void unregisterSection(int);
- field public static final int FLAG_CONFIRMATION_DIALOG = 1; // 0x1
- field public static final int PRIVACY_POLICY_AUTO = 200; // 0xc8
- field public static final int PRIVACY_POLICY_EXPLICIT = 100; // 0x64
- field public static final int PRIVACY_POLICY_LOCAL = 0; // 0x0
- }
-
- public static class IncidentManager.AuthListener {
- ctor public IncidentManager.AuthListener();
- method public void onReportApproved();
- method public void onReportDenied();
- }
-
- public static class IncidentManager.DumpCallback {
- ctor public IncidentManager.DumpCallback();
- method public void onDumpSection(int, @NonNull java.io.OutputStream);
- }
-
- public static class IncidentManager.IncidentReport implements java.io.Closeable android.os.Parcelable {
- ctor public IncidentManager.IncidentReport(android.os.Parcel);
- method public void close();
- method public int describeContents();
- method public java.io.InputStream getInputStream() throws java.io.IOException;
- method public long getPrivacyPolicy();
- method public long getTimestamp();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.os.IncidentManager.IncidentReport> CREATOR;
- }
-
- public static class IncidentManager.PendingReport {
- ctor public IncidentManager.PendingReport(@NonNull android.net.Uri);
- method public int getFlags();
- method @NonNull public String getRequestingPackage();
- method public long getTimestamp();
- method @NonNull public android.net.Uri getUri();
- }
-
- public final class IncidentReportArgs implements android.os.Parcelable {
- ctor public IncidentReportArgs();
- ctor public IncidentReportArgs(android.os.Parcel);
- method public void addHeader(byte[]);
- method public void addSection(int);
- method public boolean containsSection(int);
- method public int describeContents();
- method public boolean isAll();
- method public void readFromParcel(android.os.Parcel);
- method public int sectionCount();
- method public void setAll(boolean);
- method public void setPrivacyPolicy(int);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.os.IncidentReportArgs> CREATOR;
- }
-
public final class MessageQueue {
method public int postSyncBarrier();
method public void removeSyncBarrier(int);
}
- public final class NativeHandle implements java.io.Closeable {
- ctor public NativeHandle();
- ctor public NativeHandle(@NonNull java.io.FileDescriptor, boolean);
- ctor public NativeHandle(@NonNull java.io.FileDescriptor[], @NonNull int[], boolean);
- method public void close() throws java.io.IOException;
- method @NonNull public android.os.NativeHandle dup() throws java.io.IOException;
- method @NonNull public java.io.FileDescriptor getFileDescriptor();
- method @NonNull public java.io.FileDescriptor[] getFileDescriptors();
- method @NonNull public int[] getInts();
- method public boolean hasSingleFileDescriptor();
- }
-
public final class Parcel {
method public boolean allowSquashing();
method public int readExceptionCode();
@@ -2782,24 +1048,6 @@
method public static java.io.File getFile(java.io.FileDescriptor) throws java.io.IOException;
}
- public final class PowerManager {
- method @RequiresPermission("android.permission.POWER_SAVER") public int getPowerSaveModeTrigger();
- method @RequiresPermission("android.permission.POWER_SAVER") public boolean setDynamicPowerSaveHint(boolean, int);
- method @RequiresPermission(anyOf={"android.permission.DEVICE_POWER", "android.permission.POWER_SAVER"}) public boolean setPowerSaveModeEnabled(boolean);
- field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1
- field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0
- }
-
- public class PowerWhitelistManager {
- method @RequiresPermission("android.permission.DEVICE_POWER") public void addToWhitelist(@NonNull String);
- method @RequiresPermission("android.permission.DEVICE_POWER") public void addToWhitelist(@NonNull java.util.List<java.lang.String>);
- method @RequiresPermission("android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST") public void whitelistAppTemporarily(@NonNull String, long);
- method @RequiresPermission("android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST") public long whitelistAppTemporarilyForEvent(@NonNull String, int, @NonNull String);
- field public static final int EVENT_MMS = 2; // 0x2
- field public static final int EVENT_SMS = 1; // 0x1
- field public static final int EVENT_UNSPECIFIED = 0; // 0x0
- }
-
public class Process {
method public static final int getThreadScheduler(int) throws java.lang.IllegalArgumentException;
field public static final int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000; // 0x15f90
@@ -2809,19 +1057,6 @@
field public static final int NUM_UIDS_PER_APP_ZYGOTE = 100; // 0x64
}
- public final class RemoteCallback implements android.os.Parcelable {
- ctor public RemoteCallback(android.os.RemoteCallback.OnResultListener);
- ctor public RemoteCallback(@NonNull android.os.RemoteCallback.OnResultListener, @Nullable android.os.Handler);
- method public int describeContents();
- method public void sendResult(@Nullable android.os.Bundle);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.os.RemoteCallback> CREATOR;
- }
-
- public static interface RemoteCallback.OnResultListener {
- method public void onResult(@Nullable android.os.Bundle);
- }
-
public final class StrictMode {
method public static void conditionallyCheckInstanceCounts();
method public static void setViolationLogger(android.os.StrictMode.ViolationLogger);
@@ -2859,40 +1094,19 @@
method @NonNull public android.os.StrictMode.VmPolicy.Builder permitIncorrectContextUse();
}
- public class SystemConfigManager {
- method @NonNull @RequiresPermission("android.permission.READ_CARRIER_APP_INFO") public java.util.Set<java.lang.String> getDisabledUntilUsedPreinstalledCarrierApps();
- method @NonNull @RequiresPermission("android.permission.READ_CARRIER_APP_INFO") public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
- }
-
- public class SystemProperties {
- method @NonNull public static String get(@NonNull String);
- method @NonNull public static String get(@NonNull String, @Nullable String);
- method public static boolean getBoolean(@NonNull String, boolean);
- method public static int getInt(@NonNull String, int);
- method public static long getLong(@NonNull String, long);
- }
-
public final class UserHandle implements android.os.Parcelable {
- method public static int getAppId(int);
- method public int getIdentifier();
method public static int getUid(int, int);
method public static int getUserId(int);
method public static boolean isApp(int);
- method public static int myUserId();
- method public static android.os.UserHandle of(int);
- field @NonNull public static final android.os.UserHandle ALL;
- field @NonNull public static final android.os.UserHandle CURRENT;
field public static final int MIN_SECONDARY_USER_ID = 10; // 0xa
- field @NonNull public static final android.os.UserHandle SYSTEM;
field public static final int USER_ALL = -1; // 0xffffffff
field public static final int USER_NULL = -10000; // 0xffffd8f0
field public static final int USER_SYSTEM = 0; // 0x0
}
public class UserManager {
- method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.CREATE_USERS"}) public boolean hasBaseUserRestriction(@NonNull String, @NonNull android.os.UserHandle);
+ method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean hasBaseUserRestriction(@NonNull String, @NonNull android.os.UserHandle);
method public static boolean isSplitSystemUser();
- field public static final String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED";
}
public final class VibrationAttributes implements android.os.Parcelable {
@@ -2955,17 +1169,6 @@
field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect.Waveform> CREATOR;
}
- public abstract class Vibrator {
- method @RequiresPermission("android.permission.ACCESS_VIBRATOR_STATE") public void addVibratorStateListener(@NonNull android.os.Vibrator.OnVibratorStateChangedListener);
- method @RequiresPermission("android.permission.ACCESS_VIBRATOR_STATE") public void addVibratorStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.Vibrator.OnVibratorStateChangedListener);
- method @RequiresPermission("android.permission.ACCESS_VIBRATOR_STATE") public boolean isVibrating();
- method @RequiresPermission("android.permission.ACCESS_VIBRATOR_STATE") public void removeVibratorStateListener(@NonNull android.os.Vibrator.OnVibratorStateChangedListener);
- }
-
- public static interface Vibrator.OnVibratorStateChangedListener {
- method public void onVibratorStateChanged(boolean);
- }
-
public class VintfObject {
method public static String[] getHalNamesAndVersions();
method public static String getSepolicyVersion();
@@ -2985,16 +1188,10 @@
}
public class WorkSource implements android.os.Parcelable {
- ctor public WorkSource(int);
method public boolean add(int);
method public boolean add(int, String);
method @Deprecated public android.os.WorkSource addReturningNewbs(android.os.WorkSource);
- method @Nullable public String getPackageName(int);
- method public int getUid(int);
- method public boolean isEmpty();
method @Deprecated public android.os.WorkSource[] setReturningDiffs(android.os.WorkSource);
- method public int size();
- method @NonNull public android.os.WorkSource withoutNames();
}
}
@@ -3054,36 +1251,6 @@
}
-package android.os.image {
-
- public class DynamicSystemClient {
- ctor public DynamicSystemClient(@NonNull android.content.Context);
- method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void bind();
- method public void setOnStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
- method public void setOnStatusChangedListener(@NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
- method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void start(@NonNull android.net.Uri, long);
- method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void start(@NonNull android.net.Uri, long, long);
- method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void unbind();
- field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6
- field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4
- field public static final int CAUSE_ERROR_IO = 3; // 0x3
- field public static final int CAUSE_ERROR_IPC = 5; // 0x5
- field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2
- field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1
- field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0
- field public static final int STATUS_IN_PROGRESS = 2; // 0x2
- field public static final int STATUS_IN_USE = 4; // 0x4
- field public static final int STATUS_NOT_STARTED = 1; // 0x1
- field public static final int STATUS_READY = 3; // 0x3
- field public static final int STATUS_UNKNOWN = 0; // 0x0
- }
-
- public static interface DynamicSystemClient.OnStatusChangedListener {
- method public void onStatusChanged(int, int, long, @Nullable Throwable);
- }
-
-}
-
package android.os.storage {
public final class CrateInfo implements android.os.Parcelable {
@@ -3097,10 +1264,6 @@
field @NonNull public static final android.os.Parcelable.Creator<android.os.storage.CrateInfo> CREATOR;
}
- public class StorageManager {
- method public static boolean hasIsolatedStorage();
- }
-
public final class StorageVolume implements android.os.Parcelable {
method public String getPath();
}
@@ -3117,17 +1280,9 @@
package android.permission {
public final class PermissionControllerManager {
- method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void applyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void countPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, @Nullable android.os.Handler);
- method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler);
- method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getRuntimePermissionBackup(@NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<byte[]>);
- method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermission(@NonNull String, @NonNull String);
- method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback);
- method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[], @NonNull android.os.UserHandle);
- field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1
- field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2
- field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2
- field public static final int REASON_MALWARE = 1; // 0x1
+ method @RequiresPermission(android.Manifest.permission.GET_RUNTIME_PERMISSIONS) public void countPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, @Nullable android.os.Handler);
+ method @RequiresPermission(android.Manifest.permission.GET_RUNTIME_PERMISSIONS) public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler);
+ method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermission(@NonNull String, @NonNull String);
}
public static interface PermissionControllerManager.OnCountPermissionAppsResultCallback {
@@ -3138,33 +1293,6 @@
method public void onGetAppPermissions(@NonNull java.util.List<android.permission.RuntimePermissionPresentationInfo>);
}
- public abstract static class PermissionControllerManager.OnRevokeRuntimePermissionsCallback {
- ctor public PermissionControllerManager.OnRevokeRuntimePermissionsCallback();
- method public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>);
- }
-
- public final class PermissionManager {
- method @IntRange(from=0) @RequiresPermission(anyOf={"android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY", android.Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS}) public int getRuntimePermissionsVersion();
- method @NonNull public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions();
- method @RequiresPermission(anyOf={"android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY", android.Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS}) public void setRuntimePermissionsVersion(@IntRange(from=0) int);
- }
-
- public static final class PermissionManager.SplitPermissionInfo {
- method @NonNull public java.util.List<java.lang.String> getNewPermissions();
- method @NonNull public String getSplitPermission();
- method public int getTargetSdk();
- }
-
- public final class RuntimePermissionPresentationInfo implements android.os.Parcelable {
- ctor public RuntimePermissionPresentationInfo(@NonNull CharSequence, boolean, boolean);
- method public int describeContents();
- method @NonNull public CharSequence getLabel();
- method public boolean isGranted();
- method public boolean isStandard();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.permission.RuntimePermissionPresentationInfo> CREATOR;
- }
-
}
package android.print {
@@ -3212,78 +1340,15 @@
}
public final class DeviceConfig {
- method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
- method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static boolean getBoolean(@NonNull String, @NonNull String, boolean);
- method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static float getFloat(@NonNull String, @NonNull String, float);
- method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static int getInt(@NonNull String, @NonNull String, int);
- method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static long getLong(@NonNull String, @NonNull String, long);
- method @NonNull @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static android.provider.DeviceConfig.Properties getProperties(@NonNull String, @NonNull java.lang.String...);
- method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getProperty(@NonNull String, @NonNull String);
- method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getString(@NonNull String, @NonNull String, @Nullable String);
- method public static void removeOnPropertiesChangedListener(@NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
- method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static void resetToDefaults(int, @Nullable String);
- method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperties(@NonNull android.provider.DeviceConfig.Properties) throws android.provider.DeviceConfig.BadConfigException;
- method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(@NonNull String, @NonNull String, @Nullable String, boolean);
field public static final String NAMESPACE_ANDROID = "android";
- field public static final String NAMESPACE_AUTOFILL = "autofill";
- field public static final String NAMESPACE_BIOMETRICS = "biometrics";
- field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
- field public static final String NAMESPACE_PERMISSIONS = "permissions";
- field public static final String NAMESPACE_PRIVACY = "privacy";
- field public static final String NAMESPACE_ROLLBACK = "rollback";
- field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
- }
-
- public static class DeviceConfig.BadConfigException extends java.lang.Exception {
- ctor public DeviceConfig.BadConfigException();
- }
-
- public static interface DeviceConfig.OnPropertiesChangedListener {
- method public void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
- }
-
- public static class DeviceConfig.Properties {
- method public boolean getBoolean(@NonNull String, boolean);
- method public float getFloat(@NonNull String, float);
- method public int getInt(@NonNull String, int);
- method @NonNull public java.util.Set<java.lang.String> getKeyset();
- method public long getLong(@NonNull String, long);
- method @NonNull public String getNamespace();
- method @Nullable public String getString(@NonNull String, @Nullable String);
- }
-
- public static final class DeviceConfig.Properties.Builder {
- ctor public DeviceConfig.Properties.Builder(@NonNull String);
- method @NonNull public android.provider.DeviceConfig.Properties build();
- method @NonNull public android.provider.DeviceConfig.Properties.Builder setBoolean(@NonNull String, boolean);
- method @NonNull public android.provider.DeviceConfig.Properties.Builder setFloat(@NonNull String, float);
- method @NonNull public android.provider.DeviceConfig.Properties.Builder setInt(@NonNull String, int);
- method @NonNull public android.provider.DeviceConfig.Properties.Builder setLong(@NonNull String, long);
- method @NonNull public android.provider.DeviceConfig.Properties.Builder setString(@NonNull String, @Nullable String);
- }
-
- public final class DocumentsContract {
- method public static boolean isManageMode(@NonNull android.net.Uri);
- method @NonNull public static android.net.Uri setManageMode(@NonNull android.net.Uri);
- }
-
- public final class MediaStore {
- method @NonNull @WorkerThread public static android.net.Uri scanFile(@NonNull android.content.ContentResolver, @NonNull java.io.File);
- method @WorkerThread public static void scanVolume(@NonNull android.content.ContentResolver, @NonNull String);
- method @WorkerThread public static void waitForIdle(@NonNull android.content.ContentResolver);
}
public final class Settings {
- field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
- field public static final String ACTION_MANAGE_APP_OVERLAY_PERMISSION = "android.settings.MANAGE_APP_OVERLAY_PERMISSION";
- field public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE = "android.settings.REQUEST_ENABLE_CONTENT_CAPTURE";
- field public static final String ACTION_TETHER_PROVISIONING_UI = "android.settings.TETHER_PROVISIONING_UI";
field public static final int RESET_MODE_PACKAGE_DEFAULTS = 1; // 0x1
}
public static final class Settings.Global extends android.provider.Settings.NameValueTable {
field public static final String APP_OPS_CONSTANTS = "app_ops_constants";
- field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
field public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode";
field public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
field public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = "dynamic_power_savings_disable_threshold";
@@ -3296,74 +1361,26 @@
field public static final String LOW_POWER_MODE_STICKY = "low_power_sticky";
field public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
field public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices";
- field public static final String TETHER_OFFLOAD_DISABLED = "tether_offload_disabled";
field public static final String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package";
}
public static final class Settings.Secure extends android.provider.Settings.NameValueTable {
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static void resetToDefaults(@NonNull android.content.ContentResolver, @Nullable String);
field public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED = "accessibility_display_magnification_enabled";
field public static final String ACCESSIBILITY_SHORTCUT_TARGET_SERVICE = "accessibility_shortcut_target_service";
- field public static final String AUTOFILL_FEATURE_FIELD_CLASSIFICATION = "autofill_field_classification";
field public static final String AUTOFILL_SERVICE = "autofill_service";
- field public static final String AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT = "autofill_user_data_max_category_count";
- field public static final String AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE = "autofill_user_data_max_field_classification_size";
- field public static final String AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE = "autofill_user_data_max_user_data_size";
- field public static final String AUTOFILL_USER_DATA_MAX_VALUE_LENGTH = "autofill_user_data_max_value_length";
- field public static final String AUTOFILL_USER_DATA_MIN_VALUE_LENGTH = "autofill_user_data_min_value_length";
field public static final String CONTENT_CAPTURE_ENABLED = "content_capture_enabled";
field public static final String DISABLED_PRINT_SERVICES = "disabled_print_services";
- field public static final String DOZE_ALWAYS_ON = "doze_always_on";
field @Deprecated public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES = "enabled_notification_policy_access_packages";
field public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners";
field public static final String IMMERSIVE_MODE_CONFIRMATIONS = "immersive_mode_confirmations";
- field public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS = "location_access_check_delay_millis";
- field public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS = "location_access_check_interval_millis";
- field public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS = "lock_screen_allow_private_notifications";
- field public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS = "lock_screen_show_notifications";
field public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
field public static final String NOTIFICATION_BADGING = "notification_badging";
field public static final String POWER_MENU_LOCKED_SHOW_CONTENT = "power_menu_locked_show_content";
field public static final String SHOW_IME_WITH_HARD_KEYBOARD = "show_ime_with_hard_keyboard";
field @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds";
- field public static final String USER_SETUP_COMPLETE = "user_setup_complete";
field public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
}
- public static final class Telephony.CellBroadcasts implements android.provider.BaseColumns {
- field public static final String CID = "cid";
- field public static final String CMAS_CATEGORY = "cmas_category";
- field public static final String CMAS_CERTAINTY = "cmas_certainty";
- field public static final String CMAS_MESSAGE_CLASS = "cmas_message_class";
- field public static final String CMAS_RESPONSE_TYPE = "cmas_response_type";
- field public static final String CMAS_SEVERITY = "cmas_severity";
- field public static final String CMAS_URGENCY = "cmas_urgency";
- field @NonNull public static final android.net.Uri CONTENT_URI;
- field public static final String DATA_CODING_SCHEME = "dcs";
- field public static final String DEFAULT_SORT_ORDER = "date DESC";
- field public static final String DELIVERY_TIME = "date";
- field public static final String ETWS_WARNING_TYPE = "etws_warning_type";
- field public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
- field public static final String GEOMETRIES = "geometries";
- field public static final String LAC = "lac";
- field public static final String LANGUAGE_CODE = "language";
- field public static final String LOCATION_CHECK_TIME = "location_check_time";
- field public static final String MAXIMUM_WAIT_TIME = "maximum_wait_time";
- field public static final String MESSAGE_BODY = "body";
- field public static final String MESSAGE_BROADCASTED = "message_broadcasted";
- field public static final String MESSAGE_DISPLAYED = "message_displayed";
- field public static final String MESSAGE_FORMAT = "format";
- field @NonNull @RequiresPermission(android.Manifest.permission.READ_CELL_BROADCASTS) public static final android.net.Uri MESSAGE_HISTORY_URI;
- field public static final String MESSAGE_PRIORITY = "priority";
- field public static final String MESSAGE_READ = "read";
- field public static final String PLMN = "plmn";
- field public static final String RECEIVED_TIME = "received_time";
- field public static final String SERIAL_NUMBER = "serial_number";
- field public static final String SERVICE_CATEGORY = "service_category";
- field public static final String SLOT_INDEX = "slot_index";
- field public static final String SUBSCRIPTION_ID = "sub_id";
- }
-
public static final class Telephony.Sms.Intents {
field public static final String SMS_CARRIER_PROVISION_ACTION = "android.provider.Telephony.SMS_CARRIER_PROVISION";
}
@@ -3385,19 +1402,6 @@
package android.security.keystore {
- public abstract class AttestationUtils {
- method @NonNull @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public static java.security.cert.X509Certificate[] attestDeviceIds(android.content.Context, @NonNull int[], @NonNull byte[]) throws android.security.keystore.DeviceIdAttestationException;
- field public static final int ID_TYPE_IMEI = 2; // 0x2
- field public static final int ID_TYPE_MEID = 3; // 0x3
- field public static final int ID_TYPE_SERIAL = 1; // 0x1
- field public static final int USE_INDIVIDUAL_ATTESTATION = 4; // 0x4
- }
-
- public class DeviceIdAttestationException extends java.lang.Exception {
- ctor public DeviceIdAttestationException(@Nullable String);
- ctor public DeviceIdAttestationException(@Nullable String, @Nullable Throwable);
- }
-
public static final class KeyGenParameterSpec.Builder {
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUniqueIdIncluded(boolean);
}
@@ -3412,37 +1416,8 @@
}
-package android.service.appprediction {
-
- public abstract class AppPredictionService extends android.app.Service {
- ctor public AppPredictionService();
- method @MainThread public abstract void onAppTargetEvent(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull android.app.prediction.AppTargetEvent);
- method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method public void onCreatePredictionSession(@NonNull android.app.prediction.AppPredictionContext, @NonNull android.app.prediction.AppPredictionSessionId);
- method @MainThread public void onDestroyPredictionSession(@NonNull android.app.prediction.AppPredictionSessionId);
- method @MainThread public abstract void onLaunchLocationShown(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>);
- method @MainThread public abstract void onRequestPredictionUpdate(@NonNull android.app.prediction.AppPredictionSessionId);
- method @MainThread public abstract void onSortAppTargets(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull java.util.List<android.app.prediction.AppTarget>, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<java.util.List<android.app.prediction.AppTarget>>);
- method @MainThread public void onStartPredictionUpdates();
- method @MainThread public void onStopPredictionUpdates();
- method public final void updatePredictions(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull java.util.List<android.app.prediction.AppTarget>);
- }
-
-}
-
package android.service.autofill {
- public abstract class AutofillFieldClassificationService extends android.app.Service {
- ctor public AutofillFieldClassificationService();
- method public android.os.IBinder onBind(android.content.Intent);
- field public static final String REQUIRED_ALGORITHM_CREDIT_CARD = "CREDIT_CARD";
- field public static final String REQUIRED_ALGORITHM_EDIT_DISTANCE = "EDIT_DISTANCE";
- field public static final String REQUIRED_ALGORITHM_EXACT_MATCH = "EXACT_MATCH";
- field public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillFieldClassificationService";
- field public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS = "android.autofill.field_classification.available_algorithms";
- field public static final String SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM = "android.autofill.field_classification.default_algorithm";
- }
-
public final class CharSequenceTransformation extends android.service.autofill.InternalTransformation implements android.os.Parcelable android.service.autofill.Transformation {
method public void apply(@NonNull android.service.autofill.ValueFinder, @NonNull android.widget.RemoteViews, int) throws java.lang.Exception;
}
@@ -3465,11 +1440,6 @@
method @Nullable public android.util.SparseArray<android.service.autofill.InternalOnClickAction> getActions();
}
- public static final class Dataset.Builder {
- ctor public Dataset.Builder(@NonNull android.service.autofill.InlinePresentation);
- method @NonNull public android.service.autofill.Dataset.Builder setFieldInlinePresentation(@NonNull android.view.autofill.AutofillId, @Nullable android.view.autofill.AutofillValue, @Nullable java.util.regex.Pattern, @NonNull android.service.autofill.InlinePresentation);
- }
-
public final class DateTransformation extends android.service.autofill.InternalTransformation implements android.os.Parcelable android.service.autofill.Transformation {
method public void apply(@NonNull android.service.autofill.ValueFinder, @NonNull android.widget.RemoteViews, int) throws java.lang.Exception;
}
@@ -3486,15 +1456,6 @@
method public void apply(@NonNull android.service.autofill.ValueFinder, @NonNull android.widget.RemoteViews, int) throws java.lang.Exception;
}
- public abstract class InlineSuggestionRenderService extends android.app.Service {
- ctor public InlineSuggestionRenderService();
- method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method @NonNull public android.os.Bundle onGetInlineSuggestionsRendererInfo();
- method @Nullable public android.view.View onRenderSuggestion(@NonNull android.service.autofill.InlinePresentation, int, int);
- method public final void startIntentSender(@NonNull android.content.IntentSender);
- field public static final String SERVICE_INTERFACE = "android.service.autofill.InlineSuggestionRenderService";
- }
-
public abstract class InternalOnClickAction implements android.service.autofill.OnClickAction android.os.Parcelable {
ctor public InternalOnClickAction();
method public abstract void onClick(@NonNull android.view.ViewGroup);
@@ -3544,26 +1505,6 @@
package android.service.autofill.augmented {
- public abstract class AugmentedAutofillService extends android.app.Service {
- ctor public AugmentedAutofillService();
- method protected final void dump(java.io.FileDescriptor, java.io.PrintWriter, String[]);
- method protected void dump(@NonNull java.io.PrintWriter, @NonNull String[]);
- method @Nullable public final android.service.autofill.FillEventHistory getFillEventHistory();
- method public void onConnected();
- method public void onDisconnected();
- method public void onFillRequest(@NonNull android.service.autofill.augmented.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.augmented.FillController, @NonNull android.service.autofill.augmented.FillCallback);
- method public final boolean requestAutofill(@NonNull android.content.ComponentName, @NonNull android.view.autofill.AutofillId);
- field public static final String SERVICE_INTERFACE = "android.service.autofill.augmented.AugmentedAutofillService";
- }
-
- public final class FillCallback {
- method public void onSuccess(@Nullable android.service.autofill.augmented.FillResponse);
- }
-
- public final class FillController {
- method public void autofill(@NonNull java.util.List<android.util.Pair<android.view.autofill.AutofillId,android.view.autofill.AutofillValue>>);
- }
-
public final class FillRequest {
method @NonNull public android.content.ComponentName getActivityComponent();
method @NonNull public android.view.autofill.AutofillId getFocusedId();
@@ -3573,181 +1514,14 @@
method public int getTaskId();
}
- public final class FillResponse {
- }
-
- public static final class FillResponse.Builder {
- ctor public FillResponse.Builder();
- method @NonNull public android.service.autofill.augmented.FillResponse build();
- method @NonNull public android.service.autofill.augmented.FillResponse.Builder setClientState(@NonNull android.os.Bundle);
- method @NonNull public android.service.autofill.augmented.FillResponse.Builder setFillWindow(@NonNull android.service.autofill.augmented.FillWindow);
- method @NonNull public android.service.autofill.augmented.FillResponse.Builder setInlineSuggestions(@NonNull java.util.List<android.service.autofill.Dataset>);
- }
-
- public final class FillWindow implements java.lang.AutoCloseable {
- ctor public FillWindow();
- method public void destroy();
- method public boolean update(@NonNull android.service.autofill.augmented.PresentationParams.Area, @NonNull android.view.View, long);
- }
-
- public abstract class PresentationParams {
- method @Nullable public android.service.autofill.augmented.PresentationParams.Area getSuggestionArea();
- }
-
- public abstract static class PresentationParams.Area {
- method @NonNull public android.graphics.Rect getBounds();
- }
-
-}
-
-package android.service.contentcapture {
-
- public final class ActivityEvent implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.content.ComponentName getComponentName();
- method public int getEventType();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.contentcapture.ActivityEvent> CREATOR;
- field public static final int TYPE_ACTIVITY_DESTROYED = 24; // 0x18
- field public static final int TYPE_ACTIVITY_PAUSED = 2; // 0x2
- field public static final int TYPE_ACTIVITY_RESUMED = 1; // 0x1
- field public static final int TYPE_ACTIVITY_STOPPED = 23; // 0x17
- }
-
- public abstract class ContentCaptureService extends android.app.Service {
- ctor public ContentCaptureService();
- method public final void disableSelf();
- method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent);
- method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData);
- method public void onConnected();
- method public void onContentCaptureEvent(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.view.contentcapture.ContentCaptureEvent);
- method public void onCreateContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureContext, @NonNull android.view.contentcapture.ContentCaptureSessionId);
- method public void onDataRemovalRequest(@NonNull android.view.contentcapture.DataRemovalRequest);
- method public void onDataShareRequest(@NonNull android.view.contentcapture.DataShareRequest, @NonNull android.service.contentcapture.DataShareCallback);
- method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
- method public void onDisconnected();
- method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set<android.view.contentcapture.ContentCaptureCondition>);
- method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
- field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
- field public static final String SERVICE_META_DATA = "android.content_capture";
- }
-
- public interface DataShareCallback {
- method public void onAccept(@NonNull java.util.concurrent.Executor, @NonNull android.service.contentcapture.DataShareReadAdapter);
- method public void onReject();
- }
-
- public interface DataShareReadAdapter {
- method public void onError(int);
- method public void onStart(@NonNull android.os.ParcelFileDescriptor);
- }
-
- public final class SnapshotData implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public android.app.assist.AssistContent getAssistContent();
- method @NonNull public android.os.Bundle getAssistData();
- method @NonNull public android.app.assist.AssistStructure getAssistStructure();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.contentcapture.SnapshotData> CREATOR;
- }
-
}
package android.service.notification {
- public final class Adjustment implements android.os.Parcelable {
- ctor public Adjustment(String, String, android.os.Bundle, CharSequence, int);
- ctor public Adjustment(@NonNull String, @NonNull String, @NonNull android.os.Bundle, @NonNull CharSequence, @NonNull android.os.UserHandle);
- method public int describeContents();
- method @NonNull public CharSequence getExplanation();
- method @NonNull public String getKey();
- method @NonNull public String getPackage();
- method @NonNull public android.os.Bundle getSignals();
- method public int getUser();
- method @NonNull public android.os.UserHandle getUserHandle();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR;
- field public static final String KEY_CONTEXTUAL_ACTIONS = "key_contextual_actions";
- field public static final String KEY_IMPORTANCE = "key_importance";
- field public static final String KEY_RANKING_SCORE = "key_ranking_score";
- field public static final String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
- field public static final String KEY_TEXT_REPLIES = "key_text_replies";
- field public static final String KEY_USER_SENTIMENT = "key_user_sentiment";
- }
-
@Deprecated public abstract class ConditionProviderService extends android.app.Service {
method @Deprecated public boolean isBound();
}
- public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService {
- ctor public NotificationAssistantService();
- method public final void adjustNotification(@NonNull android.service.notification.Adjustment);
- method public final void adjustNotifications(@NonNull java.util.List<android.service.notification.Adjustment>);
- method public void onActionInvoked(@NonNull String, @NonNull android.app.Notification.Action, int);
- method public void onAllowedAdjustmentsChanged();
- method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent);
- method public void onNotificationDirectReplied(@NonNull String);
- method @Nullable public abstract android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification);
- method @Nullable public android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification, @NonNull android.app.NotificationChannel);
- method public void onNotificationExpansionChanged(@NonNull String, boolean, boolean);
- method public abstract void onNotificationSnoozedUntilContext(@NonNull android.service.notification.StatusBarNotification, @NonNull String);
- method public void onNotificationVisibilityChanged(@NonNull String, boolean);
- method public void onNotificationsSeen(@NonNull java.util.List<java.lang.String>);
- method public void onPanelHidden();
- method public void onPanelRevealed(int);
- method public void onSuggestedReplySent(@NonNull String, @NonNull CharSequence, int);
- method public final void unsnoozeNotification(@NonNull String);
- field public static final String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
- field public static final int SOURCE_FROM_APP = 0; // 0x0
- field public static final int SOURCE_FROM_ASSISTANT = 1; // 0x1
- }
-
- public abstract class NotificationListenerService extends android.app.Service {
- method public void onNotificationRemoved(@NonNull android.service.notification.StatusBarNotification, @NonNull android.service.notification.NotificationListenerService.RankingMap, @NonNull android.service.notification.NotificationStats, int);
- }
-
- public final class NotificationStats implements android.os.Parcelable {
- ctor public NotificationStats();
- method public int describeContents();
- method public int getDismissalSentiment();
- method public int getDismissalSurface();
- method public boolean hasDirectReplied();
- method public boolean hasExpanded();
- method public boolean hasInteracted();
- method public boolean hasSeen();
- method public boolean hasSnoozed();
- method public boolean hasViewedSettings();
- method public void setDirectReplied();
- method public void setDismissalSentiment(int);
- method public void setDismissalSurface(int);
- method public void setExpanded();
- method public void setSeen();
- method public void setSnoozed();
- method public void setViewedSettings();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.NotificationStats> CREATOR;
- field public static final int DISMISSAL_AOD = 2; // 0x2
- field public static final int DISMISSAL_NOT_DISMISSED = -1; // 0xffffffff
- field public static final int DISMISSAL_OTHER = 0; // 0x0
- field public static final int DISMISSAL_PEEK = 1; // 0x1
- field public static final int DISMISSAL_SHADE = 3; // 0x3
- field public static final int DISMISS_SENTIMENT_NEGATIVE = 0; // 0x0
- field public static final int DISMISS_SENTIMENT_NEUTRAL = 1; // 0x1
- field public static final int DISMISS_SENTIMENT_POSITIVE = 2; // 0x2
- field public static final int DISMISS_SENTIMENT_UNKNOWN = -1000; // 0xfffffc18
- }
-
- public final class SnoozeCriterion implements android.os.Parcelable {
- ctor public SnoozeCriterion(String, CharSequence, CharSequence);
- ctor protected SnoozeCriterion(android.os.Parcel);
- method public int describeContents();
- method public CharSequence getConfirmation();
- method public CharSequence getExplanation();
- method public String getId();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.SnoozeCriterion> CREATOR;
- }
-
}
package android.service.quickaccesswallet {
@@ -3788,67 +1562,16 @@
}
-package android.service.textclassifier {
-
- public abstract class TextClassifierService extends android.app.Service {
- ctor public TextClassifierService();
- method @NonNull public static android.view.textclassifier.TextClassifier getDefaultTextClassifierImplementation(@NonNull android.content.Context);
- method @Deprecated public final android.view.textclassifier.TextClassifier getLocalTextClassifier();
- method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method @MainThread public abstract void onClassifyText(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextClassification.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextClassification>);
- method public void onConnected();
- method @MainThread public void onCreateTextClassificationSession(@NonNull android.view.textclassifier.TextClassificationContext, @NonNull android.view.textclassifier.TextClassificationSessionId);
- method @MainThread public void onDestroyTextClassificationSession(@NonNull android.view.textclassifier.TextClassificationSessionId);
- method @MainThread public void onDetectLanguage(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextLanguage.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextLanguage>);
- method public void onDisconnected();
- method @MainThread public abstract void onGenerateLinks(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextLinks.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextLinks>);
- method @Deprecated @MainThread public void onSelectionEvent(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.SelectionEvent);
- method @MainThread public void onSuggestConversationActions(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.ConversationActions.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.ConversationActions>);
- method @MainThread public abstract void onSuggestSelection(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextSelection.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextSelection>);
- method @MainThread public void onTextClassifierEvent(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextClassifierEvent);
- field public static final String SERVICE_INTERFACE = "android.service.textclassifier.TextClassifierService";
- }
-
- public static interface TextClassifierService.Callback<T> {
- method public void onFailure(@NonNull CharSequence);
- method public void onSuccess(T);
- }
-
-}
-
package android.service.watchdog {
public abstract class ExplicitHealthCheckService extends android.app.Service {
- ctor public ExplicitHealthCheckService();
- method public final void notifyHealthCheckPassed(@NonNull String);
- method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method public abstract void onCancelHealthCheck(@NonNull String);
- method @NonNull public abstract java.util.List<java.lang.String> onGetRequestedPackages();
- method @NonNull public abstract java.util.List<android.service.watchdog.ExplicitHealthCheckService.PackageConfig> onGetSupportedPackages();
- method public abstract void onRequestHealthCheck(@NonNull String);
method public void setCallback(@Nullable android.os.RemoteCallback);
- field public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
- field public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService";
- }
-
- public static final class ExplicitHealthCheckService.PackageConfig implements android.os.Parcelable {
- ctor public ExplicitHealthCheckService.PackageConfig(@NonNull String, long);
- method public int describeContents();
- method public long getHealthCheckTimeoutMillis();
- method @NonNull public String getPackageName();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.watchdog.ExplicitHealthCheckService.PackageConfig> CREATOR;
}
}
package android.telecom {
- public final class Call {
- method public void enterBackgroundAudioProcessing();
- method public void exitBackgroundAudioProcessing(boolean);
- }
-
public static class Call.Details {
method public String getTelecomCallId();
}
@@ -3857,42 +1580,6 @@
ctor public CallAudioState(boolean, int, int, @Nullable android.bluetooth.BluetoothDevice, @NonNull java.util.Collection<android.bluetooth.BluetoothDevice>);
}
- public static class CallScreeningService.CallResponse.Builder {
- method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean);
- }
-
- public abstract class Conference extends android.telecom.Conferenceable {
- method public android.telecom.Connection getPrimaryConnection();
- method @NonNull public final String getTelecomCallId();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public final void setAddress(@NonNull android.net.Uri, int);
- method public final void setCallerDisplayName(@NonNull String, int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setConferenceState(boolean);
- }
-
- public abstract class Connection extends android.telecom.Conferenceable {
- method @IntRange(from=0) public final long getConnectTimeMillis();
- method public final long getConnectionStartElapsedRealtimeMillis();
- method @Nullable public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
- method @Nullable public final String getTelecomCallId();
- method public final void resetConnectionTime();
- method public void setCallDirection(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public final void setConnectTimeMillis(@IntRange(from=0) long);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public final void setConnectionStartElapsedRealtimeMillis(long);
- method public void setPhoneAccountHandle(@NonNull android.telecom.PhoneAccountHandle);
- method public void setTelecomCallId(@NonNull String);
- field public static final int CAPABILITY_CONFERENCE_HAS_NO_CHILDREN = 2097152; // 0x200000
- field public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 262144; // 0x40000
- field public static final String EXTRA_DISABLE_ADD_CALL = "android.telecom.extra.DISABLE_ADD_CALL";
- field public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 1; // 0x1
- field public static final int PROPERTY_GENERIC_CONFERENCE = 2; // 0x2
- field public static final int PROPERTY_IS_DOWNGRADED_CONFERENCE = 64; // 0x40
- field public static final int PROPERTY_REMOTELY_HOSTED = 2048; // 0x800
- }
-
- public final class ConnectionRequest implements android.os.Parcelable {
- method @Nullable public String getTelecomCallId();
- }
-
public static final class ConnectionRequest.Builder {
ctor public ConnectionRequest.Builder();
method @NonNull public android.telecom.ConnectionRequest build();
@@ -3908,48 +1595,11 @@
method @NonNull public android.telecom.ConnectionRequest.Builder setVideoState(int);
}
- public static class PhoneAccount.Builder {
- method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telecom.PhoneAccount.Builder setGroupId(@NonNull String);
- }
-
- public class PhoneAccountSuggestionService extends android.app.Service {
- ctor public PhoneAccountSuggestionService();
- method public void onAccountSuggestionRequest(@NonNull String);
- method public android.os.IBinder onBind(android.content.Intent);
- method public final void suggestPhoneAccounts(@NonNull String, @NonNull java.util.List<android.telecom.PhoneAccountSuggestion>);
- field public static final String SERVICE_INTERFACE = "android.telecom.PhoneAccountSuggestionService";
- }
-
- public class TelecomManager {
- method @NonNull public android.content.Intent createLaunchEmergencyDialerIntent(@Nullable String);
- method @NonNull @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public java.util.List<android.telecom.PhoneAccountHandle> getCallCapablePhoneAccounts(boolean);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getCurrentTtyMode();
- method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getDefaultDialerPackage(@NonNull android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isInEmergencyCall();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUserSelectedOutgoingPhoneAccount(@Nullable android.telecom.PhoneAccountHandle);
- field public static final int TTY_MODE_FULL = 1; // 0x1
- field public static final int TTY_MODE_HCO = 2; // 0x2
- field public static final int TTY_MODE_OFF = 0; // 0x0
- field public static final int TTY_MODE_VCO = 3; // 0x3
- }
-
}
package android.telephony {
- public final class AccessNetworkConstants {
- field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
- }
-
- public static final class AccessNetworkConstants.NgranBands {
- method public static int getFrequencyRangeGroup(int);
- field public static final int FREQUENCY_RANGE_GROUP_1 = 1; // 0x1
- field public static final int FREQUENCY_RANGE_GROUP_2 = 2; // 0x2
- field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0
- }
-
public final class BarringInfo implements android.os.Parcelable {
- ctor public BarringInfo();
ctor public BarringInfo(@Nullable android.telephony.CellIdentity, @NonNull android.util.SparseArray<android.telephony.BarringInfo.BarringServiceInfo>);
}
@@ -3957,57 +1607,6 @@
ctor public BarringInfo.BarringServiceInfo(int, boolean, int, int);
}
- public final class CallQuality implements android.os.Parcelable {
- ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
- ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean);
- method public int describeContents();
- method public int getAverageRelativeJitter();
- method public int getAverageRoundTripTime();
- method public int getCallDuration();
- method public int getCodecType();
- method public int getDownlinkCallQualityLevel();
- method public int getMaxRelativeJitter();
- method public int getNumRtpPacketsNotReceived();
- method public int getNumRtpPacketsReceived();
- method public int getNumRtpPacketsTransmitted();
- method public int getNumRtpPacketsTransmittedLost();
- method public int getUplinkCallQualityLevel();
- method public boolean isIncomingSilenceDetectedAtCallSetup();
- method public boolean isOutgoingSilenceDetectedAtCallSetup();
- method public boolean isRtpInactivityDetected();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CALL_QUALITY_BAD = 4; // 0x4
- field public static final int CALL_QUALITY_EXCELLENT = 0; // 0x0
- field public static final int CALL_QUALITY_FAIR = 2; // 0x2
- field public static final int CALL_QUALITY_GOOD = 1; // 0x1
- field public static final int CALL_QUALITY_NOT_AVAILABLE = 5; // 0x5
- field public static final int CALL_QUALITY_POOR = 3; // 0x3
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
- }
-
- public class CarrierConfigManager {
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
- }
-
- public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
- }
-
- public final class LteVopsSupportInfo implements android.os.Parcelable {
- ctor public LteVopsSupportInfo(int, int);
- method public int describeContents();
- method public int getEmcBearerSupport();
- method public int getVopsSupport();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR;
- field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1
- field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3
- field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2
- }
-
public class MbmsDownloadSession implements java.lang.AutoCloseable {
field public static final String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA = "mbms-download-service-override";
}
@@ -4020,50 +1619,11 @@
field public static final String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override";
}
- public final class NetworkRegistrationInfo implements android.os.Parcelable {
- method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
- method public int getRegistrationState();
- method public int getRejectCause();
- method public int getRoamingType();
- method public boolean isEmergencyEnabled();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
- field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
- field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
- field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
- field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
- field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
- }
-
- public static final class NetworkRegistrationInfo.Builder {
- ctor public NetworkRegistrationInfo.Builder();
- method @NonNull public android.telephony.NetworkRegistrationInfo build();
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull java.util.List<java.lang.Integer>);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
- }
-
public class PhoneNumberUtils {
method public static int getMinMatchForTest();
- method @NonNull public static String getUsernameFromUriNumber(@NonNull String);
- method public static boolean isUriNumber(@Nullable String);
- method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String);
method public static void setMinMatchForTest(int);
}
- public class PhoneStateListener {
- method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
- method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
- field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
- field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
- }
-
public final class PreciseDataConnectionState implements android.os.Parcelable {
ctor @Deprecated public PreciseDataConnectionState(int, int, int, @NonNull String, @Nullable android.net.LinkProperties, int);
}
@@ -4089,40 +1649,16 @@
field public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2; // 0x2
}
- public class SubscriptionManager {
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
- field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
- field @NonNull public static final android.net.Uri VT_ENABLED_CONTENT_URI;
- field @NonNull public static final android.net.Uri WFC_ENABLED_CONTENT_URI;
- field @NonNull public static final android.net.Uri WFC_MODE_CONTENT_URI;
- field @NonNull public static final android.net.Uri WFC_ROAMING_ENABLED_CONTENT_URI;
- field @NonNull public static final android.net.Uri WFC_ROAMING_MODE_CONTENT_URI;
- }
-
public class TelephonyManager {
method public int addDevicePolicyOverrideApn(@NonNull android.content.Context, @NonNull android.telephony.data.ApnSetting);
- method public int checkCarrierPrivilegesForPackage(String);
- method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
method public int getCarrierIdListVersion();
- method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
- method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public android.content.ComponentName getDefaultRespondViaMessageApplication();
method @NonNull public java.util.List<android.telephony.data.ApnSetting> getDevicePolicyOverrideApns(@NonNull android.content.Context);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getEmergencyNumberDbVersion();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion();
method public boolean modifyDevicePolicyOverrideApn(@NonNull android.content.Context, int, @NonNull android.telephony.data.ApnSetting);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile();
- method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void resetOtaEmergencyNumberDbFilePath();
method @Deprecated public void setCarrierTestOverride(String, String, String, String, String, String, String);
method public void setCarrierTestOverride(String, String, String, String, String, String, String, String, String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>);
- method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor);
- field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
- field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
- field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
- field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
- field public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1; // 0xffffffff
field public static final int UNKNOWN_CARRIER_ID_LIST_VERSION = -1; // 0xffffffff
}
@@ -4138,834 +1674,18 @@
package android.telephony.ims {
- public final class ImsCallForwardInfo implements android.os.Parcelable {
- ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int);
- method public int describeContents();
- method public int getCondition();
- method public String getNumber();
- method public int getServiceClass();
- method public int getStatus();
- method public int getTimeSeconds();
- method public int getToA();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CDIV_CF_REASON_ALL = 4; // 0x4
- field public static final int CDIV_CF_REASON_ALL_CONDITIONAL = 5; // 0x5
- field public static final int CDIV_CF_REASON_BUSY = 1; // 0x1
- field public static final int CDIV_CF_REASON_NOT_LOGGED_IN = 6; // 0x6
- field public static final int CDIV_CF_REASON_NOT_REACHABLE = 3; // 0x3
- field public static final int CDIV_CF_REASON_NO_REPLY = 2; // 0x2
- field public static final int CDIV_CF_REASON_UNCONDITIONAL = 0; // 0x0
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallForwardInfo> CREATOR;
- field public static final int STATUS_ACTIVE = 1; // 0x1
- field public static final int STATUS_NOT_ACTIVE = 0; // 0x0
- field public static final int TYPE_OF_ADDRESS_INTERNATIONAL = 145; // 0x91
- field public static final int TYPE_OF_ADDRESS_UNKNOWN = 129; // 0x81
- }
-
public final class ImsCallProfile implements android.os.Parcelable {
- ctor public ImsCallProfile();
- ctor public ImsCallProfile(int, int);
- ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
- method public int describeContents();
- method public String getCallExtra(String);
- method public String getCallExtra(String, String);
- method public boolean getCallExtraBoolean(String);
- method public boolean getCallExtraBoolean(String, boolean);
- method public int getCallExtraInt(String);
- method public int getCallExtraInt(String, int);
- method public android.os.Bundle getCallExtras();
- method public int getCallType();
- method public static int getCallTypeFromVideoState(int);
- method public int getCallerNumberVerificationStatus();
- method public int getEmergencyCallRouting();
- method public int getEmergencyServiceCategories();
- method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
- method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
- method @NonNull public android.os.Bundle getProprietaryCallExtras();
- method public int getRestrictCause();
- method public int getServiceType();
- method public static int getVideoStateFromCallType(int);
- method public static int getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile);
- method public boolean hasKnownUserIntentEmergency();
- method public boolean isEmergencyCallTesting();
- method public boolean isVideoCall();
- method public boolean isVideoPaused();
- method public static int presentationToOir(int);
- method public void setCallExtra(String, String);
- method public void setCallExtraBoolean(String, boolean);
- method public void setCallExtraInt(String, int);
- method public void setCallRestrictCause(int);
- method public void setCallerNumberVerificationStatus(int);
- method public void setEmergencyCallRouting(int);
- method public void setEmergencyCallTesting(boolean);
- method public void setEmergencyServiceCategories(int);
- method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
- method public void setHasKnownUserIntentEmergency(boolean);
- method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
- method public void updateCallType(android.telephony.ims.ImsCallProfile);
- method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; // 0x2
- field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3
- field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0
- field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1
- field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3
- field public static final int CALL_TYPE_VOICE = 2; // 0x2
- field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1
- field public static final int CALL_TYPE_VS = 8; // 0x8
- field public static final int CALL_TYPE_VS_RX = 10; // 0xa
- field public static final int CALL_TYPE_VS_TX = 9; // 0x9
- field public static final int CALL_TYPE_VT = 4; // 0x4
- field public static final int CALL_TYPE_VT_NODIR = 7; // 0x7
- field public static final int CALL_TYPE_VT_RX = 6; // 0x6
- field public static final int CALL_TYPE_VT_TX = 5; // 0x5
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallProfile> CREATOR;
- field public static final int DIALSTRING_NORMAL = 0; // 0x0
- field public static final int DIALSTRING_SS_CONF = 1; // 0x1
- field public static final int DIALSTRING_USSD = 2; // 0x2
- field public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
- field public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS = "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS";
- field public static final String EXTRA_CALL_DISCONNECT_CAUSE = "android.telephony.ims.extra.CALL_DISCONNECT_CAUSE";
- field public static final String EXTRA_CALL_NETWORK_TYPE = "android.telephony.ims.extra.CALL_NETWORK_TYPE";
- field @Deprecated public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
- field public static final String EXTRA_CHILD_NUMBER = "ChildNum";
- field public static final String EXTRA_CNA = "cna";
- field public static final String EXTRA_CNAP = "cnap";
- field public static final String EXTRA_CODEC = "Codec";
- field public static final String EXTRA_DIALSTRING = "dialstring";
- field public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
- field public static final String EXTRA_EMERGENCY_CALL = "e_call";
- field public static final String EXTRA_FORWARDED_NUMBER = "android.telephony.ims.extra.FORWARDED_NUMBER";
- field public static final String EXTRA_IS_CALL_PULL = "CallPull";
field public static final String EXTRA_OEM_EXTRAS = "android.telephony.ims.extra.OEM_EXTRAS";
- field public static final String EXTRA_OI = "oi";
- field public static final String EXTRA_OIR = "oir";
- field public static final String EXTRA_REMOTE_URI = "remote_uri";
- field public static final String EXTRA_USSD = "ussd";
- field public static final int OIR_DEFAULT = 0; // 0x0
- field public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; // 0x2
- field public static final int OIR_PRESENTATION_PAYPHONE = 4; // 0x4
- field public static final int OIR_PRESENTATION_RESTRICTED = 1; // 0x1
- field public static final int OIR_PRESENTATION_UNKNOWN = 3; // 0x3
- field public static final int SERVICE_TYPE_EMERGENCY = 2; // 0x2
- field public static final int SERVICE_TYPE_NONE = 0; // 0x0
- field public static final int SERVICE_TYPE_NORMAL = 1; // 0x1
- field public static final int VERIFICATION_STATUS_FAILED = 2; // 0x2
- field public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0; // 0x0
- field public static final int VERIFICATION_STATUS_PASSED = 1; // 0x1
- }
-
- public class ImsCallSessionListener {
- method public void callQualityChanged(@NonNull android.telephony.CallQuality);
- method public void callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
- method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
- method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
- method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
- method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
- method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
- method public void callSessionHoldFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionHoldReceived(android.telephony.ims.ImsCallProfile);
- method public void callSessionInitiated(android.telephony.ims.ImsCallProfile);
- method public void callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionInviteParticipantsRequestDelivered();
- method public void callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
- method @Deprecated public void callSessionMayHandover(int, int);
- method public void callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase);
- method public void callSessionMergeFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
- method public void callSessionMultipartyStateChanged(boolean);
- method public void callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile);
- method public void callSessionRemoveParticipantsRequestDelivered();
- method public void callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
- method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
- method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
- method public void callSessionRttMessageReceived(String);
- method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
- method public void callSessionRttModifyResponseReceived(int);
- method public void callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification);
- method public void callSessionTerminated(android.telephony.ims.ImsReasonInfo);
- method public void callSessionTtyModeReceived(int);
- method public void callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionUpdateReceived(android.telephony.ims.ImsCallProfile);
- method public void callSessionUpdated(android.telephony.ims.ImsCallProfile);
- method public void callSessionUssdMessageReceived(int, String);
- method public void onHandover(int, int, @Nullable android.telephony.ims.ImsReasonInfo);
- method public void onHandoverFailed(int, int, @NonNull android.telephony.ims.ImsReasonInfo);
- method public void onMayHandover(int, int);
- }
-
- public final class ImsConferenceState implements android.os.Parcelable {
- method public int describeContents();
- method public static int getConnectionStateForStatus(String);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsConferenceState> CREATOR;
- field public static final String DISPLAY_TEXT = "display-text";
- field public static final String ENDPOINT = "endpoint";
- field public static final String SIP_STATUS_CODE = "sipstatuscode";
- field public static final String STATUS = "status";
- field public static final String STATUS_ALERTING = "alerting";
- field public static final String STATUS_CONNECTED = "connected";
- field public static final String STATUS_CONNECT_FAIL = "connect-fail";
- field public static final String STATUS_DIALING_IN = "dialing-in";
- field public static final String STATUS_DIALING_OUT = "dialing-out";
- field public static final String STATUS_DISCONNECTED = "disconnected";
- field public static final String STATUS_DISCONNECTING = "disconnecting";
- field public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus";
- field public static final String STATUS_ON_HOLD = "on-hold";
- field public static final String STATUS_PENDING = "pending";
- field public static final String STATUS_SEND_ONLY = "sendonly";
- field public static final String STATUS_SEND_RECV = "sendrecv";
- field public static final String USER = "user";
- field public final java.util.HashMap<java.lang.String,android.os.Bundle> mParticipants;
- }
-
- public final class ImsException extends java.lang.Exception {
- ctor public ImsException(@Nullable String);
- ctor public ImsException(@Nullable String, int);
- ctor public ImsException(@Nullable String, int, @Nullable Throwable);
- }
-
- public final class ImsExternalCallState implements android.os.Parcelable {
- ctor public ImsExternalCallState(@NonNull String, @NonNull android.net.Uri, @Nullable android.net.Uri, boolean, int, int, boolean);
- method public int describeContents();
- method @NonNull public android.net.Uri getAddress();
- method public int getCallId();
- method public int getCallState();
- method public int getCallType();
- method @Nullable public android.net.Uri getLocalAddress();
- method public boolean isCallHeld();
- method public boolean isCallPullable();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CALL_STATE_CONFIRMED = 1; // 0x1
- field public static final int CALL_STATE_TERMINATED = 2; // 0x2
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsExternalCallState> CREATOR;
- }
-
- public class ImsMmTelManager implements android.telephony.ims.RegistrationManager {
- method @Deprecated @NonNull @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException;
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getVoWiFiRoamingModeSetting();
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isAvailable(int, int);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isCapable(int, int);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void isSupported(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>) throws android.telephony.ims.ImsException;
- method @Deprecated @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiModeSetting(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiNonPersistent(boolean, int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingModeSetting(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingSettingEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean);
- method @Deprecated @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback);
- }
-
- @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback {
- ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
- }
-
- public class ImsService extends android.app.Service {
- ctor public ImsService();
- method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
- method public android.telephony.ims.feature.RcsFeature createRcsFeature(int);
- method public void disableIms(int);
- method public void enableIms(int);
- method public android.telephony.ims.stub.ImsConfigImplBase getConfig(int);
- method public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int);
- method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException;
- method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures();
- method public void readyForFeatureCreation();
- }
-
- public final class ImsSsData implements android.os.Parcelable {
- ctor public ImsSsData(int, int, int, int, int);
- method public int describeContents();
- method @Nullable public java.util.List<android.telephony.ims.ImsCallForwardInfo> getCallForwardInfo();
- method public int getRequestType();
- method public int getResult();
- method public int getServiceClass();
- method public int getServiceType();
- method @NonNull public java.util.List<android.telephony.ims.ImsSsInfo> getSuppServiceInfo();
- method public int getTeleserviceType();
- method public boolean isTypeBarring();
- method public boolean isTypeCf();
- method public boolean isTypeClip();
- method public boolean isTypeClir();
- method public boolean isTypeColp();
- method public boolean isTypeColr();
- method public boolean isTypeCw();
- method public boolean isTypeIcb();
- method public boolean isTypeInterrogation();
- method public boolean isTypeUnConditional();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsData> CREATOR;
- field public static final int RESULT_SUCCESS = 0; // 0x0
- field public static final int SERVICE_CLASS_DATA = 2; // 0x2
- field public static final int SERVICE_CLASS_DATA_CIRCUIT_ASYNC = 32; // 0x20
- field public static final int SERVICE_CLASS_DATA_CIRCUIT_SYNC = 16; // 0x10
- field public static final int SERVICE_CLASS_DATA_PACKET_ACCESS = 64; // 0x40
- field public static final int SERVICE_CLASS_DATA_PAD = 128; // 0x80
- field public static final int SERVICE_CLASS_FAX = 4; // 0x4
- field public static final int SERVICE_CLASS_NONE = 0; // 0x0
- field public static final int SERVICE_CLASS_SMS = 8; // 0x8
- field public static final int SERVICE_CLASS_VOICE = 1; // 0x1
- field public static final int SS_ACTIVATION = 0; // 0x0
- field public static final int SS_ALL_BARRING = 18; // 0x12
- field public static final int SS_ALL_DATA_TELESERVICES = 3; // 0x3
- field public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; // 0x5
- field public static final int SS_ALL_TELESEVICES = 1; // 0x1
- field public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; // 0x0
- field public static final int SS_BAIC = 16; // 0x10
- field public static final int SS_BAIC_ROAMING = 17; // 0x11
- field public static final int SS_BAOC = 13; // 0xd
- field public static final int SS_BAOIC = 14; // 0xe
- field public static final int SS_BAOIC_EXC_HOME = 15; // 0xf
- field public static final int SS_CFU = 0; // 0x0
- field public static final int SS_CFUT = 6; // 0x6
- field public static final int SS_CF_ALL = 4; // 0x4
- field public static final int SS_CF_ALL_CONDITIONAL = 5; // 0x5
- field public static final int SS_CF_BUSY = 1; // 0x1
- field public static final int SS_CF_NOT_REACHABLE = 3; // 0x3
- field public static final int SS_CF_NO_REPLY = 2; // 0x2
- field public static final int SS_CLIP = 7; // 0x7
- field public static final int SS_CLIR = 8; // 0x8
- field public static final int SS_CNAP = 11; // 0xb
- field public static final int SS_COLP = 9; // 0x9
- field public static final int SS_COLR = 10; // 0xa
- field public static final int SS_DEACTIVATION = 1; // 0x1
- field public static final int SS_ERASURE = 4; // 0x4
- field public static final int SS_INCOMING_BARRING = 20; // 0x14
- field public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; // 0x16
- field public static final int SS_INCOMING_BARRING_DN = 21; // 0x15
- field public static final int SS_INTERROGATION = 2; // 0x2
- field public static final int SS_OUTGOING_BARRING = 19; // 0x13
- field public static final int SS_REGISTRATION = 3; // 0x3
- field public static final int SS_SMS_SERVICES = 4; // 0x4
- field public static final int SS_TELEPHONY = 2; // 0x2
- field public static final int SS_WAIT = 12; // 0xc
- }
-
- public static final class ImsSsData.Builder {
- ctor public ImsSsData.Builder(int, int, int, int, int);
- method @NonNull public android.telephony.ims.ImsSsData build();
- method @NonNull public android.telephony.ims.ImsSsData.Builder setCallForwardingInfo(@NonNull java.util.List<android.telephony.ims.ImsCallForwardInfo>);
- method @NonNull public android.telephony.ims.ImsSsData.Builder setSuppServiceInfo(@NonNull java.util.List<android.telephony.ims.ImsSsInfo>);
- }
-
- public final class ImsSsInfo implements android.os.Parcelable {
- ctor @Deprecated public ImsSsInfo(int, @Nullable String);
- method public int describeContents();
- method public int getClirInterrogationStatus();
- method public int getClirOutgoingState();
- method @Deprecated public String getIcbNum();
- method @Nullable public String getIncomingCommunicationBarringNumber();
- method public int getProvisionStatus();
- method public int getStatus();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CLIR_OUTGOING_DEFAULT = 0; // 0x0
- field public static final int CLIR_OUTGOING_INVOCATION = 1; // 0x1
- field public static final int CLIR_OUTGOING_SUPPRESSION = 2; // 0x2
- field public static final int CLIR_STATUS_NOT_PROVISIONED = 0; // 0x0
- field public static final int CLIR_STATUS_PROVISIONED_PERMANENT = 1; // 0x1
- field public static final int CLIR_STATUS_TEMPORARILY_ALLOWED = 4; // 0x4
- field public static final int CLIR_STATUS_TEMPORARILY_RESTRICTED = 3; // 0x3
- field public static final int CLIR_STATUS_UNKNOWN = 2; // 0x2
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsInfo> CREATOR;
- field public static final int DISABLED = 0; // 0x0
- field public static final int ENABLED = 1; // 0x1
- field public static final int NOT_REGISTERED = -1; // 0xffffffff
- field public static final int SERVICE_NOT_PROVISIONED = 0; // 0x0
- field public static final int SERVICE_PROVISIONED = 1; // 0x1
- field public static final int SERVICE_PROVISIONING_UNKNOWN = -1; // 0xffffffff
- }
-
- public static final class ImsSsInfo.Builder {
- ctor public ImsSsInfo.Builder(int);
- method @NonNull public android.telephony.ims.ImsSsInfo build();
- method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirInterrogationStatus(int);
- method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirOutgoingState(int);
- method @NonNull public android.telephony.ims.ImsSsInfo.Builder setIncomingCommunicationBarringNumber(@NonNull String);
- method @NonNull public android.telephony.ims.ImsSsInfo.Builder setProvisionStatus(int);
- }
-
- public final class ImsStreamMediaProfile implements android.os.Parcelable {
- ctor public ImsStreamMediaProfile(int, int, int, int, int);
- method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
- method public int describeContents();
- method public int getAudioDirection();
- method public int getAudioQuality();
- method public int getRttMode();
- method public int getVideoDirection();
- method public int getVideoQuality();
- method public boolean isReceivingRttAudio();
- method public boolean isRttCall();
- method public void setReceivingRttAudio(boolean);
- method public void setRttMode(int);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int AUDIO_QUALITY_AMR = 1; // 0x1
- field public static final int AUDIO_QUALITY_AMR_WB = 2; // 0x2
- field public static final int AUDIO_QUALITY_EVRC = 4; // 0x4
- field public static final int AUDIO_QUALITY_EVRC_B = 5; // 0x5
- field public static final int AUDIO_QUALITY_EVRC_NW = 7; // 0x7
- field public static final int AUDIO_QUALITY_EVRC_WB = 6; // 0x6
- field public static final int AUDIO_QUALITY_EVS_FB = 20; // 0x14
- field public static final int AUDIO_QUALITY_EVS_NB = 17; // 0x11
- field public static final int AUDIO_QUALITY_EVS_SWB = 19; // 0x13
- field public static final int AUDIO_QUALITY_EVS_WB = 18; // 0x12
- field public static final int AUDIO_QUALITY_G711A = 13; // 0xd
- field public static final int AUDIO_QUALITY_G711AB = 15; // 0xf
- field public static final int AUDIO_QUALITY_G711U = 11; // 0xb
- field public static final int AUDIO_QUALITY_G722 = 14; // 0xe
- field public static final int AUDIO_QUALITY_G723 = 12; // 0xc
- field public static final int AUDIO_QUALITY_G729 = 16; // 0x10
- field public static final int AUDIO_QUALITY_GSM_EFR = 8; // 0x8
- field public static final int AUDIO_QUALITY_GSM_FR = 9; // 0x9
- field public static final int AUDIO_QUALITY_GSM_HR = 10; // 0xa
- field public static final int AUDIO_QUALITY_NONE = 0; // 0x0
- field public static final int AUDIO_QUALITY_QCELP13K = 3; // 0x3
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsStreamMediaProfile> CREATOR;
- field public static final int DIRECTION_INACTIVE = 0; // 0x0
- field public static final int DIRECTION_INVALID = -1; // 0xffffffff
- field public static final int DIRECTION_RECEIVE = 1; // 0x1
- field public static final int DIRECTION_SEND = 2; // 0x2
- field public static final int DIRECTION_SEND_RECEIVE = 3; // 0x3
- field public static final int RTT_MODE_DISABLED = 0; // 0x0
- field public static final int RTT_MODE_FULL = 1; // 0x1
- field public static final int VIDEO_QUALITY_NONE = 0; // 0x0
- field public static final int VIDEO_QUALITY_QCIF = 1; // 0x1
- field public static final int VIDEO_QUALITY_QVGA_LANDSCAPE = 2; // 0x2
- field public static final int VIDEO_QUALITY_QVGA_PORTRAIT = 4; // 0x4
- field public static final int VIDEO_QUALITY_VGA_LANDSCAPE = 8; // 0x8
- field public static final int VIDEO_QUALITY_VGA_PORTRAIT = 16; // 0x10
- }
-
- public final class ImsSuppServiceNotification implements android.os.Parcelable {
- ctor public ImsSuppServiceNotification(int, int, int, int, String, String[]);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSuppServiceNotification> CREATOR;
- field public final int code;
- field public final String[] history;
- field public final int index;
- field public final int notificationType;
- field public final String number;
- field public final int type;
- }
-
- public class ImsUtListener {
- method public void onLineIdentificationSupplementaryServiceResponse(int, @NonNull android.telephony.ims.ImsSsInfo);
- method public void onSupplementaryServiceIndication(android.telephony.ims.ImsSsData);
- method public void onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]);
- method public void onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]);
- method public void onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]);
- method @Deprecated public void onUtConfigurationQueried(int, android.os.Bundle);
- method public void onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo);
- method public void onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo);
- method public void onUtConfigurationUpdated(int);
- field @Deprecated public static final String BUNDLE_KEY_CLIR = "queryClir";
- field @Deprecated public static final String BUNDLE_KEY_SSINFO = "imsSsInfo";
- }
-
- public abstract class ImsVideoCallProvider {
- ctor public ImsVideoCallProvider();
- method public void changeCallDataUsage(long);
- method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities);
- method public void changePeerDimensions(int, int);
- method public void changeVideoQuality(int);
- method public void handleCallSessionEvent(int);
- method public abstract void onRequestCallDataUsage();
- method public abstract void onRequestCameraCapabilities();
- method public abstract void onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile);
- method public abstract void onSendSessionModifyResponse(android.telecom.VideoProfile);
- method public abstract void onSetCamera(String);
- method public void onSetCamera(String, int);
- method public abstract void onSetDeviceOrientation(int);
- method public abstract void onSetDisplaySurface(android.view.Surface);
- method public abstract void onSetPauseImage(android.net.Uri);
- method public abstract void onSetPreviewSurface(android.view.Surface);
- method public abstract void onSetZoom(float);
- method public void receiveSessionModifyRequest(android.telecom.VideoProfile);
- method public void receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile);
- }
-
- public class ProvisioningManager {
- method @NonNull public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @WorkerThread public int getProvisioningIntValue(int);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @WorkerThread public boolean getProvisioningStatusForCapability(int, int);
- method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @WorkerThread public String getProvisioningStringValue(int);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @WorkerThread public boolean getRcsProvisioningStatusForCapability(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setProvisioningStatusForCapability(int, int, boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
- field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
- field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
- field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
- field public static final int PROVISIONING_VALUE_ENABLED = 1; // 0x1
- field public static final String STRING_QUERY_RESULT_ERROR_GENERIC = "STRING_QUERY_RESULT_ERROR_GENERIC";
- field public static final String STRING_QUERY_RESULT_ERROR_NOT_READY = "STRING_QUERY_RESULT_ERROR_NOT_READY";
- }
-
- public static class ProvisioningManager.Callback {
- ctor public ProvisioningManager.Callback();
- method public void onProvisioningIntChanged(int, int);
- method public void onProvisioningStringChanged(int, @NonNull String);
- }
-
- public class RcsUceAdapter {
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
}
}
package android.telephony.ims.feature {
- public final class CapabilityChangeRequest implements android.os.Parcelable {
- method public void addCapabilitiesToDisableForTech(int, int);
- method public void addCapabilitiesToEnableForTech(int, int);
- method public int describeContents();
- method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToDisable();
- method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToEnable();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.feature.CapabilityChangeRequest> CREATOR;
- }
-
- public static class CapabilityChangeRequest.CapabilityPair {
- ctor public CapabilityChangeRequest.CapabilityPair(int, int);
- method public int getCapability();
- method public int getRadioTech();
- }
-
- public abstract class ImsFeature {
- ctor public ImsFeature();
- method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
- method public int getFeatureState();
- method public final int getSlotIndex();
- method public abstract void onFeatureReady();
- method public abstract void onFeatureRemoved();
- method public final void setFeatureState(int);
- field public static final int CAPABILITY_ERROR_GENERIC = -1; // 0xffffffff
- field public static final int CAPABILITY_SUCCESS = 0; // 0x0
- field public static final int FEATURE_EMERGENCY_MMTEL = 0; // 0x0
- field public static final int FEATURE_MMTEL = 1; // 0x1
- field public static final int FEATURE_RCS = 2; // 0x2
- field public static final int STATE_INITIALIZING = 1; // 0x1
- field public static final int STATE_READY = 2; // 0x2
- field public static final int STATE_UNAVAILABLE = 0; // 0x0
- }
-
@Deprecated public static class ImsFeature.Capabilities {
field @Deprecated protected int mCapabilities;
}
- protected static class ImsFeature.CapabilityCallbackProxy {
- method public void onChangeCapabilityConfigurationError(int, int, int);
- }
-
- public class MmTelFeature extends android.telephony.ims.feature.ImsFeature {
- ctor public MmTelFeature();
- method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
- method @Nullable public android.telephony.ims.ImsCallProfile createCallProfile(int, int);
- method @Nullable public android.telephony.ims.stub.ImsCallSessionImplBase createCallSession(@NonNull android.telephony.ims.ImsCallProfile);
- method @NonNull public android.telephony.ims.stub.ImsEcbmImplBase getEcbm();
- method @NonNull public android.telephony.ims.stub.ImsMultiEndpointImplBase getMultiEndpoint();
- method @NonNull public android.telephony.ims.stub.ImsSmsImplBase getSmsImplementation();
- method @NonNull public android.telephony.ims.stub.ImsUtImplBase getUt();
- method public final void notifyCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
- method public final void notifyIncomingCall(@NonNull android.telephony.ims.stub.ImsCallSessionImplBase, @NonNull android.os.Bundle);
- method public final void notifyRejectedCall(@NonNull android.telephony.ims.ImsCallProfile, @NonNull android.telephony.ims.ImsReasonInfo);
- method public final void notifyVoiceMessageCountUpdate(int);
- method public void onFeatureReady();
- method public void onFeatureRemoved();
- method public boolean queryCapabilityConfiguration(int, int);
- method @NonNull public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus();
- method public void setUiTtyMode(int, @Nullable android.os.Message);
- method public int shouldProcessCall(@NonNull String[]);
- field public static final String EXTRA_IS_UNKNOWN_CALL = "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
- field public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD";
- field public static final int PROCESS_CALL_CSFB = 1; // 0x1
- field public static final int PROCESS_CALL_IMS = 0; // 0x0
- }
-
- public static class MmTelFeature.MmTelCapabilities extends android.telephony.ims.feature.ImsFeature.Capabilities {
- ctor public MmTelFeature.MmTelCapabilities();
- ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
- ctor public MmTelFeature.MmTelCapabilities(int);
- method public final void addCapabilities(int);
- method public final boolean isCapable(int);
- method public final void removeCapabilities(int);
- }
-
- public class RcsFeature extends android.telephony.ims.feature.ImsFeature {
- ctor public RcsFeature();
- method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
- method public void onFeatureReady();
- method public void onFeatureRemoved();
- }
-
-}
-
-package android.telephony.ims.stub {
-
- public class ImsCallSessionImplBase implements java.lang.AutoCloseable {
- ctor public ImsCallSessionImplBase();
- method public void accept(int, android.telephony.ims.ImsStreamMediaProfile);
- method public void close();
- method public void deflect(String);
- method public void extendToConference(String[]);
- method public String getCallId();
- method public android.telephony.ims.ImsCallProfile getCallProfile();
- method public android.telephony.ims.ImsVideoCallProvider getImsVideoCallProvider();
- method public android.telephony.ims.ImsCallProfile getLocalCallProfile();
- method public String getProperty(String);
- method public android.telephony.ims.ImsCallProfile getRemoteCallProfile();
- method public int getState();
- method public void hold(android.telephony.ims.ImsStreamMediaProfile);
- method public void inviteParticipants(String[]);
- method public boolean isInCall();
- method public boolean isMultiparty();
- method public void merge();
- method public void reject(int);
- method public void removeParticipants(String[]);
- method public void resume(android.telephony.ims.ImsStreamMediaProfile);
- method public void sendDtmf(char, android.os.Message);
- method public void sendRttMessage(String);
- method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
- method public void sendRttModifyResponse(boolean);
- method public void sendUssd(String);
- method public void setListener(android.telephony.ims.ImsCallSessionListener);
- method public void setMute(boolean);
- method public void start(String, android.telephony.ims.ImsCallProfile);
- method public void startConference(String[], android.telephony.ims.ImsCallProfile);
- method public void startDtmf(char);
- method public void stopDtmf();
- method public void terminate(int);
- method public void update(int, android.telephony.ims.ImsStreamMediaProfile);
- field public static final int USSD_MODE_NOTIFY = 0; // 0x0
- field public static final int USSD_MODE_REQUEST = 1; // 0x1
- }
-
- public static class ImsCallSessionImplBase.State {
- method public static String toString(int);
- field public static final int ESTABLISHED = 4; // 0x4
- field public static final int ESTABLISHING = 3; // 0x3
- field public static final int IDLE = 0; // 0x0
- field public static final int INITIATED = 1; // 0x1
- field public static final int INVALID = -1; // 0xffffffff
- field public static final int NEGOTIATING = 2; // 0x2
- field public static final int REESTABLISHING = 6; // 0x6
- field public static final int RENEGOTIATING = 5; // 0x5
- field public static final int TERMINATED = 8; // 0x8
- field public static final int TERMINATING = 7; // 0x7
- }
-
- public class ImsConfigImplBase {
- ctor public ImsConfigImplBase();
- method public int getConfigInt(int);
- method public String getConfigString(int);
- method public final void notifyProvisionedValueChanged(int, int);
- method public final void notifyProvisionedValueChanged(int, String);
- method public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
- method public int setConfig(int, int);
- method public int setConfig(int, String);
- field public static final int CONFIG_RESULT_FAILED = 1; // 0x1
- field public static final int CONFIG_RESULT_SUCCESS = 0; // 0x0
- field public static final int CONFIG_RESULT_UNKNOWN = -1; // 0xffffffff
- }
-
- public class ImsEcbmImplBase {
- ctor public ImsEcbmImplBase();
- method public final void enteredEcbm();
- method public void exitEmergencyCallbackMode();
- method public final void exitedEcbm();
- }
-
- public final class ImsFeatureConfiguration implements android.os.Parcelable {
- method public int describeContents();
- method public java.util.Set<android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair> getServiceFeatures();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.stub.ImsFeatureConfiguration> CREATOR;
- }
-
- public static class ImsFeatureConfiguration.Builder {
- ctor public ImsFeatureConfiguration.Builder();
- method public android.telephony.ims.stub.ImsFeatureConfiguration.Builder addFeature(int, int);
- method public android.telephony.ims.stub.ImsFeatureConfiguration build();
- }
-
- public static final class ImsFeatureConfiguration.FeatureSlotPair {
- ctor public ImsFeatureConfiguration.FeatureSlotPair(int, int);
- field public final int featureType;
- field public final int slotId;
- }
-
- public class ImsMultiEndpointImplBase {
- ctor public ImsMultiEndpointImplBase();
- method public final void onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>);
- method public void requestImsExternalCallStateInfo();
- }
-
- public class ImsRegistrationImplBase {
- ctor public ImsRegistrationImplBase();
- method public final void onDeregistered(android.telephony.ims.ImsReasonInfo);
- method public final void onRegistered(int);
- method public final void onRegistering(int);
- method public final void onSubscriberAssociatedUriChanged(android.net.Uri[]);
- method public final void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo);
- field public static final int REGISTRATION_TECH_IWLAN = 1; // 0x1
- field public static final int REGISTRATION_TECH_LTE = 0; // 0x0
- field public static final int REGISTRATION_TECH_NONE = -1; // 0xffffffff
- }
-
- public class ImsSmsImplBase {
- ctor public ImsSmsImplBase();
- method public void acknowledgeSms(int, @IntRange(from=0, to=65535) int, int);
- method public void acknowledgeSmsReport(int, @IntRange(from=0, to=65535) int, int);
- method public String getSmsFormat();
- method public void onReady();
- method @Deprecated public final void onSendSmsResult(int, @IntRange(from=0, to=65535) int, int, int) throws java.lang.RuntimeException;
- method public final void onSendSmsResultError(int, @IntRange(from=0, to=65535) int, int, int, int) throws java.lang.RuntimeException;
- method public final void onSendSmsResultSuccess(int, @IntRange(from=0, to=65535) int) throws java.lang.RuntimeException;
- method public final void onSmsReceived(int, String, byte[]) throws java.lang.RuntimeException;
- method @Deprecated public final void onSmsStatusReportReceived(int, @IntRange(from=0, to=65535) int, String, byte[]) throws java.lang.RuntimeException;
- method public final void onSmsStatusReportReceived(int, String, byte[]) throws java.lang.RuntimeException;
- method public void sendSms(int, @IntRange(from=0, to=65535) int, String, String, boolean, byte[]);
- field public static final int DELIVER_STATUS_ERROR_GENERIC = 2; // 0x2
- field public static final int DELIVER_STATUS_ERROR_NO_MEMORY = 3; // 0x3
- field public static final int DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED = 4; // 0x4
- field public static final int DELIVER_STATUS_OK = 1; // 0x1
- field public static final int RESULT_NO_NETWORK_ERROR = -1; // 0xffffffff
- field public static final int SEND_STATUS_ERROR = 2; // 0x2
- field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4
- field public static final int SEND_STATUS_ERROR_RETRY = 3; // 0x3
- field public static final int SEND_STATUS_OK = 1; // 0x1
- field public static final int STATUS_REPORT_STATUS_ERROR = 2; // 0x2
- field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1
- }
-
- public class ImsUtImplBase {
- ctor public ImsUtImplBase();
- method public void close();
- method public int queryCallBarring(int);
- method public int queryCallBarringForServiceClass(int, int);
- method public int queryCallForward(int, String);
- method public int queryCallWaiting();
- method public int queryClip();
- method public int queryClir();
- method public int queryColp();
- method public int queryColr();
- method public void setListener(android.telephony.ims.ImsUtListener);
- method public int transact(android.os.Bundle);
- method public int updateCallBarring(int, int, String[]);
- method public int updateCallBarringForServiceClass(int, int, String[], int);
- method public int updateCallForward(int, int, String, int, int);
- method public int updateCallWaiting(boolean, int);
- method public int updateClip(boolean);
- method public int updateClir(int);
- method public int updateColp(boolean);
- method public int updateColr(int);
- }
-
-}
-
-package android.telephony.mbms {
-
- public static class DownloadRequest.Builder {
- method public android.telephony.mbms.DownloadRequest.Builder setServiceId(String);
- }
-
- public final class FileInfo implements android.os.Parcelable {
- ctor public FileInfo(android.net.Uri, String);
- }
-
- public final class FileServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
- ctor public FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>);
- }
-
- public final class StreamingServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
- ctor public StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date);
- }
-
- public final class UriPathPair implements android.os.Parcelable {
- method public int describeContents();
- method public android.net.Uri getContentUri();
- method public android.net.Uri getFilePathUri();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.mbms.UriPathPair> CREATOR;
- }
-
-}
-
-package android.telephony.mbms.vendor {
-
- public class MbmsDownloadServiceBase extends android.os.Binder implements android.os.IInterface {
- ctor public MbmsDownloadServiceBase();
- method public int addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
- method public int addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
- method public android.os.IBinder asBinder();
- method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
- method public void dispose(int) throws android.os.RemoteException;
- method public int download(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
- method public int initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) throws android.os.RemoteException;
- method @NonNull public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(int) throws android.os.RemoteException;
- method public void onAppCallbackDied(int, int);
- method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
- method public int removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
- method public int removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
- method public int requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException;
- method public int requestUpdateFileServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
- method public int resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
- method public int setTempFileRootDirectory(int, String) throws android.os.RemoteException;
- }
-
- public class MbmsGroupCallServiceBase extends android.app.Service {
- ctor public MbmsGroupCallServiceBase();
- method public void dispose(int) throws android.os.RemoteException;
- method public int initialize(@NonNull android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException;
- method public void onAppCallbackDied(int, int);
- method public android.os.IBinder onBind(android.content.Intent);
- method public int startGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>, @NonNull android.telephony.mbms.GroupCallCallback);
- method public void stopGroupCall(int, long);
- method public void updateGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>);
- }
-
- public class MbmsStreamingServiceBase extends android.os.Binder implements android.os.IInterface {
- ctor public MbmsStreamingServiceBase();
- method public android.os.IBinder asBinder();
- method public void dispose(int) throws android.os.RemoteException;
- method @Nullable public android.net.Uri getPlaybackUri(int, String) throws android.os.RemoteException;
- method public int initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) throws android.os.RemoteException;
- method public void onAppCallbackDied(int, int);
- method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
- method public int requestUpdateStreamingServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
- method public int startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) throws android.os.RemoteException;
- method public void stopStreaming(int, String) throws android.os.RemoteException;
- }
-
- public class VendorUtils {
- ctor public VendorUtils();
- method public static android.content.ComponentName getAppReceiverFromPackageName(android.content.Context, String);
- field public static final String ACTION_CLEANUP = "android.telephony.mbms.action.CLEANUP";
- field public static final String ACTION_DOWNLOAD_RESULT_INTERNAL = "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL";
- field public static final String ACTION_FILE_DESCRIPTOR_REQUEST = "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST";
- field public static final String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT";
- field public static final String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI";
- field public static final String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST";
- field public static final String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST";
- field public static final String EXTRA_PAUSED_URI_LIST = "android.telephony.mbms.extra.PAUSED_URI_LIST";
- field public static final String EXTRA_SERVICE_ID = "android.telephony.mbms.extra.SERVICE_ID";
- field public static final String EXTRA_TEMP_FILES_IN_USE = "android.telephony.mbms.extra.TEMP_FILES_IN_USE";
- field public static final String EXTRA_TEMP_FILE_ROOT = "android.telephony.mbms.extra.TEMP_FILE_ROOT";
- field public static final String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST";
- }
-
}
package android.text {
@@ -5209,7 +1929,7 @@
field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000
field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40
field public CharSequence accessibilityTitle;
- field @android.view.ViewDebug.ExportedProperty(flagMapping={@android.view.ViewDebug.FlagToString(mask=0x1, equals=0x1, name="FAKE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x2, equals=0x2, name="FORCE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x4, equals=0x4, name="WANTS_OFFSET_NOTIFICATIONS"), @android.view.ViewDebug.FlagToString(mask=0x10, equals=0x10, name="SHOW_FOR_ALL_USERS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, equals=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, name="NO_MOVE_ANIMATION"), @android.view.ViewDebug.FlagToString(mask=0x80, equals=0x80, name="COMPATIBLE_WINDOW"), @android.view.ViewDebug.FlagToString(mask=0x100, equals=0x100, name="SYSTEM_ERROR"), @android.view.ViewDebug.FlagToString(mask=0x800, equals=0x800, name="DISABLE_WALLPAPER_TOUCH_EVENTS"), @android.view.ViewDebug.FlagToString(mask=0x1000, equals=0x1000, name="FORCE_STATUS_BAR_VISIBLE"), @android.view.ViewDebug.FlagToString(mask=0x2000, equals=0x2000, name="PRESERVE_GEOMETRY"), @android.view.ViewDebug.FlagToString(mask=0x4000, equals=0x4000, name="FORCE_DECOR_VIEW_VISIBILITY"), @android.view.ViewDebug.FlagToString(mask=0x8000, equals=0x8000, name="WILL_NOT_REPLACE_ON_RELAUNCH"), @android.view.ViewDebug.FlagToString(mask=0x10000, equals=0x10000, name="LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME"), @android.view.ViewDebug.FlagToString(mask=0x20000, equals=0x20000, name="FORCE_DRAW_STATUS_BAR_BACKGROUND"), @android.view.ViewDebug.FlagToString(mask=0x40000, equals=0x40000, name="SUSTAINED_PERFORMANCE_MODE"), @android.view.ViewDebug.FlagToString(mask=0x80000, equals=0x80000, name="HIDE_NON_SYSTEM_OVERLAY_WINDOWS"), @android.view.ViewDebug.FlagToString(mask=0x100000, equals=0x100000, name="IS_ROUNDED_CORNERS_OVERLAY"), @android.view.ViewDebug.FlagToString(mask=0x400000, equals=0x400000, name="IS_SCREEN_DECOR"), @android.view.ViewDebug.FlagToString(mask=0x800000, equals=0x800000, name="STATUS_FORCE_SHOW_NAVIGATION"), @android.view.ViewDebug.FlagToString(mask=0x1000000, equals=0x1000000, name="COLOR_SPACE_AGNOSTIC"), @android.view.ViewDebug.FlagToString(mask=0x4000000, equals=0x4000000, name="APPEARANCE_CONTROLLED"), @android.view.ViewDebug.FlagToString(mask=0x8000000, equals=0x8000000, name="BEHAVIOR_CONTROLLED"), @android.view.ViewDebug.FlagToString(mask=0x10000000, equals=0x10000000, name="FIT_INSETS_CONTROLLED")}) public int privateFlags;
+ field public int privateFlags;
}
}
@@ -5218,11 +1938,8 @@
public final class AccessibilityManager {
method public void addAccessibilityServicesStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener, @Nullable android.os.Handler);
- method @NonNull @RequiresPermission("android.permission.MANAGE_ACCESSIBILITY") public java.util.List<java.lang.String> getAccessibilityShortcutTargets(int);
- method @RequiresPermission("android.permission.MANAGE_ACCESSIBILITY") public void performAccessibilityShortcut();
- method @RequiresPermission("android.permission.MANAGE_ACCESSIBILITY") public void registerSystemAction(@NonNull android.app.RemoteAction, int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public java.util.List<java.lang.String> getAccessibilityShortcutTargets(int);
method public void removeAccessibilityServicesStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener);
- method @RequiresPermission("android.permission.MANAGE_ACCESSIBILITY") public void unregisterSystemAction(int);
}
public static interface AccessibilityManager.AccessibilityServicesStateChangeListener {
@@ -5268,7 +1985,6 @@
}
public final class AutofillManager {
- method public void setAugmentedAutofillWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
field public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES = "smart_suggestion_supported_modes";
field public static final int FLAG_SMART_SUGGESTION_OFF = 0; // 0x0
field public static final int FLAG_SMART_SUGGESTION_SYSTEM = 1; // 0x1
@@ -5279,42 +1995,7 @@
package android.view.contentcapture {
- public final class ContentCaptureContext implements android.os.Parcelable {
- method @Nullable public android.content.ComponentName getActivityComponent();
- method public int getDisplayId();
- method public int getFlags();
- method @Nullable public android.view.contentcapture.ContentCaptureSessionId getParentSessionId();
- method public int getTaskId();
- field public static final int FLAG_DISABLED_BY_APP = 1; // 0x1
- field public static final int FLAG_DISABLED_BY_FLAG_SECURE = 2; // 0x2
- field public static final int FLAG_RECONNECTED = 4; // 0x4
- }
-
- public final class ContentCaptureEvent implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public android.view.contentcapture.ContentCaptureContext getContentCaptureContext();
- method public long getEventTime();
- method @Nullable public android.view.autofill.AutofillId getId();
- method @Nullable public java.util.List<android.view.autofill.AutofillId> getIds();
- method @Nullable public android.graphics.Insets getInsets();
- method @Nullable public CharSequence getText();
- method public int getType();
- method @Nullable public android.view.contentcapture.ViewNode getViewNode();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureEvent> CREATOR;
- field public static final int TYPE_CONTEXT_UPDATED = 6; // 0x6
- field public static final int TYPE_SESSION_PAUSED = 8; // 0x8
- field public static final int TYPE_SESSION_RESUMED = 7; // 0x7
- field public static final int TYPE_VIEW_APPEARED = 1; // 0x1
- field public static final int TYPE_VIEW_DISAPPEARED = 2; // 0x2
- field public static final int TYPE_VIEW_INSETS_CHANGED = 9; // 0x9
- field public static final int TYPE_VIEW_TEXT_CHANGED = 3; // 0x3
- field public static final int TYPE_VIEW_TREE_APPEARED = 5; // 0x5
- field public static final int TYPE_VIEW_TREE_APPEARING = 4; // 0x4
- }
-
public final class ContentCaptureManager {
- method public boolean isContentCaptureFeatureEnabled();
field public static final String DEVICE_CONFIG_PROPERTY_IDLE_FLUSH_FREQUENCY = "idle_flush_frequency";
field public static final String DEVICE_CONFIG_PROPERTY_LOGGING_LEVEL = "logging_level";
field public static final String DEVICE_CONFIG_PROPERTY_LOG_HISTORY_SIZE = "log_history_size";
@@ -5327,7 +2008,6 @@
}
public final class ViewNode extends android.app.assist.AssistStructure.ViewNode {
- method @Nullable public android.view.autofill.AutofillId getParentAutofillId();
method @Nullable public static android.view.contentcapture.ViewNode readFromParcel(@NonNull android.os.Parcel);
method public static void writeToParcel(@NonNull android.os.Parcel, @Nullable android.view.contentcapture.ViewNode, int);
}
diff --git a/api/test-removed.txt b/api/test-removed.txt
index e47f6ed..d802177 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -1,10 +1 @@
// Signature format: 2.0
-package android.app.prediction {
-
- public static final class AppTarget.Builder {
- method @Deprecated @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle);
- method @Deprecated @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo);
- }
-
-}
-
diff --git a/cmds/statsd/.clang-format b/cmds/statsd/.clang-format
deleted file mode 100644
index cead3a0..0000000
--- a/cmds/statsd/.clang-format
+++ /dev/null
@@ -1,17 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: false
-AllowShortLoopsOnASingleLine: true
-BinPackArguments: true
-BinPackParameters: true
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-ContinuationIndentWidth: 8
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-AccessModifierOffset: -4
-IncludeCategories:
- - Regex: '^"Log\.h"'
- Priority: -1
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
deleted file mode 100644
index 0617eb6..0000000
--- a/cmds/statsd/Android.bp
+++ /dev/null
@@ -1,433 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// ==========================================================
-// Build the library for use on the host
-// ==========================================================
-cc_library_host_shared {
- name: "libstats_proto_host",
- srcs: [
- "src/atoms.proto",
- "src/atom_field_options.proto",
- ],
-
- shared_libs: [
- "libplatformprotos",
- ],
-
- proto: {
- type: "full",
- export_proto_headers: true,
- include_dirs: [
- "external/protobuf/src",
- ],
- },
-
- export_shared_lib_headers: [
- "libplatformprotos",
- ]
-
-}
-
-cc_defaults {
- name: "statsd_defaults",
-
- srcs: [
- "src/active_config_list.proto",
- "src/anomaly/AlarmMonitor.cpp",
- "src/anomaly/AlarmTracker.cpp",
- "src/anomaly/AnomalyTracker.cpp",
- "src/anomaly/DurationAnomalyTracker.cpp",
- "src/anomaly/subscriber_util.cpp",
- "src/condition/CombinationConditionTracker.cpp",
- "src/condition/condition_util.cpp",
- "src/condition/ConditionWizard.cpp",
- "src/condition/SimpleConditionTracker.cpp",
- "src/config/ConfigKey.cpp",
- "src/config/ConfigListener.cpp",
- "src/config/ConfigManager.cpp",
- "src/experiment_ids.proto",
- "src/external/Perfetto.cpp",
- "src/external/PullResultReceiver.cpp",
- "src/external/puller_util.cpp",
- "src/external/StatsCallbackPuller.cpp",
- "src/external/StatsPuller.cpp",
- "src/external/StatsPullerManager.cpp",
- "src/external/TrainInfoPuller.cpp",
- "src/FieldValue.cpp",
- "src/guardrail/StatsdStats.cpp",
- "src/hash.cpp",
- "src/HashableDimensionKey.cpp",
- "src/logd/LogEvent.cpp",
- "src/logd/LogEventQueue.cpp",
- "src/matchers/CombinationLogMatchingTracker.cpp",
- "src/matchers/EventMatcherWizard.cpp",
- "src/matchers/matcher_util.cpp",
- "src/matchers/SimpleLogMatchingTracker.cpp",
- "src/metadata_util.cpp",
- "src/metrics/CountMetricProducer.cpp",
- "src/metrics/duration_helper/MaxDurationTracker.cpp",
- "src/metrics/duration_helper/OringDurationTracker.cpp",
- "src/metrics/DurationMetricProducer.cpp",
- "src/metrics/EventMetricProducer.cpp",
- "src/metrics/GaugeMetricProducer.cpp",
- "src/metrics/MetricProducer.cpp",
- "src/metrics/metrics_manager_util.cpp",
- "src/metrics/MetricsManager.cpp",
- "src/metrics/ValueMetricProducer.cpp",
- "src/packages/UidMap.cpp",
- "src/shell/shell_config.proto",
- "src/shell/ShellSubscriber.cpp",
- "src/socket/StatsSocketListener.cpp",
- "src/state/StateManager.cpp",
- "src/state/StateTracker.cpp",
- "src/stats_log_util.cpp",
- "src/statscompanion_util.cpp",
- "src/statsd_config.proto",
- "src/statsd_metadata.proto",
- "src/StatsLogProcessor.cpp",
- "src/StatsService.cpp",
- "src/storage/StorageManager.cpp",
- "src/subscriber/IncidentdReporter.cpp",
- "src/subscriber/SubscriberReporter.cpp",
- "src/uid_data.proto",
- "src/utils/MultiConditionTrigger.cpp",
- ],
-
- local_include_dirs: [
- "src",
- ],
-
- static_libs: [
- "libbase",
- "libcutils",
- "libgtest_prod",
- "libprotoutil",
- "libstatslog_statsd",
- "libsysutils",
- "libutils",
- "statsd-aidl-ndk_platform",
- ],
- shared_libs: [
- "libbinder_ndk",
- "libincident",
- "liblog",
- ],
-}
-
-genrule {
- name: "statslog_statsd.h",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_statsd.h --module statsd --namespace android,os,statsd,util",
- out: [
- "statslog_statsd.h",
- ],
-}
-
-genrule {
- name: "statslog_statsd.cpp",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_statsd.cpp --module statsd --namespace android,os,statsd,util --importHeader statslog_statsd.h",
- out: [
- "statslog_statsd.cpp",
- ],
-}
-
-genrule {
- name: "statslog_statsdtest.h",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_statsdtest.h --module statsdtest --namespace android,os,statsd,util",
- out: [
- "statslog_statsdtest.h",
- ],
-}
-
-genrule {
- name: "statslog_statsdtest.cpp",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_statsdtest.cpp --module statsdtest --namespace android,os,statsd,util --importHeader statslog_statsdtest.h",
- out: [
- "statslog_statsdtest.cpp",
- ],
-}
-
-cc_library_static {
- name: "libstatslog_statsdtest",
- generated_sources: ["statslog_statsdtest.cpp"],
- generated_headers: ["statslog_statsdtest.h"],
- export_generated_headers: ["statslog_statsdtest.h"],
- shared_libs: [
- "libstatssocket",
- ]
-}
-
-cc_library_static {
- name: "libstatslog_statsd",
- generated_sources: ["statslog_statsd.cpp"],
- generated_headers: ["statslog_statsd.h"],
- export_generated_headers: ["statslog_statsd.h"],
- apex_available: [
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
- shared_libs: [
- "libstatssocket",
- ]
-}
-
-// =========
-// statsd
-// =========
-
-cc_binary {
- name: "statsd",
- defaults: ["statsd_defaults"],
-
- srcs: ["src/main.cpp"],
-
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-Wno-unused-parameter",
- // optimize for size (protobuf glop can get big)
- "-Os",
- // "-g",
- // "-O0",
- ],
-
- product_variables: {
- eng: {
- // Enable sanitizer ONLY on eng builds
- //sanitize: {
- // address: true,
- //},
- },
- debuggable: {
- // Add a flag to enable stats log printing from statsd on debug builds.
- cflags: ["-DVERY_VERBOSE_PRINTING"],
- },
- },
-
- proto: {
- type: "lite",
- static: true,
- },
- stl: "libc++_static",
-
- shared_libs: [
- "libstatssocket",
- ],
-
- apex_available: [
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
-}
-
-// ==============
-// statsd_test
-// ==============
-
-cc_test {
- name: "statsd_test",
- defaults: ["statsd_defaults"],
- test_suites: ["device-tests", "mts"],
- test_config: "statsd_test.xml",
-
- //TODO(b/153588990): Remove when the build system properly separates
- //32bit and 64bit architectures.
- compile_multilib: "both",
- multilib: {
- lib64: {
- suffix: "64",
- },
- lib32: {
- suffix: "32",
- },
- },
-
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-missing-field-initializers",
- "-Wno-unused-variable",
- "-Wno-unused-function",
- "-Wno-unused-parameter",
- ],
-
- require_root: true,
-
- srcs: [
- // atom_field_options.proto needs field_options.proto, but that is
- // not included in libprotobuf-cpp-lite, so compile it here.
- ":libprotobuf-internal-protos",
-
- "src/atom_field_options.proto",
- "src/atoms.proto",
- "src/shell/shell_data.proto",
- "src/stats_log.proto",
- "tests/AlarmMonitor_test.cpp",
- "tests/anomaly/AlarmTracker_test.cpp",
- "tests/anomaly/AnomalyTracker_test.cpp",
- "tests/condition/CombinationConditionTracker_test.cpp",
- "tests/condition/ConditionTimer_test.cpp",
- "tests/condition/SimpleConditionTracker_test.cpp",
- "tests/ConfigManager_test.cpp",
- "tests/e2e/Alarm_e2e_test.cpp",
- "tests/e2e/Anomaly_count_e2e_test.cpp",
- "tests/e2e/Anomaly_duration_sum_e2e_test.cpp",
- "tests/e2e/Attribution_e2e_test.cpp",
- "tests/e2e/ConfigTtl_e2e_test.cpp",
- "tests/e2e/CountMetric_e2e_test.cpp",
- "tests/e2e/DurationMetric_e2e_test.cpp",
- "tests/e2e/GaugeMetric_e2e_pull_test.cpp",
- "tests/e2e/GaugeMetric_e2e_push_test.cpp",
- "tests/e2e/MetricActivation_e2e_test.cpp",
- "tests/e2e/MetricConditionLink_e2e_test.cpp",
- "tests/e2e/PartialBucket_e2e_test.cpp",
- "tests/e2e/ValueMetric_pull_e2e_test.cpp",
- "tests/e2e/WakelockDuration_e2e_test.cpp",
- "tests/external/puller_util_test.cpp",
- "tests/external/StatsCallbackPuller_test.cpp",
- "tests/external/StatsPuller_test.cpp",
- "tests/external/StatsPullerManager_test.cpp",
- "tests/FieldValue_test.cpp",
- "tests/guardrail/StatsdStats_test.cpp",
- "tests/HashableDimensionKey_test.cpp",
- "tests/indexed_priority_queue_test.cpp",
- "tests/log_event/LogEventQueue_test.cpp",
- "tests/LogEntryMatcher_test.cpp",
- "tests/LogEvent_test.cpp",
- "tests/metadata_util_test.cpp",
- "tests/metrics/CountMetricProducer_test.cpp",
- "tests/metrics/DurationMetricProducer_test.cpp",
- "tests/metrics/EventMetricProducer_test.cpp",
- "tests/metrics/GaugeMetricProducer_test.cpp",
- "tests/metrics/MaxDurationTracker_test.cpp",
- "tests/metrics/metrics_test_helper.cpp",
- "tests/metrics/OringDurationTracker_test.cpp",
- "tests/metrics/ValueMetricProducer_test.cpp",
- "tests/MetricsManager_test.cpp",
- "tests/shell/ShellSubscriber_test.cpp",
- "tests/state/StateTracker_test.cpp",
- "tests/statsd_test_util.cpp",
- "tests/StatsLogProcessor_test.cpp",
- "tests/StatsService_test.cpp",
- "tests/storage/StorageManager_test.cpp",
- "tests/UidMap_test.cpp",
- "tests/utils/MultiConditionTrigger_test.cpp",
- ],
-
- static_libs: [
- "libgmock",
- "libplatformprotos",
- "libstatslog_statsdtest",
- "libstatssocket_private",
- ],
-
- proto: {
- type: "lite",
- include_dirs: ["external/protobuf/src"],
- },
-
-}
-
-//#############################
-// statsd micro benchmark
-//#############################
-
-cc_benchmark {
- name: "statsd_benchmark",
- defaults: ["statsd_defaults"],
-
- srcs: [
- // atom_field_options.proto needs field_options.proto, but that is
- // not included in libprotobuf-cpp-lite, so compile it here.
- ":libprotobuf-internal-protos",
-
- "benchmark/duration_metric_benchmark.cpp",
- "benchmark/filter_value_benchmark.cpp",
- "benchmark/get_dimensions_for_condition_benchmark.cpp",
- "benchmark/hello_world_benchmark.cpp",
- "benchmark/log_event_benchmark.cpp",
- "benchmark/main.cpp",
- "benchmark/metric_util.cpp",
- "benchmark/stats_write_benchmark.cpp",
- "src/atom_field_options.proto",
- "src/atoms.proto",
- "src/stats_log.proto",
- ],
-
- proto: {
- type: "lite",
- include_dirs: ["external/protobuf/src"],
- },
-
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- "-Wno-unused-variable",
- "-Wno-unused-function",
-
- // Bug: http://b/29823425 Disable -Wvarargs for Clang update to r271374
- "-Wno-varargs",
- ],
-
- static_libs: [
- "libplatformprotos",
- "libstatssocket_private",
- ],
-
- shared_libs: [
- "libgtest_prod",
- "libprotobuf-cpp-lite",
- "libstatslog",
- ],
-}
-
-// ==== java proto device library (for test only) ==============================
-java_library {
- name: "statsdprotolite",
- sdk_version: "core_current",
- proto: {
- type: "lite",
- include_dirs: ["external/protobuf/src"],
- },
-
- srcs: [
- "src/atoms.proto",
- "src/shell/shell_config.proto",
- "src/shell/shell_data.proto",
- "src/stats_log.proto",
- "src/statsd_config.proto",
- ],
-
- static_libs: [
- "platformprotoslite",
- ],
- // Protos have lots of MissingOverride and similar.
- errorprone: {
- javacflags: ["-XepDisableAllChecks"],
- },
-}
-
-// Filegroup for statsd config proto definition.
-filegroup {
- name: "statsd-config-proto-def",
- srcs: ["src/statsd_config.proto"],
-}
diff --git a/cmds/statsd/OWNERS b/cmds/statsd/OWNERS
deleted file mode 100644
index a61babf..0000000
--- a/cmds/statsd/OWNERS
+++ /dev/null
@@ -1,9 +0,0 @@
-jeffreyhuang@google.com
-joeo@google.com
-jtnguyen@google.com
-muhammadq@google.com
-ruchirr@google.com
-singhtejinder@google.com
-tsaichristine@google.com
-yaochen@google.com
-yro@google.com
diff --git a/cmds/statsd/TEST_MAPPING b/cmds/statsd/TEST_MAPPING
deleted file mode 100644
index 8dee073..0000000
--- a/cmds/statsd/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "presubmit" : [
- {
- "name" : "statsd_test"
- }
- ]
-}
\ No newline at end of file
diff --git a/cmds/statsd/benchmark/duration_metric_benchmark.cpp b/cmds/statsd/benchmark/duration_metric_benchmark.cpp
deleted file mode 100644
index 2d315d9..0000000
--- a/cmds/statsd/benchmark/duration_metric_benchmark.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vector>
-#include "benchmark/benchmark.h"
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-#include "metric_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-static StatsdConfig CreateDurationMetricConfig_NoLink_AND_CombinationCondition(
- DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
- StatsdConfig config;
- *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto scheduledJobPredicate = CreateScheduledJobPredicate();
- auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
- dimensions->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
- dimensions->add_child()->set_field(2); // job name field.
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
- {Position::FIRST});
- if (addExtraDimensionInCondition) {
- syncDimension->add_child()->set_field(2 /* name field*/);
- }
-
- *config.add_predicate() = scheduledJobPredicate;
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(StringToId("CombinationPredicate"));
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("scheduledJob"));
- metric->set_what(scheduledJobPredicate.id());
- metric->set_condition(combinationPredicate->id());
- metric->set_aggregation_type(aggregationType);
- auto dimensionWhat = metric->mutable_dimensions_in_what();
- dimensionWhat->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(2); // job name field.
- *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-static StatsdConfig CreateDurationMetricConfig_Link_AND_CombinationCondition(
- DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
- StatsdConfig config;
- *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto scheduledJobPredicate = CreateScheduledJobPredicate();
- auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
- *dimensions = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- dimensions->add_child()->set_field(2); // job name field.
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- if (addExtraDimensionInCondition) {
- syncDimension->add_child()->set_field(2 /* name field*/);
- }
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
- *config.add_predicate() = scheduledJobPredicate;
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(StringToId("CombinationPredicate"));
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("scheduledJob"));
- metric->set_what(scheduledJobPredicate.id());
- metric->set_condition(combinationPredicate->id());
- metric->set_aggregation_type(aggregationType);
- *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
-
- auto links = metric->add_links();
- links->set_condition(isSyncingPredicate.id());
- *links->mutable_fields_in_what() =
- CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- *links->mutable_fields_in_condition() =
- CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-static void BM_DurationMetricNoLink(benchmark::State& state) {
- ConfigKey cfgKey;
- auto config = CreateDurationMetricConfig_NoLink_AND_CombinationCondition(
- DurationMetric::SUM, false);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 11,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(
- CreateScreenStateChangedEvent(bucketStartTimeNs + 40, android::view::DISPLAY_STATE_ON));
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 102,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 450,
- android::view::DISPLAY_STATE_ON));
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 650,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 100,
- android::view::DISPLAY_STATE_ON));
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 640,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 650,
- android::view::DISPLAY_STATE_ON));
-
- vector<int> attributionUids1 = {9999};
- vector<string> attributionTags1 = {""};
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "job0"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 101, attributionUids1,
- attributionTags1, "job0"));
-
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 201, attributionUids1,
- attributionTags1, "job2"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 500, attributionUids1,
- attributionTags1, "job2"));
-
- vector<int> attributionUids2 = {8888};
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 600, attributionUids2,
- attributionTags1, "job2"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 850,
- attributionUids2, attributionTags1, "job2"));
-
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 600,
- attributionUids2, attributionTags1, "job1"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 900,
- attributionUids2, attributionTags1, "job1"));
-
- vector<int> attributionUids3 = {111, 222, 222};
- vector<string> attributionTags3 = {"App1", "GMSCoreModule1", "GMSCoreModule2"};
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 10, attributionUids3,
- attributionTags3, "ReadEmail"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 50, attributionUids3, attributionTags3,
- "ReadEmail"));
-
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 200, attributionUids3,
- attributionTags3, "ReadEmail"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids3,
- attributionTags3, "ReadEmail"));
-
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400, attributionUids3,
- attributionTags3, "ReadDoc"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids3,
- attributionTags3, "ReadDoc"));
-
- vector<int> attributionUids4 = {333, 222, 555};
- vector<string> attributionTags4 = {"App2", "GMSCoreModule1", "GMSCoreModule2"};
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 401, attributionUids4,
- attributionTags4, "ReadEmail"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 700, attributionUids4,
- attributionTags4, "ReadEmail"));
- sortLogEventsByTimestamp(&events);
-
- while (state.KeepRunning()) {
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- }
-}
-
-BENCHMARK(BM_DurationMetricNoLink);
-
-
-static void BM_DurationMetricLink(benchmark::State& state) {
- ConfigKey cfgKey;
- auto config = CreateDurationMetricConfig_Link_AND_CombinationCondition(
- DurationMetric::SUM, false);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 55,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 120,
- android::view::DISPLAY_STATE_ON));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 121,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 450,
- android::view::DISPLAY_STATE_ON));
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 501,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 100,
- android::view::DISPLAY_STATE_ON));
-
- vector<int> attributionUids1 = {111};
- vector<string> attributionTags1 = {"App1"};
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 1, attributionUids1,
- attributionTags1, "job1"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 101, attributionUids1,
- attributionTags1, "job1"));
-
- vector<int> attributionUids2 = {333};
- vector<string> attributionTags2 = {"App2"};
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 201, attributionUids2,
- attributionTags2, "job2"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 500, attributionUids2,
- attributionTags2, "job2"));
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 600, attributionUids2,
- attributionTags2, "job2"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 850,
- attributionUids2, attributionTags2, "job2"));
-
- vector<int> attributionUids3 = {444};
- vector<string> attributionTags3 = {"App3"};
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + bucketSizeNs - 2,
- attributionUids3, attributionTags3, "job3"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 900,
- attributionUids3, attributionTags3, "job3"));
-
- vector<int> attributionUids4 = {111, 222, 222};
- vector<string> attributionTags4 = {"App1", "GMSCoreModule1", "GMSCoreModule2"};
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids4,
- attributionTags4, "ReadEmail"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 110, attributionUids4, attributionTags4,
- "ReadEmail"));
-
- vector<int> attributionUids5 = {333, 222, 555};
- vector<string> attributionTags5 = {"App2", "GMSCoreModule1", "GMSCoreModule2"};
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 300, attributionUids5,
- attributionTags5, "ReadEmail"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 700, attributionUids5,
- attributionTags5, "ReadEmail"));
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400, attributionUids5,
- attributionTags5, "ReadDoc"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids5,
- attributionTags5, "ReadDoc"));
-
- vector<int> attributionUids6 = {444, 222, 555};
- vector<string> attributionTags6 = {"App3", "GMSCoreModule1", "GMSCoreModule2"};
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 550, attributionUids6,
- attributionTags6, "ReadDoc"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 800, attributionUids6, attributionTags6,
- "ReadDoc"));
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids6,
- attributionTags6, "ReadDoc"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 700, attributionUids6,
- attributionTags6, "ReadDoc"));
- sortLogEventsByTimestamp(&events);
-
- while (state.KeepRunning()) {
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- }
-}
-
-BENCHMARK(BM_DurationMetricLink);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/filter_value_benchmark.cpp b/cmds/statsd/benchmark/filter_value_benchmark.cpp
deleted file mode 100644
index 743ccc4..0000000
--- a/cmds/statsd/benchmark/filter_value_benchmark.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vector>
-
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "benchmark/benchmark.h"
-#include "logd/LogEvent.h"
-#include "metric_util.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-static void createLogEventAndMatcher(LogEvent* event, FieldMatcher* field_matcher) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, 1);
- AStatsEvent_overwriteTimestamp(statsEvent, 100000);
-
- std::vector<int> attributionUids = {100, 100};
- std::vector<string> attributionTags = {"LOCATION", "LOCATION"};
- writeAttribution(statsEvent, attributionUids, attributionTags);
-
- AStatsEvent_writeFloat(statsEvent, 3.2f);
- AStatsEvent_writeString(statsEvent, "LOCATION");
- AStatsEvent_writeInt64(statsEvent, 990);
-
- parseStatsEventToLogEvent(statsEvent, event);
-
- field_matcher->set_field(1);
- auto child = field_matcher->add_child();
- child->set_field(1);
- child->set_position(FIRST);
- child->add_child()->set_field(1);
-}
-
-static void BM_FilterValue(benchmark::State& state) {
- LogEvent event(/*uid=*/0, /*pid=*/0);
- FieldMatcher field_matcher;
- createLogEventAndMatcher(&event, &field_matcher);
-
- std::vector<Matcher> matchers;
- translateFieldMatcher(field_matcher, &matchers);
-
- while (state.KeepRunning()) {
- HashableDimensionKey output;
- filterValues(matchers, event.getValues(), &output);
- }
-}
-
-BENCHMARK(BM_FilterValue);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp b/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp
deleted file mode 100644
index 7a45565..0000000
--- a/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vector>
-
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "benchmark/benchmark.h"
-#include "logd/LogEvent.h"
-#include "metric_util.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-static void createLogEventAndLink(LogEvent* event, Metric2Condition *link) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, 1);
- AStatsEvent_overwriteTimestamp(statsEvent, 100000);
-
- std::vector<int> attributionUids = {100, 100};
- std::vector<string> attributionTags = {"LOCATION", "LOCATION"};
- writeAttribution(statsEvent, attributionUids, attributionTags);
-
- AStatsEvent_writeFloat(statsEvent, 3.2f);
- AStatsEvent_writeString(statsEvent, "LOCATION");
- AStatsEvent_writeInt64(statsEvent, 990);
-
- parseStatsEventToLogEvent(statsEvent, event);
-
- link->conditionId = 1;
-
- FieldMatcher field_matcher;
- field_matcher.set_field(event->GetTagId());
- auto child = field_matcher.add_child();
- child->set_field(1);
- child->set_position(FIRST);
- child->add_child()->set_field(1);
-
- translateFieldMatcher(field_matcher, &link->metricFields);
- field_matcher.set_field(event->GetTagId() + 1);
- translateFieldMatcher(field_matcher, &link->conditionFields);
-}
-
-static void BM_GetDimensionInCondition(benchmark::State& state) {
- Metric2Condition link;
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createLogEventAndLink(&event, &link);
-
- while (state.KeepRunning()) {
- HashableDimensionKey output;
- getDimensionForCondition(event.getValues(), link, &output);
- }
-}
-
-BENCHMARK(BM_GetDimensionInCondition);
-
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/hello_world_benchmark.cpp b/cmds/statsd/benchmark/hello_world_benchmark.cpp
deleted file mode 100644
index c732d39..0000000
--- a/cmds/statsd/benchmark/hello_world_benchmark.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "benchmark/benchmark.h"
-
-static void BM_StringCreation(benchmark::State& state) {
- while (state.KeepRunning()) std::string empty_string;
-}
-// Register the function as a benchmark
-BENCHMARK(BM_StringCreation);
-
-// Define another benchmark
-static void BM_StringCopy(benchmark::State& state) {
- std::string x = "hello";
- while (state.KeepRunning()) std::string copy(x);
-}
-BENCHMARK(BM_StringCopy);
diff --git a/cmds/statsd/benchmark/log_event_benchmark.cpp b/cmds/statsd/benchmark/log_event_benchmark.cpp
deleted file mode 100644
index 057e00b..0000000
--- a/cmds/statsd/benchmark/log_event_benchmark.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vector>
-#include "benchmark/benchmark.h"
-#include "logd/LogEvent.h"
-#include "stats_event.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static size_t createAndParseStatsEvent(uint8_t* msg) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
- AStatsEvent_writeInt32(event, 2);
- AStatsEvent_writeFloat(event, 2.0);
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
- memcpy(msg, buf, size);
- return size;
-}
-
-static void BM_LogEventCreation(benchmark::State& state) {
- uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
- size_t size = createAndParseStatsEvent(msg);
- while (state.KeepRunning()) {
- LogEvent event(/*uid=*/ 1000, /*pid=*/ 1001);
- benchmark::DoNotOptimize(event.parseBuffer(msg, size));
- }
-}
-BENCHMARK(BM_LogEventCreation);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/main.cpp b/cmds/statsd/benchmark/main.cpp
deleted file mode 100644
index 08921f3..0000000
--- a/cmds/statsd/benchmark/main.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <benchmark/benchmark.h>
-
-BENCHMARK_MAIN();
diff --git a/cmds/statsd/benchmark/metric_util.cpp b/cmds/statsd/benchmark/metric_util.cpp
deleted file mode 100644
index 89fd3d9..0000000
--- a/cmds/statsd/benchmark/metric_util.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "metric_util.h"
-
-#include "stats_event.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(atomId);
- return atom_matcher;
-}
-
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
- ScheduledJobStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::SCHEDULED_JOB_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(3); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateStartScheduledJobAtomMatcher() {
- return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
- ScheduledJobStateChanged::STARTED);
-}
-
-AtomMatcher CreateFinishScheduledJobAtomMatcher() {
- return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
- ScheduledJobStateChanged::FINISHED);
-}
-
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::SCREEN_BRIGHTNESS_CHANGED);
- return atom_matcher;
-}
-
-AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId("UidProcessStateChanged"));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::UID_PROCESS_STATE_CHANGED);
- return atom_matcher;
-}
-
-AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
- WakelockStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::WAKELOCK_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(4); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateAcquireWakelockAtomMatcher() {
- return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
-}
-
-AtomMatcher CreateReleaseWakelockAtomMatcher() {
- return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
-}
-
-AtomMatcher CreateScreenStateChangedAtomMatcher(
- const string& name, android::view::DisplayStateEnum state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::SCREEN_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(1); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateScreenTurnedOnAtomMatcher() {
- return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-}
-
-AtomMatcher CreateScreenTurnedOffAtomMatcher() {
- return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
- ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-}
-
-AtomMatcher CreateSyncStateChangedAtomMatcher(
- const string& name, SyncStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::SYNC_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(3); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateSyncStartAtomMatcher() {
- return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
-}
-
-AtomMatcher CreateSyncEndAtomMatcher() {
- return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
-}
-
-AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
- const string& name, ActivityForegroundStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(4); // Activity field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateMoveToBackgroundAtomMatcher() {
- return CreateActivityForegroundStateChangedAtomMatcher(
- "MoveToBackground", ActivityForegroundStateChanged::BACKGROUND);
-}
-
-AtomMatcher CreateMoveToForegroundAtomMatcher() {
- return CreateActivityForegroundStateChangedAtomMatcher(
- "MoveToForeground", ActivityForegroundStateChanged::FOREGROUND);
-}
-
-Predicate CreateScheduledJobPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
- predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
- return predicate;
-}
-
-Predicate CreateBatterySaverModePredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("BatterySaverIsOn"));
- predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
- return predicate;
-}
-
-Predicate CreateScreenIsOnPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("ScreenIsOn"));
- predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
- return predicate;
-}
-
-Predicate CreateScreenIsOffPredicate() {
- Predicate predicate;
- predicate.set_id(1111123);
- predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
- return predicate;
-}
-
-Predicate CreateHoldingWakelockPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("HoldingWakelock"));
- predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
- return predicate;
-}
-
-Predicate CreateIsSyncingPredicate() {
- Predicate predicate;
- predicate.set_id(33333333333333);
- predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
- return predicate;
-}
-
-Predicate CreateIsInBackgroundPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("IsInBackground"));
- predicate.mutable_simple_predicate()->set_start(StringToId("MoveToBackground"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("MoveToForeground"));
- return predicate;
-}
-
-void addPredicateToPredicateCombination(const Predicate& predicate,
- Predicate* combinationPredicate) {
- combinationPredicate->mutable_combination()->add_predicate(predicate.id());
-}
-
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
- const std::vector<Position>& positions) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const auto position : positions) {
- auto child = dimensions.add_child();
- child->set_field(1);
- child->set_position(position);
- child->add_child()->set_field(1);
- }
- return dimensions;
-}
-
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
- const std::vector<Position>& positions) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const auto position : positions) {
- auto child = dimensions.add_child();
- child->set_field(1);
- child->set_position(position);
- child->add_child()->set_field(1);
- child->add_child()->set_field(2);
- }
- return dimensions;
-}
-
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const int field : fields) {
- dimensions.add_child()->set_field(field);
- }
- return dimensions;
-}
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
- const vector<string>& attributionTags) {
- vector<const char*> cTags(attributionTags.size());
- for (int i = 0; i < cTags.size(); i++) {
- cTags[i] = attributionTags[i].c_str();
- }
-
- AStatsEvent_writeAttributionChain(statsEvent,
- reinterpret_cast<const uint32_t*>(attributionUids.data()),
- cTags.data(), attributionUids.size());
-}
-
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
- AStatsEvent_build(statsEvent);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
- logEvent->parseBuffer(buf, size);
-
- AStatsEvent_release(statsEvent);
-}
-
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
- uint64_t timestampNs, const android::view::DisplayStateEnum state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
- const vector<int>& attributionUids, const vector<string>& attributionTags,
- const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, jobName.c_str());
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName) {
- return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
- ScheduledJobStateChanged::STARTED, timestampNs);
-}
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName) {
- return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
- ScheduledJobStateChanged::FINISHED, timestampNs);
-}
-
-std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name,
- const SyncStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, name.c_str());
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name) {
- return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
- SyncStateChanged::ON);
-}
-
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name) {
- return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
- SyncStateChanged::OFF);
-}
-
-sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config,
- const ConfigKey& key) {
- sp<UidMap> uidMap = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- sp<StatsLogProcessor> processor =
- new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec * NS_PER_SEC, [](const ConfigKey&) { return true; },
- [](const int&, const vector<int64_t>&) { return true; });
- processor->OnConfigUpdated(timeBaseSec * NS_PER_SEC, key, config);
- return processor;
-}
-
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
- std::sort(events->begin(), events->end(),
- [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
- return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
- });
-}
-
-int64_t StringToId(const string& str) {
- return static_cast<int64_t>(std::hash<std::string>()(str));
-}
-
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/metric_util.h b/cmds/statsd/benchmark/metric_util.h
deleted file mode 100644
index 3efaa85..0000000
--- a/cmds/statsd/benchmark/metric_util.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "src/StatsLogProcessor.h"
-#include "src/logd/LogEvent.h"
-#include "stats_event.h"
-#include "statslog.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Create AtomMatcher proto to simply match a specific atom type.
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId);
-
-// Create AtomMatcher proto for scheduled job state changed.
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher();
-
-// Create AtomMatcher proto for starting a scheduled job.
-AtomMatcher CreateStartScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for a scheduled job is done.
-AtomMatcher CreateFinishScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for screen brightness state changed.
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher();
-
-// Create AtomMatcher proto for acquiring wakelock.
-AtomMatcher CreateAcquireWakelockAtomMatcher();
-
-// Create AtomMatcher proto for releasing wakelock.
-AtomMatcher CreateReleaseWakelockAtomMatcher() ;
-
-// Create AtomMatcher proto for screen turned on.
-AtomMatcher CreateScreenTurnedOnAtomMatcher();
-
-// Create AtomMatcher proto for screen turned off.
-AtomMatcher CreateScreenTurnedOffAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned on.
-AtomMatcher CreateSyncStartAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned off.
-AtomMatcher CreateSyncEndAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to background.
-AtomMatcher CreateMoveToBackgroundAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to foreground.
-AtomMatcher CreateMoveToForegroundAtomMatcher();
-
-// Create Predicate proto for screen is off.
-Predicate CreateScreenIsOffPredicate();
-
-// Create Predicate proto for a running scheduled job.
-Predicate CreateScheduledJobPredicate();
-
-// Create Predicate proto for holding wakelock.
-Predicate CreateHoldingWakelockPredicate();
-
-// Create a Predicate proto for app syncing.
-Predicate CreateIsSyncingPredicate();
-
-// Create a Predicate proto for app is in background.
-Predicate CreateIsInBackgroundPredicate();
-
-// Add a predicate to the predicate combination.
-void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination);
-
-// Create dimensions from primitive fields.
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields);
-
-// Create dimensions by attribution uid and tag.
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
- const std::vector<Position>& positions);
-
-// Create dimensions by attribution uid only.
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
- const std::vector<Position>& positions);
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
- const vector<string>& attributionTags);
-
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent);
-
-// Create log event for screen state changed.
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
- uint64_t timestampNs, const android::view::DisplayStateEnum state);
-
-// Create log event when scheduled job starts.
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName);
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName);
-
-// Create log event when the app sync starts.
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name);
-
-// Create log event when the app sync ends.
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name);
-
-// Create a statsd log event processor upon the start time in seconds, config and key.
-sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config,
- const ConfigKey& key);
-
-// Util function to sort the log events by timestamp.
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events);
-
-int64_t StringToId(const string& str);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/stats_write_benchmark.cpp b/cmds/statsd/benchmark/stats_write_benchmark.cpp
deleted file mode 100644
index f5a0cd5..0000000
--- a/cmds/statsd/benchmark/stats_write_benchmark.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "benchmark/benchmark.h"
-#include <statslog.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static void BM_StatsWrite(benchmark::State& state) {
- const char* reason = "test";
- int64_t boot_end_time = 1234567;
- int64_t total_duration = 100;
- int64_t bootloader_duration = 10;
- int64_t time_since_last_boot = 99999999;
- while (state.KeepRunning()) {
- android::util::stats_write(
- android::util::BOOT_SEQUENCE_REPORTED, reason, reason,
- boot_end_time, total_duration, bootloader_duration, time_since_last_boot);
- total_duration++;
- }
-}
-BENCHMARK(BM_StatsWrite);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
deleted file mode 100644
index c9ccfb9..0000000
--- a/cmds/statsd/src/FieldValue.cpp
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false
-#include "Log.h"
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "math.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
- int32_t field = 0;
- for (int32_t i = 0; i <= depth; i++) {
- int32_t shiftBits = 8 * (kMaxLogDepth - i);
- field |= (pos[i] << shiftBits);
- }
-
- if (includeDepth) {
- field |= (depth << 24);
- }
- return field;
-}
-
-int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
- return getEncodedField(mask, depth, false) | 0xff000000;
-}
-
-bool Field::matches(const Matcher& matcher) const {
- if (mTag != matcher.mMatcher.getTag()) {
- return false;
- }
- if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
- return true;
- }
-
- if (matcher.hasAllPositionMatcher() &&
- (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
- return true;
- }
-
- return false;
-}
-
-void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
- std::vector<Matcher>* output) {
- if (depth > kMaxLogDepth) {
- ALOGE("depth > 2");
- return;
- }
-
- pos[depth] = matcher.field();
- mask[depth] = 0x7f;
-
- if (matcher.has_position()) {
- depth++;
- if (depth > 2) {
- return;
- }
- switch (matcher.position()) {
- case Position::ALL:
- pos[depth] = 0x00;
- mask[depth] = 0x7f;
- break;
- case Position::ANY:
- pos[depth] = 0;
- mask[depth] = 0;
- break;
- case Position::FIRST:
- pos[depth] = 1;
- mask[depth] = 0x7f;
- break;
- case Position::LAST:
- pos[depth] = 0x80;
- mask[depth] = 0x80;
- break;
- case Position::POSITION_UNKNOWN:
- pos[depth] = 0;
- mask[depth] = 0;
- break;
- }
- }
-
- if (matcher.child_size() == 0) {
- output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
- } else {
- for (const auto& child : matcher.child()) {
- translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
- }
- }
-}
-
-void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
- int pos[] = {1, 1, 1};
- int mask[] = {0x7f, 0x7f, 0x7f};
- int tag = matcher.field();
- for (const auto& child : matcher.child()) {
- translateFieldMatcher(tag, child, 0, pos, mask, output);
- }
-}
-
-bool isAttributionUidField(const FieldValue& value) {
- return isAttributionUidField(value.mField, value.mValue);
-}
-
-int32_t getUidIfExists(const FieldValue& value) {
- // the field is uid field if the field is the uid field in attribution node
- // or annotated as such in the atom
- bool isUid = isAttributionUidField(value) || isUidField(value);
- return isUid ? value.mValue.int_value : -1;
-}
-
-bool isAttributionUidField(const Field& field, const Value& value) {
- int f = field.getField() & 0xff007f;
- if (f == 0x10001 && value.getType() == INT) {
- return true;
- }
- return false;
-}
-
-bool isUidField(const FieldValue& fieldValue) {
- return fieldValue.mAnnotations.isUidField();
-}
-
-Value::Value(const Value& from) {
- type = from.getType();
- switch (type) {
- case INT:
- int_value = from.int_value;
- break;
- case LONG:
- long_value = from.long_value;
- break;
- case FLOAT:
- float_value = from.float_value;
- break;
- case DOUBLE:
- double_value = from.double_value;
- break;
- case STRING:
- str_value = from.str_value;
- break;
- case STORAGE:
- storage_value = from.storage_value;
- break;
- default:
- break;
- }
-}
-
-std::string Value::toString() const {
- switch (type) {
- case INT:
- return std::to_string(int_value) + "[I]";
- case LONG:
- return std::to_string(long_value) + "[L]";
- case FLOAT:
- return std::to_string(float_value) + "[F]";
- case DOUBLE:
- return std::to_string(double_value) + "[D]";
- case STRING:
- return str_value + "[S]";
- case STORAGE:
- return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
- default:
- return "[UNKNOWN]";
- }
-}
-
-bool Value::isZero() const {
- switch (type) {
- case INT:
- return int_value == 0;
- case LONG:
- return long_value == 0;
- case FLOAT:
- return fabs(float_value) <= std::numeric_limits<float>::epsilon();
- case DOUBLE:
- return fabs(double_value) <= std::numeric_limits<double>::epsilon();
- case STRING:
- return str_value.size() == 0;
- case STORAGE:
- return storage_value.size() == 0;
- default:
- return false;
- }
-}
-
-bool Value::operator==(const Value& that) const {
- if (type != that.getType()) return false;
-
- switch (type) {
- case INT:
- return int_value == that.int_value;
- case LONG:
- return long_value == that.long_value;
- case FLOAT:
- return float_value == that.float_value;
- case DOUBLE:
- return double_value == that.double_value;
- case STRING:
- return str_value == that.str_value;
- case STORAGE:
- return storage_value == that.storage_value;
- default:
- return false;
- }
-}
-
-bool Value::operator!=(const Value& that) const {
- if (type != that.getType()) return true;
- switch (type) {
- case INT:
- return int_value != that.int_value;
- case LONG:
- return long_value != that.long_value;
- case FLOAT:
- return float_value != that.float_value;
- case DOUBLE:
- return double_value != that.double_value;
- case STRING:
- return str_value != that.str_value;
- case STORAGE:
- return storage_value != that.storage_value;
- default:
- return false;
- }
-}
-
-bool Value::operator<(const Value& that) const {
- if (type != that.getType()) return type < that.getType();
-
- switch (type) {
- case INT:
- return int_value < that.int_value;
- case LONG:
- return long_value < that.long_value;
- case FLOAT:
- return float_value < that.float_value;
- case DOUBLE:
- return double_value < that.double_value;
- case STRING:
- return str_value < that.str_value;
- case STORAGE:
- return storage_value < that.storage_value;
- default:
- return false;
- }
-}
-
-bool Value::operator>(const Value& that) const {
- if (type != that.getType()) return type > that.getType();
-
- switch (type) {
- case INT:
- return int_value > that.int_value;
- case LONG:
- return long_value > that.long_value;
- case FLOAT:
- return float_value > that.float_value;
- case DOUBLE:
- return double_value > that.double_value;
- case STRING:
- return str_value > that.str_value;
- case STORAGE:
- return storage_value > that.storage_value;
- default:
- return false;
- }
-}
-
-bool Value::operator>=(const Value& that) const {
- if (type != that.getType()) return type >= that.getType();
-
- switch (type) {
- case INT:
- return int_value >= that.int_value;
- case LONG:
- return long_value >= that.long_value;
- case FLOAT:
- return float_value >= that.float_value;
- case DOUBLE:
- return double_value >= that.double_value;
- case STRING:
- return str_value >= that.str_value;
- case STORAGE:
- return storage_value >= that.storage_value;
- default:
- return false;
- }
-}
-
-Value Value::operator-(const Value& that) const {
- Value v;
- if (type != that.type) {
- ALOGE("Can't operate on different value types, %d, %d", type, that.type);
- return v;
- }
- if (type == STRING) {
- ALOGE("Can't operate on string value type");
- return v;
- }
-
- if (type == STORAGE) {
- ALOGE("Can't operate on storage value type");
- return v;
- }
-
- switch (type) {
- case INT:
- v.setInt(int_value - that.int_value);
- break;
- case LONG:
- v.setLong(long_value - that.long_value);
- break;
- case FLOAT:
- v.setFloat(float_value - that.float_value);
- break;
- case DOUBLE:
- v.setDouble(double_value - that.double_value);
- break;
- default:
- break;
- }
- return v;
-}
-
-Value& Value::operator=(const Value& that) {
- type = that.type;
- switch (type) {
- case INT:
- int_value = that.int_value;
- break;
- case LONG:
- long_value = that.long_value;
- break;
- case FLOAT:
- float_value = that.float_value;
- break;
- case DOUBLE:
- double_value = that.double_value;
- break;
- case STRING:
- str_value = that.str_value;
- break;
- case STORAGE:
- storage_value = that.storage_value;
- break;
- default:
- break;
- }
- return *this;
-}
-
-Value& Value::operator+=(const Value& that) {
- if (type != that.type) {
- ALOGE("Can't operate on different value types, %d, %d", type, that.type);
- return *this;
- }
- if (type == STRING) {
- ALOGE("Can't operate on string value type");
- return *this;
- }
- if (type == STORAGE) {
- ALOGE("Can't operate on storage value type");
- return *this;
- }
-
- switch (type) {
- case INT:
- int_value += that.int_value;
- break;
- case LONG:
- long_value += that.long_value;
- break;
- case FLOAT:
- float_value += that.float_value;
- break;
- case DOUBLE:
- double_value += that.double_value;
- break;
- default:
- break;
- }
- return *this;
-}
-
-double Value::getDouble() const {
- switch (type) {
- case INT:
- return int_value;
- case LONG:
- return long_value;
- case FLOAT:
- return float_value;
- case DOUBLE:
- return double_value;
- default:
- return 0;
- }
-}
-
-bool equalDimensions(const std::vector<Matcher>& dimension_a,
- const std::vector<Matcher>& dimension_b) {
- bool eq = dimension_a.size() == dimension_b.size();
- for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
- if (dimension_b[i] != dimension_a[i]) {
- eq = false;
- }
- }
- return eq;
-}
-
-bool subsetDimensions(const std::vector<Matcher>& dimension_a,
- const std::vector<Matcher>& dimension_b) {
- if (dimension_a.size() > dimension_b.size()) {
- return false;
- }
- for (size_t i = 0; i < dimension_a.size(); ++i) {
- bool found = false;
- for (size_t j = 0; j < dimension_b.size(); ++j) {
- if (dimension_a[i] == dimension_b[j]) {
- found = true;
- }
- }
- if (!found) {
- return false;
- }
- }
- return true;
-}
-
-bool HasPositionANY(const FieldMatcher& matcher) {
- if (matcher.has_position() && matcher.position() == Position::ANY) {
- return true;
- }
- for (const auto& child : matcher.child()) {
- if (HasPositionANY(child)) {
- return true;
- }
- }
- return false;
-}
-
-bool HasPositionALL(const FieldMatcher& matcher) {
- if (matcher.has_position() && matcher.position() == Position::ALL) {
- return true;
- }
- for (const auto& child : matcher.child()) {
- if (HasPositionALL(child)) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
deleted file mode 100644
index fd86e36..0000000
--- a/cmds/statsd/src/FieldValue.h
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "annotations.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class HashableDimensionKey;
-struct Matcher;
-struct Field;
-struct FieldValue;
-
-const int32_t kMaxLogDepth = 2;
-const int32_t kLastBitMask = 0x80;
-const int32_t kClearLastBitDeco = 0x7f;
-const int32_t kClearAllPositionMatcherMask = 0xffff00ff;
-
-enum Type { UNKNOWN, INT, LONG, FLOAT, DOUBLE, STRING, STORAGE };
-
-int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth);
-
-int32_t encodeMatcherMask(int32_t mask[], int32_t depth);
-
-// Get the encoded field for a leaf with a [field] number at depth 0;
-inline int32_t getSimpleField(size_t field) {
- return ((int32_t)field << 8 * 2);
-}
-
-/**
- * Field is a wrapper class for 2 integers that represents the field of a log element in its Atom
- * proto.
- * [mTag]: the atom id.
- * [mField]: encoded path from the root (atom) to leaf.
- *
- * For example:
- * WakeLockStateChanged {
- * repeated AttributionNode = 1;
- * int state = 2;
- * string tag = 3;
- * }
- * Read from logd, the items are structured as below:
- * [[[1000, "tag"], [2000, "tag2"],], 2,"hello"]
- *
- * When we read through the list, we will encode each field in a 32bit integer.
- * 8bit segments |--------|--------|--------|--------|
- * Depth field0 [L]field1 [L]field1
- *
- * The first 8 bits are the depth of the field. for example, the uid 1000 has depth 2.
- * The following 3 8-bit are for the item's position at each level.
- * The first bit of each 8bits field is reserved to mark if the item is the last item at that level
- * this is to make matching easier later.
- *
- * The above wakelock event is translated into FieldValue pairs.
- * 0x02010101->1000
- * 0x02010182->tag
- * 0x02018201->2000
- * 0x02018282->tag2
- * 0x00020000->2
- * 0x00030000->"hello"
- *
- * This encoding is the building block for the later operations.
- * Please see the definition for Matcher below to see how the matching is done.
- */
-struct Field {
-private:
- int32_t mTag;
- int32_t mField;
-
-public:
- Field() {}
-
- Field(int32_t tag, int32_t pos[], int32_t depth) : mTag(tag) {
- mField = getEncodedField(pos, depth, true);
- }
-
- Field(const Field& from) : mTag(from.getTag()), mField(from.getField()) {
- }
-
- Field(int32_t tag, int32_t field) : mTag(tag), mField(field){};
-
- inline void setField(int32_t field) {
- mField = field;
- }
-
- inline void setTag(int32_t tag) {
- mTag = tag;
- }
-
- inline void decorateLastPos(int32_t depth) {
- int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
- mField |= mask;
- }
-
- inline int32_t getTag() const {
- return mTag;
- }
-
- inline int32_t getDepth() const {
- return (mField >> 24);
- }
-
- inline int32_t getPath(int32_t depth) const {
- if (depth > 2 || depth < 0) return 0;
-
- int32_t field = (mField & 0x00ffffff);
- int32_t mask = 0xffffffff;
- return (field & (mask << 8 * (kMaxLogDepth - depth)));
- }
-
- inline int32_t getPrefix(int32_t depth) const {
- if (depth == 0) return 0;
- return getPath(depth - 1);
- }
-
- inline int32_t getField() const {
- return mField;
- }
-
- inline int32_t getRawPosAtDepth(int32_t depth) const {
- int32_t field = (mField & 0x00ffffff);
- int32_t shift = 8 * (kMaxLogDepth - depth);
- int32_t mask = 0xff << shift;
-
- return (field & mask) >> shift;
- }
-
- inline int32_t getPosAtDepth(int32_t depth) const {
- return getRawPosAtDepth(depth) & kClearLastBitDeco;
- }
-
- // Check if the first bit of the 8-bit segment for depth is 1
- inline bool isLastPos(int32_t depth) const {
- int32_t field = (mField & 0x00ffffff);
- int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
- return (field & mask) != 0;
- }
-
- // if the 8-bit segment is all 0's
- inline bool isAnyPosMatcher(int32_t depth) const {
- return getDepth() >= depth && getRawPosAtDepth(depth) == 0;
- }
- // if the 8bit is 0x80 (1000 0000)
- inline bool isLastPosMatcher(int32_t depth) const {
- return getDepth() >= depth && getRawPosAtDepth(depth) == kLastBitMask;
- }
-
- inline bool operator==(const Field& that) const {
- return mTag == that.getTag() && mField == that.getField();
- };
-
- inline bool operator!=(const Field& that) const {
- return mTag != that.getTag() || mField != that.getField();
- };
-
- bool operator<(const Field& that) const {
- if (mTag != that.getTag()) {
- return mTag < that.getTag();
- }
-
- if (mField != that.getField()) {
- return mField < that.getField();
- }
-
- return false;
- }
-
- bool matches(const Matcher& that) const;
-};
-
-/**
- * Matcher represents a leaf matcher in the FieldMatcher in statsd_config.
- *
- * It contains all information needed to match one or more leaf node.
- * All information is encoded in a Field(2 ints) and a bit mask(1 int).
- *
- * For example, to match the first/any/last uid field in attribution chain in Atom 10,
- * we have the following FieldMatcher in statsd_config
- * FieldMatcher {
- * field:10
- * FieldMatcher {
- * field:1
- * position: any/last/first
- * FieldMatcher {
- * field:1
- * }
- * }
- * }
- *
- * We translate the FieldMatcher into a Field, and mask
- * First: [Matcher Field] 0x02010101 [Mask]0xff7f7f7f
- * Last: [Matcher Field] 0x02018001 [Mask]0xff7f807f
- * Any: [Matcher Field] 0x02010001 [Mask]0xff7f007f
- * All: [Matcher Field] 0x02010001 [Mask]0xff7f7f7f
- *
- * [To match a log Field with a Matcher] we apply the bit mask to the log Field and check if
- * the result is equal to the Matcher Field. That's a bit wise AND operation + check if 2 ints are
- * equal. Nothing can beat the performance of this matching algorithm.
- *
- * TODO(b/110561213): ADD EXAMPLE HERE.
- */
-struct Matcher {
- Matcher(const Field& matcher, int32_t mask) : mMatcher(matcher), mMask(mask){};
-
- const Field mMatcher;
- const int32_t mMask;
-
- inline const Field& getMatcher() const {
- return mMatcher;
- }
-
- inline int32_t getMask() const {
- return mMask;
- }
-
- inline int32_t getRawMaskAtDepth(int32_t depth) const {
- int32_t field = (mMask & 0x00ffffff);
- int32_t shift = 8 * (kMaxLogDepth - depth);
- int32_t mask = 0xff << shift;
-
- return (field & mask) >> shift;
- }
-
- bool hasAllPositionMatcher() const {
- return mMatcher.getDepth() == 2 && getRawMaskAtDepth(1) == 0x7f;
- }
-
- bool hasAnyPositionMatcher(int* prefix) const {
- if (mMatcher.getDepth() == 2 && mMatcher.getRawPosAtDepth(1) == 0) {
- (*prefix) = mMatcher.getPrefix(1);
- return true;
- }
- return false;
- }
-
- inline bool operator!=(const Matcher& that) const {
- return mMatcher != that.getMatcher() || mMask != that.getMask();
- }
-
- inline bool operator==(const Matcher& that) const {
- return mMatcher == that.mMatcher && mMask == that.mMask;
- }
-};
-
-inline Matcher getSimpleMatcher(int32_t tag, size_t field) {
- return Matcher(Field(tag, getSimpleField(field)), 0xff7f0000);
-}
-
-inline Matcher getFirstUidMatcher(int32_t atomId) {
- int32_t pos[] = {1, 1, 1};
- return Matcher(Field(atomId, pos, 2), 0xff7f7f7f);
-}
-
-/**
- * A wrapper for a union type to contain multiple types of values.
- *
- */
-struct Value {
- Value() : type(UNKNOWN) {}
-
- Value(int32_t v) {
- int_value = v;
- type = INT;
- }
-
- Value(int64_t v) {
- long_value = v;
- type = LONG;
- }
-
- Value(float v) {
- float_value = v;
- type = FLOAT;
- }
-
- Value(double v) {
- double_value = v;
- type = DOUBLE;
- }
-
- Value(const std::string& v) {
- str_value = v;
- type = STRING;
- }
-
- Value(const std::vector<uint8_t>& v) {
- storage_value = v;
- type = STORAGE;
- }
-
- void setInt(int32_t v) {
- int_value = v;
- type = INT;
- }
-
- void setLong(int64_t v) {
- long_value = v;
- type = LONG;
- }
-
- void setFloat(float v) {
- float_value = v;
- type = FLOAT;
- }
-
- void setDouble(double v) {
- double_value = v;
- type = DOUBLE;
- }
-
- union {
- int32_t int_value;
- int64_t long_value;
- float float_value;
- double double_value;
- };
- std::string str_value;
- std::vector<uint8_t> storage_value;
-
- Type type;
-
- std::string toString() const;
-
- bool isZero() const;
-
- Type getType() const {
- return type;
- }
-
- double getDouble() const;
-
- Value(const Value& from);
-
- bool operator==(const Value& that) const;
- bool operator!=(const Value& that) const;
-
- bool operator<(const Value& that) const;
- bool operator>(const Value& that) const;
- bool operator>=(const Value& that) const;
- Value operator-(const Value& that) const;
- Value& operator+=(const Value& that);
- Value& operator=(const Value& that);
-};
-
-class Annotations {
-public:
- Annotations() {
- setNested(true); // Nested = true by default
- }
-
- // This enum stores where particular annotations can be found in the
- // bitmask. Note that these pos do not correspond to annotation ids.
- enum {
- NESTED_POS = 0x0,
- PRIMARY_POS = 0x1,
- EXCLUSIVE_POS = 0x2,
- UID_POS = 0x3
- };
-
- inline void setNested(bool nested) { setBitmaskAtPos(NESTED_POS, nested); }
-
- inline void setPrimaryField(bool primary) { setBitmaskAtPos(PRIMARY_POS, primary); }
-
- inline void setExclusiveState(bool exclusive) { setBitmaskAtPos(EXCLUSIVE_POS, exclusive); }
-
- inline void setUidField(bool isUid) { setBitmaskAtPos(UID_POS, isUid); }
-
- // Default value = false
- inline bool isNested() const { return getValueFromBitmask(NESTED_POS); }
-
- // Default value = false
- inline bool isPrimaryField() const { return getValueFromBitmask(PRIMARY_POS); }
-
- // Default value = false
- inline bool isExclusiveState() const { return getValueFromBitmask(EXCLUSIVE_POS); }
-
- // Default value = false
- inline bool isUidField() const { return getValueFromBitmask(UID_POS); }
-
-private:
- inline void setBitmaskAtPos(int pos, bool value) {
- mBooleanBitmask &= ~(1 << pos); // clear
- mBooleanBitmask |= (value << pos); // set
- }
-
- inline bool getValueFromBitmask(int pos) const {
- return (mBooleanBitmask >> pos) & 0x1;
- }
-
- // This is a bitmask over all annotations stored in boolean form. Because
- // there are only 4 booleans, just one byte is required.
- uint8_t mBooleanBitmask = 0;
-};
-
-/**
- * Represents a log item, or a dimension item (They are essentially the same).
- */
-struct FieldValue {
- FieldValue() {}
- FieldValue(const Field& field, const Value& value) : mField(field), mValue(value) {
- }
- bool operator==(const FieldValue& that) const {
- return mField == that.mField && mValue == that.mValue;
- }
- bool operator!=(const FieldValue& that) const {
- return mField != that.mField || mValue != that.mValue;
- }
- bool operator<(const FieldValue& that) const {
- if (mField != that.mField) {
- return mField < that.mField;
- }
-
- if (mValue != that.mValue) {
- return mValue < that.mValue;
- }
-
- return false;
- }
-
- Field mField;
- Value mValue;
- Annotations mAnnotations;
-};
-
-bool HasPositionANY(const FieldMatcher& matcher);
-bool HasPositionALL(const FieldMatcher& matcher);
-
-bool isAttributionUidField(const FieldValue& value);
-
-/* returns uid if the field is uid field, or -1 if the field is not a uid field */
-int getUidIfExists(const FieldValue& value);
-
-void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output);
-
-bool isAttributionUidField(const Field& field, const Value& value);
-bool isUidField(const FieldValue& fieldValue);
-
-bool equalDimensions(const std::vector<Matcher>& dimension_a,
- const std::vector<Matcher>& dimension_b);
-
-// Returns true if dimension_a is a subset of dimension_b.
-bool subsetDimensions(const std::vector<Matcher>& dimension_a,
- const std::vector<Matcher>& dimension_b);
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
deleted file mode 100644
index eba66e0..0000000
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "HashableDimensionKey.h"
-#include "FieldValue.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::string;
-using std::vector;
-using android::base::StringPrintf;
-
-// These constants must be kept in sync with those in StatsDimensionsValue.java
-const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2;
-const static int STATS_DIMENSIONS_VALUE_INT_TYPE = 3;
-const static int STATS_DIMENSIONS_VALUE_LONG_TYPE = 4;
-// const static int STATS_DIMENSIONS_VALUE_BOOL_TYPE = 5; (commented out because
-// unused -- statsd does not correctly support bool types)
-const static int STATS_DIMENSIONS_VALUE_FLOAT_TYPE = 6;
-const static int STATS_DIMENSIONS_VALUE_TUPLE_TYPE = 7;
-
-/**
- * Recursive helper function that populates a parent StatsDimensionsValueParcel
- * with children StatsDimensionsValueParcels.
- *
- * \param parent parcel that will be populated with children
- * \param childDepth depth of children FieldValues
- * \param childPrefix expected FieldValue prefix of children
- * \param dims vector of FieldValues stored by HashableDimensionKey
- * \param index position in dims to start reading children from
- */
-static void populateStatsDimensionsValueParcelChildren(StatsDimensionsValueParcel& parent,
- int childDepth, int childPrefix,
- const vector<FieldValue>& dims,
- size_t& index) {
- if (childDepth > 2) {
- ALOGE("Depth > 2 not supported by StatsDimensionsValueParcel.");
- return;
- }
-
- while (index < dims.size()) {
- const FieldValue& dim = dims[index];
- int fieldDepth = dim.mField.getDepth();
- int fieldPrefix = dim.mField.getPrefix(childDepth);
-
- StatsDimensionsValueParcel child;
- child.field = dim.mField.getPosAtDepth(childDepth);
-
- if (fieldDepth == childDepth && fieldPrefix == childPrefix) {
- switch (dim.mValue.getType()) {
- case INT:
- child.valueType = STATS_DIMENSIONS_VALUE_INT_TYPE;
- child.intValue = dim.mValue.int_value;
- break;
- case LONG:
- child.valueType = STATS_DIMENSIONS_VALUE_LONG_TYPE;
- child.longValue = dim.mValue.long_value;
- break;
- case FLOAT:
- child.valueType = STATS_DIMENSIONS_VALUE_FLOAT_TYPE;
- child.floatValue = dim.mValue.float_value;
- break;
- case STRING:
- child.valueType = STATS_DIMENSIONS_VALUE_STRING_TYPE;
- child.stringValue = dim.mValue.str_value;
- break;
- default:
- ALOGE("Encountered FieldValue with unsupported value type.");
- break;
- }
- index++;
- parent.tupleValue.push_back(child);
- } else if (fieldDepth > childDepth && fieldPrefix == childPrefix) {
- // This FieldValue is not a child of the current parent, but it is
- // an indirect descendant. Thus, create a direct child of TUPLE_TYPE
- // and recurse to parcel the indirect descendants.
- child.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
- populateStatsDimensionsValueParcelChildren(child, childDepth + 1,
- dim.mField.getPrefix(childDepth + 1), dims,
- index);
- parent.tupleValue.push_back(child);
- } else {
- return;
- }
- }
-}
-
-StatsDimensionsValueParcel HashableDimensionKey::toStatsDimensionsValueParcel() const {
- StatsDimensionsValueParcel root;
- if (mValues.size() == 0) {
- return root;
- }
-
- root.field = mValues[0].mField.getTag();
- root.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
-
- // Children of the root correspond to top-level (depth = 0) FieldValues.
- int childDepth = 0;
- int childPrefix = 0;
- size_t index = 0;
- populateStatsDimensionsValueParcelChildren(root, childDepth, childPrefix, mValues, index);
-
- return root;
-}
-
-android::hash_t hashDimension(const HashableDimensionKey& value) {
- android::hash_t hash = 0;
- for (const auto& fieldValue : value.getValues()) {
- hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mField.getField()));
- hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mField.getTag()));
- hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mValue.getType()));
- switch (fieldValue.mValue.getType()) {
- case INT:
- hash = android::JenkinsHashMix(hash,
- android::hash_type(fieldValue.mValue.int_value));
- break;
- case LONG:
- hash = android::JenkinsHashMix(hash,
- android::hash_type(fieldValue.mValue.long_value));
- break;
- case STRING:
- hash = android::JenkinsHashMix(hash, static_cast<uint32_t>(std::hash<std::string>()(
- fieldValue.mValue.str_value)));
- break;
- case FLOAT: {
- hash = android::JenkinsHashMix(hash,
- android::hash_type(fieldValue.mValue.float_value));
- break;
- }
- default:
- break;
- }
- }
- return JenkinsHashWhiten(hash);
-}
-
-bool filterValues(const Matcher& matcherField, const vector<FieldValue>& values,
- FieldValue* output) {
- for (const auto& value : values) {
- if (value.mField.matches(matcherField)) {
- (*output) = value;
- return true;
- }
- }
- return false;
-}
-
-bool filterValues(const vector<Matcher>& matcherFields, const vector<FieldValue>& values,
- HashableDimensionKey* output) {
- size_t num_matches = 0;
- for (const auto& value : values) {
- for (size_t i = 0; i < matcherFields.size(); ++i) {
- const auto& matcher = matcherFields[i];
- if (value.mField.matches(matcher)) {
- output->addValue(value);
- output->mutableValue(num_matches)->mField.setTag(value.mField.getTag());
- output->mutableValue(num_matches)->mField.setField(
- value.mField.getField() & matcher.mMask);
- num_matches++;
- }
- }
- }
- return num_matches > 0;
-}
-
-bool filterPrimaryKey(const std::vector<FieldValue>& values, HashableDimensionKey* output) {
- size_t num_matches = 0;
- const int32_t simpleFieldMask = 0xff7f0000;
- const int32_t attributionUidFieldMask = 0xff7f7f7f;
- for (const auto& value : values) {
- if (value.mAnnotations.isPrimaryField()) {
- output->addValue(value);
- output->mutableValue(num_matches)->mField.setTag(value.mField.getTag());
- const int32_t mask =
- isAttributionUidField(value) ? attributionUidFieldMask : simpleFieldMask;
- output->mutableValue(num_matches)->mField.setField(value.mField.getField() & mask);
- num_matches++;
- }
- }
- return num_matches > 0;
-}
-
-void filterGaugeValues(const std::vector<Matcher>& matcherFields,
- const std::vector<FieldValue>& values, std::vector<FieldValue>* output) {
- for (const auto& field : matcherFields) {
- for (const auto& value : values) {
- if (value.mField.matches(field)) {
- output->push_back(value);
- }
- }
- }
-}
-
-void getDimensionForCondition(const std::vector<FieldValue>& eventValues,
- const Metric2Condition& links,
- HashableDimensionKey* conditionDimension) {
- // Get the dimension first by using dimension from what.
- filterValues(links.metricFields, eventValues, conditionDimension);
-
- size_t count = conditionDimension->getValues().size();
- if (count != links.conditionFields.size()) {
- return;
- }
-
- for (size_t i = 0; i < count; i++) {
- conditionDimension->mutableValue(i)->mField.setField(
- links.conditionFields[i].mMatcher.getField());
- conditionDimension->mutableValue(i)->mField.setTag(
- links.conditionFields[i].mMatcher.getTag());
- }
-}
-
-void getDimensionForState(const std::vector<FieldValue>& eventValues, const Metric2State& link,
- HashableDimensionKey* statePrimaryKey) {
- // First, get the dimension from the event using the "what" fields from the
- // MetricStateLinks.
- filterValues(link.metricFields, eventValues, statePrimaryKey);
-
- // Then check that the statePrimaryKey size equals the number of state fields
- size_t count = statePrimaryKey->getValues().size();
- if (count != link.stateFields.size()) {
- return;
- }
-
- // For each dimension Value in the statePrimaryKey, set the field and tag
- // using the state atom fields from MetricStateLinks.
- for (size_t i = 0; i < count; i++) {
- statePrimaryKey->mutableValue(i)->mField.setField(link.stateFields[i].mMatcher.getField());
- statePrimaryKey->mutableValue(i)->mField.setTag(link.stateFields[i].mMatcher.getTag());
- }
-}
-
-bool containsLinkedStateValues(const HashableDimensionKey& whatKey,
- const HashableDimensionKey& primaryKey,
- const vector<Metric2State>& stateLinks, const int32_t stateAtomId) {
- if (whatKey.getValues().size() < primaryKey.getValues().size()) {
- ALOGE("Contains linked values false: whatKey is too small");
- return false;
- }
-
- for (const auto& primaryValue : primaryKey.getValues()) {
- bool found = false;
- for (const auto& whatValue : whatKey.getValues()) {
- if (linked(stateLinks, stateAtomId, primaryValue.mField, whatValue.mField) &&
- primaryValue.mValue == whatValue.mValue) {
- found = true;
- break;
- }
- }
- if (!found) {
- return false;
- }
- }
- return true;
-}
-
-bool linked(const vector<Metric2State>& stateLinks, const int32_t stateAtomId,
- const Field& stateField, const Field& metricField) {
- for (auto stateLink : stateLinks) {
- if (stateLink.stateAtomId != stateAtomId) {
- continue;
- }
-
- for (size_t i = 0; i < stateLink.stateFields.size(); i++) {
- if (stateLink.stateFields[i].mMatcher == stateField &&
- stateLink.metricFields[i].mMatcher == metricField) {
- return true;
- }
- }
- }
- return false;
-}
-
-bool LessThan(const vector<FieldValue>& s1, const vector<FieldValue>& s2) {
- if (s1.size() != s2.size()) {
- return s1.size() < s2.size();
- }
-
- size_t count = s1.size();
- for (size_t i = 0; i < count; i++) {
- if (s1[i] != s2[i]) {
- return s1[i] < s2[i];
- }
- }
- return false;
-}
-
-bool HashableDimensionKey::operator!=(const HashableDimensionKey& that) const {
- return !((*this) == that);
-}
-
-bool HashableDimensionKey::operator==(const HashableDimensionKey& that) const {
- if (mValues.size() != that.getValues().size()) {
- return false;
- }
- size_t count = mValues.size();
- for (size_t i = 0; i < count; i++) {
- if (mValues[i] != (that.getValues())[i]) {
- return false;
- }
- }
- return true;
-};
-
-bool HashableDimensionKey::operator<(const HashableDimensionKey& that) const {
- return LessThan(getValues(), that.getValues());
-};
-
-bool HashableDimensionKey::contains(const HashableDimensionKey& that) const {
- if (mValues.size() < that.getValues().size()) {
- return false;
- }
-
- if (mValues.size() == that.getValues().size()) {
- return (*this) == that;
- }
-
- for (const auto& value : that.getValues()) {
- bool found = false;
- for (const auto& myValue : mValues) {
- if (value.mField == myValue.mField && value.mValue == myValue.mValue) {
- found = true;
- break;
- }
- }
- if (!found) {
- return false;
- }
- }
-
- return true;
-}
-
-string HashableDimensionKey::toString() const {
- std::string output;
- for (const auto& value : mValues) {
- output += StringPrintf("(%d)%#x->%s ", value.mField.getTag(), value.mField.getField(),
- value.mValue.toString().c_str());
- }
- return output;
-}
-
-bool MetricDimensionKey::operator==(const MetricDimensionKey& that) const {
- return mDimensionKeyInWhat == that.getDimensionKeyInWhat() &&
- mStateValuesKey == that.getStateValuesKey();
-};
-
-string MetricDimensionKey::toString() const {
- return mDimensionKeyInWhat.toString() + mStateValuesKey.toString();
-}
-
-bool MetricDimensionKey::operator<(const MetricDimensionKey& that) const {
- if (mDimensionKeyInWhat < that.getDimensionKeyInWhat()) {
- return true;
- } else if (that.getDimensionKeyInWhat() < mDimensionKeyInWhat) {
- return false;
- }
-
- return mStateValuesKey < that.getStateValuesKey();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/HashableDimensionKey.h b/cmds/statsd/src/HashableDimensionKey.h
deleted file mode 100644
index bd01100..0000000
--- a/cmds/statsd/src/HashableDimensionKey.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/StatsDimensionsValueParcel.h>
-#include <utils/JenkinsHash.h>
-#include <vector>
-#include "android-base/stringprintf.h"
-#include "FieldValue.h"
-#include "logd/LogEvent.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using ::aidl::android::os::StatsDimensionsValueParcel;
-
-struct Metric2Condition {
- int64_t conditionId;
- std::vector<Matcher> metricFields;
- std::vector<Matcher> conditionFields;
-};
-
-struct Metric2State {
- int32_t stateAtomId;
- std::vector<Matcher> metricFields;
- std::vector<Matcher> stateFields;
-};
-
-class HashableDimensionKey {
-public:
- explicit HashableDimensionKey(const std::vector<FieldValue>& values) {
- mValues = values;
- }
-
- HashableDimensionKey() {};
-
- HashableDimensionKey(const HashableDimensionKey& that) : mValues(that.getValues()){};
-
- inline void addValue(const FieldValue& value) {
- mValues.push_back(value);
- }
-
- inline const std::vector<FieldValue>& getValues() const {
- return mValues;
- }
-
- inline std::vector<FieldValue>* mutableValues() {
- return &mValues;
- }
-
- inline FieldValue* mutableValue(size_t i) {
- if (i >= 0 && i < mValues.size()) {
- return &(mValues[i]);
- }
- return nullptr;
- }
-
- StatsDimensionsValueParcel toStatsDimensionsValueParcel() const;
-
- std::string toString() const;
-
- bool operator!=(const HashableDimensionKey& that) const;
-
- bool operator==(const HashableDimensionKey& that) const;
-
- bool operator<(const HashableDimensionKey& that) const;
-
- bool contains(const HashableDimensionKey& that) const;
-
-private:
- std::vector<FieldValue> mValues;
-};
-
-class MetricDimensionKey {
-public:
- explicit MetricDimensionKey(const HashableDimensionKey& dimensionKeyInWhat,
- const HashableDimensionKey& stateValuesKey)
- : mDimensionKeyInWhat(dimensionKeyInWhat), mStateValuesKey(stateValuesKey){};
-
- MetricDimensionKey(){};
-
- MetricDimensionKey(const MetricDimensionKey& that)
- : mDimensionKeyInWhat(that.getDimensionKeyInWhat()),
- mStateValuesKey(that.getStateValuesKey()){};
-
- MetricDimensionKey& operator=(const MetricDimensionKey& from) = default;
-
- std::string toString() const;
-
- inline const HashableDimensionKey& getDimensionKeyInWhat() const {
- return mDimensionKeyInWhat;
- }
-
- inline const HashableDimensionKey& getStateValuesKey() const {
- return mStateValuesKey;
- }
-
- inline HashableDimensionKey* getMutableStateValuesKey() {
- return &mStateValuesKey;
- }
-
- inline void setStateValuesKey(const HashableDimensionKey& key) {
- mStateValuesKey = key;
- }
-
- bool hasStateValuesKey() const {
- return mStateValuesKey.getValues().size() > 0;
- }
-
- bool operator==(const MetricDimensionKey& that) const;
-
- bool operator<(const MetricDimensionKey& that) const;
-
-private:
- HashableDimensionKey mDimensionKeyInWhat;
- HashableDimensionKey mStateValuesKey;
-};
-
-android::hash_t hashDimension(const HashableDimensionKey& key);
-
-/**
- * Returns true if a FieldValue field matches the matcher field.
- * The value of the FieldValue is output.
- */
-bool filterValues(const Matcher& matcherField, const std::vector<FieldValue>& values,
- FieldValue* output);
-
-/**
- * Creating HashableDimensionKeys from FieldValues using matcher.
- *
- * This function may make modifications to the Field if the matcher has Position=FIRST,LAST or ALL
- * in it. This is because: for example, when we create dimension from last uid in attribution chain,
- * In one event, uid 1000 is at position 5 and it's the last
- * In another event, uid 1000 is at position 6, and it's the last
- * these 2 events should be mapped to the same dimension. So we will remove the original position
- * from the dimension key for the uid field (by applying 0x80 bit mask).
- */
-bool filterValues(const std::vector<Matcher>& matcherFields, const std::vector<FieldValue>& values,
- HashableDimensionKey* output);
-
-/**
- * Creating HashableDimensionKeys from State Primary Keys in FieldValues.
- *
- * This function may make modifications to the Field if the matcher has Position=FIRST,LAST or ALL
- * in it. This is because: for example, when we create dimension from last uid in attribution chain,
- * In one event, uid 1000 is at position 5 and it's the last
- * In another event, uid 1000 is at position 6, and it's the last
- * these 2 events should be mapped to the same dimension. So we will remove the original position
- * from the dimension key for the uid field (by applying 0x80 bit mask).
- */
-bool filterPrimaryKey(const std::vector<FieldValue>& values, HashableDimensionKey* output);
-
-/**
- * Filter the values from FieldValues using the matchers.
- *
- * In contrast to the above function, this function will not do any modification to the original
- * data. Considering it as taking a snapshot on the atom event.
- */
-void filterGaugeValues(const std::vector<Matcher>& matchers, const std::vector<FieldValue>& values,
- std::vector<FieldValue>* output);
-
-void getDimensionForCondition(const std::vector<FieldValue>& eventValues,
- const Metric2Condition& links,
- HashableDimensionKey* conditionDimension);
-
-/**
- * Get dimension values using metric's "what" fields and fill statePrimaryKey's
- * mField information using "state" fields.
- */
-void getDimensionForState(const std::vector<FieldValue>& eventValues, const Metric2State& link,
- HashableDimensionKey* statePrimaryKey);
-
-/**
- * Returns true if the primaryKey values are a subset of the whatKey values.
- * The values from the primaryKey come from the state atom, so we need to
- * check that a link exists between the state atom field and what atom field.
- *
- * Example:
- * whatKey = [Atom: 10, {uid: 1005, wakelock_name: "compose"}]
- * statePrimaryKey = [Atom: 27, {uid: 1005}]
- * Returns true IF one of the Metric2State links Atom 10's uid to Atom 27's uid
- *
- * Example:
- * whatKey = [Atom: 10, {uid: 1005, wakelock_name: "compose"}]
- * statePrimaryKey = [Atom: 59, {uid: 1005, package_name: "system"}]
- * Returns false
- */
-bool containsLinkedStateValues(const HashableDimensionKey& whatKey,
- const HashableDimensionKey& primaryKey,
- const std::vector<Metric2State>& stateLinks,
- const int32_t stateAtomId);
-
-/**
- * Returns true if there is a Metric2State link that links the stateField and
- * the metricField (they are equal fields from different atoms).
- */
-bool linked(const std::vector<Metric2State>& stateLinks, const int32_t stateAtomId,
- const Field& stateField, const Field& metricField);
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-namespace std {
-
-using android::os::statsd::HashableDimensionKey;
-using android::os::statsd::MetricDimensionKey;
-
-template <>
-struct hash<HashableDimensionKey> {
- std::size_t operator()(const HashableDimensionKey& key) const {
- return hashDimension(key);
- }
-};
-
-template <>
-struct hash<MetricDimensionKey> {
- std::size_t operator()(const MetricDimensionKey& key) const {
- android::hash_t hash = hashDimension(key.getDimensionKeyInWhat());
- hash = android::JenkinsHashMix(hash, hashDimension(key.getStateValuesKey()));
- return android::JenkinsHashWhiten(hash);
- }
-};
-} // namespace std
diff --git a/cmds/statsd/src/Log.h b/cmds/statsd/src/Log.h
deleted file mode 100644
index 87f4cba..0000000
--- a/cmds/statsd/src/Log.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * This file must be included at the top of the file. Other header files
- * occasionally include log.h, and if LOG_TAG isn't set when that happens
- * we'll get a preprocesser error when we try to define it here.
- */
-
-#pragma once
-
-#define LOG_TAG "statsd"
-
-#include <log/log.h>
-
-// Use the local value to turn on/off debug logs instead of using log.tag. properties.
-// The advantage is that in production compiler can remove the logging code if the local
-// DEBUG/VERBOSE is false.
-#define VLOG(...) \
- if (DEBUG) ALOGD(__VA_ARGS__);
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
deleted file mode 100644
index e7b32c5..0000000
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ /dev/null
@@ -1,1097 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsLogProcessor.h"
-
-#include <android-base/file.h>
-#include <cutils/multiuser.h>
-#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
-#include <frameworks/base/cmds/statsd/src/experiment_ids.pb.h>
-
-#include "android-base/stringprintf.h"
-#include "external/StatsPullerManager.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "metrics/CountMetricProducer.h"
-#include "StatsService.h"
-#include "state/StateManager.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "statslog_statsd.h"
-#include "storage/StorageManager.h"
-
-using namespace android;
-using android::base::StringPrintf;
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for ConfigMetricsReportList
-const int FIELD_ID_CONFIG_KEY = 1;
-const int FIELD_ID_REPORTS = 2;
-// for ConfigKey
-const int FIELD_ID_UID = 1;
-const int FIELD_ID_ID = 2;
-// for ConfigMetricsReport
-// const int FIELD_ID_METRICS = 1; // written in MetricsManager.cpp
-const int FIELD_ID_UID_MAP = 2;
-const int FIELD_ID_LAST_REPORT_ELAPSED_NANOS = 3;
-const int FIELD_ID_CURRENT_REPORT_ELAPSED_NANOS = 4;
-const int FIELD_ID_LAST_REPORT_WALL_CLOCK_NANOS = 5;
-const int FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS = 6;
-const int FIELD_ID_DUMP_REPORT_REASON = 8;
-const int FIELD_ID_STRINGS = 9;
-
-// for ActiveConfigList
-const int FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG = 1;
-
-// for permissions checks
-constexpr const char* kPermissionDump = "android.permission.DUMP";
-constexpr const char* kPermissionUsage = "android.permission.PACKAGE_USAGE_STATS";
-
-#define NS_PER_HOUR 3600 * NS_PER_SEC
-
-#define STATS_ACTIVE_METRIC_DIR "/data/misc/stats-active-metric"
-#define STATS_METADATA_DIR "/data/misc/stats-metadata"
-
-// Cool down period for writing data to disk to avoid overwriting files.
-#define WRITE_DATA_COOL_DOWN_SEC 5
-
-StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap,
- const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& periodicAlarmMonitor,
- const int64_t timeBaseNs,
- const std::function<bool(const ConfigKey&)>& sendBroadcast,
- const std::function<bool(
- const int&, const vector<int64_t>&)>& activateBroadcast)
- : mUidMap(uidMap),
- mPullerManager(pullerManager),
- mAnomalyAlarmMonitor(anomalyAlarmMonitor),
- mPeriodicAlarmMonitor(periodicAlarmMonitor),
- mSendBroadcast(sendBroadcast),
- mSendActivationBroadcast(activateBroadcast),
- mTimeBaseNs(timeBaseNs),
- mLargestTimestampSeen(0),
- mLastTimestampSeen(0) {
- mPullerManager->ForceClearPullerCache();
- StateManager::getInstance().updateLogSources(uidMap);
-}
-
-StatsLogProcessor::~StatsLogProcessor() {
-}
-
-static void flushProtoToBuffer(ProtoOutputStream& proto, vector<uint8_t>* outData) {
- outData->clear();
- outData->resize(proto.size());
- size_t pos = 0;
- sp<android::util::ProtoReader> reader = proto.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((*outData)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-}
-
-void StatsLogProcessor::onAnomalyAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- for (const auto& itr : mMetricsManagers) {
- itr.second->onAnomalyAlarmFired(timestampNs, alarmSet);
- }
-}
-void StatsLogProcessor::onPeriodicAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
-
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- for (const auto& itr : mMetricsManagers) {
- itr.second->onPeriodicAlarmFired(timestampNs, alarmSet);
- }
-}
-
-void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
- if (std::pair<int, int> indexRange; event->hasAttributionChain(&indexRange)) {
- vector<FieldValue>* const fieldValues = event->getMutableValues();
- for (int i = indexRange.first; i <= indexRange.second; i++) {
- FieldValue& fieldValue = fieldValues->at(i);
- if (isAttributionUidField(fieldValue)) {
- const int hostUid = mUidMap->getHostUidOrSelf(fieldValue.mValue.int_value);
- fieldValue.mValue.setInt(hostUid);
- }
- }
- } else {
- int uidFieldIndex = event->getUidFieldIndex();
- if (uidFieldIndex != -1) {
- Value& value = (*event->getMutableValues())[uidFieldIndex].mValue;
- const int hostUid = mUidMap->getHostUidOrSelf(value.int_value);
- value.setInt(hostUid);
- }
- }
-}
-
-void StatsLogProcessor::onIsolatedUidChangedEventLocked(const LogEvent& event) {
- status_t err = NO_ERROR, err2 = NO_ERROR, err3 = NO_ERROR;
- bool is_create = event.GetBool(3, &err);
- auto parent_uid = int(event.GetLong(1, &err2));
- auto isolated_uid = int(event.GetLong(2, &err3));
- if (err == NO_ERROR && err2 == NO_ERROR && err3 == NO_ERROR) {
- if (is_create) {
- mUidMap->assignIsolatedUid(isolated_uid, parent_uid);
- } else {
- mUidMap->removeIsolatedUid(isolated_uid);
- }
- } else {
- ALOGE("Failed to parse uid in the isolated uid change event.");
- }
-}
-
-void StatsLogProcessor::onBinaryPushStateChangedEventLocked(LogEvent* event) {
- pid_t pid = event->GetPid();
- uid_t uid = event->GetUid();
- if (!checkPermissionForIds(kPermissionDump, pid, uid) ||
- !checkPermissionForIds(kPermissionUsage, pid, uid)) {
- return;
- }
- // The Get* functions don't modify the status on success, they only write in
- // failure statuses, so we can use one status variable for all calls then
- // check if it is no longer NO_ERROR.
- status_t err = NO_ERROR;
- InstallTrainInfo trainInfo;
- trainInfo.trainName = string(event->GetString(1 /*train name field id*/, &err));
- trainInfo.trainVersionCode = event->GetLong(2 /*train version field id*/, &err);
- trainInfo.requiresStaging = event->GetBool(3 /*requires staging field id*/, &err);
- trainInfo.rollbackEnabled = event->GetBool(4 /*rollback enabled field id*/, &err);
- trainInfo.requiresLowLatencyMonitor =
- event->GetBool(5 /*requires low latency monitor field id*/, &err);
- trainInfo.status = int32_t(event->GetLong(6 /*state field id*/, &err));
- std::vector<uint8_t> trainExperimentIdBytes =
- event->GetStorage(7 /*experiment ids field id*/, &err);
- bool is_rollback = event->GetBool(10 /*is rollback field id*/, &err);
-
- if (err != NO_ERROR) {
- ALOGE("Failed to parse fields in binary push state changed log event");
- return;
- }
- ExperimentIds trainExperimentIds;
- if (!trainExperimentIds.ParseFromArray(trainExperimentIdBytes.data(),
- trainExperimentIdBytes.size())) {
- ALOGE("Failed to parse experimentids in binary push state changed.");
- return;
- }
- trainInfo.experimentIds = {trainExperimentIds.experiment_id().begin(),
- trainExperimentIds.experiment_id().end()};
-
- // Update the train info on disk and get any data the logevent is missing.
- getAndUpdateTrainInfoOnDisk(is_rollback, &trainInfo);
-
- std::vector<uint8_t> trainExperimentIdProto;
- writeExperimentIdsToProto(trainInfo.experimentIds, &trainExperimentIdProto);
- int32_t userId = multiuser_get_user_id(uid);
-
- event->updateValue(2 /*train version field id*/, trainInfo.trainVersionCode, LONG);
- event->updateValue(7 /*experiment ids field id*/, trainExperimentIdProto, STORAGE);
- event->updateValue(8 /*user id field id*/, userId, INT);
-
- // If this event is a rollback event, then the following bits in the event
- // are invalid and we will need to update them with the values we pulled
- // from disk.
- if (is_rollback) {
- int bit = trainInfo.requiresStaging ? 1 : 0;
- event->updateValue(3 /*requires staging field id*/, bit, INT);
- bit = trainInfo.rollbackEnabled ? 1 : 0;
- event->updateValue(4 /*rollback enabled field id*/, bit, INT);
- bit = trainInfo.requiresLowLatencyMonitor ? 1 : 0;
- event->updateValue(5 /*requires low latency monitor field id*/, bit, INT);
- }
-}
-
-void StatsLogProcessor::getAndUpdateTrainInfoOnDisk(bool is_rollback,
- InstallTrainInfo* trainInfo) {
- // If the train name is empty, we don't know which train to attribute the
- // event to, so return early.
- if (trainInfo->trainName.empty()) {
- return;
- }
- bool readTrainInfoSuccess = false;
- InstallTrainInfo trainInfoOnDisk;
- readTrainInfoSuccess = StorageManager::readTrainInfo(trainInfo->trainName, trainInfoOnDisk);
-
- bool resetExperimentIds = false;
- if (readTrainInfoSuccess) {
- // Keep the old train version if we received an empty version.
- if (trainInfo->trainVersionCode == -1) {
- trainInfo->trainVersionCode = trainInfoOnDisk.trainVersionCode;
- } else if (trainInfo->trainVersionCode != trainInfoOnDisk.trainVersionCode) {
- // Reset experiment ids if we receive a new non-empty train version.
- resetExperimentIds = true;
- }
-
- // Reset if we received a different experiment id.
- if (!trainInfo->experimentIds.empty() &&
- (trainInfoOnDisk.experimentIds.empty() ||
- trainInfo->experimentIds.at(0) != trainInfoOnDisk.experimentIds[0])) {
- resetExperimentIds = true;
- }
- }
-
- // Find the right experiment IDs
- if ((!resetExperimentIds || is_rollback) && readTrainInfoSuccess) {
- trainInfo->experimentIds = trainInfoOnDisk.experimentIds;
- }
-
- if (!trainInfo->experimentIds.empty()) {
- int64_t firstId = trainInfo->experimentIds.at(0);
- auto& ids = trainInfo->experimentIds;
- switch (trainInfo->status) {
- case android::os::statsd::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALL_SUCCESS:
- if (find(ids.begin(), ids.end(), firstId + 1) == ids.end()) {
- ids.push_back(firstId + 1);
- }
- break;
- case android::os::statsd::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALLER_ROLLBACK_INITIATED:
- if (find(ids.begin(), ids.end(), firstId + 2) == ids.end()) {
- ids.push_back(firstId + 2);
- }
- break;
- case android::os::statsd::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALLER_ROLLBACK_SUCCESS:
- if (find(ids.begin(), ids.end(), firstId + 3) == ids.end()) {
- ids.push_back(firstId + 3);
- }
- break;
- }
- }
-
- // If this event is a rollback event, the following fields are invalid and
- // need to be replaced by the fields stored to disk.
- if (is_rollback) {
- trainInfo->requiresStaging = trainInfoOnDisk.requiresStaging;
- trainInfo->rollbackEnabled = trainInfoOnDisk.rollbackEnabled;
- trainInfo->requiresLowLatencyMonitor = trainInfoOnDisk.requiresLowLatencyMonitor;
- }
-
- StorageManager::writeTrainInfo(*trainInfo);
-}
-
-void StatsLogProcessor::onWatchdogRollbackOccurredLocked(LogEvent* event) {
- pid_t pid = event->GetPid();
- uid_t uid = event->GetUid();
- if (!checkPermissionForIds(kPermissionDump, pid, uid) ||
- !checkPermissionForIds(kPermissionUsage, pid, uid)) {
- return;
- }
- // The Get* functions don't modify the status on success, they only write in
- // failure statuses, so we can use one status variable for all calls then
- // check if it is no longer NO_ERROR.
- status_t err = NO_ERROR;
- int32_t rollbackType = int32_t(event->GetInt(1 /*rollback type field id*/, &err));
- string packageName = string(event->GetString(2 /*package name field id*/, &err));
-
- if (err != NO_ERROR) {
- ALOGE("Failed to parse fields in watchdog rollback occurred log event");
- return;
- }
-
- vector<int64_t> experimentIds =
- processWatchdogRollbackOccurred(rollbackType, packageName);
- vector<uint8_t> experimentIdProto;
- writeExperimentIdsToProto(experimentIds, &experimentIdProto);
-
- event->updateValue(6 /*experiment ids field id*/, experimentIdProto, STORAGE);
-}
-
-vector<int64_t> StatsLogProcessor::processWatchdogRollbackOccurred(const int32_t rollbackTypeIn,
- const string& packageNameIn) {
- // If the package name is empty, we can't attribute it to any train, so
- // return early.
- if (packageNameIn.empty()) {
- return vector<int64_t>();
- }
- bool readTrainInfoSuccess = false;
- InstallTrainInfo trainInfoOnDisk;
- // We use the package name of the event as the train name.
- readTrainInfoSuccess = StorageManager::readTrainInfo(packageNameIn, trainInfoOnDisk);
-
- if (!readTrainInfoSuccess) {
- return vector<int64_t>();
- }
-
- if (trainInfoOnDisk.experimentIds.empty()) {
- return vector<int64_t>();
- }
-
- int64_t firstId = trainInfoOnDisk.experimentIds[0];
- auto& ids = trainInfoOnDisk.experimentIds;
- switch (rollbackTypeIn) {
- case android::os::statsd::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE:
- if (find(ids.begin(), ids.end(), firstId + 4) == ids.end()) {
- ids.push_back(firstId + 4);
- }
- StorageManager::writeTrainInfo(trainInfoOnDisk);
- break;
- case android::os::statsd::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS:
- if (find(ids.begin(), ids.end(), firstId + 5) == ids.end()) {
- ids.push_back(firstId + 5);
- }
- StorageManager::writeTrainInfo(trainInfoOnDisk);
- break;
- }
-
- return trainInfoOnDisk.experimentIds;
-}
-
-void StatsLogProcessor::resetConfigs() {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- resetConfigsLocked(getElapsedRealtimeNs());
-}
-
-void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs) {
- std::vector<ConfigKey> configKeys;
- for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
- configKeys.push_back(it->first);
- }
- resetConfigsLocked(timestampNs, configKeys);
-}
-
-void StatsLogProcessor::OnLogEvent(LogEvent* event) {
- OnLogEvent(event, getElapsedRealtimeNs());
-}
-
-void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
-
- // Tell StatsdStats about new event
- const int64_t eventElapsedTimeNs = event->GetElapsedTimestampNs();
- int atomId = event->GetTagId();
- StatsdStats::getInstance().noteAtomLogged(atomId, eventElapsedTimeNs / NS_PER_SEC);
- if (!event->isValid()) {
- StatsdStats::getInstance().noteAtomError(atomId);
- return;
- }
-
- // Hard-coded logic to update train info on disk and fill in any information
- // this log event may be missing.
- if (atomId == android::os::statsd::util::BINARY_PUSH_STATE_CHANGED) {
- onBinaryPushStateChangedEventLocked(event);
- }
-
- // Hard-coded logic to update experiment ids on disk for certain rollback
- // types and fill the rollback atom with experiment ids
- if (atomId == android::os::statsd::util::WATCHDOG_ROLLBACK_OCCURRED) {
- onWatchdogRollbackOccurredLocked(event);
- }
-
-#ifdef VERY_VERBOSE_PRINTING
- if (mPrintAllLogs) {
- ALOGI("%s", event->ToString().c_str());
- }
-#endif
- resetIfConfigTtlExpiredLocked(eventElapsedTimeNs);
-
- // Hard-coded logic to update the isolated uid's in the uid-map.
- // The field numbers need to be currently updated by hand with atoms.proto
- if (atomId == android::os::statsd::util::ISOLATED_UID_CHANGED) {
- onIsolatedUidChangedEventLocked(*event);
- } else {
- // Map the isolated uid to host uid if necessary.
- mapIsolatedUidToHostUidIfNecessaryLocked(event);
- }
-
- StateManager::getInstance().onLogEvent(*event);
-
- if (mMetricsManagers.empty()) {
- return;
- }
-
- int64_t curTimeSec = getElapsedRealtimeSec();
- if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) {
- mPullerManager->ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC);
- mLastPullerCacheClearTimeSec = curTimeSec;
- }
-
- std::unordered_set<int> uidsWithActiveConfigsChanged;
- std::unordered_map<int, std::vector<int64_t>> activeConfigsPerUid;
- // pass the event to metrics managers.
- for (auto& pair : mMetricsManagers) {
- int uid = pair.first.GetUid();
- int64_t configId = pair.first.GetId();
- bool isPrevActive = pair.second->isActive();
- pair.second->onLogEvent(*event);
- bool isCurActive = pair.second->isActive();
- // Map all active configs by uid.
- if (isCurActive) {
- auto activeConfigs = activeConfigsPerUid.find(uid);
- if (activeConfigs != activeConfigsPerUid.end()) {
- activeConfigs->second.push_back(configId);
- } else {
- vector<int64_t> newActiveConfigs;
- newActiveConfigs.push_back(configId);
- activeConfigsPerUid[uid] = newActiveConfigs;
- }
- }
- // The activation state of this config changed.
- if (isPrevActive != isCurActive) {
- VLOG("Active status changed for uid %d", uid);
- uidsWithActiveConfigsChanged.insert(uid);
- StatsdStats::getInstance().noteActiveStatusChanged(pair.first, isCurActive);
- }
- flushIfNecessaryLocked(pair.first, *(pair.second));
- }
-
- // Don't use the event timestamp for the guardrail.
- for (int uid : uidsWithActiveConfigsChanged) {
- // Send broadcast so that receivers can pull data.
- auto lastBroadcastTime = mLastActivationBroadcastTimes.find(uid);
- if (lastBroadcastTime != mLastActivationBroadcastTimes.end()) {
- if (elapsedRealtimeNs - lastBroadcastTime->second <
- StatsdStats::kMinActivationBroadcastPeriodNs) {
- StatsdStats::getInstance().noteActivationBroadcastGuardrailHit(uid);
- VLOG("StatsD would've sent an activation broadcast but the rate limit stopped us.");
- return;
- }
- }
- auto activeConfigs = activeConfigsPerUid.find(uid);
- if (activeConfigs != activeConfigsPerUid.end()) {
- if (mSendActivationBroadcast(uid, activeConfigs->second)) {
- VLOG("StatsD sent activation notice for uid %d", uid);
- mLastActivationBroadcastTimes[uid] = elapsedRealtimeNs;
- }
- } else {
- std::vector<int64_t> emptyActiveConfigs;
- if (mSendActivationBroadcast(uid, emptyActiveConfigs)) {
- VLOG("StatsD sent EMPTY activation notice for uid %d", uid);
- mLastActivationBroadcastTimes[uid] = elapsedRealtimeNs;
- }
- }
- }
-}
-
-void StatsLogProcessor::GetActiveConfigs(const int uid, vector<int64_t>& outActiveConfigs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- GetActiveConfigsLocked(uid, outActiveConfigs);
-}
-
-void StatsLogProcessor::GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs) {
- outActiveConfigs.clear();
- for (auto& pair : mMetricsManagers) {
- if (pair.first.GetUid() == uid && pair.second->isActive()) {
- outActiveConfigs.push_back(pair.first.GetId());
- }
- }
-}
-
-void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- WriteDataToDiskLocked(key, timestampNs, CONFIG_UPDATED, NO_TIME_CONSTRAINTS);
- OnConfigUpdatedLocked(timestampNs, key, config);
-}
-
-void StatsLogProcessor::OnConfigUpdatedLocked(
- const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config) {
- VLOG("Updated configuration for key %s", key.ToString().c_str());
- sp<MetricsManager> newMetricsManager =
- new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager,
- mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
- if (newMetricsManager->isConfigValid()) {
- newMetricsManager->init();
- mUidMap->OnConfigUpdated(key);
- newMetricsManager->refreshTtl(timestampNs);
- mMetricsManagers[key] = newMetricsManager;
- VLOG("StatsdConfig valid");
- } else {
- // If there is any error in the config, don't use it.
- // Remove any existing config with the same key.
- ALOGE("StatsdConfig NOT valid");
- mMetricsManagers.erase(key);
- }
-}
-
-size_t StatsLogProcessor::GetMetricsSize(const ConfigKey& key) const {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- ALOGW("Config source %s does not exist", key.ToString().c_str());
- return 0;
- }
- return it->second->byteSize();
-}
-
-void StatsLogProcessor::dumpStates(int out, bool verbose) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- FILE* fout = fdopen(out, "w");
- if (fout == NULL) {
- return;
- }
- fprintf(fout, "MetricsManager count: %lu\n", (unsigned long)mMetricsManagers.size());
- for (auto metricsManager : mMetricsManagers) {
- metricsManager.second->dumpStates(fout, verbose);
- }
-
- fclose(fout);
-}
-
-/*
- * onDumpReport dumps serialized ConfigMetricsReportList into proto.
- */
-void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency,
- ProtoOutputStream* proto) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
-
- // Start of ConfigKey.
- uint64_t configKeyToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid());
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId());
- proto->end(configKeyToken);
- // End of ConfigKey.
-
- bool keepFile = false;
- auto it = mMetricsManagers.find(key);
- if (it != mMetricsManagers.end() && it->second->shouldPersistLocalHistory()) {
- keepFile = true;
- }
-
- // Then, check stats-data directory to see there's any file containing
- // ConfigMetricsReport from previous shutdowns to concatenate to reports.
- StorageManager::appendConfigMetricsReport(
- key, proto, erase_data && !keepFile /* should remove file after appending it */,
- dumpReportReason == ADB_DUMP /*if caller is adb*/);
-
- if (it != mMetricsManagers.end()) {
- // This allows another broadcast to be sent within the rate-limit period if we get close to
- // filling the buffer again soon.
- mLastBroadcastTimes.erase(key);
-
- vector<uint8_t> buffer;
- onConfigMetricsReportLocked(key, dumpTimeStampNs, include_current_partial_bucket,
- erase_data, dumpReportReason, dumpLatency,
- false /* is this data going to be saved on disk */, &buffer);
- proto->write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS,
- reinterpret_cast<char*>(buffer.data()), buffer.size());
- } else {
- ALOGW("Config source %s does not exist", key.ToString().c_str());
- }
-}
-
-/*
- * onDumpReport dumps serialized ConfigMetricsReportList into outData.
- */
-void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency,
- vector<uint8_t>* outData) {
- ProtoOutputStream proto;
- onDumpReport(key, dumpTimeStampNs, include_current_partial_bucket, erase_data,
- dumpReportReason, dumpLatency, &proto);
-
- if (outData != nullptr) {
- flushProtoToBuffer(proto, outData);
- VLOG("output data size %zu", outData->size());
- }
-
- StatsdStats::getInstance().noteMetricsReportSent(key, proto.size());
-}
-
-/*
- * onConfigMetricsReportLocked dumps serialized ConfigMetricsReport into outData.
- */
-void StatsLogProcessor::onConfigMetricsReportLocked(
- const ConfigKey& key, const int64_t dumpTimeStampNs,
- const bool include_current_partial_bucket, const bool erase_data,
- const DumpReportReason dumpReportReason, const DumpLatency dumpLatency,
- const bool dataSavedOnDisk, vector<uint8_t>* buffer) {
- // We already checked whether key exists in mMetricsManagers in
- // WriteDataToDisk.
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- return;
- }
- int64_t lastReportTimeNs = it->second->getLastReportTimeNs();
- int64_t lastReportWallClockNs = it->second->getLastReportWallClockNs();
-
- std::set<string> str_set;
-
- ProtoOutputStream tempProto;
- // First, fill in ConfigMetricsReport using current data on memory, which
- // starts from filling in StatsLogReport's.
- it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
- dumpLatency, &str_set, &tempProto);
-
- // Fill in UidMap if there is at least one metric to report.
- // This skips the uid map if it's an empty config.
- if (it->second->getNumMetrics() > 0) {
- uint64_t uidMapToken = tempProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_UID_MAP);
- mUidMap->appendUidMap(
- dumpTimeStampNs, key, it->second->hashStringInReport() ? &str_set : nullptr,
- it->second->versionStringsInReport(), it->second->installerInReport(), &tempProto);
- tempProto.end(uidMapToken);
- }
-
- // Fill in the timestamps.
- tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_LAST_REPORT_ELAPSED_NANOS,
- (long long)lastReportTimeNs);
- tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_CURRENT_REPORT_ELAPSED_NANOS,
- (long long)dumpTimeStampNs);
- tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_LAST_REPORT_WALL_CLOCK_NANOS,
- (long long)lastReportWallClockNs);
- tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS,
- (long long)getWallClockNs());
- // Dump report reason
- tempProto.write(FIELD_TYPE_INT32 | FIELD_ID_DUMP_REPORT_REASON, dumpReportReason);
-
- for (const auto& str : str_set) {
- tempProto.write(FIELD_TYPE_STRING | FIELD_COUNT_REPEATED | FIELD_ID_STRINGS, str);
- }
-
- flushProtoToBuffer(tempProto, buffer);
-
- // save buffer to disk if needed
- if (erase_data && !dataSavedOnDisk && it->second->shouldPersistLocalHistory()) {
- VLOG("save history to disk");
- string file_name = StorageManager::getDataHistoryFileName((long)getWallClockSec(),
- key.GetUid(), key.GetId());
- StorageManager::writeFile(file_name.c_str(), buffer->data(), buffer->size());
- }
-}
-
-void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs,
- const std::vector<ConfigKey>& configs) {
- for (const auto& key : configs) {
- StatsdConfig config;
- if (StorageManager::readConfigFromDisk(key, &config)) {
- OnConfigUpdatedLocked(timestampNs, key, config);
- StatsdStats::getInstance().noteConfigReset(key);
- } else {
- ALOGE("Failed to read backup config from disk for : %s", key.ToString().c_str());
- auto it = mMetricsManagers.find(key);
- if (it != mMetricsManagers.end()) {
- it->second->refreshTtl(timestampNs);
- }
- }
- }
-}
-
-void StatsLogProcessor::resetIfConfigTtlExpiredLocked(const int64_t timestampNs) {
- std::vector<ConfigKey> configKeysTtlExpired;
- for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
- if (it->second != nullptr && !it->second->isInTtl(timestampNs)) {
- configKeysTtlExpired.push_back(it->first);
- }
- }
- if (configKeysTtlExpired.size() > 0) {
- WriteDataToDiskLocked(CONFIG_RESET, NO_TIME_CONSTRAINTS);
- resetConfigsLocked(timestampNs, configKeysTtlExpired);
- }
-}
-
-void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- auto it = mMetricsManagers.find(key);
- if (it != mMetricsManagers.end()) {
- WriteDataToDiskLocked(key, getElapsedRealtimeNs(), CONFIG_REMOVED,
- NO_TIME_CONSTRAINTS);
- mMetricsManagers.erase(it);
- mUidMap->OnConfigRemoved(key);
- }
- StatsdStats::getInstance().noteConfigRemoved(key);
-
- mLastBroadcastTimes.erase(key);
-
- int uid = key.GetUid();
- bool lastConfigForUid = true;
- for (auto it : mMetricsManagers) {
- if (it.first.GetUid() == uid) {
- lastConfigForUid = false;
- break;
- }
- }
- if (lastConfigForUid) {
- mLastActivationBroadcastTimes.erase(uid);
- }
-
- if (mMetricsManagers.empty()) {
- mPullerManager->ForceClearPullerCache();
- }
-}
-
-void StatsLogProcessor::flushIfNecessaryLocked(const ConfigKey& key,
- MetricsManager& metricsManager) {
- int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
- auto lastCheckTime = mLastByteSizeTimes.find(key);
- if (lastCheckTime != mLastByteSizeTimes.end()) {
- if (elapsedRealtimeNs - lastCheckTime->second < StatsdStats::kMinByteSizeCheckPeriodNs) {
- return;
- }
- }
-
- // We suspect that the byteSize() computation is expensive, so we set a rate limit.
- size_t totalBytes = metricsManager.byteSize();
- mLastByteSizeTimes[key] = elapsedRealtimeNs;
- bool requestDump = false;
- if (totalBytes > StatsdStats::kMaxMetricsBytesPerConfig) {
- // Too late. We need to start clearing data.
- metricsManager.dropData(elapsedRealtimeNs);
- StatsdStats::getInstance().noteDataDropped(key, totalBytes);
- VLOG("StatsD had to toss out metrics for %s", key.ToString().c_str());
- } else if ((totalBytes > StatsdStats::kBytesPerConfigTriggerGetData) ||
- (mOnDiskDataConfigs.find(key) != mOnDiskDataConfigs.end())) {
- // Request to send a broadcast if:
- // 1. in memory data > threshold OR
- // 2. config has old data report on disk.
- requestDump = true;
- }
-
- if (requestDump) {
- // Send broadcast so that receivers can pull data.
- auto lastBroadcastTime = mLastBroadcastTimes.find(key);
- if (lastBroadcastTime != mLastBroadcastTimes.end()) {
- if (elapsedRealtimeNs - lastBroadcastTime->second <
- StatsdStats::kMinBroadcastPeriodNs) {
- VLOG("StatsD would've sent a broadcast but the rate limit stopped us.");
- return;
- }
- }
- if (mSendBroadcast(key)) {
- mOnDiskDataConfigs.erase(key);
- VLOG("StatsD triggered data fetch for %s", key.ToString().c_str());
- mLastBroadcastTimes[key] = elapsedRealtimeNs;
- StatsdStats::getInstance().noteBroadcastSent(key);
- }
- }
-}
-
-void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key,
- const int64_t timestampNs,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency) {
- if (mMetricsManagers.find(key) == mMetricsManagers.end() ||
- !mMetricsManagers.find(key)->second->shouldWriteToDisk()) {
- return;
- }
- vector<uint8_t> buffer;
- onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/,
- true /* erase_data */, dumpReportReason, dumpLatency, true,
- &buffer);
- string file_name =
- StorageManager::getDataFileName((long)getWallClockSec(), key.GetUid(), key.GetId());
- StorageManager::writeFile(file_name.c_str(), buffer.data(), buffer.size());
-
- // We were able to write the ConfigMetricsReport to disk, so we should trigger collection ASAP.
- mOnDiskDataConfigs.insert(key);
-}
-
-void StatsLogProcessor::SaveActiveConfigsToDisk(int64_t currentTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- const int64_t timeNs = getElapsedRealtimeNs();
- // Do not write to disk if we already have in the last few seconds.
- if (static_cast<unsigned long long> (timeNs) <
- mLastActiveMetricsWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
- ALOGI("Statsd skipping writing active metrics to disk. Already wrote data in last %d seconds",
- WRITE_DATA_COOL_DOWN_SEC);
- return;
- }
- mLastActiveMetricsWriteNs = timeNs;
-
- ProtoOutputStream proto;
- WriteActiveConfigsToProtoOutputStreamLocked(currentTimeNs, DEVICE_SHUTDOWN, &proto);
-
- string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
- StorageManager::deleteFile(file_name.c_str());
- android::base::unique_fd fd(
- open(file_name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR));
- if (fd == -1) {
- ALOGE("Attempt to write %s but failed", file_name.c_str());
- return;
- }
- proto.flush(fd.get());
-}
-
-void StatsLogProcessor::SaveMetadataToDisk(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- // Do not write to disk if we already have in the last few seconds.
- if (static_cast<unsigned long long> (systemElapsedTimeNs) <
- mLastMetadataWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
- ALOGI("Statsd skipping writing metadata to disk. Already wrote data in last %d seconds",
- WRITE_DATA_COOL_DOWN_SEC);
- return;
- }
- mLastMetadataWriteNs = systemElapsedTimeNs;
-
- metadata::StatsMetadataList metadataList;
- WriteMetadataToProtoLocked(
- currentWallClockTimeNs, systemElapsedTimeNs, &metadataList);
-
- string file_name = StringPrintf("%s/metadata", STATS_METADATA_DIR);
- StorageManager::deleteFile(file_name.c_str());
-
- if (metadataList.stats_metadata_size() == 0) {
- // Skip the write if we have nothing to write.
- return;
- }
-
- std::string data;
- metadataList.SerializeToString(&data);
- StorageManager::writeFile(file_name.c_str(), data.c_str(), data.size());
-}
-
-void StatsLogProcessor::WriteMetadataToProto(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadataList* metadataList) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- WriteMetadataToProtoLocked(currentWallClockTimeNs, systemElapsedTimeNs, metadataList);
-}
-
-void StatsLogProcessor::WriteMetadataToProtoLocked(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadataList* metadataList) {
- for (const auto& pair : mMetricsManagers) {
- const sp<MetricsManager>& metricsManager = pair.second;
- metadata::StatsMetadata* statsMetadata = metadataList->add_stats_metadata();
- bool metadataWritten = metricsManager->writeMetadataToProto(currentWallClockTimeNs,
- systemElapsedTimeNs, statsMetadata);
- if (!metadataWritten) {
- metadataList->mutable_stats_metadata()->RemoveLast();
- }
- }
-}
-
-void StatsLogProcessor::LoadMetadataFromDisk(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- string file_name = StringPrintf("%s/metadata", STATS_METADATA_DIR);
- int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
- if (-1 == fd) {
- VLOG("Attempt to read %s but failed", file_name.c_str());
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
- string content;
- if (!android::base::ReadFdToString(fd, &content)) {
- ALOGE("Attempt to read %s but failed", file_name.c_str());
- close(fd);
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
-
- close(fd);
-
- metadata::StatsMetadataList statsMetadataList;
- if (!statsMetadataList.ParseFromString(content)) {
- ALOGE("Attempt to read %s but failed; failed to metadata", file_name.c_str());
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
- SetMetadataStateLocked(statsMetadataList, currentWallClockTimeNs, systemElapsedTimeNs);
- StorageManager::deleteFile(file_name.c_str());
-}
-
-void StatsLogProcessor::SetMetadataState(const metadata::StatsMetadataList& statsMetadataList,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- SetMetadataStateLocked(statsMetadataList, currentWallClockTimeNs, systemElapsedTimeNs);
-}
-
-void StatsLogProcessor::SetMetadataStateLocked(
- const metadata::StatsMetadataList& statsMetadataList,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- for (const metadata::StatsMetadata& metadata : statsMetadataList.stats_metadata()) {
- ConfigKey key(metadata.config_key().uid(), metadata.config_key().config_id());
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- ALOGE("No config found for configKey %s", key.ToString().c_str());
- continue;
- }
- VLOG("Setting metadata %s", key.ToString().c_str());
- it->second->loadMetadata(metadata, currentWallClockTimeNs, systemElapsedTimeNs);
- }
- VLOG("Successfully loaded %d metadata.", statsMetadataList.stats_metadata_size());
-}
-
-void StatsLogProcessor::WriteActiveConfigsToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- WriteActiveConfigsToProtoOutputStreamLocked(currentTimeNs, reason, proto);
-}
-
-void StatsLogProcessor::WriteActiveConfigsToProtoOutputStreamLocked(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
- for (const auto& pair : mMetricsManagers) {
- const sp<MetricsManager>& metricsManager = pair.second;
- uint64_t configToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG);
- metricsManager->writeActiveConfigToProtoOutputStream(currentTimeNs, reason, proto);
- proto->end(configToken);
- }
-}
-void StatsLogProcessor::LoadActiveConfigsFromDisk() {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
- int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
- if (-1 == fd) {
- VLOG("Attempt to read %s but failed", file_name.c_str());
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
- string content;
- if (!android::base::ReadFdToString(fd, &content)) {
- ALOGE("Attempt to read %s but failed", file_name.c_str());
- close(fd);
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
-
- close(fd);
-
- ActiveConfigList activeConfigList;
- if (!activeConfigList.ParseFromString(content)) {
- ALOGE("Attempt to read %s but failed; failed to load active configs", file_name.c_str());
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
- // Passing in mTimeBaseNs only works as long as we only load from disk is when statsd starts.
- SetConfigsActiveStateLocked(activeConfigList, mTimeBaseNs);
- StorageManager::deleteFile(file_name.c_str());
-}
-
-void StatsLogProcessor::SetConfigsActiveState(const ActiveConfigList& activeConfigList,
- int64_t currentTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- SetConfigsActiveStateLocked(activeConfigList, currentTimeNs);
-}
-
-void StatsLogProcessor::SetConfigsActiveStateLocked(const ActiveConfigList& activeConfigList,
- int64_t currentTimeNs) {
- for (int i = 0; i < activeConfigList.config_size(); i++) {
- const auto& config = activeConfigList.config(i);
- ConfigKey key(config.uid(), config.id());
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- ALOGE("No config found for config %s", key.ToString().c_str());
- continue;
- }
- VLOG("Setting active config %s", key.ToString().c_str());
- it->second->loadActiveConfig(config, currentTimeNs);
- }
- VLOG("Successfully loaded %d active configs.", activeConfigList.config_size());
-}
-
-void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency) {
- const int64_t timeNs = getElapsedRealtimeNs();
- // Do not write to disk if we already have in the last few seconds.
- // This is to avoid overwriting files that would have the same name if we
- // write twice in the same second.
- if (static_cast<unsigned long long> (timeNs) <
- mLastWriteTimeNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
- ALOGI("Statsd skipping writing data to disk. Already wrote data in last %d seconds",
- WRITE_DATA_COOL_DOWN_SEC);
- return;
- }
- mLastWriteTimeNs = timeNs;
- for (auto& pair : mMetricsManagers) {
- WriteDataToDiskLocked(pair.first, timeNs, dumpReportReason, dumpLatency);
- }
-}
-
-void StatsLogProcessor::WriteDataToDisk(const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- WriteDataToDiskLocked(dumpReportReason, dumpLatency);
-}
-
-void StatsLogProcessor::informPullAlarmFired(const int64_t timestampNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- mPullerManager->OnAlarmFired(timestampNs);
-}
-
-int64_t StatsLogProcessor::getLastReportTimeNs(const ConfigKey& key) {
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- return 0;
- } else {
- return it->second->getLastReportTimeNs();
- }
-}
-
-void StatsLogProcessor::notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk,
- const int uid, const int64_t version) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- VLOG("Received app upgrade");
- StateManager::getInstance().notifyAppChanged(apk, mUidMap);
- for (const auto& it : mMetricsManagers) {
- it.second->notifyAppUpgrade(eventTimeNs, apk, uid, version);
- }
-}
-
-void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const string& apk,
- const int uid) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- VLOG("Received app removed");
- StateManager::getInstance().notifyAppChanged(apk, mUidMap);
- for (const auto& it : mMetricsManagers) {
- it.second->notifyAppRemoved(eventTimeNs, apk, uid);
- }
-}
-
-void StatsLogProcessor::onUidMapReceived(const int64_t& eventTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- VLOG("Received uid map");
- StateManager::getInstance().updateLogSources(mUidMap);
- for (const auto& it : mMetricsManagers) {
- it.second->onUidMapReceived(eventTimeNs);
- }
-}
-
-void StatsLogProcessor::onStatsdInitCompleted(const int64_t& elapsedTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- VLOG("Received boot completed signal");
- for (const auto& it : mMetricsManagers) {
- it.second->onStatsdInitCompleted(elapsedTimeNs);
- }
-}
-
-void StatsLogProcessor::noteOnDiskData(const ConfigKey& key) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- mOnDiskDataConfigs.insert(key);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
deleted file mode 100644
index 23f2584..0000000
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-#include "config/ConfigListener.h"
-#include "logd/LogEvent.h"
-#include "metrics/MetricsManager.h"
-#include "packages/UidMap.h"
-#include "external/StatsPullerManager.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"
-
-#include <stdio.h>
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-class StatsLogProcessor : public ConfigListener, public virtual PackageInfoListener {
-public:
- StatsLogProcessor(const sp<UidMap>& uidMap, const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& subscriberTriggerAlarmMonitor,
- const int64_t timeBaseNs,
- const std::function<bool(const ConfigKey&)>& sendBroadcast,
- const std::function<bool(const int&,
- const vector<int64_t>&)>& sendActivationBroadcast);
- virtual ~StatsLogProcessor();
-
- void OnLogEvent(LogEvent* event);
-
- void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config);
- void OnConfigRemoved(const ConfigKey& key);
-
- size_t GetMetricsSize(const ConfigKey& key) const;
-
- void GetActiveConfigs(const int uid, vector<int64_t>& outActiveConfigs);
-
- void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
- const bool include_current_partial_bucket, const bool erase_data,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency,
- vector<uint8_t>* outData);
- void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
- const bool include_current_partial_bucket, const bool erase_data,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency,
- ProtoOutputStream* proto);
-
- /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
- void onAnomalyAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
-
- /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */
- void onPeriodicAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
-
- /* Flushes data to disk. Data on memory will be gone after written to disk. */
- void WriteDataToDisk(const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency);
-
- /* Persist configs containing metrics with active activations to disk. */
- void SaveActiveConfigsToDisk(int64_t currentTimeNs);
-
- /* Writes the current active status/ttl for all configs and metrics to ProtoOutputStream. */
- void WriteActiveConfigsToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
- /* Load configs containing metrics with active activations from disk. */
- void LoadActiveConfigsFromDisk();
-
- /* Persist metadata for configs and metrics to disk. */
- void SaveMetadataToDisk(int64_t currentWallClockTimeNs, int64_t systemElapsedTimeNs);
-
- /* Writes the statsd metadata for all configs and metrics to StatsMetadataList. */
- void WriteMetadataToProto(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadataList* metadataList);
-
- /* Load stats metadata for configs and metrics from disk. */
- void LoadMetadataFromDisk(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs);
-
- /* Sets the metadata for all configs and metrics */
- void SetMetadataState(const metadata::StatsMetadataList& statsMetadataList,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs);
-
- /* Sets the active status/ttl for all configs and metrics to the status in ActiveConfigList. */
- void SetConfigsActiveState(const ActiveConfigList& activeConfigList, int64_t currentTimeNs);
-
- /* Notify all MetricsManagers of app upgrades */
- void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
- const int64_t version) override;
-
- /* Notify all MetricsManagers of app removals */
- void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid) override;
-
- /* Notify all MetricsManagers of uid map snapshots received */
- void onUidMapReceived(const int64_t& eventTimeNs) override;
-
- /* Notify all metrics managers of boot completed
- * This will force a bucket split when the boot is finished.
- */
- void onStatsdInitCompleted(const int64_t& elapsedTimeNs);
-
- // Reset all configs.
- void resetConfigs();
-
- inline sp<UidMap> getUidMap() {
- return mUidMap;
- }
-
- void dumpStates(int outFd, bool verbose);
-
- void informPullAlarmFired(const int64_t timestampNs);
-
- int64_t getLastReportTimeNs(const ConfigKey& key);
-
- inline void setPrintLogs(bool enabled) {
-#ifdef VERY_VERBOSE_PRINTING
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- mPrintAllLogs = enabled;
-#endif
- }
-
- // Add a specific config key to the possible configs to dump ASAP.
- void noteOnDiskData(const ConfigKey& key);
-
-private:
- // For testing only.
- inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
- return mAnomalyAlarmMonitor;
- }
-
- inline sp<AlarmMonitor> getPeriodicAlarmMonitor() const {
- return mPeriodicAlarmMonitor;
- }
-
- mutable mutex mMetricsMutex;
-
- std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers;
-
- std::unordered_map<ConfigKey, int64_t> mLastBroadcastTimes;
-
- // Last time we sent a broadcast to this uid that the active configs had changed.
- std::unordered_map<int, int64_t> mLastActivationBroadcastTimes;
-
- // Tracks when we last checked the bytes consumed for each config key.
- std::unordered_map<ConfigKey, int64_t> mLastByteSizeTimes;
-
- // Tracks which config keys has metric reports on disk
- std::set<ConfigKey> mOnDiskDataConfigs;
-
- sp<UidMap> mUidMap; // Reference to the UidMap to lookup app name and version for each uid.
-
- sp<StatsPullerManager> mPullerManager; // Reference to StatsPullerManager
-
- sp<AlarmMonitor> mAnomalyAlarmMonitor;
-
- sp<AlarmMonitor> mPeriodicAlarmMonitor;
-
- void OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs);
-
- void resetIfConfigTtlExpiredLocked(const int64_t timestampNs);
-
- void OnConfigUpdatedLocked(
- const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config);
-
- void GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs);
-
- void WriteActiveConfigsToProtoOutputStreamLocked(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
- void SetConfigsActiveStateLocked(const ActiveConfigList& activeConfigList,
- int64_t currentTimeNs);
-
- void SetMetadataStateLocked(const metadata::StatsMetadataList& statsMetadataList,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs);
-
- void WriteMetadataToProtoLocked(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadataList* metadataList);
-
- void WriteDataToDiskLocked(const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency);
-
- void WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency);
-
- void onConfigMetricsReportLocked(
- const ConfigKey& key, const int64_t dumpTimeStampNs,
- const bool include_current_partial_bucket, const bool erase_data,
- const DumpReportReason dumpReportReason, const DumpLatency dumpLatency,
- /*if dataSavedToDisk is true, it indicates the caller will write the data to disk
- (e.g., before reboot). So no need to further persist local history.*/
- const bool dataSavedToDisk, vector<uint8_t>* proto);
-
- /* Check if we should send a broadcast if approaching memory limits and if we're over, we
- * actually delete the data. */
- void flushIfNecessaryLocked(const ConfigKey& key, MetricsManager& metricsManager);
-
- // Maps the isolated uid in the log event to host uid if the log event contains uid fields.
- void mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const;
-
- // Handler over the isolated uid change event.
- void onIsolatedUidChangedEventLocked(const LogEvent& event);
-
- // Handler over the binary push state changed event.
- void onBinaryPushStateChangedEventLocked(LogEvent* event);
-
- // Handler over the watchdog rollback occurred event.
- void onWatchdogRollbackOccurredLocked(LogEvent* event);
-
- // Updates train info on disk based on binary push state changed info and
- // write disk info into parameters.
- void getAndUpdateTrainInfoOnDisk(bool is_rollback, InstallTrainInfo* trainInfoIn);
-
- // Gets experiment ids on disk for associated train and updates them
- // depending on rollback type. Then writes them back to disk and returns
- // them.
- std::vector<int64_t> processWatchdogRollbackOccurred(const int32_t rollbackTypeIn,
- const string& packageName);
-
- // Reset all configs.
- void resetConfigsLocked(const int64_t timestampNs);
- // Reset the specified configs.
- void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs);
-
- // Function used to send a broadcast so that receiver for the config key can call getData
- // to retrieve the stored data.
- std::function<bool(const ConfigKey& key)> mSendBroadcast;
-
- // Function used to send a broadcast so that receiver can be notified of which configs
- // are currently active.
- std::function<bool(const int& uid, const vector<int64_t>& configIds)> mSendActivationBroadcast;
-
- const int64_t mTimeBaseNs;
-
- // Largest timestamp of the events that we have processed.
- int64_t mLargestTimestampSeen = 0;
-
- int64_t mLastTimestampSeen = 0;
-
- int64_t mLastPullerCacheClearTimeSec = 0;
-
- // Last time we wrote data to disk.
- int64_t mLastWriteTimeNs = 0;
-
- // Last time we wrote active metrics to disk.
- int64_t mLastActiveMetricsWriteNs = 0;
-
- //Last time we wrote metadata to disk.
- int64_t mLastMetadataWriteNs = 0;
-
-#ifdef VERY_VERBOSE_PRINTING
- bool mPrintAllLogs = false;
-#endif
-
- FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs);
- FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize);
- FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast);
- FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge);
- FRIEND_TEST(StatsLogProcessorTest, InvalidConfigRemoved);
- FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
- FRIEND_TEST(StatsLogProcessorTest,
- TestActivationOnBootMultipleActivationsDifferentActivationTypes);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
-
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3);
- FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1);
- FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2);
- FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
- FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
- FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition);
- FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents);
-
- FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_load_refractory_from_disk);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-
- FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
- FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
-
- FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
- FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
-
- FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
- FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
- FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped);
- FRIEND_TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
-
- FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
deleted file mode 100644
index 6f952f6..0000000
--- a/cmds/statsd/src/StatsService.cpp
+++ /dev/null
@@ -1,1340 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsService.h"
-#include "stats_log_util.h"
-#include "android-base/stringprintf.h"
-#include "config/ConfigKey.h"
-#include "config/ConfigManager.h"
-#include "guardrail/StatsdStats.h"
-#include "storage/StorageManager.h"
-#include "subscriber/SubscriberReporter.h"
-
-#include <android-base/file.h>
-#include <android-base/strings.h>
-#include <cutils/multiuser.h>
-#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
-#include <frameworks/base/cmds/statsd/src/uid_data.pb.h>
-#include <private/android_filesystem_config.h>
-#include <statslog_statsd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/system_properties.h>
-#include <unistd.h>
-#include <utils/String16.h>
-
-using namespace android;
-
-using android::base::StringPrintf;
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_MESSAGE;
-
-using Status = ::ndk::ScopedAStatus;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-constexpr const char* kPermissionDump = "android.permission.DUMP";
-
-constexpr const char* kPermissionRegisterPullAtom = "android.permission.REGISTER_STATS_PULL_ATOM";
-
-#define STATS_SERVICE_DIR "/data/misc/stats-service"
-
-// for StatsDataDumpProto
-const int FIELD_ID_REPORTS_LIST = 1;
-
-static Status exception(int32_t code, const std::string& msg) {
- ALOGE("%s (%d)", msg.c_str(), code);
- return Status::fromExceptionCodeWithMessage(code, msg.c_str());
-}
-
-static bool checkPermission(const char* permission) {
- pid_t pid = AIBinder_getCallingPid();
- uid_t uid = AIBinder_getCallingUid();
- return checkPermissionForIds(permission, pid, uid);
-}
-
-Status checkUid(uid_t expectedUid) {
- uid_t uid = AIBinder_getCallingUid();
- if (uid == expectedUid || uid == AID_ROOT) {
- return Status::ok();
- } else {
- return exception(EX_SECURITY,
- StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
- }
-}
-
-#define ENFORCE_UID(uid) { \
- Status status = checkUid((uid)); \
- if (!status.isOk()) { \
- return status; \
- } \
-}
-
-StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue)
- : mAnomalyAlarmMonitor(new AlarmMonitor(
- MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
- [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) {
- if (sc != nullptr) {
- sc->setAnomalyAlarm(timeMillis);
- StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
- }
- },
- [](const shared_ptr<IStatsCompanionService>& sc) {
- if (sc != nullptr) {
- sc->cancelAnomalyAlarm();
- StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
- }
- })),
- mPeriodicAlarmMonitor(new AlarmMonitor(
- MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
- [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) {
- if (sc != nullptr) {
- sc->setAlarmForSubscriberTriggering(timeMillis);
- StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
- }
- },
- [](const shared_ptr<IStatsCompanionService>& sc) {
- if (sc != nullptr) {
- sc->cancelAlarmForSubscriberTriggering();
- StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
- }
- })),
- mEventQueue(queue),
- mBootCompleteTrigger({kBootCompleteTag, kUidMapReceivedTag, kAllPullersRegisteredTag},
- [this]() { mProcessor->onStatsdInitCompleted(getElapsedRealtimeNs()); }),
- mStatsCompanionServiceDeathRecipient(
- AIBinder_DeathRecipient_new(StatsService::statsCompanionServiceDied)) {
- mUidMap = UidMap::getInstance();
- mPullerManager = new StatsPullerManager();
- StatsPuller::SetUidMap(mUidMap);
- mConfigManager = new ConfigManager();
- mProcessor = new StatsLogProcessor(
- mUidMap, mPullerManager, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor,
- getElapsedRealtimeNs(),
- [this](const ConfigKey& key) {
- shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
- if (receiver == nullptr) {
- VLOG("Could not find a broadcast receiver for %s", key.ToString().c_str());
- return false;
- } else if (receiver->sendDataBroadcast(
- mProcessor->getLastReportTimeNs(key)).isOk()) {
- return true;
- } else {
- VLOG("Failed to send a broadcast for receiver %s", key.ToString().c_str());
- return false;
- }
- },
- [this](const int& uid, const vector<int64_t>& activeConfigs) {
- shared_ptr<IPendingIntentRef> receiver =
- mConfigManager->GetActiveConfigsChangedReceiver(uid);
- if (receiver == nullptr) {
- VLOG("Could not find receiver for uid %d", uid);
- return false;
- } else if (receiver->sendActiveConfigsChangedBroadcast(activeConfigs).isOk()) {
- VLOG("StatsService::active configs broadcast succeeded for uid %d" , uid);
- return true;
- } else {
- VLOG("StatsService::active configs broadcast failed for uid %d" , uid);
- return false;
- }
- });
-
- mUidMap->setListener(mProcessor);
- mConfigManager->AddListener(mProcessor);
-
- init_system_properties();
-
- if (mEventQueue != nullptr) {
- std::thread pushedEventThread([this] { readLogs(); });
- pushedEventThread.detach();
- }
-}
-
-StatsService::~StatsService() {
-}
-
-/* Runs on a dedicated thread to process pushed events. */
-void StatsService::readLogs() {
- // Read forever..... long live statsd
- while (1) {
- // Block until an event is available.
- auto event = mEventQueue->waitPop();
- // Pass it to StatsLogProcess to all configs/metrics
- // At this point, the LogEventQueue is not blocked, so that the socketListener
- // can read events from the socket and write to buffer to avoid data drop.
- mProcessor->OnLogEvent(event.get());
- // The ShellSubscriber is only used by shell for local debugging.
- if (mShellSubscriber != nullptr) {
- mShellSubscriber->onLogEvent(*event);
- }
- }
-}
-
-void StatsService::init_system_properties() {
- mEngBuild = false;
- const prop_info* buildType = __system_property_find("ro.build.type");
- if (buildType != NULL) {
- __system_property_read_callback(buildType, init_build_type_callback, this);
- }
-}
-
-void StatsService::init_build_type_callback(void* cookie, const char* /*name*/, const char* value,
- uint32_t serial) {
- if (0 == strcmp("eng", value) || 0 == strcmp("userdebug", value)) {
- reinterpret_cast<StatsService*>(cookie)->mEngBuild = true;
- }
-}
-
-/**
- * Write data from statsd.
- * Format for statsdStats: adb shell dumpsys stats --metadata [-v] [--proto]
- * Format for data report: adb shell dumpsys stats [anything other than --metadata] [--proto]
- * Anything ending in --proto will be in proto format.
- * Anything without --metadata as the first argument will be report information.
- * (bugreports call "adb shell dumpsys stats --dump-priority NORMAL -a --proto")
- * TODO: Come up with a more robust method of enacting <serviceutils/PriorityDumper.h>.
- */
-status_t StatsService::dump(int fd, const char** args, uint32_t numArgs) {
- if (!checkPermission(kPermissionDump)) {
- return PERMISSION_DENIED;
- }
-
- int lastArg = numArgs - 1;
- bool asProto = false;
- if (lastArg >= 0 && string(args[lastArg]) == "--proto") { // last argument
- asProto = true;
- lastArg--;
- }
- if (numArgs > 0 && string(args[0]) == "--metadata") { // first argument
- // Request is to dump statsd stats.
- bool verbose = false;
- if (lastArg >= 0 && string(args[lastArg]) == "-v") {
- verbose = true;
- lastArg--;
- }
- dumpStatsdStats(fd, verbose, asProto);
- } else {
- // Request is to dump statsd report data.
- if (asProto) {
- dumpIncidentSection(fd);
- } else {
- dprintf(fd, "Non-proto format of stats data dump not available; see proto version.\n");
- }
- }
-
- return NO_ERROR;
-}
-
-/**
- * Write debugging data about statsd in text or proto format.
- */
-void StatsService::dumpStatsdStats(int out, bool verbose, bool proto) {
- if (proto) {
- vector<uint8_t> data;
- StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats.
- for (size_t i = 0; i < data.size(); i ++) {
- dprintf(out, "%c", data[i]);
- }
- } else {
- StatsdStats::getInstance().dumpStats(out);
- mProcessor->dumpStates(out, verbose);
- }
-}
-
-/**
- * Write stats report data in StatsDataDumpProto incident section format.
- */
-void StatsService::dumpIncidentSection(int out) {
- ProtoOutputStream proto;
- for (const ConfigKey& configKey : mConfigManager->GetAllConfigKeys()) {
- uint64_t reportsListToken =
- proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS_LIST);
- // Don't include the current bucket to avoid skipping buckets.
- // If we need to include the current bucket later, consider changing to NO_TIME_CONSTRAINTS
- // or other alternatives to avoid skipping buckets for pulled metrics.
- mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(),
- false /* includeCurrentBucket */, false /* erase_data */,
- ADB_DUMP,
- FAST,
- &proto);
- proto.end(reportsListToken);
- proto.flush(out);
- proto.clear();
- }
-}
-
-/**
- * Implementation of the adb shell cmd stats command.
- */
-status_t StatsService::handleShellCommand(int in, int out, int err, const char** argv,
- uint32_t argc) {
- uid_t uid = AIBinder_getCallingUid();
- if (uid != AID_ROOT && uid != AID_SHELL) {
- return PERMISSION_DENIED;
- }
-
- Vector<String8> utf8Args;
- utf8Args.setCapacity(argc);
- for (uint32_t i = 0; i < argc; i++) {
- utf8Args.push(String8(argv[i]));
- }
-
- if (argc >= 1) {
- // adb shell cmd stats config ...
- if (!utf8Args[0].compare(String8("config"))) {
- return cmd_config(in, out, err, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("print-uid-map"))) {
- return cmd_print_uid_map(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("dump-report"))) {
- return cmd_dump_report(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("pull-source")) && argc > 1) {
- return cmd_print_pulled_metrics(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("send-broadcast"))) {
- return cmd_trigger_broadcast(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("print-stats"))) {
- return cmd_print_stats(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("meminfo"))) {
- return cmd_dump_memory_info(out);
- }
-
- if (!utf8Args[0].compare(String8("write-to-disk"))) {
- return cmd_write_data_to_disk(out);
- }
-
- if (!utf8Args[0].compare(String8("log-app-breadcrumb"))) {
- return cmd_log_app_breadcrumb(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("log-binary-push"))) {
- return cmd_log_binary_push(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("clear-puller-cache"))) {
- return cmd_clear_puller_cache(out);
- }
-
- if (!utf8Args[0].compare(String8("print-logs"))) {
- return cmd_print_logs(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("send-active-configs"))) {
- return cmd_trigger_active_config_broadcast(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("data-subscribe"))) {
- {
- std::lock_guard<std::mutex> lock(mShellSubscriberMutex);
- if (mShellSubscriber == nullptr) {
- mShellSubscriber = new ShellSubscriber(mUidMap, mPullerManager);
- }
- }
- int timeoutSec = -1;
- if (argc >= 2) {
- timeoutSec = atoi(utf8Args[1].c_str());
- }
- mShellSubscriber->startNewSubscription(in, out, timeoutSec);
- return NO_ERROR;
- }
- }
-
- print_cmd_help(out);
- return NO_ERROR;
-}
-
-void StatsService::print_cmd_help(int out) {
- dprintf(out,
- "usage: adb shell cmd stats print-stats-log [tag_required] "
- "[timestamp_nsec_optional]\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats meminfo\n");
- dprintf(out, "\n");
- dprintf(out, " Prints the malloc debug information. You need to run the following first: \n");
- dprintf(out, " # adb shell stop\n");
- dprintf(out, " # adb shell setprop libc.debug.malloc.program statsd \n");
- dprintf(out, " # adb shell setprop libc.debug.malloc.options backtrace \n");
- dprintf(out, " # adb shell start\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats print-uid-map [PKG]\n");
- dprintf(out, "\n");
- dprintf(out, " Prints the UID, app name, version mapping.\n");
- dprintf(out, " PKG Optional package name to print the uids of the package\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats pull-source ATOM_TAG [PACKAGE] \n");
- dprintf(out, "\n");
- dprintf(out, " Prints the output of a pulled atom\n");
- dprintf(out, " UID The atom to pull\n");
- dprintf(out, " PACKAGE The package to pull from. Default is AID_SYSTEM\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats write-to-disk \n");
- dprintf(out, "\n");
- dprintf(out, " Flushes all data on memory to disk.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats log-app-breadcrumb [UID] LABEL STATE\n");
- dprintf(out, " Writes an AppBreadcrumbReported event to the statslog buffer.\n");
- dprintf(out, " UID The uid to use. It is only possible to pass a UID\n");
- dprintf(out, " parameter on eng builds. If UID is omitted the calling\n");
- dprintf(out, " uid is used.\n");
- dprintf(out, " LABEL Integer in [0, 15], as per atoms.proto.\n");
- dprintf(out, " STATE Integer in [0, 3], as per atoms.proto.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out,
- "usage: adb shell cmd stats log-binary-push NAME VERSION STAGING ROLLBACK_ENABLED "
- "LOW_LATENCY STATE EXPERIMENT_IDS\n");
- dprintf(out, " Log a binary push state changed event.\n");
- dprintf(out, " NAME The train name.\n");
- dprintf(out, " VERSION The train version code.\n");
- dprintf(out, " STAGING If this train requires a restart.\n");
- dprintf(out, " ROLLBACK_ENABLED If rollback should be enabled for this install.\n");
- dprintf(out, " LOW_LATENCY If the train requires low latency monitoring.\n");
- dprintf(out, " STATE The status of the train push.\n");
- dprintf(out, " Integer value of the enum in atoms.proto.\n");
- dprintf(out, " EXPERIMENT_IDS Comma separated list of experiment ids.\n");
- dprintf(out, " Leave blank for none.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats config remove [UID] [NAME]\n");
- dprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
- dprintf(out, "\n");
- dprintf(out, " Adds, updates or removes a configuration. The proto should be in\n");
- dprintf(out, " wire-encoded protobuf format and passed via stdin. If no UID and name is\n");
- dprintf(out, " provided, then all configs will be removed from memory and disk.\n");
- dprintf(out, "\n");
- dprintf(out, " UID The uid to use. It is only possible to pass the UID\n");
- dprintf(out, " parameter on eng builds. If UID is omitted the calling\n");
- dprintf(out, " uid is used.\n");
- dprintf(out, " NAME The per-uid name to use\n");
- dprintf(out, "\n");
- dprintf(out, "\n *Note: If both UID and NAME are omitted then all configs will\n");
- dprintf(out, "\n be removed from memory and disk!\n");
- dprintf(out, "\n");
- dprintf(out,
- "usage: adb shell cmd stats dump-report [UID] NAME [--keep_data] "
- "[--include_current_bucket] [--proto]\n");
- dprintf(out, " Dump all metric data for a configuration.\n");
- dprintf(out, " UID The uid of the configuration. It is only possible to pass\n");
- dprintf(out, " the UID parameter on eng builds. If UID is omitted the\n");
- dprintf(out, " calling uid is used.\n");
- dprintf(out, " NAME The name of the configuration\n");
- dprintf(out, " --keep_data Do NOT erase the data upon dumping it.\n");
- dprintf(out, " --proto Print proto binary.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats send-broadcast [UID] NAME\n");
- dprintf(out, " Send a broadcast that triggers the subscriber to fetch metrics.\n");
- dprintf(out, " UID The uid of the configuration. It is only possible to pass\n");
- dprintf(out, " the UID parameter on eng builds. If UID is omitted the\n");
- dprintf(out, " calling uid is used.\n");
- dprintf(out, " NAME The name of the configuration\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out,
- "usage: adb shell cmd stats send-active-configs [--uid=UID] [--configs] "
- "[NAME1] [NAME2] [NAME3..]\n");
- dprintf(out, " Send a broadcast that informs the subscriber of the current active configs.\n");
- dprintf(out, " --uid=UID The uid of the configurations. It is only possible to pass\n");
- dprintf(out, " the UID parameter on eng builds. If UID is omitted the\n");
- dprintf(out, " calling uid is used.\n");
- dprintf(out, " --configs Send the list of configs in the name list instead of\n");
- dprintf(out, " the currently active configs\n");
- dprintf(out, " NAME LIST List of configuration names to be included in the broadcast.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats print-stats\n");
- dprintf(out, " Prints some basic stats.\n");
- dprintf(out, " --proto Print proto binary instead of string format.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats clear-puller-cache\n");
- dprintf(out, " Clear cached puller data.\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats print-logs\n");
- dprintf(out, " Only works on eng build\n");
-}
-
-status_t StatsService::cmd_trigger_broadcast(int out, Vector<String8>& args) {
- string name;
- bool good = false;
- int uid;
- const int argCount = args.size();
- if (argCount == 2) {
- // Automatically pick the UID
- uid = AIBinder_getCallingUid();
- name.assign(args[1].c_str(), args[1].size());
- good = true;
- } else if (argCount == 3) {
- good = getUidFromArgs(args, 1, uid);
- if (!good) {
- dprintf(out, "Invalid UID. Note that the metrics can only be dumped for "
- "other UIDs on eng or userdebug builds.\n");
- }
- name.assign(args[2].c_str(), args[2].size());
- }
- if (!good) {
- print_cmd_help(out);
- return UNKNOWN_ERROR;
- }
- ConfigKey key(uid, StrToInt64(name));
- shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
- if (receiver == nullptr) {
- VLOG("Could not find receiver for %s, %s", args[1].c_str(), args[2].c_str());
- return UNKNOWN_ERROR;
- } else if (receiver->sendDataBroadcast(mProcessor->getLastReportTimeNs(key)).isOk()) {
- VLOG("StatsService::trigger broadcast succeeded to %s, %s", args[1].c_str(),
- args[2].c_str());
- } else {
- VLOG("StatsService::trigger broadcast failed to %s, %s", args[1].c_str(), args[2].c_str());
- return UNKNOWN_ERROR;
- }
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_trigger_active_config_broadcast(int out, Vector<String8>& args) {
- const int argCount = args.size();
- int uid;
- vector<int64_t> configIds;
- if (argCount == 1) {
- // Automatically pick the uid and send a broadcast that has no active configs.
- uid = AIBinder_getCallingUid();
- mProcessor->GetActiveConfigs(uid, configIds);
- } else {
- int curArg = 1;
- if(args[curArg].find("--uid=") == 0) {
- string uidArgStr(args[curArg].c_str());
- string uidStr = uidArgStr.substr(6);
- if (!getUidFromString(uidStr.c_str(), uid)) {
- dprintf(out, "Invalid UID. Note that the config can only be set for "
- "other UIDs on eng or userdebug builds.\n");
- return UNKNOWN_ERROR;
- }
- curArg++;
- } else {
- uid = AIBinder_getCallingUid();
- }
- if (curArg == argCount || args[curArg] != "--configs") {
- VLOG("Reached end of args, or specify configs not set. Sending actual active configs,");
- mProcessor->GetActiveConfigs(uid, configIds);
- } else {
- // Flag specified, use the given list of configs.
- curArg++;
- for (int i = curArg; i < argCount; i++) {
- char* endp;
- int64_t configID = strtoll(args[i].c_str(), &endp, 10);
- if (endp == args[i].c_str() || *endp != '\0') {
- dprintf(out, "Error parsing config ID.\n");
- return UNKNOWN_ERROR;
- }
- VLOG("Adding config id %ld", static_cast<long>(configID));
- configIds.push_back(configID);
- }
- }
- }
- shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetActiveConfigsChangedReceiver(uid);
- if (receiver == nullptr) {
- VLOG("Could not find receiver for uid %d", uid);
- return UNKNOWN_ERROR;
- } else if (receiver->sendActiveConfigsChangedBroadcast(configIds).isOk()) {
- VLOG("StatsService::trigger active configs changed broadcast succeeded for uid %d" , uid);
- } else {
- VLOG("StatsService::trigger active configs changed broadcast failed for uid %d", uid);
- return UNKNOWN_ERROR;
- }
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_config(int in, int out, int err, Vector<String8>& args) {
- const int argCount = args.size();
- if (argCount >= 2) {
- if (args[1] == "update" || args[1] == "remove") {
- bool good = false;
- int uid = -1;
- string name;
-
- if (argCount == 3) {
- // Automatically pick the UID
- uid = AIBinder_getCallingUid();
- name.assign(args[2].c_str(), args[2].size());
- good = true;
- } else if (argCount == 4) {
- good = getUidFromArgs(args, 2, uid);
- if (!good) {
- dprintf(err, "Invalid UID. Note that the config can only be set for "
- "other UIDs on eng or userdebug builds.\n");
- }
- name.assign(args[3].c_str(), args[3].size());
- } else if (argCount == 2 && args[1] == "remove") {
- good = true;
- }
-
- if (!good) {
- // If arg parsing failed, print the help text and return an error.
- print_cmd_help(out);
- return UNKNOWN_ERROR;
- }
-
- if (args[1] == "update") {
- char* endp;
- int64_t configID = strtoll(name.c_str(), &endp, 10);
- if (endp == name.c_str() || *endp != '\0') {
- dprintf(err, "Error parsing config ID.\n");
- return UNKNOWN_ERROR;
- }
-
- // Read stream into buffer.
- string buffer;
- if (!android::base::ReadFdToString(in, &buffer)) {
- dprintf(err, "Error reading stream for StatsConfig.\n");
- return UNKNOWN_ERROR;
- }
-
- // Parse buffer.
- StatsdConfig config;
- if (!config.ParseFromString(buffer)) {
- dprintf(err, "Error parsing proto stream for StatsConfig.\n");
- return UNKNOWN_ERROR;
- }
-
- // Add / update the config.
- mConfigManager->UpdateConfig(ConfigKey(uid, configID), config);
- } else {
- if (argCount == 2) {
- cmd_remove_all_configs(out);
- } else {
- // Remove the config.
- mConfigManager->RemoveConfig(ConfigKey(uid, StrToInt64(name)));
- }
- }
-
- return NO_ERROR;
- }
- }
- print_cmd_help(out);
- return UNKNOWN_ERROR;
-}
-
-status_t StatsService::cmd_dump_report(int out, const Vector<String8>& args) {
- if (mProcessor != nullptr) {
- int argCount = args.size();
- bool good = false;
- bool proto = false;
- bool includeCurrentBucket = false;
- bool eraseData = true;
- int uid;
- string name;
- if (!std::strcmp("--proto", args[argCount-1].c_str())) {
- proto = true;
- argCount -= 1;
- }
- if (!std::strcmp("--include_current_bucket", args[argCount-1].c_str())) {
- includeCurrentBucket = true;
- argCount -= 1;
- }
- if (!std::strcmp("--keep_data", args[argCount-1].c_str())) {
- eraseData = false;
- argCount -= 1;
- }
- if (argCount == 2) {
- // Automatically pick the UID
- uid = AIBinder_getCallingUid();
- name.assign(args[1].c_str(), args[1].size());
- good = true;
- } else if (argCount == 3) {
- good = getUidFromArgs(args, 1, uid);
- if (!good) {
- dprintf(out, "Invalid UID. Note that the metrics can only be dumped for "
- "other UIDs on eng or userdebug builds.\n");
- }
- name.assign(args[2].c_str(), args[2].size());
- }
- if (good) {
- vector<uint8_t> data;
- mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
- includeCurrentBucket, eraseData, ADB_DUMP,
- NO_TIME_CONSTRAINTS,
- &data);
- if (proto) {
- for (size_t i = 0; i < data.size(); i ++) {
- dprintf(out, "%c", data[i]);
- }
- } else {
- dprintf(out, "Non-proto stats data dump not currently supported.\n");
- }
- return android::OK;
- } else {
- // If arg parsing failed, print the help text and return an error.
- print_cmd_help(out);
- return UNKNOWN_ERROR;
- }
- } else {
- dprintf(out, "Log processor does not exist...\n");
- return UNKNOWN_ERROR;
- }
-}
-
-status_t StatsService::cmd_print_stats(int out, const Vector<String8>& args) {
- int argCount = args.size();
- bool proto = false;
- if (!std::strcmp("--proto", args[argCount-1].c_str())) {
- proto = true;
- argCount -= 1;
- }
- StatsdStats& statsdStats = StatsdStats::getInstance();
- if (proto) {
- vector<uint8_t> data;
- statsdStats.dumpStats(&data, false); // does not reset statsdStats.
- for (size_t i = 0; i < data.size(); i ++) {
- dprintf(out, "%c", data[i]);
- }
-
- } else {
- vector<ConfigKey> configs = mConfigManager->GetAllConfigKeys();
- for (const ConfigKey& key : configs) {
- dprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(),
- mProcessor->GetMetricsSize(key));
- }
- statsdStats.dumpStats(out);
- }
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_print_uid_map(int out, const Vector<String8>& args) {
- if (args.size() > 1) {
- string pkg;
- pkg.assign(args[1].c_str(), args[1].size());
- auto uids = mUidMap->getAppUid(pkg);
- dprintf(out, "%s -> [ ", pkg.c_str());
- for (const auto& uid : uids) {
- dprintf(out, "%d ", uid);
- }
- dprintf(out, "]\n");
- } else {
- mUidMap->printUidMap(out);
- }
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_write_data_to_disk(int out) {
- dprintf(out, "Writing data to disk\n");
- mProcessor->WriteDataToDisk(ADB_DUMP, NO_TIME_CONSTRAINTS);
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_log_app_breadcrumb(int out, const Vector<String8>& args) {
- bool good = false;
- int32_t uid;
- int32_t label;
- int32_t state;
- const int argCount = args.size();
- if (argCount == 3) {
- // Automatically pick the UID
- uid = AIBinder_getCallingUid();
- label = atoi(args[1].c_str());
- state = atoi(args[2].c_str());
- good = true;
- } else if (argCount == 4) {
- good = getUidFromArgs(args, 1, uid);
- if (!good) {
- dprintf(out,
- "Invalid UID. Note that selecting a UID for writing AppBreadcrumb can only be "
- "done for other UIDs on eng or userdebug builds.\n");
- }
- label = atoi(args[2].c_str());
- state = atoi(args[3].c_str());
- }
- if (good) {
- dprintf(out, "Logging AppBreadcrumbReported(%d, %d, %d) to statslog.\n", uid, label, state);
- android::os::statsd::util::stats_write(
- android::os::statsd::util::APP_BREADCRUMB_REPORTED, uid, label, state);
- } else {
- print_cmd_help(out);
- return UNKNOWN_ERROR;
- }
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_log_binary_push(int out, const Vector<String8>& args) {
- // Security checks are done in the sendBinaryPushStateChanged atom.
- const int argCount = args.size();
- if (argCount != 7 && argCount != 8) {
- dprintf(out, "Incorrect number of argument supplied\n");
- return UNKNOWN_ERROR;
- }
- string trainName = string(args[1].c_str());
- int64_t trainVersion = strtoll(args[2].c_str(), nullptr, 10);
- int32_t state = atoi(args[6].c_str());
- vector<int64_t> experimentIds;
- if (argCount == 8) {
- vector<string> experimentIdsString = android::base::Split(string(args[7].c_str()), ",");
- for (string experimentIdString : experimentIdsString) {
- int64_t experimentId = strtoll(experimentIdString.c_str(), nullptr, 10);
- experimentIds.push_back(experimentId);
- }
- }
- dprintf(out, "Logging BinaryPushStateChanged\n");
- vector<uint8_t> experimentIdBytes;
- writeExperimentIdsToProto(experimentIds, &experimentIdBytes);
- LogEvent event(trainName, trainVersion, args[3], args[4], args[5], state, experimentIdBytes, 0);
- mProcessor->OnLogEvent(&event);
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_print_pulled_metrics(int out, const Vector<String8>& args) {
- int s = atoi(args[1].c_str());
- vector<int32_t> uids;
- if (args.size() > 2) {
- string package = string(args[2].c_str());
- auto it = UidMap::sAidToUidMapping.find(package);
- if (it != UidMap::sAidToUidMapping.end()) {
- uids.push_back(it->second);
- } else {
- set<int32_t> uids_set = mUidMap->getAppUid(package);
- uids.insert(uids.end(), uids_set.begin(), uids_set.end());
- }
- } else {
- uids.push_back(AID_SYSTEM);
- }
- vector<shared_ptr<LogEvent>> stats;
- if (mPullerManager->Pull(s, uids, getElapsedRealtimeNs(), &stats)) {
- for (const auto& it : stats) {
- dprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
- }
- dprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
- return NO_ERROR;
- }
- return UNKNOWN_ERROR;
-}
-
-status_t StatsService::cmd_remove_all_configs(int out) {
- dprintf(out, "Removing all configs...\n");
- VLOG("StatsService::cmd_remove_all_configs was called");
- mConfigManager->RemoveAllConfigs();
- StorageManager::deleteAllFiles(STATS_SERVICE_DIR);
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_dump_memory_info(int out) {
- dprintf(out, "meminfo not available.\n");
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_clear_puller_cache(int out) {
- VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i",
- AIBinder_getCallingPid(), AIBinder_getCallingUid());
- if (checkPermission(kPermissionDump)) {
- int cleared = mPullerManager->ForceClearPullerCache();
- dprintf(out, "Puller removed %d cached data!\n", cleared);
- return NO_ERROR;
- } else {
- return PERMISSION_DENIED;
- }
-}
-
-status_t StatsService::cmd_print_logs(int out, const Vector<String8>& args) {
- VLOG("StatsService::cmd_print_logs with Pid %i, Uid %i", AIBinder_getCallingPid(),
- AIBinder_getCallingUid());
- if (checkPermission(kPermissionDump)) {
- bool enabled = true;
- if (args.size() >= 2) {
- enabled = atoi(args[1].c_str()) != 0;
- }
- mProcessor->setPrintLogs(enabled);
- return NO_ERROR;
- } else {
- return PERMISSION_DENIED;
- }
-}
-
-bool StatsService::getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid) {
- return getUidFromString(args[uidArgIndex].c_str(), uid);
-}
-
-bool StatsService::getUidFromString(const char* s, int32_t& uid) {
- if (*s == '\0') {
- return false;
- }
- char* endc = NULL;
- int64_t longUid = strtol(s, &endc, 0);
- if (*endc != '\0') {
- return false;
- }
- int32_t goodUid = static_cast<int32_t>(longUid);
- if (longUid < 0 || static_cast<uint64_t>(longUid) != static_cast<uid_t>(goodUid)) {
- return false; // It was not of uid_t type.
- }
- uid = goodUid;
-
- int32_t callingUid = AIBinder_getCallingUid();
- return mEngBuild // UserDebug/EngBuild are allowed to impersonate uids.
- || (callingUid == goodUid) // Anyone can 'impersonate' themselves.
- || (callingUid == AID_ROOT && goodUid == AID_SHELL); // ROOT can impersonate SHELL.
-}
-
-Status StatsService::informAllUidData(const ScopedFileDescriptor& fd) {
- ENFORCE_UID(AID_SYSTEM);
- // Read stream into buffer.
- string buffer;
- if (!android::base::ReadFdToString(fd.get(), &buffer)) {
- return exception(EX_ILLEGAL_ARGUMENT, "Failed to read all data from the pipe.");
- }
-
- // Parse buffer.
- UidData uidData;
- if (!uidData.ParseFromString(buffer)) {
- return exception(EX_ILLEGAL_ARGUMENT, "Error parsing proto stream for UidData.");
- }
-
- vector<String16> versionStrings;
- vector<String16> installers;
- vector<String16> packageNames;
- vector<int32_t> uids;
- vector<int64_t> versions;
-
- const auto numEntries = uidData.app_info_size();
- versionStrings.reserve(numEntries);
- installers.reserve(numEntries);
- packageNames.reserve(numEntries);
- uids.reserve(numEntries);
- versions.reserve(numEntries);
-
- for (const auto& appInfo: uidData.app_info()) {
- packageNames.emplace_back(String16(appInfo.package_name().c_str()));
- uids.push_back(appInfo.uid());
- versions.push_back(appInfo.version());
- versionStrings.emplace_back(String16(appInfo.version_string().c_str()));
- installers.emplace_back(String16(appInfo.installer().c_str()));
- }
-
- mUidMap->updateMap(getElapsedRealtimeNs(),
- uids,
- versions,
- versionStrings,
- packageNames,
- installers);
-
- mBootCompleteTrigger.markComplete(kUidMapReceivedTag);
- VLOG("StatsService::informAllUidData UidData proto parsed successfully.");
- return Status::ok();
-}
-
-Status StatsService::informOnePackage(const string& app, int32_t uid, int64_t version,
- const string& versionString, const string& installer) {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informOnePackage was called");
- String16 utf16App = String16(app.c_str());
- String16 utf16VersionString = String16(versionString.c_str());
- String16 utf16Installer = String16(installer.c_str());
-
- mUidMap->updateApp(getElapsedRealtimeNs(), utf16App, uid, version, utf16VersionString,
- utf16Installer);
- return Status::ok();
-}
-
-Status StatsService::informOnePackageRemoved(const string& app, int32_t uid) {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informOnePackageRemoved was called");
- String16 utf16App = String16(app.c_str());
- mUidMap->removeApp(getElapsedRealtimeNs(), utf16App, uid);
- mConfigManager->RemoveConfigs(uid);
- return Status::ok();
-}
-
-Status StatsService::informAnomalyAlarmFired() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informAnomalyAlarmFired was called");
- int64_t currentTimeSec = getElapsedRealtimeSec();
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
- mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- if (alarmSet.size() > 0) {
- VLOG("Found an anomaly alarm that fired.");
- mProcessor->onAnomalyAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
- } else {
- VLOG("Cannot find an anomaly alarm that fired. Perhaps it was recently cancelled.");
- }
- return Status::ok();
-}
-
-Status StatsService::informAlarmForSubscriberTriggeringFired() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
- int64_t currentTimeSec = getElapsedRealtimeSec();
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
- mPeriodicAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- if (alarmSet.size() > 0) {
- VLOG("Found periodic alarm fired.");
- mProcessor->onPeriodicAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
- } else {
- ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled.");
- }
- return Status::ok();
-}
-
-Status StatsService::informPollAlarmFired() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informPollAlarmFired was called");
- mProcessor->informPullAlarmFired(getElapsedRealtimeNs());
- VLOG("StatsService::informPollAlarmFired succeeded");
- return Status::ok();
-}
-
-Status StatsService::systemRunning() {
- ENFORCE_UID(AID_SYSTEM);
-
- // When system_server is up and running, schedule the dropbox task to run.
- VLOG("StatsService::systemRunning");
- sayHiToStatsCompanion();
- return Status::ok();
-}
-
-Status StatsService::informDeviceShutdown() {
- ENFORCE_UID(AID_SYSTEM);
- VLOG("StatsService::informDeviceShutdown");
- mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST);
- mProcessor->SaveActiveConfigsToDisk(getElapsedRealtimeNs());
- mProcessor->SaveMetadataToDisk(getWallClockNs(), getElapsedRealtimeNs());
- return Status::ok();
-}
-
-void StatsService::sayHiToStatsCompanion() {
- shared_ptr<IStatsCompanionService> statsCompanion = getStatsCompanionService();
- if (statsCompanion != nullptr) {
- VLOG("Telling statsCompanion that statsd is ready");
- statsCompanion->statsdReady();
- } else {
- VLOG("Could not access statsCompanion");
- }
-}
-
-Status StatsService::statsCompanionReady() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::statsCompanionReady was called");
- shared_ptr<IStatsCompanionService> statsCompanion = getStatsCompanionService();
- if (statsCompanion == nullptr) {
- return exception(EX_NULL_POINTER,
- "StatsCompanion unavailable despite it contacting statsd.");
- }
- VLOG("StatsService::statsCompanionReady linking to statsCompanion.");
- AIBinder_linkToDeath(statsCompanion->asBinder().get(),
- mStatsCompanionServiceDeathRecipient.get(), this);
- mPullerManager->SetStatsCompanionService(statsCompanion);
- mAnomalyAlarmMonitor->setStatsCompanionService(statsCompanion);
- mPeriodicAlarmMonitor->setStatsCompanionService(statsCompanion);
- return Status::ok();
-}
-
-Status StatsService::bootCompleted() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::bootCompleted was called");
- mBootCompleteTrigger.markComplete(kBootCompleteTag);
- return Status::ok();
-}
-
-void StatsService::Startup() {
- mConfigManager->Startup();
- mProcessor->LoadActiveConfigsFromDisk();
- mProcessor->LoadMetadataFromDisk(getWallClockNs(), getElapsedRealtimeNs());
-}
-
-void StatsService::Terminate() {
- ALOGI("StatsService::Terminating");
- if (mProcessor != nullptr) {
- mProcessor->WriteDataToDisk(TERMINATION_SIGNAL_RECEIVED, FAST);
- mProcessor->SaveActiveConfigsToDisk(getElapsedRealtimeNs());
- mProcessor->SaveMetadataToDisk(getWallClockNs(), getElapsedRealtimeNs());
- }
-}
-
-// Test only interface!!!
-void StatsService::OnLogEvent(LogEvent* event) {
- mProcessor->OnLogEvent(event);
- if (mShellSubscriber != nullptr) {
- mShellSubscriber->onLogEvent(*event);
- }
-}
-
-Status StatsService::getData(int64_t key, const int32_t callingUid, vector<int8_t>* output) {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::getData with Uid %i", callingUid);
- ConfigKey configKey(callingUid, key);
- // TODO(b/149254662): Since libbinder_ndk uses int8_t instead of uint8_t,
- // there are inconsistencies with internal statsd logic. Instead of
- // modifying lots of files, we create a temporary output array of int8_t and
- // copy its data into output. This is a bad hack, but hopefully
- // libbinder_ndk will transition to using uint8_t soon: progress is tracked
- // in b/144957764. Same applies to StatsService::getMetadata.
- vector<uint8_t> unsignedOutput;
- // The dump latency does not matter here since we do not include the current bucket, we do not
- // need to pull any new data anyhow.
- mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/,
- true /* erase_data */, GET_DATA_CALLED, FAST, &unsignedOutput);
- *output = vector<int8_t>(unsignedOutput.begin(), unsignedOutput.end());
- return Status::ok();
-}
-
-Status StatsService::getMetadata(vector<int8_t>* output) {
- ENFORCE_UID(AID_SYSTEM);
-
- vector<uint8_t> unsignedOutput;
- StatsdStats::getInstance().dumpStats(&unsignedOutput, false); // Don't reset the counters.
- *output = vector<int8_t>(unsignedOutput.begin(), unsignedOutput.end());
- return Status::ok();
-}
-
-Status StatsService::addConfiguration(int64_t key, const vector <int8_t>& config,
- const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- if (addConfigurationChecked(callingUid, key, config)) {
- return Status::ok();
- } else {
- return exception(EX_ILLEGAL_ARGUMENT, "Could not parse malformatted StatsdConfig.");
- }
-}
-
-bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config) {
- ConfigKey configKey(uid, key);
- StatsdConfig cfg;
- if (config.size() > 0) { // If the config is empty, skip parsing.
- if (!cfg.ParseFromArray(&config[0], config.size())) {
- return false;
- }
- }
- mConfigManager->UpdateConfig(configKey, cfg);
- return true;
-}
-
-Status StatsService::removeDataFetchOperation(int64_t key,
- const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
- ConfigKey configKey(callingUid, key);
- mConfigManager->RemoveConfigReceiver(configKey);
- return Status::ok();
-}
-
-Status StatsService::setDataFetchOperation(int64_t key,
- const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- ConfigKey configKey(callingUid, key);
- mConfigManager->SetConfigReceiver(configKey, pir);
- if (StorageManager::hasConfigMetricsReport(configKey)) {
- VLOG("StatsService::setDataFetchOperation marking configKey %s to dump reports on disk",
- configKey.ToString().c_str());
- mProcessor->noteOnDiskData(configKey);
- }
- return Status::ok();
-}
-
-Status StatsService::setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid,
- vector<int64_t>* output) {
- ENFORCE_UID(AID_SYSTEM);
-
- mConfigManager->SetActiveConfigsChangedReceiver(callingUid, pir);
- if (output != nullptr) {
- mProcessor->GetActiveConfigs(callingUid, *output);
- } else {
- ALOGW("StatsService::setActiveConfigsChanged output was nullptr");
- }
- return Status::ok();
-}
-
-Status StatsService::removeActiveConfigsChangedOperation(const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- mConfigManager->RemoveActiveConfigsChangedReceiver(callingUid);
- return Status::ok();
-}
-
-Status StatsService::removeConfiguration(int64_t key, const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- ConfigKey configKey(callingUid, key);
- mConfigManager->RemoveConfig(configKey);
- return Status::ok();
-}
-
-Status StatsService::setBroadcastSubscriber(int64_t configId,
- int64_t subscriberId,
- const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::setBroadcastSubscriber called.");
- ConfigKey configKey(callingUid, configId);
- SubscriberReporter::getInstance()
- .setBroadcastSubscriber(configKey, subscriberId, pir);
- return Status::ok();
-}
-
-Status StatsService::unsetBroadcastSubscriber(int64_t configId,
- int64_t subscriberId,
- const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::unsetBroadcastSubscriber called.");
- ConfigKey configKey(callingUid, configId);
- SubscriberReporter::getInstance()
- .unsetBroadcastSubscriber(configKey, subscriberId);
- return Status::ok();
-}
-
-Status StatsService::allPullersFromBootRegistered() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::allPullersFromBootRegistered was called");
- mBootCompleteTrigger.markComplete(kAllPullersRegisteredTag);
- return Status::ok();
-}
-
-Status StatsService::registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownMillis,
- int64_t timeoutMillis,
- const std::vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& pullerCallback) {
- ENFORCE_UID(AID_SYSTEM);
- VLOG("StatsService::registerPullAtomCallback called.");
- mPullerManager->RegisterPullAtomCallback(uid, atomTag, MillisToNano(coolDownMillis),
- MillisToNano(timeoutMillis), additiveFields,
- pullerCallback);
- return Status::ok();
-}
-
-Status StatsService::registerNativePullAtomCallback(
- int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis,
- const std::vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& pullerCallback) {
- if (!checkPermission(kPermissionRegisterPullAtom)) {
- return exception(
- EX_SECURITY,
- StringPrintf("Uid %d does not have the %s permission when registering atom %d",
- AIBinder_getCallingUid(), kPermissionRegisterPullAtom, atomTag));
- }
- VLOG("StatsService::registerNativePullAtomCallback called.");
- int32_t uid = AIBinder_getCallingUid();
- mPullerManager->RegisterPullAtomCallback(uid, atomTag, MillisToNano(coolDownMillis),
- MillisToNano(timeoutMillis), additiveFields,
- pullerCallback);
- return Status::ok();
-}
-
-Status StatsService::unregisterPullAtomCallback(int32_t uid, int32_t atomTag) {
- ENFORCE_UID(AID_SYSTEM);
- VLOG("StatsService::unregisterPullAtomCallback called.");
- mPullerManager->UnregisterPullAtomCallback(uid, atomTag);
- return Status::ok();
-}
-
-Status StatsService::unregisterNativePullAtomCallback(int32_t atomTag) {
- if (!checkPermission(kPermissionRegisterPullAtom)) {
- return exception(
- EX_SECURITY,
- StringPrintf("Uid %d does not have the %s permission when unregistering atom %d",
- AIBinder_getCallingUid(), kPermissionRegisterPullAtom, atomTag));
- }
- VLOG("StatsService::unregisterNativePullAtomCallback called.");
- int32_t uid = AIBinder_getCallingUid();
- mPullerManager->UnregisterPullAtomCallback(uid, atomTag);
- return Status::ok();
-}
-
-Status StatsService::getRegisteredExperimentIds(std::vector<int64_t>* experimentIdsOut) {
- ENFORCE_UID(AID_SYSTEM);
- // TODO: add verifier permission
-
- experimentIdsOut->clear();
- // Read the latest train info
- vector<InstallTrainInfo> trainInfoList = StorageManager::readAllTrainInfo();
- if (trainInfoList.empty()) {
- // No train info means no experiment IDs, return an empty list
- return Status::ok();
- }
-
- // Copy the experiment IDs to the out vector
- for (InstallTrainInfo& trainInfo : trainInfoList) {
- experimentIdsOut->insert(experimentIdsOut->end(),
- trainInfo.experimentIds.begin(),
- trainInfo.experimentIds.end());
- }
- return Status::ok();
-}
-
-void StatsService::statsCompanionServiceDied(void* cookie) {
- auto thiz = static_cast<StatsService*>(cookie);
- thiz->statsCompanionServiceDiedImpl();
-}
-
-void StatsService::statsCompanionServiceDiedImpl() {
- ALOGW("statscompanion service died");
- StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
- if (mProcessor != nullptr) {
- ALOGW("Reset statsd upon system server restarts.");
- int64_t systemServerRestartNs = getElapsedRealtimeNs();
- ProtoOutputStream activeConfigsProto;
- mProcessor->WriteActiveConfigsToProtoOutputStream(systemServerRestartNs,
- STATSCOMPANION_DIED, &activeConfigsProto);
- metadata::StatsMetadataList metadataList;
- mProcessor->WriteMetadataToProto(getWallClockNs(),
- systemServerRestartNs, &metadataList);
- mProcessor->WriteDataToDisk(STATSCOMPANION_DIED, FAST);
- mProcessor->resetConfigs();
-
- std::string serializedActiveConfigs;
- if (activeConfigsProto.serializeToString(&serializedActiveConfigs)) {
- ActiveConfigList activeConfigs;
- if (activeConfigs.ParseFromString(serializedActiveConfigs)) {
- mProcessor->SetConfigsActiveState(activeConfigs, systemServerRestartNs);
- }
- }
- mProcessor->SetMetadataState(metadataList, getWallClockNs(), systemServerRestartNs);
- }
- mAnomalyAlarmMonitor->setStatsCompanionService(nullptr);
- mPeriodicAlarmMonitor->setStatsCompanionService(nullptr);
- mPullerManager->SetStatsCompanionService(nullptr);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
deleted file mode 100644
index b49fa1d..0000000
--- a/cmds/statsd/src/StatsService.h
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STATS_SERVICE_H
-#define STATS_SERVICE_H
-
-#include <aidl/android/os/BnStatsd.h>
-#include <aidl/android/os/IPendingIntentRef.h>
-#include <aidl/android/os/IPullAtomCallback.h>
-#include <gtest/gtest_prod.h>
-#include <utils/Looper.h>
-
-#include <mutex>
-
-#include "StatsLogProcessor.h"
-#include "anomaly/AlarmMonitor.h"
-#include "config/ConfigManager.h"
-#include "external/StatsPullerManager.h"
-#include "logd/LogEventQueue.h"
-#include "packages/UidMap.h"
-#include "shell/ShellSubscriber.h"
-#include "statscompanion_util.h"
-#include "utils/MultiConditionTrigger.h"
-
-using namespace android;
-using namespace android::os;
-using namespace std;
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::os::BnStatsd;
-using aidl::android::os::IPendingIntentRef;
-using aidl::android::os::IPullAtomCallback;
-using ::ndk::ScopedAIBinder_DeathRecipient;
-using ::ndk::ScopedFileDescriptor;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsService : public BnStatsd {
-public:
- StatsService(const sp<Looper>& handlerLooper, std::shared_ptr<LogEventQueue> queue);
- virtual ~StatsService();
-
- /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */
- const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5;
-
- virtual status_t dump(int fd, const char** args, uint32_t numArgs) override;
- virtual status_t handleShellCommand(int in, int out, int err, const char** argv,
- uint32_t argc) override;
-
- virtual Status systemRunning();
- virtual Status statsCompanionReady();
- virtual Status bootCompleted();
- virtual Status informAnomalyAlarmFired();
- virtual Status informPollAlarmFired();
- virtual Status informAlarmForSubscriberTriggeringFired();
-
- virtual Status informAllUidData(const ScopedFileDescriptor& fd);
- virtual Status informOnePackage(const string& app, int32_t uid, int64_t version,
- const string& versionString, const string& installer);
- virtual Status informOnePackageRemoved(const string& app, int32_t uid);
- virtual Status informDeviceShutdown();
-
- /**
- * Called right before we start processing events.
- */
- void Startup();
-
- /**
- * Called when terminiation signal received.
- */
- void Terminate();
-
- /**
- * Test ONLY interface. In real world, StatsService reads from LogEventQueue.
- */
- virtual void OnLogEvent(LogEvent* event);
-
- /**
- * Binder call for clients to request data for this configuration key.
- */
- virtual Status getData(int64_t key,
- const int32_t callingUid,
- vector<int8_t>* output) override;
-
-
- /**
- * Binder call for clients to get metadata across all configs in statsd.
- */
- virtual Status getMetadata(vector<int8_t>* output) override;
-
-
- /**
- * Binder call to let clients send a configuration and indicate they're interested when they
- * should requestData for this configuration.
- */
- virtual Status addConfiguration(int64_t key,
- const vector<int8_t>& config,
- const int32_t callingUid) override;
-
- /**
- * Binder call to let clients register the data fetch operation for a configuration.
- */
- virtual Status setDataFetchOperation(int64_t key,
- const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid) override;
-
- /**
- * Binder call to remove the data fetch operation for the specified config key.
- */
- virtual Status removeDataFetchOperation(int64_t key,
- const int32_t callingUid) override;
-
- /**
- * Binder call to let clients register the active configs changed operation.
- */
- virtual Status setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid,
- vector<int64_t>* output) override;
-
- /**
- * Binder call to remove the active configs changed operation for the specified package..
- */
- virtual Status removeActiveConfigsChangedOperation(const int32_t callingUid) override;
- /**
- * Binder call to allow clients to remove the specified configuration.
- */
- virtual Status removeConfiguration(int64_t key,
- const int32_t callingUid) override;
-
- /**
- * Binder call to associate the given config's subscriberId with the given pendingIntentRef.
- */
- virtual Status setBroadcastSubscriber(int64_t configId,
- int64_t subscriberId,
- const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid) override;
-
- /**
- * Binder call to unassociate the given config's subscriberId with any pendingIntentRef.
- */
- virtual Status unsetBroadcastSubscriber(int64_t configId,
- int64_t subscriberId,
- const int32_t callingUid) override;
-
- /** Inform statsCompanion that statsd is ready. */
- virtual void sayHiToStatsCompanion();
-
- /**
- * Binder call to notify statsd that all pullers from boot have been registered.
- */
- virtual Status allPullersFromBootRegistered();
-
- /**
- * Binder call to register a callback function for a pulled atom.
- */
- virtual Status registerPullAtomCallback(
- int32_t uid, int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis,
- const std::vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& pullerCallback) override;
-
- /**
- * Binder call to register a callback function for a pulled atom.
- */
- virtual Status registerNativePullAtomCallback(
- int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis,
- const std::vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& pullerCallback) override;
-
- /**
- * Binder call to unregister any existing callback for the given uid and atom.
- */
- virtual Status unregisterPullAtomCallback(int32_t uid, int32_t atomTag) override;
-
- /**
- * Binder call to unregister any existing callback for the given atom and calling uid.
- */
- virtual Status unregisterNativePullAtomCallback(int32_t atomTag) override;
-
- /**
- * Binder call to get registered experiment IDs.
- */
- virtual Status getRegisteredExperimentIds(std::vector<int64_t>* expIdsOut);
-
-private:
- /**
- * Load system properties at init.
- */
- void init_system_properties();
-
- /**
- * Helper for loading system properties.
- */
- static void init_build_type_callback(void* cookie, const char* name, const char* value,
- uint32_t serial);
-
- /**
- * Proto output of statsd report data dumpsys, wrapped in a StatsDataDumpProto.
- */
- void dumpIncidentSection(int outFd);
-
- /**
- * Text or proto output of statsdStats dumpsys.
- */
- void dumpStatsdStats(int outFd, bool verbose, bool proto);
-
- /**
- * Print usage information for the commands
- */
- void print_cmd_help(int out);
-
- /* Runs on its dedicated thread to process pushed stats event from socket. */
- void readLogs();
-
- /**
- * Trigger a broadcast.
- */
- status_t cmd_trigger_broadcast(int outFd, Vector<String8>& args);
-
-
- /**
- * Trigger an active configs changed broadcast.
- */
- status_t cmd_trigger_active_config_broadcast(int outFd, Vector<String8>& args);
-
- /**
- * Handle the config sub-command.
- */
- status_t cmd_config(int inFd, int outFd, int err, Vector<String8>& args);
-
- /**
- * Prints some basic stats to std out.
- */
- status_t cmd_print_stats(int outFd, const Vector<String8>& args);
-
- /**
- * Print the event log.
- */
- status_t cmd_dump_report(int outFd, const Vector<String8>& args);
-
- /**
- * Print the mapping of uids to package names.
- */
- status_t cmd_print_uid_map(int outFd, const Vector<String8>& args);
-
- /**
- * Flush the data to disk.
- */
- status_t cmd_write_data_to_disk(int outFd);
-
- /**
- * Write an AppBreadcrumbReported event to the StatsLog buffer, as if calling
- * StatsLog.write(APP_BREADCRUMB_REPORTED).
- */
- status_t cmd_log_app_breadcrumb(int outFd, const Vector<String8>& args);
-
- /**
- * Write an BinaryPushStateChanged event, as if calling StatsLog.logBinaryPushStateChanged().
- */
- status_t cmd_log_binary_push(int outFd, const Vector<String8>& args);
-
- /**
- * Print contents of a pulled metrics source.
- */
- status_t cmd_print_pulled_metrics(int outFd, const Vector<String8>& args);
-
- /**
- * Removes all configs stored on disk and on memory.
- */
- status_t cmd_remove_all_configs(int outFd);
-
- /*
- * Dump memory usage by statsd.
- */
- status_t cmd_dump_memory_info(int outFd);
-
- /*
- * Clear all puller cached data
- */
- status_t cmd_clear_puller_cache(int outFd);
-
- /**
- * Print all stats logs received to logcat.
- */
- status_t cmd_print_logs(int outFd, const Vector<String8>& args);
-
- /**
- * Writes the value of args[uidArgIndex] into uid.
- * Returns whether the uid is reasonable (type uid_t) and whether
- * 1. it is equal to the calling uid, or
- * 2. the device is mEngBuild, or
- * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL).
- */
- bool getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid);
-
- /**
- * Writes the value of uidSting into uid.
- * Returns whether the uid is reasonable (type uid_t) and whether
- * 1. it is equal to the calling uid, or
- * 2. the device is mEngBuild, or
- * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL).
- */
- bool getUidFromString(const char* uidString, int32_t& uid);
-
- /**
- * Adds a configuration after checking permissions and obtaining UID from binder call.
- */
- bool addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config);
-
- /**
- * Update a configuration.
- */
- void set_config(int uid, const string& name, const StatsdConfig& config);
-
- /**
- * Death recipient callback that is called when StatsCompanionService dies.
- * The cookie is a pointer to a StatsService object.
- */
- static void statsCompanionServiceDied(void* cookie);
-
- /**
- * Implementation of statsCompanionServiceDied.
- */
- void statsCompanionServiceDiedImpl();
-
- /**
- * Tracks the uid <--> package name mapping.
- */
- sp<UidMap> mUidMap;
-
- /**
- * Fetches external metrics
- */
- sp<StatsPullerManager> mPullerManager;
-
- /**
- * Tracks the configurations that have been passed to statsd.
- */
- sp<ConfigManager> mConfigManager;
-
- /**
- * The metrics recorder.
- */
- sp<StatsLogProcessor> mProcessor;
-
- /**
- * The alarm monitor for anomaly detection.
- */
- const sp<AlarmMonitor> mAnomalyAlarmMonitor;
-
- /**
- * The alarm monitor for alarms to directly trigger subscriber.
- */
- const sp<AlarmMonitor> mPeriodicAlarmMonitor;
-
- /**
- * Whether this is an eng build.
- */
- bool mEngBuild;
-
- sp<ShellSubscriber> mShellSubscriber;
-
- /**
- * Mutex for setting the shell subscriber
- */
- mutable mutex mShellSubscriberMutex;
- std::shared_ptr<LogEventQueue> mEventQueue;
-
- MultiConditionTrigger mBootCompleteTrigger;
- static const inline string kBootCompleteTag = "BOOT_COMPLETE";
- static const inline string kUidMapReceivedTag = "UID_MAP";
- static const inline string kAllPullersRegisteredTag = "PULLERS_REGISTERED";
-
- ScopedAIBinder_DeathRecipient mStatsCompanionServiceDeathRecipient;
-
- FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
- FRIEND_TEST(StatsServiceTest, TestAddConfig_simple);
- FRIEND_TEST(StatsServiceTest, TestAddConfig_empty);
- FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid);
- FRIEND_TEST(StatsServiceTest, TestGetUidFromArgs);
- FRIEND_TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp);
- FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot);
- FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade);
- FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval);
- FRIEND_TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit);
- FRIEND_TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket);
- FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket);
- FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket);
- FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket);
- FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket);
- FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // STATS_SERVICE_H
diff --git a/cmds/statsd/src/active_config_list.proto b/cmds/statsd/src/active_config_list.proto
deleted file mode 100644
index 9929833..0000000
--- a/cmds/statsd/src/active_config_list.proto
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_multiple_files = true;
-option java_outer_classname = "ActiveConfigProto";
-
-message ActiveEventActivation {
- optional int32 atom_matcher_index = 1;
-
- // Time left in activation. When this proto is loaded after device boot,
- // the activation should be set to active for this duration.
- // This field will only be set when the state is ACTIVE
- optional int64 remaining_ttl_nanos = 2;
-
- enum State {
- UNNKNOWN = 0;
- // This metric should activate for remaining_ttl_nanos when we load the activations.
- ACTIVE = 1;
- // When we load the activations, this metric should activate on next boot for the tll
- // specified in the config.
- ACTIVATE_ON_BOOT = 2;
- }
- optional State state = 3;
-}
-
-message ActiveMetric {
- optional int64 id = 1;
- repeated ActiveEventActivation activation = 2;
-}
-
-message ActiveConfig {
- optional int64 id = 1;
- optional int32 uid = 2;
- repeated ActiveMetric metric = 3;
-}
-
-// all configs and their metrics on device.
-message ActiveConfigList {
- repeated ActiveConfig config = 1;
-}
diff --git a/cmds/statsd/src/annotations.h b/cmds/statsd/src/annotations.h
deleted file mode 100644
index cf7f543..0000000
--- a/cmds/statsd/src/annotations.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const uint8_t ANNOTATION_ID_IS_UID = 1;
-const uint8_t ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2;
-const uint8_t ANNOTATION_ID_PRIMARY_FIELD = 3;
-const uint8_t ANNOTATION_ID_EXCLUSIVE_STATE = 4;
-const uint8_t ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5;
-const uint8_t ANNOTATION_ID_TRIGGER_STATE_RESET = 7;
-const uint8_t ANNOTATION_ID_STATE_NESTED = 8;
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.cpp b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
deleted file mode 100644
index b632d04..0000000
--- a/cmds/statsd/src/anomaly/AlarmMonitor.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false
-#include "Log.h"
-
-#include "anomaly/AlarmMonitor.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AlarmMonitor::AlarmMonitor(
- uint32_t minDiffToUpdateRegisteredAlarmTimeSec,
- const std::function<void(const shared_ptr<IStatsCompanionService>&, int64_t)>& updateAlarm,
- const std::function<void(const shared_ptr<IStatsCompanionService>&)>& cancelAlarm)
- : mRegisteredAlarmTimeSec(0),
- mMinUpdateTimeSec(minDiffToUpdateRegisteredAlarmTimeSec),
- mUpdateAlarm(updateAlarm),
- mCancelAlarm(cancelAlarm) {}
-
-AlarmMonitor::~AlarmMonitor() {}
-
-void AlarmMonitor::setStatsCompanionService(
- shared_ptr<IStatsCompanionService> statsCompanionService) {
- std::lock_guard<std::mutex> lock(mLock);
- shared_ptr<IStatsCompanionService> tmpForLock = mStatsCompanionService;
- mStatsCompanionService = statsCompanionService;
- if (statsCompanionService == nullptr) {
- VLOG("Erasing link to statsCompanionService");
- return;
- }
- VLOG("Creating link to statsCompanionService");
- const sp<const InternalAlarm> top = mPq.top();
- if (top != nullptr) {
- updateRegisteredAlarmTime_l(top->timestampSec);
- }
-}
-
-void AlarmMonitor::add(sp<const InternalAlarm> alarm) {
- std::lock_guard<std::mutex> lock(mLock);
- if (alarm == nullptr) {
- ALOGW("Asked to add a null alarm.");
- return;
- }
- if (alarm->timestampSec < 1) {
- // forbidden since a timestamp 0 is used to indicate no alarm registered
- ALOGW("Asked to add a 0-time alarm.");
- return;
- }
- // TODO(b/110563466): Ensure that refractory period is respected.
- VLOG("Adding alarm with time %u", alarm->timestampSec);
- mPq.push(alarm);
- if (mRegisteredAlarmTimeSec < 1 ||
- alarm->timestampSec + mMinUpdateTimeSec < mRegisteredAlarmTimeSec) {
- updateRegisteredAlarmTime_l(alarm->timestampSec);
- }
-}
-
-void AlarmMonitor::remove(sp<const InternalAlarm> alarm) {
- std::lock_guard<std::mutex> lock(mLock);
- if (alarm == nullptr) {
- ALOGW("Asked to remove a null alarm.");
- return;
- }
- VLOG("Removing alarm with time %u", alarm->timestampSec);
- bool wasPresent = mPq.remove(alarm);
- if (!wasPresent) return;
- if (mPq.empty()) {
- VLOG("Queue is empty. Cancel any alarm.");
- cancelRegisteredAlarmTime_l();
- return;
- }
- uint32_t soonestAlarmTimeSec = mPq.top()->timestampSec;
- VLOG("Soonest alarm is %u", soonestAlarmTimeSec);
- if (soonestAlarmTimeSec > mRegisteredAlarmTimeSec + mMinUpdateTimeSec) {
- updateRegisteredAlarmTime_l(soonestAlarmTimeSec);
- }
-}
-
-// More efficient than repeatedly calling remove(mPq.top()) since it batches the
-// updates to the registered alarm.
-unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> AlarmMonitor::popSoonerThan(
- uint32_t timestampSec) {
- VLOG("Removing alarms with time <= %u", timestampSec);
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> oldAlarms;
- std::lock_guard<std::mutex> lock(mLock);
-
- for (sp<const InternalAlarm> t = mPq.top(); t != nullptr && t->timestampSec <= timestampSec;
- t = mPq.top()) {
- oldAlarms.insert(t);
- mPq.pop(); // remove t
- }
- // Always update registered alarm time (if anything has changed).
- if (!oldAlarms.empty()) {
- if (mPq.empty()) {
- VLOG("Queue is empty. Cancel any alarm.");
- cancelRegisteredAlarmTime_l();
- } else {
- // Always update the registered alarm in this case (unlike remove()).
- updateRegisteredAlarmTime_l(mPq.top()->timestampSec);
- }
- }
- return oldAlarms;
-}
-
-void AlarmMonitor::updateRegisteredAlarmTime_l(uint32_t timestampSec) {
- VLOG("Updating reg alarm time to %u", timestampSec);
- mRegisteredAlarmTimeSec = timestampSec;
- mUpdateAlarm(mStatsCompanionService, secToMs(mRegisteredAlarmTimeSec));
-}
-
-void AlarmMonitor::cancelRegisteredAlarmTime_l() {
- VLOG("Cancelling reg alarm.");
- mRegisteredAlarmTimeSec = 0;
- mCancelAlarm(mStatsCompanionService);
-}
-
-int64_t AlarmMonitor::secToMs(uint32_t timeSec) {
- return ((int64_t)timeSec) * 1000;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.h b/cmds/statsd/src/anomaly/AlarmMonitor.h
deleted file mode 100644
index 5c34e38..0000000
--- a/cmds/statsd/src/anomaly/AlarmMonitor.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "anomaly/indexed_priority_queue.h"
-
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <utils/RefBase.h>
-
-#include <unordered_set>
-#include <vector>
-
-using namespace android;
-
-using aidl::android::os::IStatsCompanionService;
-using std::function;
-using std::shared_ptr;
-using std::unordered_set;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Represents an alarm, associated with some aggregate metric, holding a
- * projected time at which the metric is expected to exceed its anomaly
- * threshold.
- * Timestamps are in seconds since epoch in a uint32, so will fail in year 2106.
- */
-struct InternalAlarm : public RefBase {
- explicit InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) {
- }
-
- const uint32_t timestampSec;
-
- /** InternalAlarm a is smaller (higher priority) than b if its timestamp is sooner. */
- struct SmallerTimestamp {
- bool operator()(sp<const InternalAlarm> a, sp<const InternalAlarm> b) const {
- return (a->timestampSec < b->timestampSec);
- }
- };
-};
-
-/**
- * Manages internal alarms that may get registered with the AlarmManager.
- */
-class AlarmMonitor : public RefBase {
-public:
- /**
- * @param minDiffToUpdateRegisteredAlarmTimeSec If the soonest alarm differs
- * from the registered alarm by more than this amount, update the registered
- * alarm.
- */
- AlarmMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec,
- const function<void(const shared_ptr<IStatsCompanionService>&, int64_t)>&
- updateAlarm,
- const function<void(const shared_ptr<IStatsCompanionService>&)>& cancelAlarm);
- ~AlarmMonitor();
-
- /**
- * Tells AnomalyMonitor what IStatsCompanionService to use and, if
- * applicable, immediately registers an existing alarm with it.
- * If nullptr, AnomalyMonitor will continue to add/remove alarms, but won't
- * update IStatsCompanionService (until such time as it is set non-null).
- */
- void setStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService);
-
- /**
- * Adds the given alarm (reference) to the queue.
- */
- void add(sp<const InternalAlarm> alarm);
-
- /**
- * Removes the given alarm (reference) from the queue.
- * Note that alarm comparison is reference-based; if another alarm exists
- * with the same timestampSec, that alarm will still remain in the queue.
- */
- void remove(sp<const InternalAlarm> alarm);
-
- /**
- * Returns and removes all alarms whose timestamp <= the given timestampSec.
- * Always updates the registered alarm if return is non-empty.
- */
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> popSoonerThan(
- uint32_t timestampSec);
-
- /**
- * Returns the projected alarm timestamp that is registered with
- * StatsCompanionService. This may not be equal to the soonest alarm,
- * but should be within minDiffToUpdateRegisteredAlarmTimeSec of it.
- */
- uint32_t getRegisteredAlarmTimeSec() const {
- return mRegisteredAlarmTimeSec;
- }
-
-private:
- std::mutex mLock;
-
- /**
- * Timestamp (seconds since epoch) of the alarm registered with
- * StatsCompanionService. This, in general, may not be equal to the soonest
- * alarm stored in mPq, but should be within minUpdateTimeSec of it.
- * A value of 0 indicates that no alarm is currently registered.
- */
- uint32_t mRegisteredAlarmTimeSec;
-
- /**
- * Priority queue of alarms, prioritized by soonest alarm.timestampSec.
- */
- indexed_priority_queue<InternalAlarm, InternalAlarm::SmallerTimestamp> mPq;
-
- /**
- * Binder interface for communicating with StatsCompanionService.
- */
- shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr;
-
- /**
- * Amount by which the soonest projected alarm must differ from
- * mRegisteredAlarmTimeSec before updateRegisteredAlarmTime_l is called.
- */
- uint32_t mMinUpdateTimeSec;
-
- /**
- * Updates the alarm registered with StatsCompanionService to the given time.
- * Also correspondingly updates mRegisteredAlarmTimeSec.
- */
- void updateRegisteredAlarmTime_l(uint32_t timestampSec);
-
- /**
- * Cancels the alarm registered with StatsCompanionService.
- * Also correspondingly sets mRegisteredAlarmTimeSec to 0.
- */
- void cancelRegisteredAlarmTime_l();
-
- /** Converts uint32 timestamp in seconds to a Java long in msec. */
- int64_t secToMs(uint32_t timeSec);
-
- // Callback function to update the alarm via StatsCompanionService.
- std::function<void(const shared_ptr<IStatsCompanionService>, int64_t)> mUpdateAlarm;
-
- // Callback function to cancel the alarm via StatsCompanionService.
- std::function<void(const shared_ptr<IStatsCompanionService>)> mCancelAlarm;
-
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp
deleted file mode 100644
index 6d9beb8..0000000
--- a/cmds/statsd/src/anomaly/AlarmTracker.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "anomaly/AlarmTracker.h"
-#include "anomaly/subscriber_util.h"
-#include "HashableDimensionKey.h"
-#include "stats_util.h"
-#include "storage/StorageManager.h"
-
-#include <time.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AlarmTracker::AlarmTracker(const int64_t startMillis,
- const int64_t currentMillis,
- const Alarm& alarm, const ConfigKey& configKey,
- const sp<AlarmMonitor>& alarmMonitor)
- : mAlarmConfig(alarm),
- mConfigKey(configKey),
- mAlarmMonitor(alarmMonitor) {
- VLOG("AlarmTracker() called");
- mAlarmSec = (startMillis + mAlarmConfig.offset_millis()) / MS_PER_SEC;
- // startMillis is the time statsd is created. We need to find the 1st alarm timestamp after
- // the config is added to statsd.
- mAlarmSec = findNextAlarmSec(currentMillis / MS_PER_SEC); // round up
- mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
- VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec);
- if (mAlarmMonitor != nullptr) {
- mAlarmMonitor->add(mInternalAlarm);
- }
-}
-
-AlarmTracker::~AlarmTracker() {
- VLOG("~AlarmTracker() called");
- if (mInternalAlarm != nullptr && mAlarmMonitor != nullptr) {
- mAlarmMonitor->remove(mInternalAlarm);
- }
-}
-
-void AlarmTracker::addSubscription(const Subscription& subscription) {
- mSubscriptions.push_back(subscription);
-}
-
-int64_t AlarmTracker::findNextAlarmSec(int64_t currentTimeSec) {
- if (currentTimeSec < mAlarmSec) {
- return mAlarmSec;
- }
- int64_t periodsForward =
- ((currentTimeSec - mAlarmSec) * MS_PER_SEC) / mAlarmConfig.period_millis() + 1;
- return mAlarmSec + periodsForward * mAlarmConfig.period_millis() / MS_PER_SEC;
-}
-
-void AlarmTracker::informAlarmsFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
- if (firedAlarms.empty() || mInternalAlarm == nullptr ||
- firedAlarms.find(mInternalAlarm) == firedAlarms.end()) {
- return;
- }
- if (!mSubscriptions.empty()) {
- VLOG("AlarmTracker triggers the subscribers.");
- triggerSubscribers(mAlarmConfig.id(), 0 /*metricId N/A*/, DEFAULT_METRIC_DIMENSION_KEY,
- 0 /* metricValue N/A */, mConfigKey, mSubscriptions);
- }
- firedAlarms.erase(mInternalAlarm);
- mAlarmSec = findNextAlarmSec((timestampNs-1) / NS_PER_SEC + 1); // round up
- mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
- VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec);
- if (mAlarmMonitor != nullptr) {
- mAlarmMonitor->add(mInternalAlarm);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.h b/cmds/statsd/src/anomaly/AlarmTracker.h
deleted file mode 100644
index 2da4a18..0000000
--- a/cmds/statsd/src/anomaly/AlarmTracker.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-
-#include "AlarmMonitor.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alarm
-
-#include <stdlib.h>
-#include <utils/RefBase.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class AlarmTracker : public virtual RefBase {
-public:
- AlarmTracker(const int64_t startMillis,
- const int64_t currentMillis,
- const Alarm& alarm, const ConfigKey& configKey,
- const sp<AlarmMonitor>& subscriberAlarmMonitor);
-
- virtual ~AlarmTracker();
-
- void onAlarmFired();
-
- void addSubscription(const Subscription& subscription);
-
- void informAlarmsFired(const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms);
-
-protected:
- // For test only. Returns the alarm timestamp in seconds. Otherwise returns 0.
- inline int32_t getAlarmTimestampSec() const {
- return mInternalAlarm == nullptr ? 0 : mInternalAlarm->timestampSec;
- }
-
- int64_t findNextAlarmSec(int64_t currentTimeMillis);
-
- // statsd_config.proto Alarm message that defines this tracker.
- const Alarm mAlarmConfig;
-
- // A reference to the Alarm's config key.
- const ConfigKey mConfigKey;
-
- // The subscriptions that depend on this alarm.
- std::vector<Subscription> mSubscriptions;
-
- // Alarm monitor.
- sp<AlarmMonitor> mAlarmMonitor;
-
- // The current expected alarm time in seconds.
- int64_t mAlarmSec;
-
- // The current alarm.
- sp<const InternalAlarm> mInternalAlarm;
-
- FRIEND_TEST(AlarmTrackerTest, TestTriggerTimestamp);
- FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
deleted file mode 100644
index 619752c..0000000
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "AnomalyTracker.h"
-#include "external/Perfetto.h"
-#include "guardrail/StatsdStats.h"
-#include "metadata_util.h"
-#include "stats_log_util.h"
-#include "subscriber_util.h"
-#include "subscriber/IncidentdReporter.h"
-#include "subscriber/SubscriberReporter.h"
-
-#include <inttypes.h>
-#include <statslog_statsd.h>
-#include <time.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AnomalyTracker::AnomalyTracker(const Alert& alert, const ConfigKey& configKey)
- : mAlert(alert), mConfigKey(configKey), mNumOfPastBuckets(mAlert.num_buckets() - 1) {
- VLOG("AnomalyTracker() called");
- if (mAlert.num_buckets() <= 0) {
- ALOGE("Cannot create AnomalyTracker with %lld buckets", (long long)mAlert.num_buckets());
- return;
- }
- if (!mAlert.has_trigger_if_sum_gt()) {
- ALOGE("Cannot create AnomalyTracker without threshold");
- return;
- }
- resetStorage(); // initialization
-}
-
-AnomalyTracker::~AnomalyTracker() {
- VLOG("~AnomalyTracker() called");
-}
-
-void AnomalyTracker::resetStorage() {
- VLOG("resetStorage() called.");
- mPastBuckets.clear();
- // Excludes the current bucket.
- mPastBuckets.resize(mNumOfPastBuckets);
- mSumOverPastBuckets.clear();
-}
-
-size_t AnomalyTracker::index(int64_t bucketNum) const {
- if (bucketNum < 0) {
- ALOGE("index() was passed a negative bucket number (%lld)!", (long long)bucketNum);
- }
- return bucketNum % mNumOfPastBuckets;
-}
-
-void AnomalyTracker::advanceMostRecentBucketTo(const int64_t& bucketNum) {
- VLOG("advanceMostRecentBucketTo() called.");
- if (mNumOfPastBuckets <= 0) {
- return;
- }
- if (bucketNum <= mMostRecentBucketNum) {
- ALOGW("Cannot advance buckets backwards (bucketNum=%lld but mMostRecentBucketNum=%lld)",
- (long long)bucketNum, (long long)mMostRecentBucketNum);
- return;
- }
- // If in the future (i.e. buckets are ancient), just empty out all past info.
- if (bucketNum >= mMostRecentBucketNum + mNumOfPastBuckets) {
- resetStorage();
- mMostRecentBucketNum = bucketNum;
- return;
- }
-
- // Clear out space by emptying out old mPastBuckets[i] values and update mSumOverPastBuckets.
- for (int64_t i = mMostRecentBucketNum + 1; i <= bucketNum; i++) {
- const int idx = index(i);
- subtractBucketFromSum(mPastBuckets[idx]);
- mPastBuckets[idx] = nullptr; // release (but not clear) the old bucket.
- }
- mMostRecentBucketNum = bucketNum;
-}
-
-void AnomalyTracker::addPastBucket(const MetricDimensionKey& key,
- const int64_t& bucketValue,
- const int64_t& bucketNum) {
- VLOG("addPastBucket(bucketValue) called.");
- if (mNumOfPastBuckets == 0 ||
- bucketNum < 0 || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets) {
- return;
- }
-
- const int bucketIndex = index(bucketNum);
- if (bucketNum <= mMostRecentBucketNum && (mPastBuckets[bucketIndex] != nullptr)) {
- // We need to insert into an already existing past bucket.
- std::shared_ptr<DimToValMap>& bucket = mPastBuckets[bucketIndex];
- auto itr = bucket->find(key);
- if (itr != bucket->end()) {
- // Old entry already exists; update it.
- subtractValueFromSum(key, itr->second);
- itr->second = bucketValue;
- } else {
- bucket->insert({key, bucketValue});
- }
- mSumOverPastBuckets[key] += bucketValue;
- } else {
- // Bucket does not exist yet (in future or was never made), so we must make it.
- std::shared_ptr<DimToValMap> bucket = std::make_shared<DimToValMap>();
- bucket->insert({key, bucketValue});
- addPastBucket(bucket, bucketNum);
- }
-}
-
-void AnomalyTracker::addPastBucket(std::shared_ptr<DimToValMap> bucket,
- const int64_t& bucketNum) {
- VLOG("addPastBucket(bucket) called.");
- if (mNumOfPastBuckets == 0 ||
- bucketNum < 0 || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets) {
- return;
- }
-
- if (bucketNum <= mMostRecentBucketNum) {
- // We are updating an old bucket, not adding a new one.
- subtractBucketFromSum(mPastBuckets[index(bucketNum)]);
- } else {
- // Clear space for the new bucket to be at bucketNum.
- advanceMostRecentBucketTo(bucketNum);
- }
- mPastBuckets[index(bucketNum)] = bucket;
- addBucketToSum(bucket);
-}
-
-void AnomalyTracker::subtractBucketFromSum(const shared_ptr<DimToValMap>& bucket) {
- if (bucket == nullptr) {
- return;
- }
- for (const auto& keyValuePair : *bucket) {
- subtractValueFromSum(keyValuePair.first, keyValuePair.second);
- }
-}
-
-
-void AnomalyTracker::subtractValueFromSum(const MetricDimensionKey& key,
- const int64_t& bucketValue) {
- auto itr = mSumOverPastBuckets.find(key);
- if (itr == mSumOverPastBuckets.end()) {
- return;
- }
- itr->second -= bucketValue;
- if (itr->second == 0) {
- mSumOverPastBuckets.erase(itr);
- }
-}
-
-void AnomalyTracker::addBucketToSum(const shared_ptr<DimToValMap>& bucket) {
- if (bucket == nullptr) {
- return;
- }
- // For each dimension present in the bucket, add its value to its corresponding sum.
- for (const auto& keyValuePair : *bucket) {
- mSumOverPastBuckets[keyValuePair.first] += keyValuePair.second;
- }
-}
-
-int64_t AnomalyTracker::getPastBucketValue(const MetricDimensionKey& key,
- const int64_t& bucketNum) const {
- if (bucketNum < 0 || mMostRecentBucketNum < 0
- || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets
- || bucketNum > mMostRecentBucketNum) {
- return 0;
- }
-
- const auto& bucket = mPastBuckets[index(bucketNum)];
- if (bucket == nullptr) {
- return 0;
- }
- const auto& itr = bucket->find(key);
- return itr == bucket->end() ? 0 : itr->second;
-}
-
-int64_t AnomalyTracker::getSumOverPastBuckets(const MetricDimensionKey& key) const {
- const auto& itr = mSumOverPastBuckets.find(key);
- if (itr != mSumOverPastBuckets.end()) {
- return itr->second;
- }
- return 0;
-}
-
-bool AnomalyTracker::detectAnomaly(const int64_t& currentBucketNum,
- const MetricDimensionKey& key,
- const int64_t& currentBucketValue) {
-
- // currentBucketNum should be the next bucket after pastBuckets. If not, advance so that it is.
- if (currentBucketNum > mMostRecentBucketNum + 1) {
- advanceMostRecentBucketTo(currentBucketNum - 1);
- }
- return mAlert.has_trigger_if_sum_gt() &&
- getSumOverPastBuckets(key) + currentBucketValue > mAlert.trigger_if_sum_gt();
-}
-
-void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, int64_t metricId,
- const MetricDimensionKey& key, int64_t metricValue) {
- // TODO(b/110563466): Why receive timestamp? RefractoryPeriod should always be based on
- // real time right now.
- if (isInRefractoryPeriod(timestampNs, key)) {
- VLOG("Skipping anomaly declaration since within refractory period");
- return;
- }
- if (mAlert.has_refractory_period_secs()) {
- mRefractoryPeriodEndsSec[key] = ((timestampNs + NS_PER_SEC - 1) / NS_PER_SEC) // round up
- + mAlert.refractory_period_secs();
- // TODO(b/110563466): If we had access to the bucket_size_millis, consider
- // calling resetStorage()
- // if (mAlert.refractory_period_secs() > mNumOfPastBuckets * bucketSizeNs) {resetStorage();}
- }
-
- if (!mSubscriptions.empty()) {
- ALOGI("An anomaly (%" PRId64 ") %s has occurred! Informing subscribers.",
- mAlert.id(), key.toString().c_str());
- informSubscribers(key, metricId, metricValue);
- } else {
- ALOGI("An anomaly has occurred! (But no subscriber for that alert.)");
- }
-
- StatsdStats::getInstance().noteAnomalyDeclared(mConfigKey, mAlert.id());
-
- // TODO(b/110564268): This should also take in the const MetricDimensionKey& key?
- util::stats_write(util::ANOMALY_DETECTED, mConfigKey.GetUid(),
- mConfigKey.GetId(), mAlert.id());
-}
-
-void AnomalyTracker::detectAndDeclareAnomaly(const int64_t& timestampNs,
- const int64_t& currBucketNum, int64_t metricId,
- const MetricDimensionKey& key,
- const int64_t& currentBucketValue) {
- if (detectAnomaly(currBucketNum, key, currentBucketValue)) {
- declareAnomaly(timestampNs, metricId, key, currentBucketValue);
- }
-}
-
-bool AnomalyTracker::isInRefractoryPeriod(const int64_t& timestampNs,
- const MetricDimensionKey& key) const {
- const auto& it = mRefractoryPeriodEndsSec.find(key);
- if (it != mRefractoryPeriodEndsSec.end()) {
- return timestampNs < (it->second * (int64_t)NS_PER_SEC);
- }
- return false;
-}
-
-void AnomalyTracker::informSubscribers(const MetricDimensionKey& key, int64_t metric_id,
- int64_t metricValue) {
- triggerSubscribers(mAlert.id(), metric_id, key, metricValue, mConfigKey, mSubscriptions);
-}
-
-bool AnomalyTracker::writeAlertMetadataToProto(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::AlertMetadata* alertMetadata) {
- bool metadataWritten = false;
-
- if (mRefractoryPeriodEndsSec.empty()) {
- return false;
- }
-
- for (const auto& it: mRefractoryPeriodEndsSec) {
- // Do not write the timestamp to disk if it has already expired
- if (it.second < systemElapsedTimeNs / NS_PER_SEC) {
- continue;
- }
-
- metadataWritten = true;
- if (alertMetadata->alert_dim_keyed_data_size() == 0) {
- alertMetadata->set_alert_id(mAlert.id());
- }
-
- metadata::AlertDimensionKeyedData* keyedData = alertMetadata->add_alert_dim_keyed_data();
- // We convert and write the refractory_end_sec to wall clock time because we do not know
- // when statsd will start again.
- int32_t refractoryEndWallClockSec = (int32_t) ((currentWallClockTimeNs / NS_PER_SEC) +
- (it.second - systemElapsedTimeNs / NS_PER_SEC));
-
- keyedData->set_last_refractory_ends_sec(refractoryEndWallClockSec);
- writeMetricDimensionKeyToMetadataDimensionKey(
- it.first, keyedData->mutable_dimension_key());
- }
-
- return metadataWritten;
-}
-
-void AnomalyTracker::loadAlertMetadata(
- const metadata::AlertMetadata& alertMetadata,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- for (const metadata::AlertDimensionKeyedData& keyedData :
- alertMetadata.alert_dim_keyed_data()) {
- if ((uint64_t) keyedData.last_refractory_ends_sec() < currentWallClockTimeNs / NS_PER_SEC) {
- // Do not update the timestamp if it has already expired.
- continue;
- }
- MetricDimensionKey metricKey = loadMetricDimensionKeyFromProto(
- keyedData.dimension_key());
- int32_t refractoryPeriodEndsSec = (int32_t) keyedData.last_refractory_ends_sec() -
- currentWallClockTimeNs / NS_PER_SEC + systemElapsedTimeNs / NS_PER_SEC;
- mRefractoryPeriodEndsSec[metricKey] = refractoryPeriodEndsSec;
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h
deleted file mode 100644
index bf36a3b..0000000
--- a/cmds/statsd/src/anomaly/AnomalyTracker.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdlib.h>
-
-#include <gtest/gtest_prod.h>
-#include <utils/RefBase.h>
-
-#include "AlarmMonitor.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alert
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h" // AlertMetadata
-#include "stats_util.h" // HashableDimensionKey and DimToValMap
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::shared_ptr;
-using std::unordered_map;
-
-// Does NOT allow negative values.
-class AnomalyTracker : public virtual RefBase {
-public:
- AnomalyTracker(const Alert& alert, const ConfigKey& configKey);
-
- virtual ~AnomalyTracker();
-
- // Add subscriptions that depend on this alert.
- void addSubscription(const Subscription& subscription) {
- mSubscriptions.push_back(subscription);
- }
-
- // Adds a bucket for the given bucketNum (index starting at 0).
- // If a bucket for bucketNum already exists, it will be replaced.
- // Also, advances to bucketNum (if not in the past), effectively filling any intervening
- // buckets with 0s.
- void addPastBucket(std::shared_ptr<DimToValMap> bucket, const int64_t& bucketNum);
-
- // Inserts (or replaces) the bucket entry for the given bucketNum at the given key to be the
- // given bucketValue. If the bucket does not exist, it will be created.
- // Also, advances to bucketNum (if not in the past), effectively filling any intervening
- // buckets with 0s.
- void addPastBucket(const MetricDimensionKey& key, const int64_t& bucketValue,
- const int64_t& bucketNum);
-
- // Returns true if, based on past buckets plus the new currentBucketValue (which generally
- // represents the partially-filled current bucket), an anomaly has happened.
- // Also advances to currBucketNum-1.
- bool detectAnomaly(const int64_t& currBucketNum, const MetricDimensionKey& key,
- const int64_t& currentBucketValue);
-
- // Informs incidentd about the detected alert.
- void declareAnomaly(const int64_t& timestampNs, int64_t metricId, const MetricDimensionKey& key,
- int64_t metricValue);
-
- // Detects if, based on past buckets plus the new currentBucketValue (which generally
- // represents the partially-filled current bucket), an anomaly has happened, and if so,
- // declares an anomaly and informs relevant subscribers.
- // Also advances to currBucketNum-1.
- void detectAndDeclareAnomaly(const int64_t& timestampNs, const int64_t& currBucketNum,
- int64_t metricId, const MetricDimensionKey& key,
- const int64_t& currentBucketValue);
-
- // Init the AlarmMonitor which is shared across anomaly trackers.
- virtual void setAlarmMonitor(const sp<AlarmMonitor>& alarmMonitor) {
- return; // Base AnomalyTracker class has no need for the AlarmMonitor.
- }
-
- // Returns the sum of all past bucket values for the given dimension key.
- int64_t getSumOverPastBuckets(const MetricDimensionKey& key) const;
-
- // Returns the value for a past bucket, or 0 if that bucket doesn't exist.
- int64_t getPastBucketValue(const MetricDimensionKey& key, const int64_t& bucketNum) const;
-
- // Returns the anomaly threshold set in the configuration.
- inline int64_t getAnomalyThreshold() const {
- return mAlert.trigger_if_sum_gt();
- }
-
- // Returns the refractory period ending timestamp (in seconds) for the given key.
- // Before this moment, any detected anomaly will be ignored.
- // If there is no stored refractory period ending timestamp, returns 0.
- uint32_t getRefractoryPeriodEndsSec(const MetricDimensionKey& key) const {
- const auto& it = mRefractoryPeriodEndsSec.find(key);
- return it != mRefractoryPeriodEndsSec.end() ? it->second : 0;
- }
-
- // Returns the (constant) number of past buckets this anomaly tracker can store.
- inline int getNumOfPastBuckets() const {
- return mNumOfPastBuckets;
- }
-
- // Declares an anomaly for each alarm in firedAlarms that belongs to this AnomalyTracker,
- // and removes it from firedAlarms. Does NOT remove the alarm from the AlarmMonitor.
- virtual void informAlarmsFired(const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
- return; // The base AnomalyTracker class doesn't have alarms.
- }
-
- // Writes metadata of the alert (refractory_period_end_sec) to AlertMetadata.
- // Returns true if at least one element is written to alertMetadata.
- bool writeAlertMetadataToProto(
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs, metadata::AlertMetadata* alertMetadata);
-
- void loadAlertMetadata(
- const metadata::AlertMetadata& alertMetadata,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs);
-
-protected:
- // For testing only.
- // Returns the alarm timestamp in seconds for the query dimension if it exists. Otherwise
- // returns 0.
- virtual uint32_t getAlarmTimestampSec(const MetricDimensionKey& dimensionKey) const {
- return 0; // The base AnomalyTracker class doesn't have alarms.
- }
-
- // statsd_config.proto Alert message that defines this tracker.
- const Alert mAlert;
-
- // The subscriptions that depend on this alert.
- std::vector<Subscription> mSubscriptions;
-
- // A reference to the Alert's config key.
- const ConfigKey mConfigKey;
-
- // Number of past buckets. One less than the total number of buckets needed
- // for the anomaly detection (since the current bucket is not in the past).
- const int mNumOfPastBuckets;
-
- // Values for each of the past mNumOfPastBuckets buckets. Always of size mNumOfPastBuckets.
- // mPastBuckets[i] can be null, meaning that no data is present in that bucket.
- std::vector<shared_ptr<DimToValMap>> mPastBuckets;
-
- // Cached sum over all existing buckets in mPastBuckets.
- // Its buckets never contain entries of 0.
- DimToValMap mSumOverPastBuckets;
-
- // The bucket number of the last added bucket.
- int64_t mMostRecentBucketNum = -1;
-
- // Map from each dimension to the timestamp that its refractory period (if this anomaly was
- // declared for that dimension) ends, in seconds. From this moment and onwards, anomalies
- // can be declared again.
- // Entries may be, but are not guaranteed to be, removed after the period is finished.
- unordered_map<MetricDimensionKey, uint32_t> mRefractoryPeriodEndsSec;
-
- // Advances mMostRecentBucketNum to bucketNum, deleting any data that is now too old.
- // Specifically, since it is now too old, removes the data for
- // [mMostRecentBucketNum - mNumOfPastBuckets + 1, bucketNum - mNumOfPastBuckets].
- void advanceMostRecentBucketTo(const int64_t& bucketNum);
-
- // Add the information in the given bucket to mSumOverPastBuckets.
- void addBucketToSum(const shared_ptr<DimToValMap>& bucket);
-
- // Subtract the information in the given bucket from mSumOverPastBuckets
- // and remove any items with value 0.
- void subtractBucketFromSum(const shared_ptr<DimToValMap>& bucket);
-
- // From mSumOverPastBuckets[key], subtracts bucketValue, removing it if it is now 0.
- void subtractValueFromSum(const MetricDimensionKey& key, const int64_t& bucketValue);
-
- // Returns true if in the refractory period, else false.
- bool isInRefractoryPeriod(const int64_t& timestampNs, const MetricDimensionKey& key) const;
-
- // Calculates the corresponding bucket index within the circular array.
- // Requires bucketNum >= 0.
- size_t index(int64_t bucketNum) const;
-
- // Resets all bucket data. For use when all the data gets stale.
- virtual void resetStorage();
-
- // Informs the subscribers (incidentd, perfetto, broadcasts, etc) that an anomaly has occurred.
- void informSubscribers(const MetricDimensionKey& key, int64_t metricId, int64_t metricValue);
-
- FRIEND_TEST(AnomalyTrackerTest, TestConsecutiveBuckets);
- FRIEND_TEST(AnomalyTrackerTest, TestSparseBuckets);
- FRIEND_TEST(GaugeMetricProducerTest, TestAnomalyDetection);
- FRIEND_TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
deleted file mode 100644
index 2b56810..0000000
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "DurationAnomalyTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-DurationAnomalyTracker::DurationAnomalyTracker(const Alert& alert, const ConfigKey& configKey,
- const sp<AlarmMonitor>& alarmMonitor)
- : AnomalyTracker(alert, configKey), mAlarmMonitor(alarmMonitor) {
- VLOG("DurationAnomalyTracker() called");
-}
-
-DurationAnomalyTracker::~DurationAnomalyTracker() {
- VLOG("~DurationAnomalyTracker() called");
- cancelAllAlarms();
-}
-
-void DurationAnomalyTracker::startAlarm(const MetricDimensionKey& dimensionKey,
- const int64_t& timestampNs) {
- // Alarms are stored in secs. Must round up, since if it fires early, it is ignored completely.
- uint32_t timestampSec = static_cast<uint32_t>((timestampNs -1) / NS_PER_SEC) + 1; // round up
- if (isInRefractoryPeriod(timestampNs, dimensionKey)) {
- VLOG("Not setting anomaly alarm since it would fall in the refractory period.");
- return;
- }
-
- auto itr = mAlarms.find(dimensionKey);
- if (itr != mAlarms.end() && mAlarmMonitor != nullptr) {
- mAlarmMonitor->remove(itr->second);
- }
-
- sp<const InternalAlarm> alarm = new InternalAlarm{timestampSec};
- mAlarms[dimensionKey] = alarm;
- if (mAlarmMonitor != nullptr) {
- mAlarmMonitor->add(alarm);
- }
-}
-
-void DurationAnomalyTracker::stopAlarm(const MetricDimensionKey& dimensionKey,
- const int64_t& timestampNs) {
- const auto itr = mAlarms.find(dimensionKey);
- if (itr == mAlarms.end()) {
- return;
- }
-
- // If the alarm is set in the past but hasn't fired yet (due to lag), catch it now.
- if (itr->second != nullptr && timestampNs >= (int64_t)NS_PER_SEC * itr->second->timestampSec) {
- declareAnomaly(timestampNs, mAlert.metric_id(), dimensionKey,
- mAlert.trigger_if_sum_gt() + (timestampNs / NS_PER_SEC) -
- itr->second->timestampSec);
- }
- if (mAlarmMonitor != nullptr) {
- mAlarmMonitor->remove(itr->second);
- }
- mAlarms.erase(dimensionKey);
-}
-
-void DurationAnomalyTracker::cancelAllAlarms() {
- if (mAlarmMonitor != nullptr) {
- for (const auto& itr : mAlarms) {
- mAlarmMonitor->remove(itr.second);
- }
- }
- mAlarms.clear();
-}
-
-void DurationAnomalyTracker::informAlarmsFired(const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
-
- if (firedAlarms.empty() || mAlarms.empty()) return;
- // Find the intersection of firedAlarms and mAlarms.
- // The for loop is inefficient, since it loops over all keys, but that's okay since it is very
- // seldomly called. The alternative would be having InternalAlarms store information about the
- // DurationAnomalyTracker and key, but that's a lot of data overhead to speed up something that
- // is rarely ever called.
- unordered_map<MetricDimensionKey, sp<const InternalAlarm>> matchedAlarms;
- for (const auto& kv : mAlarms) {
- if (firedAlarms.count(kv.second) > 0) {
- matchedAlarms.insert({kv.first, kv.second});
- }
- }
-
- // Now declare each of these alarms to have fired.
- for (const auto& kv : matchedAlarms) {
- declareAnomaly(
- timestampNs, mAlert.metric_id(), kv.first,
- mAlert.trigger_if_sum_gt() + (timestampNs / NS_PER_SEC) - kv.second->timestampSec);
- mAlarms.erase(kv.first);
- firedAlarms.erase(kv.second); // No one else can also own it, so we're done with it.
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
deleted file mode 100644
index 686d8f9..0000000
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "AlarmMonitor.h"
-#include "AnomalyTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-
-class DurationAnomalyTracker : public virtual AnomalyTracker {
-public:
- DurationAnomalyTracker(const Alert& alert, const ConfigKey& configKey,
- const sp<AlarmMonitor>& alarmMonitor);
-
- virtual ~DurationAnomalyTracker();
-
- // Sets an alarm for the given timestamp.
- // Replaces previous alarm if one already exists.
- void startAlarm(const MetricDimensionKey& dimensionKey, const int64_t& eventTime);
-
- // Stops the alarm.
- // If it should have already fired, but hasn't yet (e.g. because the AlarmManager is delayed),
- // declare the anomaly now.
- void stopAlarm(const MetricDimensionKey& dimensionKey, const int64_t& timestampNs);
-
- // Stop all the alarms owned by this tracker. Does not declare any anomalies.
- void cancelAllAlarms();
-
- // Declares an anomaly for each alarm in firedAlarms that belongs to this DurationAnomalyTracker
- // and removes it from firedAlarms. The AlarmMonitor is not informed.
- // Note that this will generally be called from a different thread from the other functions;
- // the caller is responsible for thread safety.
- void informAlarmsFired(const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) override;
-
-protected:
- // Returns the alarm timestamp in seconds for the query dimension if it exists. Otherwise
- // returns 0.
- uint32_t getAlarmTimestampSec(const MetricDimensionKey& dimensionKey) const override {
- auto it = mAlarms.find(dimensionKey);
- return it == mAlarms.end() ? 0 : it->second->timestampSec;
- }
-
- // The alarms owned by this tracker. The alarm monitor also shares the alarm pointers when they
- // are still active.
- std::unordered_map<MetricDimensionKey, sp<const InternalAlarm>> mAlarms;
-
- // Anomaly alarm monitor.
- sp<AlarmMonitor> mAlarmMonitor;
-
- FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm);
- FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyDetection);
- FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp);
- FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/indexed_priority_queue.h b/cmds/statsd/src/anomaly/indexed_priority_queue.h
deleted file mode 100644
index 99882d0..0000000
--- a/cmds/statsd/src/anomaly/indexed_priority_queue.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <utils/RefBase.h>
-#include <unordered_map>
-#include <vector>
-
-using namespace android;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/** Defines a hash function for sp<const AA>, returning the hash of the underlying pointer. */
-template <class AA>
-struct SpHash {
- size_t operator()(const sp<const AA>& k) const {
- return std::hash<const AA*>()(k.get());
- }
-};
-
-/**
- * Min priority queue for generic type AA.
- * Unlike a regular priority queue, this class is also capable of removing interior elements.
- * @tparam Comparator must implement [bool operator()(sp<const AA> a, sp<const AA> b)], returning
- * whether a should be closer to the top of the queue than b.
- */
-template <class AA, class Comparator>
-class indexed_priority_queue {
-public:
- indexed_priority_queue();
- /** Adds a into the priority queue. If already present or a==nullptr, does nothing. */
- void push(sp<const AA> a);
- /*
- * Removes a from the priority queue. If not present or a==nullptr, does nothing.
- * Returns true if a had been present (and is now removed), else false.
- */
- bool remove(sp<const AA> a);
- /** Removes the top element, if there is one. */
- void pop();
- /** Removes all elements. */
- void clear();
- /** Returns whether priority queue contains a (not just a copy of a, but a itself). */
- bool contains(sp<const AA> a) const;
- /** Returns min element. Returns nullptr iff empty(). */
- sp<const AA> top() const;
- /** Returns number of elements in priority queue. */
- size_t size() const {
- return pq.size() - 1;
- } // pq is 1-indexed
- /** Returns true iff priority queue is empty. */
- bool empty() const {
- return size() < 1;
- }
-
-private:
- /** Vector representing a min-heap (1-indexed, with nullptr at 0). */
- std::vector<sp<const AA>> pq;
- /** Mapping of each element in pq to its index in pq (i.e. the inverse of a=pq[i]). */
- std::unordered_map<sp<const AA>, size_t, SpHash<AA>> indices;
-
- void init();
- void sift_up(size_t idx);
- void sift_down(size_t idx);
- /** Returns whether pq[idx1] is considered higher than pq[idx2], according to Comparator. */
- bool higher(size_t idx1, size_t idx2) const;
- void swap_indices(size_t i, size_t j);
-};
-
-// Implementation must be done in this file due to use of template.
-
-template <class AA, class Comparator>
-indexed_priority_queue<AA, Comparator>::indexed_priority_queue() {
- init();
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::push(sp<const AA> a) {
- if (a == nullptr) return;
- if (contains(a)) return;
- pq.push_back(a);
- size_t idx = size(); // index of last element since 1-indexed
- indices.insert({a, idx});
- sift_up(idx); // get the pq back in order
-}
-
-template <class AA, class Comparator>
-bool indexed_priority_queue<AA, Comparator>::remove(sp<const AA> a) {
- if (a == nullptr) return false;
- if (!contains(a)) return false;
- size_t idx = indices[a];
- if (idx >= pq.size()) {
- return false;
- }
- if (idx == size()) { // if a is the last element, i.e. at index idx == size() == (pq.size()-1)
- pq.pop_back();
- indices.erase(a);
- return true;
- }
- // move last element (guaranteed not to be at idx) to idx, then delete a
- sp<const AA> last_a = pq.back();
- pq[idx] = last_a;
- pq.pop_back();
- indices[last_a] = idx;
- indices.erase(a);
-
- // get the heap back in order (since the element at idx is not in order)
- sift_up(idx);
- sift_down(idx);
-
- return true;
-}
-
-// The same as, but slightly more efficient than, remove(top()).
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::pop() {
- sp<const AA> a = top();
- if (a == nullptr) return;
- const size_t idx = 1;
- if (idx == size()) { // if a is the last element
- pq.pop_back();
- indices.erase(a);
- return;
- }
- // move last element (guaranteed not to be at idx) to idx, then delete a
- sp<const AA> last_a = pq.back();
- pq[idx] = last_a;
- pq.pop_back();
- indices[last_a] = idx;
- indices.erase(a);
-
- // get the heap back in order (since the element at idx is not in order)
- sift_down(idx);
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::clear() {
- pq.clear();
- indices.clear();
- init();
-}
-
-template <class AA, class Comparator>
-sp<const AA> indexed_priority_queue<AA, Comparator>::top() const {
- if (empty()) return nullptr;
- return pq[1];
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::init() {
- pq.push_back(nullptr); // so that pq is 1-indexed.
- indices.insert({nullptr, 0}); // just to be consistent with pq.
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::sift_up(size_t idx) {
- while (idx > 1) {
- size_t parent = idx / 2;
- if (higher(idx, parent))
- swap_indices(idx, parent);
- else
- break;
- idx = parent;
- }
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::sift_down(size_t idx) {
- while (2 * idx <= size()) {
- size_t child = 2 * idx;
- if (child < size() && higher(child + 1, child)) child++;
- if (higher(child, idx))
- swap_indices(child, idx);
- else
- break;
- idx = child;
- }
-}
-
-template <class AA, class Comparator>
-bool indexed_priority_queue<AA, Comparator>::higher(size_t idx1, size_t idx2) const {
- if (!(0u < idx1 && idx1 < pq.size() && 0u < idx2 && idx2 < pq.size())) {
- return false; // got to do something.
- }
- return Comparator()(pq[idx1], pq[idx2]);
-}
-
-template <class AA, class Comparator>
-bool indexed_priority_queue<AA, Comparator>::contains(sp<const AA> a) const {
- if (a == nullptr) return false; // publicly, we pretend that nullptr is not actually in pq.
- return indices.count(a) > 0;
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::swap_indices(size_t i, size_t j) {
- if (!(0u < i && i < pq.size() && 0u < j && j < pq.size())) {
- return;
- }
- sp<const AA> val_i = pq[i];
- sp<const AA> val_j = pq[j];
- pq[i] = val_j;
- pq[j] = val_i;
- indices[val_i] = j;
- indices[val_j] = i;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/subscriber_util.cpp b/cmds/statsd/src/anomaly/subscriber_util.cpp
deleted file mode 100644
index 5a4a41d..0000000
--- a/cmds/statsd/src/anomaly/subscriber_util.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "external/Perfetto.h"
-#include "subscriber/IncidentdReporter.h"
-#include "subscriber/SubscriberReporter.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void triggerSubscribers(int64_t ruleId, int64_t metricId, const MetricDimensionKey& dimensionKey,
- int64_t metricValue, const ConfigKey& configKey,
- const std::vector<Subscription>& subscriptions) {
- VLOG("informSubscribers called.");
- if (subscriptions.empty()) {
- VLOG("No Subscriptions were associated.");
- return;
- }
-
- for (const Subscription& subscription : subscriptions) {
- if (subscription.probability_of_informing() < 1
- && ((float)rand() / (float)RAND_MAX) >= subscription.probability_of_informing()) {
- // Note that due to float imprecision, 0.0 and 1.0 might not truly mean never/always.
- // The config writer was advised to use -0.1 and 1.1 for never/always.
- ALOGI("Fate decided that a subscriber would not be informed.");
- continue;
- }
- switch (subscription.subscriber_information_case()) {
- case Subscription::SubscriberInformationCase::kIncidentdDetails:
- if (!GenerateIncidentReport(subscription.incidentd_details(), ruleId, metricId,
- dimensionKey, metricValue, configKey)) {
- ALOGW("Failed to generate incident report.");
- }
- break;
- case Subscription::SubscriberInformationCase::kPerfettoDetails:
- if (!CollectPerfettoTraceAndUploadToDropbox(subscription.perfetto_details(),
- subscription.id(), ruleId, configKey)) {
- ALOGW("Failed to generate perfetto traces.");
- }
- break;
- case Subscription::SubscriberInformationCase::kBroadcastSubscriberDetails:
- SubscriberReporter::getInstance().alertBroadcastSubscriber(configKey, subscription,
- dimensionKey);
- break;
- default:
- break;
- }
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/subscriber_util.h b/cmds/statsd/src/anomaly/subscriber_util.h
deleted file mode 100644
index 1df3c89..0000000
--- a/cmds/statsd/src/anomaly/subscriber_util.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-#include "HashableDimensionKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void triggerSubscribers(const int64_t ruleId, const int64_t metricId,
- const MetricDimensionKey& dimensionKey, int64_t metricValue,
- const ConfigKey& configKey, const std::vector<Subscription>& subscriptions);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
deleted file mode 100644
index ff5717e..0000000
--- a/cmds/statsd/src/atom_field_options.proto
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_multiple_files = true;
-option java_outer_classname = "AtomFieldOptions";
-
-import "google/protobuf/descriptor.proto";
-
-// Used to annotate an atom that represents a state change. A state change atom must have exactly
-// ONE exclusive state field, and any number of primary key fields. For example, message
-// UidProcessStateChanged {
-// optional int32 uid = 1 [(state_field_option).primary_field = true];
-// optional android.app.ProcessStateEnum state =
-// 2 [(state_field_option).exclusive_state = true];
-// }
-// Each UidProcessStateChanged atom event represents a state change for a specific uid.
-// A new state automatically overrides the previous state.
-//
-// If the atom has 2 or more primary fields, it means the combination of the
-// primary fields are the primary key.
-// For example:
-// message ThreadStateChanged {
-// optional int32 pid = 1 [(state_field_option).primary_field = true];
-// optional int32 tid = 2 [(state_field_option).primary_field = true];
-// optional int32 state = 3 [(state_field_option).exclusive_state = true];
-// }
-//
-// Sometimes, there is no primary key field, when the state is GLOBAL.
-// For example,
-// message ScreenStateChanged {
-// optional android.view.DisplayStateEnum state =
-// 1 [(state_field_option).exclusive_state = true];
-// }
-//
-// For state atoms with attribution chain, sometimes the primary key is the first uid in the chain.
-// For example:
-// message AudioStateChanged {
-// repeated AttributionNode attribution_node = 1
-// [(stateFieldOption).primary_field_first_uid = true];
-//
-// enum State {
-// OFF = 0;
-// ON = 1;
-// // RESET indicates all audio stopped. Used when it (re)starts (e.g. after it crashes).
-// RESET = 2;
-// }
-// optional State state = 2 [(stateFieldOption).exclusive_state = true];
-// }
-message StateAtomFieldOption {
- // Fields that represent the key that the state belongs to.
- // Used on simple proto fields. Do not use on attribution chains.
- optional bool primary_field = 1 [default = false];
-
- // The field that represents the state. It's an exclusive state.
- optional bool exclusive_state = 2 [default = false];
-
- // Used on an attribution chain field to indicate that the first uid is the
- // primary field.
- optional bool primary_field_first_uid = 3 [default = false];
-
- // Note: We cannot annotate directly on the enums because many enums are imported from other
- // proto files in the platform. proto-lite cc library does not support annotations unfortunately
-
- // Knowing the default state value allows state trackers to remove entries that become the
- // default state. If there is no default value specified, the default value is unknown, and all
- // states will be tracked in memory.
- optional int32 default_state_value = 4;
-
- // A reset state signals all states go to default value. For example, BLE reset means all active
- // BLE scans are to be turned off.
- optional int32 trigger_state_reset_value = 5;
-
- // If the state change needs to count nesting.
- optional bool nested = 6 [default = true];
-}
-
-// Used to generate StatsLog.write APIs.
-enum LogMode {
- MODE_UNSET = 0;
- // Log fields as their actual types e.g., all primary data types.
- // Or fields that are hardcoded in stats_log_api_gen tool e.g., AttributionNode
- MODE_AUTOMATIC = 1;
- // Log fields in their proto binary format. These fields will not be parsed in statsd
- MODE_BYTES = 2;
-}
-
-extend google.protobuf.FieldOptions {
- // Flags to decorate an atom that presents a state change.
- optional StateAtomFieldOption state_field_option = 50000;
-
- // Flags to decorate the uid fields in an atom.
- optional bool is_uid = 50001 [default = false];
-
- optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];
-
- repeated string module = 50004;
-
- optional bool truncate_timestamp = 50005 [default = false];
-}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
deleted file mode 100644
index 36b46c3..0000000
--- a/cmds/statsd/src/atoms.proto
+++ /dev/null
@@ -1,11179 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_outer_classname = "AtomsProto";
-
-import "frameworks/base/cmds/statsd/src/atom_field_options.proto";
-import "frameworks/base/core/proto/android/app/enums.proto";
-import "frameworks/base/core/proto/android/app/job/enums.proto";
-import "frameworks/base/core/proto/android/app/settings_enums.proto";
-import "frameworks/base/core/proto/android/app/media_output_enum.proto";
-import "frameworks/base/core/proto/android/app/tvsettings_enums.proto";
-import "frameworks/base/core/proto/android/bluetooth/a2dp/enums.proto";
-import "frameworks/base/core/proto/android/bluetooth/enums.proto";
-import "frameworks/base/core/proto/android/bluetooth/hci/enums.proto";
-import "frameworks/base/core/proto/android/bluetooth/hfp/enums.proto";
-import "frameworks/base/core/proto/android/bluetooth/smp/enums.proto";
-import "frameworks/base/core/proto/android/debug/enums.proto";
-import "frameworks/base/core/proto/android/hardware/biometrics/enums.proto";
-import "frameworks/base/core/proto/android/hardware/sensor/assist/enums.proto";
-import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
-import "frameworks/base/core/proto/android/os/enums.proto";
-import "frameworks/base/core/proto/android/server/connectivity/data_stall_event.proto";
-import "frameworks/base/core/proto/android/server/enums.proto";
-import "frameworks/base/core/proto/android/server/job/enums.proto";
-import "frameworks/base/core/proto/android/server/location/enums.proto";
-import "frameworks/base/core/proto/android/service/procstats_enum.proto";
-import "frameworks/base/core/proto/android/service/usb.proto";
-import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto";
-import "frameworks/base/core/proto/android/stats/connectivity/tethering.proto";
-import "frameworks/base/core/proto/android/stats/dnsresolver/dns_resolver.proto";
-import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto";
-import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy_enums.proto";
-import "frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto";
-import "frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto";
-import "frameworks/base/core/proto/android/stats/enums.proto";
-import "frameworks/base/core/proto/android/stats/intelligence/enums.proto";
-import "frameworks/base/core/proto/android/stats/launcher/launcher.proto";
-import "frameworks/base/core/proto/android/stats/location/location_enums.proto";
-import "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.proto";
-import "frameworks/base/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto";
-import "frameworks/base/core/proto/android/stats/storage/storage_enums.proto";
-import "frameworks/base/core/proto/android/stats/style/style_enums.proto";
-import "frameworks/base/core/proto/android/stats/sysui/notification_enums.proto";
-import "frameworks/base/core/proto/android/telecomm/enums.proto";
-import "frameworks/base/core/proto/android/telephony/enums.proto";
-import "frameworks/base/core/proto/android/view/enums.proto";
-import "frameworks/base/core/proto/android/wifi/enums.proto";
-import "frameworks/base/core/proto/android/stats/textclassifier/textclassifier_enums.proto";
-import "frameworks/base/core/proto/android/stats/otaupdate/updateengine_enums.proto";
-
-/**
- * The master atom class. This message defines all of the available
- * raw stats log events from the Android system, also known as "atoms."
- *
- * This field contains a single oneof with all of the available messages.
- * The stats-log-api-gen tool runs as part of the Android build and
- * generates the android.util.StatsLog class, which contains the constants
- * and methods that Android uses to log.
- *
- * This Atom class is not actually built into the Android system.
- * Instead, statsd on Android constructs these messages synthetically,
- * in the format defined here and in stats_log.proto.
- */
-message Atom {
- // Pushed atoms start at 2.
- oneof pushed {
- // For StatsLog reasons, 1 is illegal and will not work. Must start at 2.
- BleScanStateChanged ble_scan_state_changed = 2
- [(module) = "bluetooth", (module) = "statsdtest"];
- ProcessStateChanged process_state_changed = 3 [(module) = "framework"];
- BleScanResultReceived ble_scan_result_received = 4 [(module) = "bluetooth"];
- SensorStateChanged sensor_state_changed =
- 5 [(module) = "framework", (module) = "statsdtest"];
- GpsScanStateChanged gps_scan_state_changed = 6 [(module) = "framework"];
- SyncStateChanged sync_state_changed = 7 [(module) = "framework", (module) = "statsdtest"];
- ScheduledJobStateChanged scheduled_job_state_changed =
- 8 [(module) = "framework", (module) = "statsdtest"];
- ScreenBrightnessChanged screen_brightness_changed =
- 9 [(module) = "framework", (module) = "statsdtest"];
- WakelockStateChanged wakelock_state_changed =
- 10 [(module) = "framework", (module) = "statsdtest"];
- LongPartialWakelockStateChanged long_partial_wakelock_state_changed =
- 11 [(module) = "framework"];
- MobileRadioPowerStateChanged mobile_radio_power_state_changed =
- 12 [(module) = "framework", (truncate_timestamp) = true];
- WifiRadioPowerStateChanged wifi_radio_power_state_changed = 13 [(module) = "framework"];
- ActivityManagerSleepStateChanged activity_manager_sleep_state_changed =
- 14 [(module) = "framework"];
- MemoryFactorStateChanged memory_factor_state_changed = 15 [(module) = "framework"];
- ExcessiveCpuUsageReported excessive_cpu_usage_reported = 16 [(module) = "framework"];
- CachedKillReported cached_kill_reported = 17 [(module) = "framework"];
- ProcessMemoryStatReported process_memory_stat_reported = 18 [(module) = "framework"];
- LauncherUIChanged launcher_event = 19 [(module) = "sysui"];
- BatterySaverModeStateChanged battery_saver_mode_state_changed =
- 20 [(module) = "framework", (module) = "statsdtest"];
- DeviceIdleModeStateChanged device_idle_mode_state_changed = 21 [(module) = "framework"];
- DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22 [(module) = "framework"];
- AudioStateChanged audio_state_changed =
- 23 [(module) = "framework", (truncate_timestamp) = true];
- MediaCodecStateChanged media_codec_state_changed = 24 [(module) = "framework"];
- CameraStateChanged camera_state_changed = 25 [(module) = "framework"];
- FlashlightStateChanged flashlight_state_changed = 26 [(module) = "framework"];
- UidProcessStateChanged uid_process_state_changed =
- 27 [(module) = "framework", (module) = "statsdtest"];
- ProcessLifeCycleStateChanged process_life_cycle_state_changed =
- 28 [(module) = "framework", (module) = "statsdtest"];
- ScreenStateChanged screen_state_changed =
- 29 [(module) = "framework", (module) = "statsdtest"];
- BatteryLevelChanged battery_level_changed =
- 30 [(module) = "framework", (module) = "statsdtest"];
- ChargingStateChanged charging_state_changed = 31 [(module) = "framework"];
- PluggedStateChanged plugged_state_changed = 32
- [(module) = "framework", (module) = "statsdtest"];
- InteractiveStateChanged interactive_state_changed = 33 [(module) = "framework"];
- TouchEventReported touch_event_reported = 34;
- WakeupAlarmOccurred wakeup_alarm_occurred = 35 [(module) = "framework"];
- KernelWakeupReported kernel_wakeup_reported = 36 [(module) = "framework"];
- WifiLockStateChanged wifi_lock_state_changed = 37 [(module) = "wifi"];
- WifiSignalStrengthChanged wifi_signal_strength_changed = 38 [(module) = "wifi"];
- WifiScanStateChanged wifi_scan_state_changed = 39 [(module) = "wifi"];
- PhoneSignalStrengthChanged phone_signal_strength_changed =
- 40 [(module) = "framework", (truncate_timestamp) = true];
- SettingChanged setting_changed = 41 [(module) = "framework"];
- ActivityForegroundStateChanged activity_foreground_state_changed =
- 42 [(module) = "framework", (module) = "statsdtest"];
- IsolatedUidChanged isolated_uid_changed =
- 43 [(module) = "framework", (module) = "statsd", (module) = "statsdtest"];
- PacketWakeupOccurred packet_wakeup_occurred = 44 [(module) = "framework"];
- WallClockTimeShifted wall_clock_time_shifted = 45 [(module) = "framework"];
- AnomalyDetected anomaly_detected = 46 [(module) = "statsd"];
- AppBreadcrumbReported app_breadcrumb_reported = 47 [(module) = "statsd"];
- AppStartOccurred app_start_occurred = 48 [(module) = "framework", (module) = "statsdtest"];
- AppStartCanceled app_start_canceled = 49 [(module) = "framework"];
- AppStartFullyDrawn app_start_fully_drawn = 50 [(module) = "framework"];
- LmkKillOccurred lmk_kill_occurred = 51 [(module) = "lmkd"];
- PictureInPictureStateChanged picture_in_picture_state_changed = 52 [(module) = "framework"];
- WifiMulticastLockStateChanged wifi_multicast_lock_state_changed = 53 [(module) = "wifi"];
- LmkStateChanged lmk_state_changed = 54 [(module) = "lmkd"];
- AppStartMemoryStateCaptured app_start_memory_state_captured = 55 [(module) = "framework"];
- ShutdownSequenceReported shutdown_sequence_reported = 56 [(module) = "framework"];
- BootSequenceReported boot_sequence_reported = 57;
- DaveyOccurred davey_occurred = 58 [(module) = "statsd"];
- OverlayStateChanged overlay_state_changed =
- 59 [(module) = "framework", (module) = "statsdtest"];
- ForegroundServiceStateChanged foreground_service_state_changed
- = 60 [(module) = "framework"];
- CallStateChanged call_state_changed =
- 61 [(module) = "telecom", (truncate_timestamp) = true];
- KeyguardStateChanged keyguard_state_changed = 62 [(module) = "sysui"];
- KeyguardBouncerStateChanged keyguard_bouncer_state_changed = 63 [(module) = "sysui"];
- KeyguardBouncerPasswordEntered keyguard_bouncer_password_entered = 64 [(module) = "sysui"];
- AppDied app_died = 65 [(module) = "framework"];
- ResourceConfigurationChanged resource_configuration_changed = 66 [(module) = "framework"];
- BluetoothEnabledStateChanged bluetooth_enabled_state_changed = 67 [(module) = "framework"];
- BluetoothConnectionStateChanged bluetooth_connection_state_changed =
- 68 [(module) = "bluetooth"];
- GpsSignalQualityChanged gps_signal_quality_changed = 69 [(module) = "framework"];
- UsbConnectorStateChanged usb_connector_state_changed = 70 [(module) = "framework"];
- SpeakerImpedanceReported speaker_impedance_reported = 71;
- HardwareFailed hardware_failed = 72;
- PhysicalDropDetected physical_drop_detected = 73;
- ChargeCyclesReported charge_cycles_reported = 74;
- MobileConnectionStateChanged mobile_connection_state_changed = 75 [(module) = "telephony"];
- MobileRadioTechnologyChanged mobile_radio_technology_changed = 76 [(module) = "telephony"];
- UsbDeviceAttached usb_device_attached = 77 [(module) = "framework"];
- AppCrashOccurred app_crash_occurred = 78 [(module) = "framework", (module) = "statsdtest"];
- ANROccurred anr_occurred = 79 [(module) = "framework"];
- WTFOccurred wtf_occurred = 80 [(module) = "framework"];
- LowMemReported low_mem_reported = 81 [(module) = "framework"];
- GenericAtom generic_atom = 82;
- KeyValuePairsAtom key_value_pairs_atom = 83 [(module) = "framework", (module) = "statsd"];
- VibratorStateChanged vibrator_state_changed = 84 [(module) = "framework"];
- DeferredJobStatsReported deferred_job_stats_reported = 85 [(module) = "framework"];
- ThermalThrottlingStateChanged thermal_throttling = 86 [deprecated=true];
- BiometricAcquired biometric_acquired = 87 [(module) = "framework"];
- BiometricAuthenticated biometric_authenticated = 88 [(module) = "framework"];
- BiometricErrorOccurred biometric_error_occurred = 89 [(module) = "framework"];
- UiEventReported ui_event_reported = 90 [(module) = "framework", (module) = "sysui"];
- BatteryHealthSnapshot battery_health_snapshot = 91;
- SlowIo slow_io = 92;
- BatteryCausedShutdown battery_caused_shutdown = 93;
- PhoneServiceStateChanged phone_service_state_changed = 94 [(module) = "framework"];
- PhoneStateChanged phone_state_changed = 95 [(module) = "framework"];
- UserRestrictionChanged user_restriction_changed = 96;
- SettingsUIChanged settings_ui_changed = 97 [(module) = "settings"];
- ConnectivityStateChanged connectivity_state_changed = 98 [(module) = "framework"];
- // TODO: service state change is very noisy shortly after boot, as well
- // as at other transitions - coming out of doze, device plugged in, etc.
- // Consider removing this if it becomes a problem
- ServiceStateChanged service_state_changed = 99 [(module) = "framework"];
- ServiceLaunchReported service_launch_reported = 100 [(module) = "framework"];
- FlagFlipUpdateOccurred flag_flip_update_occurred = 101 [(module) = "framework"];
- BinaryPushStateChanged binary_push_state_changed = 102 [(module) = "statsd"];
- DevicePolicyEvent device_policy_event = 103 [(module) = "framework"];
- DocsUIFileOperationCanceledReported docs_ui_file_op_canceled = 104 [(module) = "docsui"];
- DocsUIFileOperationCopyMoveModeReported docs_ui_file_op_copy_move_mode_reported =
- 105 [(module) = "docsui"];
- DocsUIFileOperationFailureReported docs_ui_file_op_failure = 106 [(module) = "docsui"];
- DocsUIFileOperationReported docs_ui_provider_file_op = 107 [(module) = "docsui"];
- DocsUIInvalidScopedAccessRequestReported docs_ui_invalid_scoped_access_request =
- 108 [(module) = "docsui"];
- DocsUILaunchReported docs_ui_launch_reported = 109 [(module) = "docsui"];
- DocsUIRootVisitedReported docs_ui_root_visited = 110 [(module) = "docsui"];
- DocsUIStartupMsReported docs_ui_startup_ms = 111 [(module) = "docsui"];
- DocsUIUserActionReported docs_ui_user_action_reported = 112 [(module) = "docsui"];
- WifiEnabledStateChanged wifi_enabled_state_changed = 113 [(module) = "framework"];
- WifiRunningStateChanged wifi_running_state_changed = 114
- [(module) = "framework", deprecated = true];
- AppCompacted app_compacted = 115 [(module) = "framework"];
- NetworkDnsEventReported network_dns_event_reported = 116 [(module) = "resolv"];
- DocsUIPickerLaunchedFromReported docs_ui_picker_launched_from_reported =
- 117 [(module) = "docsui"];
- DocsUIPickResultReported docs_ui_pick_result_reported = 118 [(module) = "docsui"];
- DocsUISearchModeReported docs_ui_search_mode_reported = 119 [(module) = "docsui"];
- DocsUISearchTypeReported docs_ui_search_type_reported = 120 [(module) = "docsui"];
- DataStallEvent data_stall_event = 121 [(module) = "network_stack"];
- RescuePartyResetReported rescue_party_reset_reported = 122 [(module) = "framework"];
- SignedConfigReported signed_config_reported = 123 [(module) = "framework"];
- GnssNiEventReported gnss_ni_event_reported = 124 [(module) = "framework"];
- BluetoothLinkLayerConnectionEvent bluetooth_link_layer_connection_event =
- 125 [(module) = "bluetooth"];
- BluetoothAclConnectionStateChanged bluetooth_acl_connection_state_changed =
- 126 [(module) = "bluetooth"];
- BluetoothScoConnectionStateChanged bluetooth_sco_connection_state_changed =
- 127 [(module) = "bluetooth"];
- AppDowngraded app_downgraded = 128 [(module) = "framework"];
- AppOptimizedAfterDowngraded app_optimized_after_downgraded = 129;
- LowStorageStateChanged low_storage_state_changed = 130 [(module) = "framework"];
- GnssNfwNotificationReported gnss_nfw_notification_reported = 131 [(module) = "framework"];
- GnssConfigurationReported gnss_configuration_reported = 132 [(module) = "framework"];
- UsbPortOverheatEvent usb_port_overheat_event_reported = 133;
- NfcErrorOccurred nfc_error_occurred = 134 [(module) = "nfc"];
- NfcStateChanged nfc_state_changed = 135 [(module) = "nfc"];
- NfcBeamOccurred nfc_beam_occurred = 136 [(module) = "nfc"];
- NfcCardemulationOccurred nfc_cardemulation_occurred = 137 [(module) = "nfc"];
- NfcTagOccurred nfc_tag_occurred = 138 [(module) = "nfc"];
- NfcHceTransactionOccurred nfc_hce_transaction_occurred = 139 [(module) = "nfc"];
- SeStateChanged se_state_changed = 140 [(module) = "secure_element"];
- SeOmapiReported se_omapi_reported = 141 [(module) = "secure_element"];
- BroadcastDispatchLatencyReported broadcast_dispatch_latency_reported =
- 142 [(module) = "framework"];
- AttentionManagerServiceResultReported attention_manager_service_result_reported =
- 143 [(module) = "framework"];
- AdbConnectionChanged adb_connection_changed = 144 [(module) = "framework"];
- SpeechDspStatReported speech_dsp_stat_reported = 145;
- UsbContaminantReported usb_contaminant_reported = 146 [(module) = "framework"];
- WatchdogRollbackOccurred watchdog_rollback_occurred =
- 147 [(module) = "framework", (module) = "statsd"];
- BiometricSystemHealthIssueDetected biometric_system_health_issue_detected =
- 148 [(module) = "framework"];
- BubbleUIChanged bubble_ui_changed = 149 [(module) = "sysui"];
- ScheduledJobConstraintChanged scheduled_job_constraint_changed =
- 150 [(module) = "framework"];
- BluetoothActiveDeviceChanged bluetooth_active_device_changed =
- 151 [(module) = "bluetooth"];
- BluetoothA2dpPlaybackStateChanged bluetooth_a2dp_playback_state_changed =
- 152 [(module) = "bluetooth"];
- BluetoothA2dpCodecConfigChanged bluetooth_a2dp_codec_config_changed =
- 153 [(module) = "bluetooth"];
- BluetoothA2dpCodecCapabilityChanged bluetooth_a2dp_codec_capability_changed =
- 154 [(module) = "bluetooth"];
- BluetoothA2dpAudioUnderrunReported bluetooth_a2dp_audio_underrun_reported =
- 155 [(module) = "bluetooth"];
- BluetoothA2dpAudioOverrunReported bluetooth_a2dp_audio_overrun_reported =
- 156 [(module) = "bluetooth"];
- BluetoothDeviceRssiReported bluetooth_device_rssi_reported =
- 157 [(module) = "bluetooth"];
- BluetoothDeviceFailedContactCounterReported
- bluetooth_device_failed_contact_counter_reported = 158 [(module) = "bluetooth"];
- BluetoothDeviceTxPowerLevelReported bluetooth_device_tx_power_level_reported =
- 159 [(module) = "bluetooth"];
- BluetoothHciTimeoutReported bluetooth_hci_timeout_reported =
- 160 [(module) = "bluetooth"];
- BluetoothQualityReportReported bluetooth_quality_report_reported =
- 161 [(module) = "bluetooth"];
- BluetoothDeviceInfoReported bluetooth_device_info_reported =
- 162 [(module) = "bluetooth"];
- BluetoothRemoteVersionInfoReported bluetooth_remote_version_info_reported =
- 163 [(module) = "bluetooth"];
- BluetoothSdpAttributeReported bluetooth_sdp_attribute_reported =
- 164 [(module) = "bluetooth"];
- BluetoothBondStateChanged bluetooth_bond_state_changed =
- 165 [(module) = "bluetooth"];
- BluetoothClassicPairingEventReported bluetooth_classic_pairing_event_reported =
- 166 [(module) = "bluetooth"];
- BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported =
- 167 [(module) = "bluetooth"];
- ScreenTimeoutExtensionReported screen_timeout_extension_reported =
- 168 [(module) = "framework"];
- ProcessStartTime process_start_time = 169 [(module) = "framework"];
- PermissionGrantRequestResultReported permission_grant_request_result_reported =
- 170 [(module) = "permissioncontroller"];
- BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
- DeviceIdentifierAccessDenied device_identifier_access_denied =
- 172 [(module) = "telephony_common"];
- BubbleDeveloperErrorReported bubble_developer_error_reported = 173 [(module) = "framework"];
- AssistGestureStageReported assist_gesture_stage_reported = 174 [(module) = "sysui"];
- AssistGestureFeedbackReported assist_gesture_feedback_reported = 175 [(module) = "sysui"];
- AssistGestureProgressReported assist_gesture_progress_reported = 176 [(module) = "sysui"];
- TouchGestureClassified touch_gesture_classified = 177 [(module) = "framework"];
- HiddenApiUsed hidden_api_used = 178 [(module) = "framework"];
- StyleUIChanged style_ui_changed = 179 [(module) = "sysui"];
- PrivacyIndicatorsInteracted privacy_indicators_interacted =
- 180 [(module) = "permissioncontroller"];
- AppInstallOnExternalStorageReported app_install_on_external_storage_reported =
- 181 [(module) = "framework"];
- NetworkStackReported network_stack_reported = 182 [(module) = "network_stack"];
- AppMovedStorageReported app_moved_storage_reported = 183 [(module) = "framework"];
- BiometricEnrolled biometric_enrolled = 184 [(module) = "framework"];
- SystemServerWatchdogOccurred system_server_watchdog_occurred = 185 [(module) = "framework"];
- TombStoneOccurred tomb_stone_occurred = 186 [(module) = "framework"];
- BluetoothClassOfDeviceReported bluetooth_class_of_device_reported =
- 187 [(module) = "bluetooth"];
- IntelligenceEventReported intelligence_event_reported =
- 188 [(module) = "intelligence"];
- ThermalThrottlingSeverityStateChanged thermal_throttling_severity_state_changed =
- 189 [(module) = "framework"];
- RoleRequestResultReported role_request_result_reported =
- 190 [(module) = "permissioncontroller"];
- MediametricsAudiopolicyReported mediametrics_audiopolicy_reported = 191;
- MediametricsAudiorecordReported mediametrics_audiorecord_reported = 192;
- MediametricsAudiothreadReported mediametrics_audiothread_reported = 193;
- MediametricsAudiotrackReported mediametrics_audiotrack_reported = 194;
- MediametricsCodecReported mediametrics_codec_reported = 195;
- MediametricsDrmWidevineReported mediametrics_drm_widevine_reported = 196;
- MediametricsExtractorReported mediametrics_extractor_reported = 197;
- MediametricsMediadrmReported mediametrics_mediadrm_reported = 198;
- MediametricsNuPlayerReported mediametrics_nuplayer_reported = 199;
- MediametricsRecorderReported mediametrics_recorder_reported = 200;
- MediametricsDrmManagerReported mediametrics_drmmanager_reported = 201;
- CarPowerStateChanged car_power_state_changed = 203 [(module) = "car"];
- GarageModeInfo garage_mode_info = 204 [(module) = "car"];
- TestAtomReported test_atom_reported = 205 [(module) = "cts"];
- ContentCaptureCallerMismatchReported content_capture_caller_mismatch_reported =
- 206 [(module) = "framework"];
- ContentCaptureServiceEvents content_capture_service_events = 207 [(module) = "framework"];
- ContentCaptureSessionEvents content_capture_session_events = 208 [(module) = "framework"];
- ContentCaptureFlushed content_capture_flushed = 209 [(module) = "framework"];
- LocationManagerApiUsageReported location_manager_api_usage_reported =
- 210 [(module) = "framework"];
- ReviewPermissionsFragmentResultReported review_permissions_fragment_result_reported =
- 211 [(module) = "permissioncontroller"];
- RuntimePermissionsUpgradeResult runtime_permissions_upgrade_result =
- 212 [(module) = "permissioncontroller"];
- GrantPermissionsActivityButtonActions grant_permissions_activity_button_actions =
- 213 [(module) = "permissioncontroller"];
- LocationAccessCheckNotificationAction location_access_check_notification_action =
- 214 [(module) = "permissioncontroller"];
- AppPermissionFragmentActionReported app_permission_fragment_action_reported =
- 215 [(module) = "permissioncontroller"];
- AppPermissionFragmentViewed app_permission_fragment_viewed =
- 216 [(module) = "permissioncontroller"];
- AppPermissionsFragmentViewed app_permissions_fragment_viewed =
- 217 [(module) = "permissioncontroller"];
- PermissionAppsFragmentViewed permission_apps_fragment_viewed =
- 218 [(module) = "permissioncontroller"];
- TextSelectionEvent text_selection_event = 219 [(module) = "textclassifier"];
- TextLinkifyEvent text_linkify_event = 220 [(module) = "textclassifier"];
- ConversationActionsEvent conversation_actions_event = 221 [(module) = "textclassifier"];
- LanguageDetectionEvent language_detection_event = 222 [(module) = "textclassifier"];
- ExclusionRectStateChanged exclusion_rect_state_changed = 223 [(module) = "framework"];
- BackGesture back_gesture_reported_reported = 224 [(module) = "sysui"];
- UpdateEngineUpdateAttemptReported update_engine_update_attempt_reported = 225;
- UpdateEngineSuccessfulUpdateReported update_engine_successful_update_reported = 226;
- CameraActionEvent camera_action_event = 227 [(module) = "framework"];
- AppCompatibilityChangeReported app_compatibility_change_reported =
- 228 [(module) = "framework"];
- PerfettoUploaded perfetto_uploaded = 229 [(module) = "perfetto"];
- VmsClientConnectionStateChanged vms_client_connection_state_changed =
- 230 [(module) = "car"];
- MediaProviderScanOccurred media_provider_scan_occurred = 233 [(module) = "mediaprovider"];
- MediaContentDeleted media_content_deleted = 234 [(module) = "mediaprovider"];
- MediaProviderPermissionRequested media_provider_permission_requested =
- 235 [(module) = "mediaprovider"];
- MediaProviderSchemaChanged media_provider_schema_changed = 236 [(module) = "mediaprovider"];
- MediaProviderIdleMaintenanceFinished media_provider_idle_maintenance_finished =
- 237 [(module) = "mediaprovider"];
- RebootEscrowRecoveryReported reboot_escrow_recovery_reported = 238 [(module) = "framework"];
- BootTimeEventDuration boot_time_event_duration_reported = 239 [(module) = "framework"];
- BootTimeEventElapsedTime boot_time_event_elapsed_time_reported =
- 240 [(module) = "framework"];
- BootTimeEventUtcTime boot_time_event_utc_time_reported = 241;
- BootTimeEventErrorCode boot_time_event_error_code_reported = 242 [(module) = "framework"];
- UserspaceRebootReported userspace_reboot_reported = 243 [(module) = "framework"];
- NotificationReported notification_reported = 244 [(module) = "framework"];
- NotificationPanelReported notification_panel_reported = 245 [(module) = "sysui"];
- NotificationChannelModified notification_channel_modified = 246 [(module) = "framework"];
- IntegrityCheckResultReported integrity_check_result_reported = 247 [(module) = "framework"];
- IntegrityRulesPushed integrity_rules_pushed = 248 [(module) = "framework"];
- CellBroadcastMessageReported cb_message_reported =
- 249 [(module) = "cellbroadcast"];
- CellBroadcastMessageError cb_message_error =
- 250 [(module) = "cellbroadcast"];
- WifiHealthStatReported wifi_health_stat_reported = 251 [(module) = "wifi"];
- WifiFailureStatReported wifi_failure_stat_reported = 252 [(module) = "wifi"];
- WifiConnectionResultReported wifi_connection_result_reported = 253 [(module) = "wifi"];
- AppFreezeChanged app_freeze_changed = 254 [(module) = "framework"];
- SnapshotMergeReported snapshot_merge_reported = 255;
- ForegroundServiceAppOpSessionEnded foreground_service_app_op_session_ended =
- 256 [(module) = "framework"];
- DisplayJankReported display_jank_reported = 257;
- AppStandbyBucketChanged app_standby_bucket_changed = 258 [(module) = "framework"];
- SharesheetStarted sharesheet_started = 259 [(module) = "framework"];
- RankingSelected ranking_selected = 260 [(module) = "framework", (module) = "sysui"];
- TvSettingsUIInteracted tvsettings_ui_interacted = 261 [(module) = "tv_settings"];
- LauncherStaticLayout launcher_snapshot = 262 [(module) = "sysui"];
- PackageInstallerV2Reported package_installer_v2_reported = 263 [(module) = "framework"];
- UserLifecycleJourneyReported user_lifecycle_journey_reported = 264 [(module) = "framework"];
- UserLifecycleEventOccurred user_lifecycle_event_occurred = 265 [(module) = "framework"];
- AccessibilityShortcutReported accessibility_shortcut_reported =
- 266 [(module) = "framework"];
- AccessibilityServiceReported accessibility_service_reported = 267 [(module) = "settings"];
- DocsUIDragAndDropReported docs_ui_drag_and_drop_reported = 268 [(module) = "docsui"];
- AppUsageEventOccurred app_usage_event_occurred = 269 [(module) = "framework"];
- AutoRevokeNotificationClicked auto_revoke_notification_clicked =
- 270 [(module) = "permissioncontroller"];
- AutoRevokeFragmentAppViewed auto_revoke_fragment_app_viewed =
- 271 [(module) = "permissioncontroller"];
- AutoRevokedAppInteraction auto_revoked_app_interaction =
- 272 [(module) = "permissioncontroller", (module) = "settings"];
- AppPermissionGroupsFragmentAutoRevokeAction
- app_permission_groups_fragment_auto_revoke_action =
- 273 [(module) = "permissioncontroller"];
- EvsUsageStatsReported evs_usage_stats_reported = 274 [(module) = "evs"];
- AudioPowerUsageDataReported audio_power_usage_data_reported = 275;
- TvTunerStateChanged tv_tuner_state_changed = 276 [(module) = "framework"];
- MediaOutputOpSwitchReported mediaoutput_op_switch_reported =
- 277 [(module) = "settings"];
- CellBroadcastMessageFiltered cb_message_filtered =
- 278 [(module) = "cellbroadcast"];
- TvTunerDvrStatus tv_tuner_dvr_status = 279 [(module) = "framework"];
- TvCasSessionOpenStatus tv_cas_session_open_status =
- 280 [(module) = "framework"];
- AssistantInvocationReported assistant_invocation_reported = 281 [(module) = "framework"];
- DisplayWakeReported display_wake_reported = 282 [(module) = "framework"];
- CarUserHalModifyUserRequestReported car_user_hal_modify_user_request_reported =
- 283 [(module) = "car"];
- CarUserHalModifyUserResponseReported car_user_hal_modify_user_response_reported =
- 284 [(module) = "car"];
- CarUserHalPostSwitchResponseReported car_user_hal_post_switch_response_reported =
- 285 [(module) = "car"];
- CarUserHalInitialUserInfoRequestReported car_user_hal_initial_user_info_request_reported =
- 286 [(module) = "car"];
- CarUserHalInitialUserInfoResponseReported car_user_hal_initial_user_info_response_reported =
- 287 [(module) = "car"];
- CarUserHalUserAssociationRequestReported car_user_hal_user_association_request_reported =
- 288 [(module) = "car"];
- CarUserHalSetUserAssociationResponseReported car_user_hal_set_user_association_response_reported =
- 289 [(module) = "car"];
- NetworkIpProvisioningReported network_ip_provisioning_reported =
- 290 [(module) = "network_stack"];
- NetworkDhcpRenewReported network_dhcp_renew_reported = 291 [(module) = "network_stack"];
- NetworkValidationReported network_validation_reported = 292 [(module) = "network_stack"];
- NetworkStackQuirkReported network_stack_quirk_reported = 293 [(module) = "network_stack"];
- MediametricsAudioRecordDeviceUsageReported mediametrics_audiorecorddeviceusage_reported =
- 294;
- MediametricsAudioThreadDeviceUsageReported mediametrics_audiothreaddeviceusage_reported =
- 295;
- MediametricsAudioTrackDeviceUsageReported mediametrics_audiotrackdeviceusage_reported =
- 296;
- MediametricsAudioDeviceConnectionReported mediametrics_audiodeviceconnection_reported =
- 297;
- BlobCommitted blob_committed = 298 [(module) = "framework"];
- BlobLeased blob_leased = 299 [(module) = "framework"];
- BlobOpened blob_opened = 300 [(module) = "framework"];
- ContactsProviderStatusReported contacts_provider_status_reported = 301;
- KeystoreKeyEventReported keystore_key_event_reported = 302;
- NetworkTetheringReported network_tethering_reported =
- 303 [(module) = "network_tethering"];
- ImeTouchReported ime_touch_reported = 304 [(module) = "sysui"];
-
- // StatsdStats tracks platform atoms with ids upto 500.
- // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value.
- }
-
- // Pulled events will start at field 10000.
- // Next: 10084
- oneof pulled {
- WifiBytesTransfer wifi_bytes_transfer = 10000 [(module) = "framework"];
- WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001 [(module) = "framework"];
- MobileBytesTransfer mobile_bytes_transfer =
- 10002 [(module) = "framework", (truncate_timestamp) = true];
- MobileBytesTransferByFgBg mobile_bytes_transfer_by_fg_bg =
- 10003 [(module) = "framework", (truncate_timestamp) = true];
- BluetoothBytesTransfer bluetooth_bytes_transfer = 10006 [(module) = "framework"];
- KernelWakelock kernel_wakelock = 10004 [(module) = "framework"];
- SubsystemSleepState subsystem_sleep_state = 10005 [(module) = "statsdtest"];
- CpuTimePerFreq cpu_time_per_freq = 10008 [(module) = "framework"];
- CpuTimePerUid cpu_time_per_uid = 10009 [(module) = "framework", (module) = "statsdtest"];
- CpuTimePerUidFreq cpu_time_per_uid_freq =
- 10010 [(module) = "framework", (module) = "statsd"];
- WifiActivityInfo wifi_activity_info = 10011 [(module) = "framework"];
- ModemActivityInfo modem_activity_info = 10012 [(module) = "framework"];
- BluetoothActivityInfo bluetooth_activity_info = 10007 [(module) = "framework"];
- ProcessMemoryState process_memory_state = 10013 [(module) = "framework"];
- SystemElapsedRealtime system_elapsed_realtime = 10014 [(module) = "framework"];
- SystemUptime system_uptime = 10015 [(module) = "framework"];
- CpuActiveTime cpu_active_time = 10016 [(module) = "framework", (module) = "statsdtest"];
- CpuClusterTime cpu_cluster_time = 10017 [(module) = "framework"];
- DiskSpace disk_space = 10018 [deprecated=true, (module) = "statsdtest"];
- RemainingBatteryCapacity remaining_battery_capacity = 10019 [(module) = "framework"];
- FullBatteryCapacity full_battery_capacity = 10020 [(module) = "framework"];
- Temperature temperature = 10021 [(module) = "framework", (module) = "statsdtest"];
- BinderCalls binder_calls = 10022 [(module) = "framework", (module) = "statsd"];
- BinderCallsExceptions binder_calls_exceptions = 10023 [(module) = "framework"];
- LooperStats looper_stats = 10024 [(module) = "framework", (module) = "statsd"];
- DiskStats disk_stats = 10025 [(module) = "framework"];
- DirectoryUsage directory_usage = 10026 [(module) = "framework"];
- AppSize app_size = 10027 [(module) = "framework"];
- CategorySize category_size = 10028 [(module) = "framework"];
- ProcStats proc_stats = 10029 [(module) = "framework"];
- BatteryVoltage battery_voltage = 10030 [(module) = "framework"];
- NumFingerprintsEnrolled num_fingerprints_enrolled = 10031 [(module) = "framework"];
- DiskIo disk_io = 10032 [(module) = "framework"];
- PowerProfile power_profile = 10033 [(module) = "framework"];
- ProcStatsPkgProc proc_stats_pkg_proc = 10034 [(module) = "framework"];
- ProcessCpuTime process_cpu_time = 10035 [(module) = "framework"];
- CpuTimePerThreadFreq cpu_time_per_thread_freq = 10037 [(module) = "framework"];
- OnDevicePowerMeasurement on_device_power_measurement = 10038;
- DeviceCalculatedPowerUse device_calculated_power_use = 10039 [(module) = "framework"];
- DeviceCalculatedPowerBlameUid device_calculated_power_blame_uid =
- 10040 [(module) = "framework"];
- DeviceCalculatedPowerBlameOther device_calculated_power_blame_other =
- 10041 [(module) = "framework"];
- ProcessMemoryHighWaterMark process_memory_high_water_mark = 10042 [(module) = "framework"];
- BatteryLevel battery_level = 10043 [(module) = "framework"];
- BuildInformation build_information = 10044 [(module) = "framework"];
- BatteryCycleCount battery_cycle_count = 10045 [(module) = "framework"];
- DebugElapsedClock debug_elapsed_clock = 10046 [(module) = "framework"];
- DebugFailingElapsedClock debug_failing_elapsed_clock = 10047 [(module) = "framework"];
- NumFacesEnrolled num_faces_enrolled = 10048 [(module) = "framework"];
- RoleHolder role_holder = 10049 [(module) = "framework"];
- DangerousPermissionState dangerous_permission_state = 10050 [(module) = "framework"];
- TrainInfo train_info = 10051 [(module) = "statsd"];
- TimeZoneDataInfo time_zone_data_info = 10052 [(module) = "framework"];
- ExternalStorageInfo external_storage_info = 10053 [(module) = "framework"];
- GpuStatsGlobalInfo gpu_stats_global_info = 10054;
- GpuStatsAppInfo gpu_stats_app_info = 10055;
- SystemIonHeapSize system_ion_heap_size = 10056 [deprecated = true, (module) = "framework"];
- AppsOnExternalStorageInfo apps_on_external_storage_info = 10057 [(module) = "framework"];
- FaceSettings face_settings = 10058 [(module) = "framework"];
- CoolingDevice cooling_device = 10059 [(module) = "framework"];
- AppOps app_ops = 10060 [(module) = "framework"];
- ProcessSystemIonHeapSize process_system_ion_heap_size = 10061 [(module) = "framework"];
- SurfaceflingerStatsGlobalInfo surfaceflinger_stats_global_info = 10062;
- SurfaceflingerStatsLayerInfo surfaceflinger_stats_layer_info = 10063;
- ProcessMemorySnapshot process_memory_snapshot = 10064 [(module) = "framework"];
- VmsClientStats vms_client_stats = 10065 [(module) = "car"];
- NotificationRemoteViews notification_remote_views = 10066 [(module) = "framework"];
- DangerousPermissionStateSampled dangerous_permission_state_sampled =
- 10067 [(module) = "framework"];
- GraphicsStats graphics_stats = 10068;
- RuntimeAppOpAccess runtime_app_op_access = 10069 [(module) = "framework"];
- IonHeapSize ion_heap_size = 10070 [(module) = "framework"];
- PackageNotificationPreferences package_notification_preferences =
- 10071 [(module) = "framework"];
- PackageNotificationChannelPreferences package_notification_channel_preferences =
- 10072 [(module) = "framework"];
- PackageNotificationChannelGroupPreferences package_notification_channel_group_preferences =
- 10073 [(module) = "framework"];
- GnssStats gnss_stats = 10074 [(module) = "framework"];
- AttributedAppOps attributed_app_ops = 10075 [(module) = "framework"];
- VoiceCallSession voice_call_session = 10076 [(module) = "telephony"];
- VoiceCallRatUsage voice_call_rat_usage = 10077 [(module) = "telephony"];
- SimSlotState sim_slot_state = 10078 [(module) = "telephony"];
- SupportedRadioAccessFamily supported_radio_access_family = 10079 [(module) = "telephony"];
- SettingSnapshot setting_snapshot = 10080 [(module) = "framework"];
- BlobInfo blob_info = 10081 [(module) = "framework"];
- DataUsageBytesTransfer data_usage_bytes_transfer = 10082 [(module) = "framework"];
- BytesTransferByTagAndMetered bytes_transfer_by_tag_and_metered =
- 10083 [(module) = "framework"];
- DNDModeProto dnd_mode_rule = 10084 [(module) = "framework"];
- GeneralExternalStorageAccessStats general_external_storage_access_stats =
- 10085 [(module) = "mediaprovider"];
- }
-
- // DO NOT USE field numbers above 100,000 in AOSP.
- // Field numbers 100,000 - 199,999 are reserved for non-AOSP (e.g. OEMs) to use.
- // Field numbers 200,000 and above are reserved for future use; do not use them at all.
-
- reserved 10036;
-}
-
-/**
- * This proto represents a node of an attribution chain.
- * Note: All attribution chains are represented as a repeated field of type
- * AttributionNode. It is understood that in such arrays, the order is that
- * of calls, that is [A, B, C] if A calls B that calls C.
- */
-message AttributionNode {
- // The uid for a given element in the attribution chain.
- optional int32 uid = 1;
-
- // The (optional) string tag for an element in the attribution chain. If the
- // element has no tag, it is encoded as an empty string.
- optional string tag = 2;
-}
-
-message KeyValuePair {
- optional int32 key = 1;
- oneof value {
- int32 value_int = 2;
- int64 value_long = 3;
- string value_str = 4;
- float value_float = 5;
- }
-}
-
-message KeyValuePairsAtom {
- optional int32 uid = 1;
- repeated KeyValuePair pairs = 2;
-}
-
-/*
- * *****************************************************************************
- * Below are all of the individual atoms that are logged by Android via statsd.
- *
- * RULES:
- * - The field ids for each atom must start at 1, and count upwards by 1.
- * Skipping field ids is not allowed.
- * - These form an API, so renaming, renumbering or removing fields is
- * not allowed between android releases. (This is not currently enforced,
- * but there will be a tool to enforce this restriction).
- * - The types must be built-in protocol buffer types, namely, no sub-messages
- * are allowed (yet). The bytes type is also not allowed.
- * - The CamelCase name of the message type should match the
- * underscore_separated name as defined in Atom.
- * - If an atom represents work that can be attributed to an app, there can
- * be exactly one AttributionChain field. It must be field number 1.
- * - A field that is a uid should be a string field, tagged with the [xxx]
- * annotation. The generated code on android will be represented by UIDs,
- * and those UIDs will be translated in xxx to those strings.
- *
- * CONVENTIONS:
- * - Events are past tense. e.g. ScreenStateChanged, not ScreenStateChange.
- * - If there is a UID, it goes first. Think in an object-oriented fashion.
- * *****************************************************************************
- */
-
-/**
- * This atom is deprecated starting in Q. Please use ThermalThrottlingSeverityStateChanged.
- * Logs when the Thermal service HAL notifies the throttling start/stop events.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/stats/StatsCompanionService.java
- */
-message ThermalThrottlingStateChanged {
- // The type of temperature being reported (CPU, GPU, SKIN, etc)
- optional android.os.TemperatureTypeEnum sensor_type = 1;
-
- // Throttling state, this field is DEPRECATED
- enum State {
- UNKNOWN = 0;
- START = 1; // START indicated that throttling was triggered.
- STOP = 2; // STOP indicates that throttling was cleared.
- }
- optional State state = 2;
-
- optional float temperature = 3;
-}
-
-/**
- * Logs when the screen state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ScreenStateChanged {
- // New screen state, from frameworks/base/core/proto/android/view/enums.proto.
- optional android.view.DisplayStateEnum state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs that the process state of the uid, as determined by ActivityManager
- * (i.e. the highest process state of that uid's processes) has changed.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message UidProcessStateChanged {
- optional int32 uid = 1 [(state_field_option).primary_field = true, (is_uid) = true];
-
- // The state, from frameworks/base/core/proto/android/app/enums.proto.
- optional android.app.ProcessStateEnum state = 2
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs process state change of a process, as per the activity manager.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
- */
-message ProcessStateChanged {
- optional int32 uid = 1;
- optional string process_name = 2;
- optional string package_name = 3;
- // TODO: remove this when validation is done
- optional int64 version = 5;
- // The state, from frameworks/base/core/proto/android/app/enums.proto.
- optional android.app.ProcessStateEnum state = 4;
-}
-
-/**
- * Logs when ActivityManagerService sleep state is changed.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityTaskManagerService.java
- */
-message ActivityManagerSleepStateChanged {
- // TODO: import frameworks proto
- enum State {
- UNKNOWN = 0;
- ASLEEP = 1;
- AWAKE = 2;
- }
- optional State state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs when system memory state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message MemoryFactorStateChanged {
- // TODO: import frameworks proto
- enum State {
- MEMORY_UNKNOWN = 0;
- NORMAL = 1; // normal.
- MODERATE = 2; // moderate memory pressure.
- LOW = 3; // low memory.
- CRITICAL = 4; // critical memory.
-
- }
- optional State factor = 1 [(state_field_option).exclusive_state = true];
-}
-
-/**
- * Logs when app is using too much cpu, according to ActivityManagerService.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message ExcessiveCpuUsageReported {
- optional int32 uid = 1;
- optional string process_name = 2;
- optional string package_name = 3;
- // package version. TODO: remove this when validation is done
- optional int64 version = 4;
-}
-
-/**
- * Logs when a cached process is killed, along with its pss.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message CachedKillReported {
- optional int32 uid = 1;
- optional string process_name = 2;
- optional string package_name = 3;
- // TODO: remove this when validation is done
- optional int64 version = 5;
- optional int64 pss = 4;
-}
-
-/**
- * Logs the change in wifi health.
- *
- * Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiDataStall.java
- */
-message WifiHealthStatReported {
- enum Band {
- UNKNOWN = 0;
- // All of 2.4GHz band
- BAND_2G = 1;
- // Frequencies in the range of [5150, 5250) GHz
- BAND_5G_LOW = 2;
- // Frequencies in the range of [5250, 5725) GHz
- BAND_5G_MIDDLE = 3;
- // Frequencies in the range of [5725, 5850) GHz
- BAND_5G_HIGH = 4;
- // Frequencies in the range of [5925, 6425) GHz
- BAND_6G_LOW = 5;
- // Frequencies in the range of [6425, 6875) GHz
- BAND_6G_MIDDLE = 6;
- // Frequencies in the range of [6875, 7125) GHz
- BAND_6G_HIGH = 7;
- }
- // duration this stat is obtained over in milliseconds
- optional int32 duration_millis = 1;
- // whether wifi is classified as sufficient for the user's data traffic, determined
- // by whether the calculated throughput exceeds the average demand within |duration_millis|
- optional bool is_sufficient = 2;
- // whether cellular data is available
- optional bool is_cell_data_available = 3;
- // the Band bucket the connected network is on
- optional Band band = 4;
-}
-
-/**
- * Logged when wifi detects a significant change in connection failure rate.
- *
- * Logged from: frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiHealthMonitor.java
- *
- */
-message WifiFailureStatReported {
- enum AbnormalityType {
- UNKNOWN = 0;
- SIGNIFICANT_INCREASE = 1;
- SIGNIFICANT_DECREASE = 2;
- SIMPLY_HIGH = 3;
- }
- enum FailureType {
- FAILURE_UNKNOWN = 0;
- FAILURE_CONNECTION = 1;
- FAILURE_ASSOCIATION_REJECTION = 2;
- FAILURE_ASSOCIATION_TIMEOUT = 3;
- FAILURE_AUTHENTICATION = 4;
- FAILURE_NON_LOCAL_DISCONNECTION = 5;
- FAILURE_SHORT_CONNECTION_DUE_TO_NON_LOCAL_DISCONNECTION = 6;
- }
- // Reason for uploading this stat
- optional AbnormalityType abnormality_type = 1;
- // The particular type of failure
- optional FailureType failure_type = 2;
- // How many times we have encountered this combination of AbnormalityType and FailureType
- optional int32 failure_count = 3;
-}
-
-/**
- * Logs whether a wifi connection is successful and reasons for failure if it isn't.
- *
- * Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java
- */
-message WifiConnectionResultReported {
- enum FailureCode {
- FAILURE_UNKNOWN = 0;
- FAILURE_ASSOCIATION_TIMEOUT = 1;
- FAILURE_ASSOCIATION_REJECTION = 2;
- FAILURE_AUTHENTICATION_GENERAL = 3;
- FAILURE_AUTHENTICATION_EAP = 4;
- FAILURE_DHCP = 5;
- FAILURE_NETWORK_DISCONNECTION = 6;
- FAILURE_ROAM_TIMEOUT = 7;
- }
- // true represents a successful connection
- optional bool connection_result = 1;
- // reason for the connection failure
- optional FailureCode failure_code = 2;
- // scan rssi before the connection attempt
- optional int32 rssi = 3;
-}
-
-/**
- * Logs when memory stats of a process is reported.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
- */
-message ProcessMemoryStatReported {
- optional int32 uid = 1;
- optional string process_name = 2;
- optional string package_name = 3;
- //TODO: remove this when validation is done
- optional int64 version = 9;
- optional int64 pss = 4;
- optional int64 uss = 5;
- optional int64 rss = 6;
- enum Type {
- ADD_PSS_INTERNAL_SINGLE = 0;
- ADD_PSS_INTERNAL_ALL_MEM = 1;
- ADD_PSS_INTERNAL_ALL_POLL = 2;
- ADD_PSS_EXTERNAL = 3;
- ADD_PSS_EXTERNAL_SLOW = 4;
- }
- optional Type type = 7;
- optional int64 duration_millis = 8;
-}
-
-/**
- * Logs that a process started, finished, crashed, or ANRed.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ProcessLifeCycleStateChanged {
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name (usually same as the app name).
- optional string process_name = 2;
-
- // What lifecycle state the process changed to.
- // This enum is specific to atoms.proto.
- enum State {
- FINISHED = 0;
- STARTED = 1;
- CRASHED = 2;
- }
- optional State state = 3;
-}
-
-/**
- * Logs when the ble scan state changes.
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/gatt/AppScanStats.java
- */
-message BleScanStateChanged {
- repeated AttributionNode attribution_node = 1
- [(state_field_option).primary_field_first_uid = true];
-
- enum State {
- OFF = 0;
- ON = 1;
- // RESET indicates all ble stopped. Used when it (re)starts (e.g. after it crashes).
- RESET = 2;
- }
- optional State state = 2 [
- (state_field_option).exclusive_state = true,
- (state_field_option).default_state_value = 0 /* State.OFF */,
- (state_field_option).trigger_state_reset_value = 2 /* State.RESET */,
- (state_field_option).nested = true
- ];
-
- // Does the scan have a filter.
- optional bool is_filtered = 3 [(state_field_option).primary_field = true];
- // Whether the scan is a CALLBACK_TYPE_FIRST_MATCH scan. Called 'background' scan internally.
- optional bool is_first_match = 4 [(state_field_option).primary_field = true];
- // Whether the scan set to piggy-back off the results of other scans (SCAN_MODE_OPPORTUNISTIC).
- optional bool is_opportunistic = 5 [(state_field_option).primary_field = true];
-}
-
-/**
- * Logs reporting of a ble scan finding results.
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/gatt/AppScanStats.java
- */
-// TODO: Consider also tracking per-scanner-id.
-message BleScanResultReceived {
- repeated AttributionNode attribution_node = 1;
-
- // Number of ble scan results returned.
- optional int32 num_results = 2;
-}
-
-/**
- * Logs when a sensor state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message SensorStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // The id (int) of the sensor.
- optional int32 sensor_id = 2;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 3;
-}
-
-/**
- * Logs when GPS state changes.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message GpsScanStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-}
-
-/**
- * Logs when GPS signal quality.
- *
- * Logged from:
- * /frameworks/base/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
- */
-message GpsSignalQualityChanged {
- optional android.server.location.GpsSignalQualityEnum level = 1;
-}
-
-
-/**
- * Logs when a sync manager sync state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message SyncStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // Name of the sync (as named in the app). Can be chosen at run-time.
- optional string sync_name = 2;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 3;
-}
-
-/*
- * Deferred job stats.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/job/JobSchedulerService.java
-*/
-message DeferredJobStatsReported {
- repeated AttributionNode attribution_node = 1;
-
- // Number of jobs deferred.
- optional int32 num_jobs_deferred = 2;
-
- // Time since the last job runs.
- optional int64 time_since_last_job_millis = 3;
-}
-
-/**
- * Logs when a job scheduler job state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ScheduledJobStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // Name of the job (as named in the app)
- optional string job_name = 2;
-
- enum State {
- FINISHED = 0;
- STARTED = 1;
- SCHEDULED = 2;
- }
- optional State state = 3;
-
- // The reason a job has stopped.
- // This is only applicable when the state is FINISHED.
- // The default value is STOP_REASON_UNKNOWN.
- optional android.app.job.StopReasonEnum stop_reason = 4;
-
- // The standby bucket of the app that scheduled the job. These match the framework constants
- // defined in JobSchedulerService.java with the addition of UNKNOWN using -1, as ACTIVE is
- // already assigned 0.
- enum Bucket {
- UNKNOWN = -1;
- ACTIVE = 0;
- WORKING_SET = 1;
- FREQUENT = 2;
- RARE = 3;
- NEVER = 4;
- RESTRICTED = 5;
- }
- optional Bucket standby_bucket = 5 [default = UNKNOWN];
-
- // The job id (as assigned by the app).
- optional int32 job_id = 6;
-
- // One flag for each of the API constraints defined by Jobscheduler. Does not include implcit
- // constraints as they are always assumed to be set.
- optional bool has_charging_constraint = 7;
- optional bool has_battery_not_low_constraint = 8;
- optional bool has_storage_not_low_constraint = 9;
- optional bool has_timing_delay_constraint = 10;
- optional bool has_deadline_constraint = 11;
- optional bool has_idle_constraint = 12;
- optional bool has_connectivity_constraint = 13;
- optional bool has_content_trigger_constraint = 14;
-}
-
-/**
- * Logs when the audio state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message AudioStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- // RESET indicates all audio stopped. Used when it (re)starts (e.g. after it crashes).
- RESET = 2;
- }
- optional State state = 2;
-}
-
-/**
- * Logs when the video codec state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message MediaCodecStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- // RESET indicates all mediaCodec stopped. Used when it (re)starts (e.g. after it crashes).
- RESET = 2;
- }
- optional State state = 2;
-}
-
-/**
- * Logs when the flashlight state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message FlashlightStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- // RESET indicates all flashlight stopped. Used when it (re)starts (e.g. after it crashes).
- RESET = 2;
- }
- optional State state = 2;
-}
-
-/**
- * Logs when the camera state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message CameraStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- // RESET indicates all camera stopped. Used when it (re)starts (e.g. after it crashes).
- RESET = 2;
- }
- optional State state = 2;
-}
-
-/**
- * Logs that the state of a wakelock (per app and per wakelock name) has changed.
- *
- * Logged from:
- * TODO
- */
-message WakelockStateChanged {
- repeated AttributionNode attribution_node = 1
- [(state_field_option).primary_field_first_uid = true];
-
- // The type (level) of the wakelock; e.g. a partial wakelock or a full wakelock.
- // From frameworks/base/core/proto/android/os/enums.proto.
- optional android.os.WakeLockLevelEnum type = 2 [(state_field_option).primary_field = true];
-
- // The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
- optional string tag = 3 [(state_field_option).primary_field = true];
-
- enum State {
- RELEASE = 0;
- ACQUIRE = 1;
- CHANGE_RELEASE = 2;
- CHANGE_ACQUIRE = 3;
- }
- optional State state = 4 [
- (state_field_option).exclusive_state = true,
- (state_field_option).default_state_value = 0,
- (state_field_option).nested = true
- ];
-}
-
-/**
- * Logs when a partial wakelock is considered 'long' (over 1 min).
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message LongPartialWakelockStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
- optional string tag = 2;
-
- // TODO: I have no idea what this is.
- optional string history_tag = 3;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 4;
-}
-
-/**
- * Logs when the device is interactive, according to the PowerManager Notifier.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/power/Notifier.java
- */
-message InteractiveStateChanged {
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 1;
-}
-
-/**
- * Logs Battery Saver state change.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message BatterySaverModeStateChanged {
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs Doze mode state change.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message DeviceIdleModeStateChanged {
- optional android.server.DeviceIdleModeEnum state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-
-/**
- * Logs state change of Doze mode including maintenance windows.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message DeviceIdlingModeStateChanged {
- optional android.server.DeviceIdleModeEnum state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs screen brightness level.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ScreenBrightnessChanged {
- // Screen brightness level. Should be in [-1, 255] according to PowerManager.java.
- optional int32 level = 1;
-}
-
-/**
- * Logs battery level (percent full, from 0 to 100).
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message BatteryLevelChanged {
- // Battery level. Should be in [0, 100].
- optional int32 battery_level = 1;
-}
-
-/**
- * Logs change in charging status of the device.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message ChargingStateChanged {
- // State of the battery, from frameworks/base/core/proto/android/os/enums.proto.
- optional android.os.BatteryStatusEnum state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs whether the device is plugged in, and what power source it is using.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message PluggedStateChanged {
- // Whether the device is plugged in, from frameworks/base/core/proto/android/os/enums.proto.
- optional android.os.BatteryPluggedStateEnum state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs when an app's wakeup alarm fires.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message WakeupAlarmOccurred {
- repeated AttributionNode attribution_node = 1;
-
- // Name of the wakeup alarm.
- optional string tag = 2;
-
- // Name of source package (for historical reasons, since BatteryStats tracked it).
- optional string package_name = 3;
-
- // The App Standby bucket of the app that scheduled the alarm at the time the alarm fired.
- optional AppStandbyBucketChanged.Bucket app_standby_bucket = 4;
-}
-
-/**
- * Logs when an an app causes the mobile radio to change state.
- * Changing from LOW to MEDIUM or HIGH can be considered the app waking the mobile radio.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
- */
-message MobileRadioPowerStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // Power state, from frameworks/base/core/proto/android/telephony/enums.proto.
- optional android.telephony.DataConnectionPowerStateEnum state = 2;
-}
-
-/**
- * Logs when an an app causes the wifi radio to change state.
- * Changing from LOW to MEDIUM or HIGH can be considered the app waking the wifi radio.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
- */
-message WifiRadioPowerStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // Power state, from frameworks/base/core/proto/android/telephony/enums.proto.
- optional android.telephony.DataConnectionPowerStateEnum state = 2;
-}
-
-/**
- * Logs kernel wakeup reasons and aborts.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message KernelWakeupReported {
- // Name of the kernel wakeup reason (or abort).
- optional string wakeup_reason_name = 1;
-
- // Duration (in microseconds) for the wake-up interrupt to be serviced.
- optional int64 duration_micros = 2;
-}
-
-/**
- * Logs when Wifi is toggled on/off.
- * Note that Wifi may still perform certain functions (e.g. location scanning) even when disabled.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message WifiEnabledStateChanged {
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 1;
-}
-
-/**
- * This atom is deprecated starting in R.
- *
- * Logs when an app causes Wifi to run. In this context, 'to run' means to use Wifi Client Mode.
- * TODO: Include support for Hotspot, perhaps by using an extra field to denote 'mode'.
- * Note that Wifi Scanning is monitored separately in WifiScanStateChanged.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message WifiRunningStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-}
-
-/**
- * Logs wifi locks held by an app.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message WifiLockStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-
- // WifiLock type, from frameworks/base/core/proto/android/wifi/enums.proto.
- optional android.net.wifi.WifiModeEnum mode = 3;
-}
-
-/**
- * Logs wifi signal strength changes.
- *
- * Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java
- */
-message WifiSignalStrengthChanged {
- // Signal strength, from frameworks/base/core/proto/android/telephony/enums.proto.
- optional android.telephony.SignalStrengthEnum signal_strength = 1;
-}
-
-/**
- * Logs wifi scans performed by an app.
- *
- * Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
- */
-message WifiScanStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-}
-
-/**
- * Logs wifi multicast locks held by an app
- *
- * Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMulticastLockManager.java
- */
-message WifiMulticastLockStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-
- optional string tag = 3;
-}
-
-/**
- * Logs shutdown reason and duration on next boot.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/server/BootReceiver.java
- */
-message ShutdownSequenceReported {
- // True if shutdown is for a reboot. Default: false if we do not know.
- optional bool reboot = 1;
-
- // Reason for shutdown. Eg: userrequested. Default: "<EMPTY>".
- optional string reason = 2;
-
- // Beginning of shutdown time in ms using wall clock time since unix epoch.
- // Default: 0 if no start time received.
- optional int64 start_time_millis = 3;
-
- // Duration of shutdown in ms. Default: 0 if no duration received.
- optional int64 duration_millis = 4;
-}
-
-
-/**
- * Logs boot reason and duration.
- *
- * Logged from:
- * system/core/bootstat/bootstat.cpp
- */
-message BootSequenceReported {
- // Reason for bootloader boot. Eg. reboot. See bootstat.cpp for larger list
- // Default: "<EMPTY>" if not available.
- optional string bootloader_reason = 1;
-
- // Reason for system boot. Eg. bootloader, reboot,userrequested
- // Default: "<EMPTY>" if not available.
- optional string system_reason = 2;
-
- // End of boot time in ms from unix epoch using system wall clock.
- optional int64 end_time_millis = 3;
-
- // Total boot duration in ms.
- optional int64 total_duration_millis = 4;
-
- // Bootloader duration in ms.
- optional int64 bootloader_duration_millis = 5;
-
- // Time since last boot in ms. Default: 0 if not available.
- optional int64 time_since_last_boot = 6;
-}
-
-
-/**
- * Logs call state and disconnect cause (if applicable).
- *
- * Logged from:
- * packages/services/Telecomm/src/com/android/server/telecom/Call.java
- */
-message CallStateChanged {
- // The state of the call. Eg. DIALING, ACTIVE, ON_HOLD, DISCONNECTED.
- // From frameworks/base/core/proto/android/telecomm/enums.proto.
- optional android.telecom.CallStateEnum call_state = 1;
-
- // The reason the call disconnected. Eg. ERROR, MISSED, REJECTED, BUSY.
- // This value is only applicable when the call_state is DISCONNECTED, and
- // should always be UNKNOWN if the call_state is not DISCONNECTED.
- // From frameworks/base/core/proto/android/telecomm/enums.proto.
- optional android.telecom.DisconnectCauseEnum disconnect_cause = 2;
-
- // True if the call is self-managed, which are apps that use the
- // telecom infrastructure to make their own calls.
- optional bool self_managed = 3;
-
- // True if call is external. External calls are calls on connected Wear
- // devices but show up in Telecom so the user can pull them onto the device.
- optional bool external_call = 4;
-}
-
-/**
- * Logs keyguard state. The keyguard is the lock screen.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
- */
-message KeyguardStateChanged {
- enum State {
- UNKNOWN = 0;
- // The keyguard is hidden when the phone is unlocked.
- HIDDEN = 1;
- // The keyguard is shown when the phone is locked (screen turns off).
- SHOWN= 2;
- // The keyguard is occluded when something is overlaying the keyguard.
- // Eg. Opening the camera while on the lock screen.
- OCCLUDED = 3;
- }
- optional State state = 1;
-}
-
-/**
- * Logs keyguard bouncer state. The bouncer is a part of the keyguard, and
- * prompts the user to enter a password (pattern, pin, etc).
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
- */
-
-message KeyguardBouncerStateChanged {
- enum State {
- UNKNOWN = 0;
- // Bouncer is hidden, either as a result of successfully entering the
- // password, screen timing out, or user going back to lock screen.
- HIDDEN = 1;
- // This is when the user is being prompted to enter the password.
- SHOWN = 2;
- }
- optional State state = 1;
-}
-
-/**
- * Logs the result of entering a password into the keyguard bouncer.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
- */
-message KeyguardBouncerPasswordEntered {
- enum BouncerResult {
- UNKNOWN = 0;
- // The password entered was incorrect.
- FAILURE = 1;
- // The password entered was correct.
- SUCCESS = 2;
- }
- optional BouncerResult result = 1;
-}
-
-/*
- * Logs changes to the configuration of the device. The configuration is defined
- * in frameworks/base/core/java/android/content/res/Configuration.java
- * More documentation is at https://d.android.com/reference/android/content/res/Configuration.html
- * Please go there to interpret the possible values each field can be.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message ResourceConfigurationChanged {
- // Bit mask of color capabilities of the screen.
- // Contains information about the color gamut and hdr mode of the screen.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#colorMode
- optional int32 color_mode = 1;
-
- // The target screen density being rendered to.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#densityDpi
- optional int32 density_dpi = 2;
-
- // Current user preference for the scaling factor for fonts,
- // relative to the base density scaling.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#fontScale
- optional float font_scale = 3;
-
- // Flag indicating whether the hard keyboard is hidden.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#hardKeyboardHidden
- optional int32 hard_keyboard_hidden = 4;
-
- // The type of keyboard attached to the device.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#keyboard
- optional int32 keyboard = 5;
-
- // Flag indicating whether any keyboard is available. Takes soft keyboards into account.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#keyboardHidden
- optional int32 keyboard_hidden = 6;
-
- // IMSI MCC (Mobile Country Code), corresponding to mcc resource qualifier.
- // 0 if undefined.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#mcc
- optional int32 mcc = 7;
-
- // IMSI MNC (Mobile Network Code), corresponding to mnc resource qualifier.
- // 0 if undefined. Note: the actual MNC may be 0, to check for this use the
- // MNC_ZERO symbol defined in Configuration.java.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#mnc
- optional int32 mnc = 8;
-
- // The kind of navigation available on the device.
- // See: https://developer.android.com/reference/android/content/res/Configuration.html#navigation
- optional int32 navigation = 9;
-
- // Flag indicating whether the navigation is available.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#navigationHidden
- optional int32 navigation_hidden = 10;
-
- // Overall orientation of the screen.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#orientation
- optional int32 orientation = 11;
-
- // The current height of the available screen space, in dp units.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#screenHeightDp
- optional int32 screen_height_dp = 12;
-
- // Bit mask of overall layout of the screen.
- // Contains information about screen size, whether the screen is wider/taller
- // than normal, whether the screen layout is right-tl-left or left-to-right,
- // and whether the screen has a rounded shape.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#screenLayout
- optional int32 screen_layout = 13;
-
- // Current width of the available screen space, in dp units.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#screenWidthDp
- optional int32 screen_width_dp = 14;
-
- // The smallest screen size an application will see in normal operation.
- // This is the smallest value of both screenWidthDp and screenHeightDp
- // in portrait and landscape.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#smallestScreenWidthDp
- optional int32 smallest_screen_width_dp = 15;
-
- // The type of touch screen attached to the device.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#touchscreen
- optional int32 touchscreen = 16;
-
- // Bit mask of the ui mode.
- // Contains information about the overall ui mode of the device.
- // Eg: NORMAL, DESK, CAR, TELEVISION, WATCH, VR_HEADSET
- // Also contains information about whether the device is in night mode.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#uiMode
- optional int32 ui_mode = 17;
-}
-
-
-/**
- * Logs changes in the connection state of the mobile radio.
- *
- * Logged from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
- */
-message MobileConnectionStateChanged {
- // States are from the state machine DataConnection.java.
- enum State {
- UNKNOWN = 0;
- // The connection is inactive, or disconnected.
- INACTIVE = 1;
- // The connection is being activated, or connecting.
- ACTIVATING = 2;
- // The connection is active, or connected.
- ACTIVE = 3;
- // The connection is disconnecting.
- DISCONNECTING = 4;
- // The connection is disconnecting after creating a connection.
- DISCONNECTION_ERROR_CREATING_CONNECTION = 5;
- }
- optional State state = 1;
- // For multi-sim phones, this distinguishes between the sim cards.
- optional int32 sim_slot_index = 2;
- // Used to identify the connection. Starts at 0 and increments by 1 for
- // every new network created. Resets whenever the device reboots.
- optional int32 data_connection_id = 3;
- // A bitmask for the capabilities of this connection.
- // Eg. DEFAULT (internet), MMS, SUPL, DUN, IMS.
- // Default value (if we have no information): 0
- optional int64 capabilities = 4;
- // If this connection has internet.
- // This just checks if the DEFAULT bit of capabilities is set.
- optional bool has_internet = 5;
-}
-
-/**
- * Logs changes in mobile radio technology. eg: LTE, EDGE, CDMA.
- *
- * Logged from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/ServiceStateTracker.java
- */
-message MobileRadioTechnologyChanged {
- optional android.telephony.NetworkTypeEnum state = 1;
- // For multi-sim phones, this distinguishes between the sim cards.
- optional int32 sim_slot_index = 2;
-}
-
-/**
- * Logs the VID and PID of any connected USB devices.
- *
- * Notes if any Audio, HID (input buttons/mouse/keyboard), or Storage interfaces are present.
- *
- * Logged by Vendor.
- */
-message UsbDeviceAttached {
- optional int32 vid = 1;
- optional int32 pid = 2;
- optional bool has_audio = 3;
- optional bool has_hid = 4;
- optional bool has_storage = 5;
- enum State {
- STATE_DISCONNECTED = 0;
- STATE_CONNECTED = 1;
- }
- optional State state = 6;
- optional int64 last_connect_duration_millis = 7;
-}
-
-
-/**
- * Logs when Bluetooth is enabled and disabled.
- *
- * Logged from:
- * services/core/java/com/android/server/BluetoothManagerService.java
- */
-message BluetoothEnabledStateChanged {
- repeated AttributionNode attribution_node = 1;
- // Whether or not bluetooth is enabled on the device.
- enum State {
- UNKNOWN = 0;
- ENABLED = 1;
- DISABLED = 2;
- }
- optional State state = 2;
- // The reason for being enabled/disabled.
- // Eg. Airplane mode, crash, application request.
- optional android.bluetooth.EnableDisableReasonEnum reason = 3;
- // If the reason is an application request, this will be the package name.
- optional string pkg_name = 4;
-}
-
-/**
- * Logs when profiles on a Bluetooth device connects and disconnects.
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/RemoteDevices.java
- *
- * Next Tag: 6
- */
-message BluetoothConnectionStateChanged {
- // The state of the connection.
- // Eg: CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED.
- optional android.bluetooth.ConnectionStateEnum state = 1;
- // An identifier that can be used to match connect and disconnect events.
- // Currently is last two bytes of a hash of a device level ID and
- // the mac address of the bluetooth device that is connected.
- // Deprecated: use obfuscated_id instead, this one is always 0 for Q+
- optional int32 obfuscated_id = 2 [deprecated = true];
- // The profile that is connected. Eg. GATT, A2DP, HEADSET.
- // From android.bluetooth.BluetoothAdapter.java
- // Default: 0 when not used
- optional int32 bt_profile = 3;
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes new_obfuscated_id = 4 [(android.os.statsd.log_mode) = MODE_BYTES];
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when a Bluetooth device connects and disconnects over ACL
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java
- *
- * Next Tag: 4
- */
-message BluetoothAclConnectionStateChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // The state of the connection.
- // Eg: CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED.
- optional android.bluetooth.ConnectionStateEnum state = 2;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 3;
-}
-
-/**
- * Logs when a Bluetooth device connects and disconnects over SCO
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetClientStateMachine.java
- *
- * Next Tag: 5
- */
-message BluetoothScoConnectionStateChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // The state of the connection.
- // Eg: CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED.
- optional android.bluetooth.ConnectionStateEnum state = 2;
- // Codec used for this SCO connection
- // Default: UNKNOWN
- optional android.bluetooth.hfp.ScoCodec codec = 3;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 4;
-}
-
-/**
- * Logged when active device of a profile changes
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetService.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/hearingaid/HearingAidService.java
- */
-message BluetoothActiveDeviceChanged {
- // The profile whose active device has changed. Eg. A2DP, HEADSET, HEARING_AID
- // From android.bluetooth.BluetoothProfile
- optional int32 bt_profile = 1;
- // An identifier that can be used to match events for this new active device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if there is no active device for this profile
- optional bytes obfuscated_id = 2 [(android.os.statsd.log_mode) = MODE_BYTES];
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 3;
-}
-
-// Logs when there is an event affecting Bluetooth device's link layer connection.
-// - This event is triggered when there is a related HCI command or event
-// - Users of this metrics can deduce Bluetooth device's connection state from these events
-// - HCI commands are logged before the command is sent, after receiving command status, and after
-// receiving command complete
-// - HCI events are logged when they arrive
-//
-// Low level log from system/bt
-//
-// Bluetooth classic commands:
-// - CMD_CREATE_CONNECTION
-// - CMD_DISCONNECT
-// - CMD_CREATE_CONNECTION_CANCEL
-// - CMD_ACCEPT_CONNECTION_REQUEST
-// - CMD_REJECT_CONNECTION_REQUEST
-// - CMD_SETUP_ESCO_CONNECTION
-// - CMD_ACCEPT_ESCO_CONNECTION
-// - CMD_REJECT_ESCO_CONNECTION
-// - CMD_ENH_SETUP_ESCO_CONNECTION
-// - CMD_ENH_ACCEPT_ESCO_CONNECTION
-//
-// Bluetooth low energy commands:
-// - CMD_BLE_CREATE_LL_CONN [Only logged on error or when initiator filter policy is 0x00]
-// - CMD_BLE_CREATE_CONN_CANCEL [Only logged when there is an error]
-// - CMD_BLE_EXTENDED_CREATE_CONNECTION [Only logged on error or when initiator filter policy is 0x00]
-// - CMD_BLE_CLEAR_WHITE_LIST
-// - CMD_BLE_ADD_WHITE_LIST
-// - CMD_BLE_REMOVE_WHITE_LIST
-//
-// Bluetooth classic events:
-// - EVT_CONNECTION_COMP
-// - EVT_CONNECTION_REQUEST
-// - EVT_DISCONNECTION_COMP
-// - EVT_ESCO_CONNECTION_COMP
-// - EVT_ESCO_CONNECTION_CHANGED
-//
-// Bluetooth low energy meta events:
-// - BLE_EVT_CONN_COMPLETE_EVT
-// - BLE_EVT_ENHANCED_CONN_COMPLETE_EVT
-//
-// Next tag: 10
-message BluetoothLinkLayerConnectionEvent {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Connection handle of this connection if available
- // Range: 0x0000 - 0x0EFF (12 bits)
- // Default: 0xFFFF if the handle is unknown
- optional int32 connection_handle = 2;
- // Direction of the link
- // Default: DIRECTION_UNKNOWN
- optional android.bluetooth.DirectionEnum direction = 3;
- // Type of this link
- // Default: LINK_TYPE_UNKNOWN
- optional android.bluetooth.LinkTypeEnum type = 4;
-
- // Reason metadata for this link layer connection event, rules for interpretation:
- // 1. If hci_cmd is set and valid, hci_event can be either EVT_COMMAND_STATUS or
- // EVT_COMMAND_COMPLETE, ignore hci_ble_event in this case
- // 2. If hci_event is set to EVT_BLE_META, look at hci_ble_event; otherwise, if hci_event is
- // set and valid, ignore hci_ble_event
-
- // HCI command associated with this event
- // Default: CMD_UNKNOWN
- optional android.bluetooth.hci.CommandEnum hci_cmd = 5;
- // HCI event associated with this event
- // Default: EVT_UNKNOWN
- optional android.bluetooth.hci.EventEnum hci_event = 6;
- // HCI BLE meta event associated with this event
- // Default: BLE_EVT_UNKNOWN
- optional android.bluetooth.hci.BleMetaEventEnum hci_ble_event = 7;
- // HCI command status code if this is triggerred by hci_cmd
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum cmd_status = 8;
- // HCI reason code associated with this event
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum reason_code = 9;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 10;
-}
-
-/**
- * Logs when a module is rolled back by Watchdog.
- *
- * Logged from: Rollback Manager
- */
-message WatchdogRollbackOccurred {
- enum RollbackType {
- UNKNOWN = 0;
- ROLLBACK_INITIATE = 1;
- ROLLBACK_SUCCESS = 2;
- ROLLBACK_FAILURE = 3;
- ROLLBACK_BOOT_TRIGGERED = 4;
- }
- optional RollbackType rollback_type = 1;
-
- optional string package_name = 2;
-
- optional int32 package_version_code = 3;
-
- enum RollbackReasonType {
- REASON_UNKNOWN = 0;
- REASON_NATIVE_CRASH = 1;
- REASON_EXPLICIT_HEALTH_CHECK = 2;
- REASON_APP_CRASH = 3;
- REASON_APP_NOT_RESPONDING = 4;
- REASON_NATIVE_CRASH_DURING_BOOT = 5;
- }
- optional RollbackReasonType rollback_reason = 4;
-
- // Set by RollbackPackageHealthObserver to be the package that is failing when a rollback
- // is initiated. Empty if the package is unknown.
- optional string failing_package_name = 5;
-
- optional TrainExperimentIds experiment_ids = 6 [(log_mode) = MODE_BYTES];
-}
-
-/**
- * Logs when there is a change in Bluetooth A2DP playback state
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java
- */
-message BluetoothA2dpPlaybackStateChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Current playback state
- // Default: PLAYBACK_STATE_UNKNOWN
- optional android.bluetooth.a2dp.PlaybackStateEnum playback_state = 2;
- // Current audio coding mode
- // Default: AUDIO_CODING_MODE_UNKNOWN
- optional android.bluetooth.a2dp.AudioCodingModeEnum audio_coding_mode = 3;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 4;
-}
-
-/**
- * Logs when there is a change in A2DP codec config for a particular remote device
- *
- * Logged from:
- * frameworks/base/core/java/android/bluetooth/BluetoothCodecConfig.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java
- */
-message BluetoothA2dpCodecConfigChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Type of codec as defined by various SOURCE_CODEC_TYPE_* constants in BluetoothCodecConfig
- // Default SOURCE_CODEC_TYPE_INVALID
- optional int32 codec_type = 2;
- // Codec priroity, the higher the more preferred, -1 for disabled
- // Default: CODEC_PRIORITY_DEFAULT
- optional int32 codec_priority = 3;
- // Sample rate in Hz as defined by various SAMPLE_RATE_* constants in BluetoothCodecConfig
- // Default: SAMPLE_RATE_NONE
- optional int32 sample_rate = 4;
- // Bits per sample as defined by various BITS_PER_SAMPLE_* constants in BluetoothCodecConfig
- // Default: BITS_PER_SAMPLE_NONE
- optional int32 bits_per_sample = 5;
- // Channel mode as defined by various CHANNEL_MODE_* constants in BluetoothCodecConfig
- // Default: CHANNEL_MODE_NONE
- optional int32 channel_mode = 6;
- // Codec specific values
- // Default 0
- optional int64 codec_specific_1 = 7;
- optional int64 codec_specific_2 = 8;
- optional int64 codec_specific_3 = 9;
- optional int64 codec_specific_4 = 10;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 11;
-}
-
-/**
- * Logs when there is a change in selectable A2DP codec capability for a paricular remote device
- * Each codec's capability is logged separately due to statsd restriction
- *
- * Logged from:
- * frameworks/base/core/java/android/bluetooth/BluetoothCodecConfig.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java
- */
-message BluetoothA2dpCodecCapabilityChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Type of codec as defined by various SOURCE_CODEC_TYPE_* constants in BluetoothCodecConfig
- // Default SOURCE_CODEC_TYPE_INVALID
- optional int32 codec_type = 2;
- // Codec priroity, the higher the more preferred, -1 for disabled
- // Default: CODEC_PRIORITY_DEFAULT
- optional int32 codec_priority = 3;
- // A bit field of supported sample rates as defined by various SAMPLE_RATE_* constants
- // in BluetoothCodecConfig
- // Default: empty and SAMPLE_RATE_NONE for individual item
- optional int32 sample_rate = 4;
- // A bit field of supported bits per sample as defined by various BITS_PER_SAMPLE_* constants
- // in BluetoothCodecConfig
- // Default: empty and BITS_PER_SAMPLE_NONE for individual item
- optional int32 bits_per_sample = 5;
- // A bit field of supported channel mode as defined by various CHANNEL_MODE_* constants in
- // BluetoothCodecConfig
- // Default: empty and CHANNEL_MODE_NONE for individual item
- optional int32 channel_mode = 6;
- // Codec specific values
- // Default 0
- optional int64 codec_specific_1 = 7;
- optional int64 codec_specific_2 = 8;
- optional int64 codec_specific_3 = 9;
- optional int64 codec_specific_4 = 10;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 11;
-}
-
-/**
- * Logs when A2DP failed to read from PCM source.
- * This typically happens when audio HAL cannot supply A2DP with data fast enough for encoding.
- *
- * Logged from:
- * system/bt
- */
-message BluetoothA2dpAudioUnderrunReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Encoding interval in nanoseconds
- // Default: 0
- optional int64 encoding_interval_nanos = 2;
- // Number of bytes of PCM data that could not be read from the source
- // Default: 0
- optional int32 num_missing_pcm_bytes = 3;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 4;
-}
-
-/**
- * Logs when A2DP failed send encoded data to the remote device fast enough such that the transmit
- * buffer queue is full and we have to drop data
- *
- * Logged from:
- * system/bt
- */
-message BluetoothA2dpAudioOverrunReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Encoding interval in nanoseconds
- // Default: 0
- optional int64 encoding_interval_nanos = 2;
- // Number of buffers dropped in this event
- // Each buffer is encoded in one encoding interval and consists of multiple encoded frames
- // Default: 0
- optional int32 num_dropped_buffers = 3;
- // Number of encoded buffers dropped in this event
- // Default 0
- optional int32 num_dropped_encoded_frames = 4;
- // Number of encoded bytes dropped in this event
- // Default: 0
- optional int32 num_dropped_encoded_bytes = 5;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 6;
-}
-
-/**
- * Logs when we receive reports regarding a device's RSSI value
- *
- * Logged from:
- * system/bt
- */
-message BluetoothDeviceRssiReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Connection handle of this connection if available
- // Range: 0x0000 - 0x0EFF (12 bits)
- // Default: 0xFFFF if the handle is unknown
- optional int32 connection_handle = 2;
- // HCI command status code if this is triggerred by hci_cmd
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum hci_status = 3;
- // BR/EDR
- // Range: -128 ≤ N ≤ 127 (signed integer)
- // Units: dB
- // LE:
- // Range: -127 to 20, 127 (signed integer)
- // Units: dBm
- // Invalid when an out of range value is reported
- optional int32 rssi = 4;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when we receive reports regarding how many consecutive failed contacts for a connection
- *
- * Logged from:
- * system/bt
- */
-message BluetoothDeviceFailedContactCounterReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Connection handle of this connection if available
- // Range: 0x0000 - 0x0EFF (12 bits)
- // Default: 0xFFFF if the handle is unknown
- optional int32 connection_handle = 2;
- // HCI command status code if this is triggerred by hci_cmd
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum cmd_status = 3;
- // Number of consecutive failed contacts for a connection corresponding to the Handle
- // Range: uint16_t, 0-0xFFFF
- // Default: 0xFFFFF
- optional int32 failed_contact_counter = 4;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when we receive reports regarding the tranmit power level used for a specific connection
- *
- * Logged from:
- * system/bt
- */
-message BluetoothDeviceTxPowerLevelReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Connection handle of this connection if available
- // Range: 0x0000 - 0x0EFF (12 bits)
- // Default: 0xFFFF if the handle is unknown
- optional int32 connection_handle = 2;
- // HCI command status code if this is triggered by hci_cmd
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum hci_status = 3;
- // Range: -30 ≤ N ≤ 20
- // Units: dBm
- // Invalid when an out of range value is reported
- optional int32 transmit_power_level = 4;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when Bluetooth controller failed to reply with command status within a timeout period after
- * receiving an HCI command from the host
- *
- * Logged from: system/bt
- */
-message BluetoothHciTimeoutReported {
- // HCI command associated with this event
- // Default: CMD_UNKNOWN
- optional android.bluetooth.hci.CommandEnum hci_command = 1;
-}
-
-/**
- * Logs when we receive Bluetooth Link Quality Report event from the controller
- * See Android Bluetooth HCI specification for more details
- *
- * Note: all count and bytes field are counted since last event
- *
- * Logged from: system/bt
- */
-message BluetoothQualityReportReported {
- // Quality report ID
- // Original type: uint8_t
- // Default: BQR_ID_UNKNOWN
- optional android.bluetooth.hci.BqrIdEnum quality_report_id = 1;
- // Packet type of the connection
- // Original type: uint8_t
- // Default: BQR_PACKET_TYPE_UNKNOWN
- optional android.bluetooth.hci.BqrPacketTypeEnum packet_types = 2;
- // Connection handle of the connection
- // Original type: uint16_t
- optional int32 connection_handle = 3;
- // Performing Role for the connection
- // Original type: uint8_t
- optional int32 connection_role = 4;
- // Current Transmit Power Level for the connection. This value is the same as the controller's
- // response to the HCI_Read_Transmit_Power_Level HCI command
- // Original type: uint8_t
- optional int32 tx_power_level = 5;
- // Received Signal Strength Indication (RSSI) value for the connection. This value is an
- // absolute receiver signal strength value
- // Original type: int8_t
- optional int32 rssi = 6;
- // Signal-to-Noise Ratio (SNR) value for the connection. It is the average SNR of all the
- // channels used by the link currently
- // Original type: uint8_t
- optional int32 snr = 7;
- // Indicates the number of unused channels in AFH_channel_map
- // Original type: uint8_t
- optional int32 unused_afh_channel_count = 8;
- // Indicates the number of the channels which are interfered and quality is bad but are still
- // selected for AFH
- // Original type: uint8_t
- optional int32 afh_select_unideal_channel_count = 9;
- // Current Link Supervision Timeout Setting
- // Unit: N * 0.3125 ms (1 Bluetooth Clock)
- // Original type: uint16_t
- optional int32 lsto = 10;
- // Piconet Clock for the specified Connection_Handle. This value is the same as the controller's
- // response to HCI_Read_Clock HCI command with the parameter "Which_Clock" of
- // 0x01 (Piconet Clock)
- // Unit: N * 0.3125 ms (1 Bluetooth Clock)
- // Original type: uint32_t
- optional int64 connection_piconet_clock = 11;
- // The count of retransmission
- // Original type: uint32_t
- optional int64 retransmission_count = 12;
- // The count of no RX
- // Original type: uint32_t
- optional int64 no_rx_count = 13;
- // The count of NAK (Negative Acknowledge)
- // Original type: uint32_t
- optional int64 nak_count = 14;
- // Controller timestamp of last TX ACK
- // Unit: N * 0.3125 ms (1 Bluetooth Clock)
- // Original type: uint32_t
- optional int64 last_tx_ack_timestamp = 15;
- // The count of Flow-off (STOP)
- // Original type: uint32_t
- optional int64 flow_off_count = 16;
- // Controller timestamp of last Flow-on (GO)
- // Unit: N * 0.3125 ms (1 Bluetooth Clock)
- // Original type: uint32_t
- optional int64 last_flow_on_timestamp = 17;
- // Buffer overflow count (how many bytes of TX data are dropped) since the last event
- // Original type: uint32_t
- optional int64 buffer_overflow_bytes = 18;
- // Buffer underflow count (in byte) since last event
- // Original type: uint32_t
- optional int64 buffer_underflow_bytes = 19;
-}
-
-/**
- * Logs when a Bluetooth device's manufacturer information is learnt by the Bluetooth stack
- *
- * Notes:
- * - Each event can be partially filled as we might learn different pieces of device
- * information at different time
- * - Multiple device info events can be combined to give more complete picture
- * - When multiple device info events tries to describe the same information, the
- * later one wins
- *
- * Logged from:
- * packages/apps/Bluetooth
- */
-message BluetoothDeviceInfoReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Where is this device info obtained from
- optional android.bluetooth.DeviceInfoSrcEnum source_type = 2;
- // Name of the data source
- // For EXTERNAL: package name of the data source
- // For INTERNAL: null for general case, component name otherwise
- optional string source_name = 3;
- // Name of the manufacturer of this device
- optional string manufacturer = 4;
- // Model of this device
- optional string model = 5;
- // Hardware version of this device
- optional string hardware_version = 6;
- // Software version of this device
- optional string software_version = 7;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 8;
-}
-
-/**
- * Logs when we receive Bluetooth Read Remote Version Information Complete Event from the remote
- * device, as documented by the Bluetooth Core HCI specification
- * Reference: https://www.bluetooth.com/specifications/bluetooth-core-specification
- * Vol 2, Part E, Page 1118
- *
- * Logged from:
- * system/bt
- */
-message BluetoothRemoteVersionInfoReported {
- // Connection handle of the connection
- // Original type: uint16_t
- optional int32 connection_handle = 1;
- // HCI command status code
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum hci_status = 2;
- // 1 byte Version of current LMP in the remote controller
- optional int32 lmp_version = 3;
- // 2 bytes LMP manufacturer code of the remote controller
- // https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers
- optional int32 lmp_manufacturer_code = 4;
- // 4 bytes subversion of the LMP in the remote controller
- optional int32 lmp_subversion = 5;
-}
-
-/**
- * Logs when certain Bluetooth SDP attributes are discovered
- * Constant definitions are from:
- * https://www.bluetooth.com/specifications/assigned-numbers/service-discovery
- *
- * Current logged attributes:
- * - BluetoothProfileDescriptorList
- * - Supported Features Bitmask
- *
- * Logged from:
- * system/bt
- */
-message BluetoothSdpAttributeReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Short form UUIDs used to identify Bluetooth protocols, profiles, and service classes
- // Original type: uint16_t
- optional int32 protocol_uuid = 2;
- // Short form UUIDs used to identify Bluetooth SDP attribute types
- // Original type: uint16_t
- optional int32 attribute_id = 3;
- // Attribute value for the particular attribute
- optional bytes attribute_value = 4 [(android.os.statsd.log_mode) = MODE_BYTES];
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when bond state of a Bluetooth device changes
- *
- * Logged from:
- * frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
- */
-message BluetoothBondStateChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Preferred transport type to remote dual mode device
- // Default: TRANSPORT_AUTO means no preference
- optional android.bluetooth.TransportTypeEnum transport = 2;
- // The type of this Bluetooth device (Classic, LE, or Dual mode)
- // Default: UNKNOWN
- optional android.bluetooth.DeviceTypeEnum type = 3;
- // Current bond state (NONE, BONDING, BONDED)
- // Default: BOND_STATE_UNKNOWN
- optional android.bluetooth.BondStateEnum bond_state = 4;
- // Bonding sub state
- // Default: BOND_SUB_STATE_UNKNOWN
- optional android.bluetooth.BondSubStateEnum bonding_sub_state = 5;
- // Unbond Reason
- // Default: UNBOND_REASON_UNKNOWN
- optional android.bluetooth.UnbondReasonEnum unbond_reason = 6;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 7;
-}
-
-/**
- * Logs there is an event related Bluetooth classic pairing
- *
- * Logged from:
- * system/bt
- */
-message BluetoothClassicPairingEventReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Connection handle of this connection if available
- // Range: 0x0000 - 0x0EFF (12 bits)
- // Default: 0xFFFF if the handle is unknown
- optional int32 connection_handle = 2;
- // HCI command associated with this event
- // Default: CMD_UNKNOWN
- optional android.bluetooth.hci.CommandEnum hci_cmd = 3;
- // HCI event associated with this event
- // Default: EVT_UNKNOWN
- optional android.bluetooth.hci.EventEnum hci_event = 4;
- // HCI command status code if this is triggerred by hci_cmd
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum cmd_status = 5;
- // HCI reason code associated with this event
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum reason_code = 6;
- // A status value related to this specific event
- // Default: 0
- optional int64 event_value = 7;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 8;
-}
-
-/**
- * Logs when there is an event related to Bluetooth Security Manager Protocol (SMP)
- *
- * Logged from:
- * system/bt
- */
-message BluetoothSmpPairingEventReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // SMP command sent or received over L2CAP
- // Default: CMD_UNKNOWN
- optional android.bluetooth.smp.CommandEnum smp_command = 2;
- // Whether this command is sent or received
- // Default: DIRECTION_UNKNOWN
- optional android.bluetooth.DirectionEnum direction = 3;
- // SMP failure reason code
- // Default: PAIRING_FAIL_REASON_DEFAULT
- optional android.bluetooth.smp.PairingFailReasonEnum smp_fail_reason = 4;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when a Bluetooth socket’s connection state changed
- *
- * Logged from:
- * system/bt
- */
-message BluetoothSocketConnectionStateChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if this is a server listener socket
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Temporary port of this socket for the current connection or session only
- // Default 0 when unknown or don't care
- optional int32 port = 2;
- // Socket type as mentioned in
- // frameworks/base/core/java/android/bluetooth/BluetoothSocket.java
- // Default: SOCKET_TYPE_UNKNOWN
- optional android.bluetooth.SocketTypeEnum type = 3;
- // Socket connection state
- // Default: SOCKET_CONNECTION_STATE_UNKNOWN
- optional android.bluetooth.SocketConnectionstateEnum state = 4;
- // Number of bytes sent to remote device during this connection
- optional int64 tx_bytes = 5;
- // Number of bytes received from remote device during this connection
- optional int64 rx_bytes = 6;
- // Socket owner's UID
- optional int32 uid = 7 [(is_uid) = true];
- // Server port of this socket, if any. When both |server_port| and |port| fields are populated,
- // |port| must be spawned by |server_port|
- // Default 0 when unknown or don't care
- optional int32 server_port = 8;
- // Whether this is a server listener socket
- optional android.bluetooth.SocketRoleEnum is_server = 9;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 10;
-}
-
-/**
- * Logs when Class of Device (CoD) value is learnt for a device during pairing or connection
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/RemoteDevices.java
- *
- */
-message BluetoothClassOfDeviceReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if this is a server listener socket
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Class of Device (CoD) value including both Major, Minor device class and service class
- // Defined in: https://www.bluetooth.com/specifications/assigned-numbers/baseband
- // Also defined in: https://developer.android.com/reference/android/bluetooth/BluetoothClass
- // Default: 0
- optional int32 class_of_device = 2;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 3;
-}
-
-/**
- * Logs when something is plugged into or removed from the USB-C connector.
- *
- * Logged from:
- * UsbService
- */
-message UsbConnectorStateChanged {
- enum State {
- STATE_DISCONNECTED = 0;
- STATE_CONNECTED = 1;
- }
- optional State state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
- optional string id = 2 [(state_field_option).primary_field = true];
- // Last active session in ms.
- // 0 when the port is in connected state.
- optional int64 last_connect_duration_millis = 3;
-}
-
-/**
- * Logs the reported speaker impedance.
- *
- * Logged from:
- * Vendor audio implementation.
- */
-message SpeakerImpedanceReported {
- optional int32 speaker_location = 1;
- optional int32 impedance = 2;
-}
-
-/**
- * Logs the report of a failed hardware.
- *
- * Logged from:
- * Vendor HALs.
- *
- */
-message HardwareFailed {
- enum HardwareType {
- HARDWARE_FAILED_UNKNOWN = 0;
- HARDWARE_FAILED_MICROPHONE = 1;
- HARDWARE_FAILED_CODEC = 2;
- HARDWARE_FAILED_SPEAKER = 3;
- HARDWARE_FAILED_FINGERPRINT = 4;
- }
- optional HardwareType hardware_type = 1;
-
- /**
- * hardware_location allows vendors to differentiate between multiple instances of
- * the same hardware_type. The specific locations are vendor defined integers,
- * referring to board-specific numbering schemes.
- */
- optional int32 hardware_location = 2;
-
- /**
- * failure_code is specific to the HardwareType of the failed hardware.
- * It should use one of the enum values defined below.
- */
- enum HardwareErrorCode {
- UNKNOWN = 0;
- COMPLETE = 1;
- SPEAKER_HIGH_Z = 2;
- SPEAKER_SHORT = 3;
- FINGERPRINT_SENSOR_BROKEN = 4;
- FINGERPRINT_TOO_MANY_DEAD_PIXELS = 5;
- DEGRADE = 6;
- }
- optional int32 failure_code = 3;
-}
-
-/**
- * Log an event when the device has been physically dropped.
- * Reported from the /vendor partition.
- */
-message PhysicalDropDetected {
- // Confidence that the event was actually a drop, 0 -> 100
- optional int32 confidence_pctg = 1;
- // Peak acceleration of the drop, in 1/1000s of a g.
- optional int32 accel_peak_thousandths_g = 2;
- // Duration of freefall in ms
- optional int32 freefall_time_millis = 3;
-}
-
-/**
- * Log bucketed battery charge cycles.
- *
- * Each bucket represents cycles of the battery past
- * a given charge point. For example, if 10 cycle buckets are
- * initialized, bucket 1 is the lowest 1/10th of the battery,
- * and bucket 10 is 100%.
- *
- * Logged from:
- * /sys/class/power_supply/bms/cycle_count, via Vendor.
- */
-message ChargeCyclesReported {
- optional int32 cycle_bucket_1 = 1;
- optional int32 cycle_bucket_2 = 2;
- optional int32 cycle_bucket_3 = 3;
- optional int32 cycle_bucket_4 = 4;
- optional int32 cycle_bucket_5 = 5;
- optional int32 cycle_bucket_6 = 6;
- optional int32 cycle_bucket_7 = 7;
- optional int32 cycle_bucket_8 = 8;
- optional int32 cycle_bucket_9 = 9;
- optional int32 cycle_bucket_10 = 10;
-}
-
-/**
- * Log battery health snapshot.
- *
- * Resistance, Voltage, Open Circuit Voltage, Temperature, and Charge Level
- * are snapshotted periodically over 24hrs.
- */
-message BatteryHealthSnapshot {
- enum BatterySnapshotType {
- UNKNOWN = 0;
- MIN_TEMP = 1; // Snapshot at min batt temp over 24hrs.
- MAX_TEMP = 2; // Snapshot at max batt temp over 24hrs.
- MIN_RESISTANCE = 3; // Snapshot at min batt resistance over 24hrs.
- MAX_RESISTANCE = 4; // Snapshot at max batt resistance over 24hrs.
- MIN_VOLTAGE = 5; // Snapshot at min batt voltage over 24hrs.
- MAX_VOLTAGE = 6; // Snapshot at max batt voltage over 24hrs.
- MIN_CURRENT = 7; // Snapshot at min batt current over 24hrs.
- MAX_CURRENT = 8; // Snapshot at max batt current over 24hrs.
- MIN_BATT_LEVEL = 9; // Snapshot at min battery level (SoC) over 24hrs.
- MAX_BATT_LEVEL = 10; // Snapshot at max battery level (SoC) over 24hrs.
- AVG_RESISTANCE = 11; // Snapshot at average battery resistance over 24hrs.
- }
- optional BatterySnapshotType type = 1;
- // Temperature, in 1/10ths of degree C.
- optional int32 temperature_deci_celsius = 2;
- // Voltage Battery Voltage, in microVolts.
- optional int32 voltage_micro_volt = 3;
- // Current Battery current, in microAmps.
- optional int32 current_micro_amps = 4;
- // OpenCircuitVoltage Battery Open Circuit Voltage, in microVolts.
- optional int32 open_circuit_micro_volt = 5;
- // Resistance Battery Resistance, in microOhms.
- optional int32 resistance_micro_ohm = 6;
- // Level Battery Level, as % of full.
- optional int32 level_percent = 7;
-}
-
-/**
- * Log slow I/O operations on the primary storage.
- */
-message SlowIo {
- // Classifications of IO Operations.
- enum IoOperation {
- UNKNOWN = 0;
- READ = 1;
- WRITE = 2;
- UNMAP = 3;
- SYNC = 4;
- }
- optional IoOperation operation = 1;
-
- // The number of slow IO operations of this type over 24 hours.
- optional int32 count = 2;
-}
-
-/**
- * Log battery caused shutdown with the last recorded voltage.
- */
-message BatteryCausedShutdown {
- // The last recorded battery voltage prior to shutdown.
- optional int32 last_recorded_micro_volt = 1;
-}
-
-/**
- * Logs when ThermalService receives throttling events.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/stats/StatsCompanionService.java
- */
-message ThermalThrottlingSeverityStateChanged {
- // The type of temperature being reported (CPU, GPU, SKIN, etc)
- optional android.os.TemperatureTypeEnum sensor_type = 1;
-
- // The name of the temperature source. Eg. CPU0
- optional string sensor_name = 2;
-
- // Temperature in tenths of a degree C.
- // For BCL, it is decimillivolt, decimilliamps, and percentage * 10.
- optional int32 temperature_deci_celsius = 3;
-
- // Relative severity of the throttling, see enum definition.
- optional android.os.ThrottlingSeverityEnum severity = 4;
-}
-
-/**
- * Logs the duration of a davey (jank of >=700ms) when it occurs
- *
- * Logged from:
- * frameworks/base/libs/hwui/JankTracker.cpp
- */
-message DaveyOccurred {
- // The UID that logged this atom.
- optional int32 uid = 1 [(is_uid) = true];
-
- // Amount of time it took to render the frame. Should be >=700ms.
- optional int64 jank_duration_millis = 2;
-}
-
-/**
- * Logs phone signal strength changes.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message PhoneSignalStrengthChanged {
- // Signal strength, from frameworks/base/core/proto/android/telephony/enums.proto.
- optional android.telephony.SignalStrengthEnum signal_strength = 1;
-}
-
-
-/**
- * Logs when the phone state, sim state or signal strength changes
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message PhoneServiceStateChanged {
- optional android.telephony.ServiceStateEnum state = 1;
- optional android.telephony.SimStateEnum sim_state = 2;
- optional android.telephony.SignalStrengthEnum signal_strength = 3;
-}
-
-/**
- * Logs when the phone becomes on or off.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/TelephonyRegistry.java
- */
-message PhoneStateChanged {
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 1;
-}
-
-message BackGesture {
- enum BackType {
- DEFAULT_BACK_TYPE = 0;
- COMPLETED = 1;
- COMPLETED_REJECTED = 2; // successful because coming from rejected area
- INCOMPLETE_EXCLUDED = 3; // would have been successful but in the exclusion area
- INCOMPLETE = 4; // Unsuccessful, for reasons other than below.
- INCOMPLETE_FAR_FROM_EDGE = 5; // Unsuccessful, far from the edge.
- INCOMPLETE_MULTI_TOUCH = 6; // Unsuccessful, multi touch.
- INCOMPLETE_LONG_PRESS = 7; // Unsuccessful, long press.
- INCOMPLETE_VERTICAL_MOVE = 8; // Unsuccessful, move vertically.
- }
- optional BackType type = 1;
-
- optional int32 y_coordinate = 2 [deprecated = true]; // y coordinate for ACTION_DOWN event
- optional int32 start_x = 4; // X coordinate for ACTION_DOWN event.
- optional int32 start_y = 5; // Y coordinate for ACTION_DOWN event.
- optional int32 end_x = 6; // X coordinate for ACTION_MOVE event.
- optional int32 end_y = 7; // Y coordinate for ACTION_MOVE event.
- optional int32 left_boundary = 8; // left edge width + left inset
- optional int32 right_boundary = 9; // screen width - (right edge width + right inset)
-
- enum WindowHorizontalLocation {
- DEFAULT_LOCATION = 0;
- LEFT = 1;
- RIGHT = 2;
- }
- optional WindowHorizontalLocation x_location = 3 [deprecated = true];
-}
-
-message ExclusionRectStateChanged {
- optional string component_name = 1; // if not available, simply packageName
- optional int32 requested_height = 2; // px
- optional int32 rejected_height = 3; // px
-
- enum WindowHorizontalLocation {
- DEFAULT_LOCATION = 0;
- LEFT = 1;
- RIGHT = 2;
- }
- optional WindowHorizontalLocation x_location = 4;
- optional bool landscape = 5;
- optional bool splitscreen = 6;
- optional int32 duration_millis = 7;
-}
-
-/**
- * Logs when IME is on.
- *
- * Logged from: /packages/SystemUI/src/com/android/systemui/
- statusbar/phone/NavigationBarView.java
- *
- */
-message ImeTouchReported {
- optional int32 x_coordinate = 1; // X coordinate for ACTION_DOWN event.
- optional int32 y_coordinate = 2; // Y coordinate for ACTION_DOWN event.
-}
-
-/**
- * Logs when Launcher (HomeScreen) UI has changed or was interacted.
- *
- * Logged from:
- * packages/apps/Launcher3
- */
-message LauncherUIChanged {
- optional android.stats.launcher.LauncherAction action = 1 [deprecated = true];
- optional android.stats.launcher.LauncherState src_state = 2;
- optional android.stats.launcher.LauncherState dst_state = 3;
- optional android.stats.launcher.LauncherExtension extension = 4 [(log_mode) = MODE_BYTES, deprecated = true];
- optional bool is_swipe_up_enabled = 5 [deprecated = true];
-
- // The event id (e.g., app launch, drag and drop, long press)
- optional int32 event_id = 6;
- // The event's source or target id (e.g., icon, task, button)
- optional int32 target_id = 7;
- // If the target needs to be tracked, use this id field
- optional int32 instance_id = 8;
- optional int32 uid = 9 [(is_uid) = true];
- optional string package_name = 10;
- optional string component_name = 11;
-
- // (x, y) coordinate and the index information of the target on the container
- optional int32 grid_x = 12 [default = -1];
- optional int32 grid_y = 13 [default = -1];
- optional int32 page_id = 14 [default = -2];
-
- // e.g., folder icon's (x, y) location and index information on the workspace
- optional int32 grid_x_parent = 15 [default = -1];
- optional int32 grid_y_parent = 16 [default = -1];
- optional int32 page_id_parent = 17 [default = -2];
-
- // e.g., SEARCHBOX_ALLAPPS, FOLDER_WORKSPACE
- optional int32 hierarchy = 18;
-
- optional bool is_work_profile = 19;
-
- // Used to store the predicted rank of the target
- optional int32 rank = 20 [default = -1];
-
- // e.g., folderLabelState can be captured in the following two fields
- optional int32 from_state = 21;
- optional int32 to_state = 22;
-
- // e.g., autofilled or suggested texts that are not user entered
- optional string edittext = 23;
-
- // e.g., number of contents inside a container (e.g., icons inside a folder)
- optional int32 cardinality = 24;
-}
-
-/**
- * Used for snapshot of the HomeScreen UI elements
- *
- * Logged from:
- * packages/apps/Launcher3
- */
-message LauncherStaticLayout {
- // The event id (e.g., snapshot, drag and drop)
- optional int32 event_id = 1;
- // The event's source or target id (e.g., icon, shortcut, widget)
- optional int32 target_id = 2;
- // If the target needs to be tracked, use this id field
- optional int32 instance_id = 3;
- optional int32 uid = 4 [(is_uid) = true];
- optional string package_name = 5;
- optional string component_name = 6;
-
- // (x, y) coordinate and the index information of the target on the container
- optional int32 grid_x = 7 [default = -1];
- optional int32 grid_y = 8 [default = -1];
- optional int32 page_id = 9 [default = -2];
-
- // e.g., folder icon's (x, y) location and index information on the workspace
- // e.g., when used with widgets target, use these values for (span_x, span_y)
- optional int32 grid_x_parent = 10 [default = -1];
- optional int32 grid_y_parent = 11 [default = -1];
- optional int32 page_id_parent = 12 [default = -2];
-
- // UNKNOWN = 0
- // HOTSEAT = 1
- // WORKSPACE = 2
- // FOLDER_HOTSEAT = 3
- // FOLDER_WORKSPACE = 4
- optional int32 hierarchy = 13;
-
- optional bool is_work_profile = 14;
-
- // e.g., PIN, WIDGET TRAY, APPS TRAY, PREDICTION
- optional int32 origin = 15;
-
- // e.g., number of icons inside a folder
- optional int32 cardinality = 16;
-
- // e.g., (x, y) span of the widget inside homescreen grid system
- optional int32 span_x = 17 [default = 1];
- optional int32 span_y = 18 [default = 1];
-}
-
-/**
- * Logs when Wallpaper or ThemePicker UI has changed.
- *
- * Logged from:
- * packages/apps/ThemePicker
- * packages/apps/WallpaperPicker2
- */
-message StyleUIChanged {
- optional android.stats.style.Action action = 1;
- optional int32 color_package_hash = 2;
- optional int32 font_package_hash = 3;
- optional int32 shape_package_hash = 4;
- optional int32 clock_package_hash = 5;
- optional int32 launcher_grid = 6;
- optional int32 wallpaper_category_hash = 7;
- optional int32 wallpaper_id_hash = 8;
- optional int32 color_preference = 9;
- optional android.stats.style.LocationPreference location_preference = 10;
-}
-
-/**
- * Logs when Settings UI has changed.
- *
- * Logged from:
- * packages/apps/Settings
- */
-message SettingsUIChanged {
- /**
- * Where this SettingsUIChange event comes from. For example, if
- * it's a PAGE_VISIBLE event, where the page is opened from.
- */
- optional android.app.settings.PageId attribution = 1;
-
- /**
- * What the UI action is.
- */
- optional android.app.settings.Action action = 2;
-
- /**
- * Where the action is happening
- */
- optional android.app.settings.PageId page_id = 3;
-
- /**
- * What preference changed in this event.
- */
- optional string changed_preference_key = 4;
-
- /**
- * The new value of the changed preference.
- */
- optional int64 changed_preference_int_value = 5;
-}
-
-/**
- * Logs basic timing information about touch events.
- * Reported at most every 5 minutes while device is being interacted with.
- *
- * Logged from:
- * frameworks/native/services/inputflinger
- */
-message TouchEventReported {
- /**
- * The fields latency_{min|max|mean|stdev} represent minimum, maximum, mean,
- * and the standard deviation of the time spent processing touchscreen events
- * in the kernel and inputflinger. The units are microseconds.
- *
- * On supported devices, the starting point is taken during the hard interrupt inside the
- * kernel touch driver. On all other devices, the starting point is taken inside
- * the kernel's input event subsystem upon receipt of the input event.
- * The ending point is taken inside InputDispatcher, just after the input event
- * is sent to the app.
- */
- // Minimum value
- optional float latency_min_micros = 1;
- // Maximum value
- optional float latency_max_micros = 2;
- // Average value
- optional float latency_mean_micros = 3;
- // Standard deviation
- optional float latency_stdev_micros = 4;
- // Number of touch events (input_event) in this report
- optional int32 count = 5;
-}
-
-/**
- * Logs gesture classification and timing information for touch events.
- *
- * Logged from:
- * frameworks/base/core/java/android/view/GestureDetector.java
- * frameworks/base/core/java/android/view/View.java
- */
-message TouchGestureClassified {
- // The source of the classification (e.g. Java class name).
- optional string source = 1;
-
- enum Classification {
- UNKNOWN_CLASSIFICATION = 0;
- SINGLE_TAP = 1;
- DOUBLE_TAP = 2;
- LONG_PRESS = 3;
- DEEP_PRESS = 4;
- SCROLL = 5;
- }
- // The classification of the gesture.
- optional Classification classification = 2;
-
- // The interval from the start of a touch event stream until the
- // classification was made.
- optional int32 latency_millis = 3;
-
- // The distance from the location of the first touch event to the
- // location of the touch event when the classification was made.
- optional float displacement_px = 4;
-}
-
-/**
- * Logs that a setting was updated.
- * Logged from:
- * frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
- * The tag and is_default allow resetting of settings to default values based on the specified
- * tag. See Settings#putString(ContentResolver, String, String, String, boolean) for more details.
- */
-message SettingChanged {
- // The name of the setting.
- optional string setting = 1;
-
- // The change being imposed on this setting. May represent a number, eg "3".
- optional string value = 2;
-
- // The new value of this setting. For most settings, this is same as value. For some settings,
- // value is +X or -X where X represents an element in a set. For example, if the previous value
- // is A,B,C and value is -B, then new_value is A,C and prev_value is A,B,C.
- // The +/- feature is currently only used for location_providers_allowed.
- optional string new_value = 3;
-
- // The previous value of this setting.
- optional string prev_value = 4;
-
- // The tag used with the is_default for resetting sets of settings. This is generally null.
- optional string tag = 5;
-
- // True if this setting with tag should be resettable.
- optional bool is_default = 6;
-
- // The associated user (for multi-user feature). Defined in android/os/UserHandle.java
- optional int32 user = 7;
-
- enum ChangeReason {
- UPDATED = 1; // Updated can be an insertion or an update.
- DELETED = 2;
- }
- optional ChangeReason reason = 8;
-}
-
-/**
- * Logs activity going to foreground or background
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
- */
-message ActivityForegroundStateChanged {
- optional int32 uid = 1 [(is_uid) = true];
- optional string pkg_name = 2;
- optional string class_name = 3;
-
- enum State {
- BACKGROUND = 0;
- FOREGROUND = 1;
- }
- optional State state = 4;
-}
-
-/**
- * Logs when a volume entered low Storage state.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
- */
-message LowStorageStateChanged {
- // Volume that ran out of storage.
- optional string volume_description = 1;
-
- enum State {
- UNKNOWN = 0;
- OFF = 1;
- ON = 2;
- }
- optional State state = 2;
-}
-
-/**
- * Logs when an app is downgraded.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/pm/BackgroundDexOptService.java
- */
-message AppDowngraded {
- optional string package_name = 1;
- // Size of the package (all data) before being downgraded.
- optional int64 size_in_bytes_before = 2;
- // Size of the package (all data) after being downgraded.
- optional int64 size_in_bytes_after = 3;
-
- optional bool aggressive = 4;
-}
-
-/**
- * Logs when an app is optimized after being downgraded.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/pm/BackgroundDexOptService.java
- */
-message AppOptimizedAfterDowngraded {
- optional string package_name = 1;
-}
-
-/**
- * Logs whenever an app is installed on external storage.
- * Logged from:
- frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
- */
-message AppInstallOnExternalStorageReported {
- // The type of external storage.
- optional android.stats.storage.ExternalStorageType storage_type = 1;
- // The name of the package that is installed on the sd card.
- optional string package_name = 2;
-}
-
-/**
- * Logs when an app crashes.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message AppCrashOccurred {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string event_type = 2;
-
- // The name of the process.
- // system_server if it is not by an app
- optional string process_name = 3;
-
- // The pid if available. -1 means not available.
- optional int32 pid = 4;
-
- optional string package_name = 5;
-
- enum InstantApp {
- UNAVAILABLE = 0;
- FALSE = 1;
- TRUE = 2;
- }
- optional InstantApp is_instant_app = 6;
-
- enum ForegroundState {
- UNKNOWN = 0;
- BACKGROUND = 1;
- FOREGROUND = 2;
- }
- optional ForegroundState foreground_state = 7;
-
- optional android.server.ErrorSource error_source = 8;
-}
-
-/**
- * Logs when a WTF (What a Terrible Failure) happened.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message WTFOccurred {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string tag = 2;
-
- // The name of the process.
- // system_server if it is not by an app
- optional string process_name = 3;
-
- // The pid if available. -1 means not available.
- optional int32 pid = 4;
-
- optional android.server.ErrorSource error_source = 5;
-}
-
-/**
- * Logs when system server reports low memory.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message LowMemReported {
-}
-
-/**
- * Logs when an app ANR (App Not Responding) occurs.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/AppErrors.java
- */
-message ANROccurred {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string process_name = 2;
-
- optional string short_component_name = 3;
-
- optional string reason = 4;
-
- enum InstantApp {
- UNAVAILABLE = 0;
- FALSE = 1;
- TRUE = 2;
- }
- optional InstantApp is_instant_app = 5;
-
- enum ForegroundState {
- UNKNOWN = 0;
- BACKGROUND = 1;
- FOREGROUND = 2;
- }
- optional ForegroundState foreground_state = 6;
-
- optional android.server.ErrorSource error_source = 7;
-
- optional string package_name = 8;
-}
-
-/**
- * Logs when the vibrator state changes.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/VibratorService.java
- */
-message VibratorStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-
- // Duration (in milliseconds) requested to keep the vibrator on.
- // Only applicable for State == ON.
- optional int64 duration_millis = 3;
-}
-
-/*
- * Allows other apps to push events into statsd.
- * Logged from:
- * frameworks/base/core/java/android/util/StatsLog.java
- */
-message AppBreadcrumbReported {
- // The uid of the application that sent this custom atom.
- optional int32 uid = 1 [(is_uid) = true];
-
- // An arbitrary label chosen by the developer. For Android P, the label should be in [0, 16).
- optional int32 label = 2;
-
- // Allows applications to easily use a custom event as start/stop boundaries (ie, define custom
- // predicates for the metrics).
- enum State {
- UNKNOWN = 0;
- UNSPECIFIED = 1; // For events that are known to not represent START/STOP.
- STOP = 2;
- START = 3;
- }
- optional State state = 3;
-}
-
-/**
- * Logs the wall-clock time when a significant wall-clock time shift occurs.
- * For example, this could be due to the user manually changing the time.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/AlarmManagerService.java
- */
-message WallClockTimeShifted {
- // New wall-clock time in milliseconds, according to System.currentTimeMillis().
- optional int64 wall_clock_timestamp_millis = 1;
-}
-
-/**
- * Logs when statsd detects an anomaly.
- *
- * Logged from:
- * frameworks/base/cmds/statsd/src/anomaly/AnomalyTracker.cpp
- */
-message AnomalyDetected {
- // Uid that owns the config whose anomaly detection alert fired.
- optional int32 config_uid = 1 [(is_uid) = true];
-
- // Id of the config whose anomaly detection alert fired.
- optional int64 config_id = 2;
-
- // Id of the alert (i.e. name of the anomaly that was detected).
- optional int64 alert_id = 3;
-}
-
-message AppStartOccurred {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The app package name.
- optional string pkg_name = 2;
-
- enum TransitionType {
- UNKNOWN = 0;
- WARM = 1;
- HOT = 2;
- COLD = 3;
- }
- // The transition type.
- optional TransitionType type = 3;
-
- // The activity name.
- optional string activity_name = 4;
-
- // The name of the calling app. Empty if not set.
- optional string calling_pkg_name = 5;
-
- // Whether the app is an instant app.
- optional bool is_instant_app = 6;
-
- // Device uptime when activity started.
- optional int64 activity_start_millis = 7;
-
- optional android.app.AppTransitionReasonEnum reason = 8;
-
- optional int32 transition_delay_millis = 9;
- // -1 if not set.
- optional int32 starting_window_delay_millis = 10;
- // -1 if not set.
- optional int32 bind_application_delay_millis = 11;
- optional int32 windows_drawn_delay_millis = 12;
-
- // Empty if not set.
- optional string launch_token = 13;
-
- // The compiler filter used when when the package was optimized.
- optional int32 package_optimization_compilation_filter = 14;
-
- // The reason why the package was optimized.
- optional int32 package_optimization_compilation_reason = 15;
-}
-
-message AppStartCanceled {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The app package name.
- optional string pkg_name = 2;
-
- enum TransitionType {
- UNKNOWN = 0;
- WARM = 1;
- HOT = 2;
- COLD = 3;
- }
- // The transition type.
- optional TransitionType type = 3;
-
- // The activity name.
- optional string activity_name = 4;
-}
-
-message AppStartFullyDrawn {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The app package name.
- optional string pkg_name = 2;
-
- enum TransitionType {
- UNKNOWN = 0;
- WITH_BUNDLE = 1;
- WITHOUT_BUNDLE = 2;
- }
- // The transition type.
- optional TransitionType type = 3;
-
- // The activity name.
- optional string activity_name = 4;
-
- optional bool transition_process_running = 5;
-
- // App startup time (until call to Activity#reportFullyDrawn()).
- optional int64 app_startup_time_millis = 6;
-}
-
-/**
- * Logs a picture-in-picture action
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- * frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
- * frameworks/base/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
- */
-message PictureInPictureStateChanged {
- // -1 if it is not available
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string short_name = 2;
-
- enum State {
- ENTERED = 1;
- EXPANDED_TO_FULL_SCREEN = 2;
- MINIMIZED = 3;
- DISMISSED = 4;
- }
- optional State state = 3;
-}
-
-/**
- * Logs overlay action
- * Logged from:
- * services/core/java/com/android/server/wm/Session.java
- */
-message OverlayStateChanged {
- optional int32 uid = 1 [(state_field_option).primary_field = true, (is_uid) = true];
-
- optional string package_name = 2 [(state_field_option).primary_field = true];
-
- optional bool using_alert_window = 3;
-
- enum State {
- ENTERED = 1;
- EXITED = 2;
- }
- optional State state = 4
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs foreground service starts and stops.
- * Note that this is not when a service starts or stops, but when it is
- * considered foreground.
- * Logged from
- * frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
- */
-message ForegroundServiceStateChanged {
- optional int32 uid = 1 [(is_uid) = true];
- // package_name + "/" + class_name
- optional string short_name = 2;
-
- enum State {
- ENTER = 1;
- EXIT = 2;
- }
- optional State state = 3;
-
- // Whether the fgs is allowed while-in-use permissions, i.e. is considered 'in-use' to the user.
- // (If the fgs was started while the app wasn't TOP it usually will be denied these permissions)
- optional bool allow_while_in_use_permission = 4;
-}
-
-/**
- * Logs the number of times a uid accesses a sensitive AppOp during a foreground service session.
- * A foreground service session is any continuous period during which the uid holds at least one
- * foreground service; the atom will be pushed when the uid no longer holds any foreground services.
- * Accesses initiated while the uid is in the TOP state are ignored.
- * Sessions with no attempted accesses are not logged.
- * Logged from
- * frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
- */
-message ForegroundServiceAppOpSessionEnded {
- optional int32 uid = 1 [(is_uid) = true];
-
- // The operation's name.
- // Only following four ops are logged
- // COARSE_LOCATION = 0
- // FINE_LOCATION = 1
- // CAMERA = 26
- // RECORD_AUDIO = 27
- optional android.app.AppOpEnum app_op_name = 2 [default = APP_OP_NONE];
-
- // The uid's permission mode for accessing the AppOp during this fgs session.
- enum Mode {
- MODE_UNKNOWN = 0;
- MODE_ALLOWED = 1; // Always allowed
- MODE_IGNORED = 2; // Denied
- MODE_FOREGROUND = 3; // Allow-while-in-use (or allowed-one-time)
- }
- optional Mode app_op_mode = 3;
-
- // Number of times this AppOp was requested and allowed.
- optional int32 count_ops_accepted = 4;
- // Number of times this AppOp was requested but denied.
- optional int32 count_ops_rejected = 5;
-}
-
-/**
- * Logs creation or removal of an isolated uid. Isolated uid's are temporary uid's to sandbox risky
- * behavior in its own uid. However, the metrics of these isolated uid's almost always should be
- * attributed back to the parent (host) uid. One example is Chrome.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message IsolatedUidChanged {
- // The host UID. Generally, we should attribute metrics from the isolated uid to the host uid.
- // NOTE: DO NOT annotate uid field in this atom. This atom is specially handled in statsd.
- // This field is ignored when event == REMOVED.
- optional int32 parent_uid = 1;
-
- optional int32 isolated_uid = 2;
-
- // We expect an isolated uid to be removed before if it's used for another parent uid.
- enum Event {
- REMOVED = 0;
- CREATED = 1;
- }
- optional Event event = 3;
-}
-
-/*
- * Logs the reception of an incoming network packet causing the main system to wake up for
- * processing that packet. These events are notified by the kernel via Netlink NFLOG to Netd
- * and processed by WakeupController.cpp.
- */
-message PacketWakeupOccurred {
- // The uid owning the socket into which the packet was delivered, or -1 if the packet was
- // delivered nowhere.
- optional int32 uid = 1 [(is_uid) = true];
- // The interface name on which the packet was received.
- optional string iface = 2;
- // The ethertype value of the packet.
- optional int32 ethertype = 3;
- // String representation of the destination MAC address of the packet.
- optional string destination_hardware_address = 4;
- // String representation of the source address of the packet if this was an IP packet.
- optional string source_ip = 5;
- // String representation of the destination address of the packet if this was an IP packet.
- optional string destination_ip = 6;
- // The value of the protocol field if this was an IPv4 packet or the value of the Next Header
- // field if this was an IPv6 packet. The range of possible values is the same for both IP
- // families.
- optional int32 ip_next_header = 7;
- // The source port if this was a TCP or UDP packet.
- optional int32 source_port = 8;
- // The destination port if this was a TCP or UDP packet.
- optional int32 destination_port = 9;
-}
-
-/*
- * Logs the memory stats for an app on startup.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message AppStartMemoryStateCaptured {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name.
- optional string process_name = 2;
-
- // The activity name.
- optional string activity_name = 3;
-
- // # of page-faults
- optional int64 page_fault = 4;
-
- // # of major page-faults
- optional int64 page_major_fault = 5;
-
- // RSS
- optional int64 rss_in_bytes = 6;
-
- // CACHE
- optional int64 cache_in_bytes = 7;
-
- // SWAP
- optional int64 swap_in_bytes = 8;
-}
-
-/*
- * Logs the change in Low Memory Killer Daemon (LMKD) state which is used as start/stop boundaries
- * for LMK event.
- * Logged from:
- * system/core/lmkd/lmkd.c
- */
-message LmkStateChanged {
- enum State {
- UNKNOWN = 0;
- START = 1;
- STOP = 2;
- }
- optional State state = 1;
-}
-
-/*
- * Logs the event when Low Memory Killer Daemon (LMKD) kills a process to reduce memory pressure.
- * Logged from:
- * system/core/lmkd/lmkd.c
- */
-message LmkKillOccurred {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name.
- optional string process_name = 2;
-
- // oom adj score.
- optional int32 oom_adj_score = 3;
-
- // # of page-faults
- optional int64 page_fault = 4;
-
- // # of major page-faults
- optional int64 page_major_fault = 5;
-
- // RSS
- optional int64 rss_in_bytes = 6;
-
- // CACHE
- optional int64 cache_in_bytes = 7;
-
- // SWAP
- optional int64 swap_in_bytes = 8;
-
- // The elapsed real time of start of the process.
- optional int64 process_start_time_nanos = 9;
-
- // Min oom adj score considered by lmkd.
- optional int32 min_oom_score = 10;
-}
-
-/*
- * Logs when the ActivityManagerService detects that an app died.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message AppDied {
- // timestamp(elapsedRealtime) of record creation
- optional uint64 timestamp_millis = 1 [(state_field_option).exclusive_state = true];
-}
-
-/**
- * An atom for generic metrics logging. Available from Android Q.
- */
-message GenericAtom {
- // The uid of the application that sent this custom atom.
- optional int32 uid = 1 [(is_uid) = true];
-
- // An event_id indicates the type of event.
- optional android.stats.EventType event_id = 2;
-}
-
-/**
- * Atom for simple logging of user interaction and impression events, such as "the user touched
- * this button" or "this dialog was displayed".
- * Keep the UI event stream clean: don't use for system or background events.
- * Log using the UiEventLogger wrapper - don't write with the StatsLog API directly.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/
- * frameworks/base/packages/SystemUI/src/com/android/systemui/
- */
-message UiEventReported {
- // The event_id.
- optional int32 event_id = 1;
- // The event's source or target uid and package, if applicable.
- // For example, the package posting a notification, or the destination package of a share.
- optional int32 uid = 2 [(is_uid) = true];
- optional string package_name = 3;
- // An identifier used to disambiguate which logs refer to a particular instance of some
- // UI element. Useful when there might be multiple instances simultaneously active.
- optional int32 instance_id = 4;
-}
-
-/**
- * Reports a notification was created or updated.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/notification/
- */
-message NotificationReported {
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
- // The notifying app's uid and package.
- optional int32 uid = 2 [(is_uid) = true];
- optional string package_name = 3;
- // A small system-assigned identifier for the notification.
- // Locally probably-unique, but expect collisions across users and/or days.
- optional int32 instance_id = 4;
- optional int32 notification_id_hash = 5; // Small hash of the app-assigned notif ID + tag
- optional int32 channel_id_hash = 6; // Small hash of app-assigned channel ID
-
- // Grouping information
- optional int32 group_id_hash = 7; // Small hash of the group ID of the notification
- optional int32 group_instance_id = 8; // Instance_id of the group-summary notification
- optional bool is_group_summary = 9; // Tags the group-summary notification
-
- // Attributes
- optional string category = 10; // App-assigned notification category (API-defined strings)
- optional int32 style = 11; // App-assigned notification style
- optional int32 num_people = 12; // Number of Person records attached to the notification
-
- // Ordering, importance and interruptiveness
-
- optional int32 position = 13; // Position in NotificationManager's list
-
- optional android.stats.sysui.NotificationImportance importance = 14;
- optional int32 alerting = 15; // Bitfield, 1=buzz 2=beep 4=blink
-
- enum NotificationImportanceExplanation {
- IMPORTANCE_EXPLANATION_UNKNOWN = 0;
- IMPORTANCE_EXPLANATION_APP = 1; // App-specified channel importance.
- IMPORTANCE_EXPLANATION_USER = 2; // User-specified channel importance.
- IMPORTANCE_EXPLANATION_ASST = 3; // Notification Assistant override.
- IMPORTANCE_EXPLANATION_SYSTEM = 4; // System override.
- // Like _APP, but based on pre-channels priority signal.
- IMPORTANCE_EXPLANATION_APP_PRE_CHANNELS = 5;
- }
-
- optional NotificationImportanceExplanation importance_source = 16;
- optional android.stats.sysui.NotificationImportance importance_initial = 17;
- optional NotificationImportanceExplanation importance_initial_source = 18;
- optional android.stats.sysui.NotificationImportance importance_asst = 19;
- optional int32 assistant_hash = 20;
- optional float assistant_ranking_score = 21;
-}
-
-message Notification {
- // The notifying app's uid and package.
- optional int32 uid = 1 [(is_uid) = true];
- optional string package_name = 2;
- // A small system-assigned identifier for the notification.
- optional int32 instance_id = 3;
-
- // Grouping information.
- optional int32 group_instance_id = 4;
- optional bool is_group_summary = 5;
-
- // The section of the shade that the notification is in.
- // See NotificationSectionsManager.PriorityBucket.
- enum NotificationSection {
- SECTION_UNKNOWN = 0;
- SECTION_HEADS_UP = 1;
- SECTION_MEDIA_CONTROLS = 2;
- SECTION_PEOPLE = 3;
- SECTION_ALERTING = 4;
- SECTION_SILENT = 5;
- }
- optional NotificationSection section = 6;
-}
-
-message NotificationList {
- repeated Notification notifications = 1; // An ordered sequence of notifications.
-}
-
-/**
- * Reports a notification panel was displayed, e.g. from the lockscreen or status bar.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/
- */
-message NotificationPanelReported {
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
- optional int32 num_notifications = 2;
- // The notifications in the panel, in the order that they appear there.
- optional NotificationList notifications = 3 [(log_mode) = MODE_BYTES];
-}
-
-/**
- * Reports a notification channel, or channel group, was created, updated, or deleted.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/notification/
- */
-message NotificationChannelModified {
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
- // The notifying app's uid and package.
- optional int32 uid = 2 [(is_uid) = true];
- optional string package_name = 3;
- // Hash of app-assigned notification channel ID or channel-group ID
- optional int32 channel_id_hash = 4;
- // Previous importance setting, if applicable
- optional android.stats.sysui.NotificationImportance old_importance = 5;
- // New importance setting
- optional android.stats.sysui.NotificationImportance importance = 6;
-}
-
-
-/**
- * Logs when a biometric acquire event occurs.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/biometrics
- */
-message BiometricAcquired {
- // Biometric modality that was acquired.
- optional android.hardware.biometrics.ModalityEnum modality = 1;
- // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java.
- optional int32 user = 2;
- // If this acquire is for a crypto operation. e.g. Secure purchases, unlock password storage.
- optional bool is_crypto = 3;
- // Action that the device is performing. Acquired messages are only expected for enroll and
- // authenticate. Other actions may indicate an error.
- optional android.hardware.biometrics.ActionEnum action = 4;
- // The client that this acquisition was received for.
- optional android.hardware.biometrics.ClientEnum client = 5;
- // Acquired constants, e.g. ACQUIRED_GOOD. See constants defined by <Biometric>Manager.
- optional int32 acquire_info = 6;
- // Vendor-specific acquire info. Valid only if acquire_info == ACQUIRED_VENDOR.
- optional int32 acquire_info_vendor = 7;
- // Dictates if this message should trigger additional debugging.
- optional bool debug = 8;
-}
-
-/**
- * Logs when a biometric authentication event occurs.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/biometrics
- */
-message BiometricAuthenticated {
- // Biometric modality that was used.
- optional android.hardware.biometrics.ModalityEnum modality = 1;
- // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java
- optional int32 user = 2;
- // If this authentication is for a crypto operation. e.g. Secure purchases, unlock password
- // storage.
- optional bool is_crypto = 3;
- // The client that this acquisition was received for.
- optional android.hardware.biometrics.ClientEnum client = 4;
- // If authentication requires user confirmation. See BiometricPrompt's
- // setRequireConfirmation(bool) method.
- optional bool require_confirmation = 5;
-
- enum State {
- UNKNOWN = 0;
- REJECTED = 1;
- PENDING_CONFIRMATION = 2;
- CONFIRMED = 3;
- }
-
- // State of the current auth attempt.
- optional State state = 6;
- // Time it took to authenticate. For BiometricPrompt where setRequireConfirmation(false) is
- // specified and supported by the biometric modality, this is from the first ACQUIRED_GOOD to
- // AUTHENTICATED. for setRequireConfirmation(true), this is from PENDING_CONFIRMATION to
- // CONFIRMED.
- optional int64 latency_millis = 7;
- // Dictates if this message should trigger additional debugging.
- optional bool debug = 8;
-}
-
-/**
- * Logs when a biometric error occurs.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/biometrics
- */
-message BiometricErrorOccurred {
- // Biometric modality that was used.
- optional android.hardware.biometrics.ModalityEnum modality = 1;
- // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java
- optional int32 user = 2;
- // If this error is for a crypto operation. e.g. Secure purchases, unlock password storage.
- optional bool is_crypto = 3;
- // Action that the device is performing.
- optional android.hardware.biometrics.ActionEnum action = 4;
- // The client that this acquisition was received for.
- optional android.hardware.biometrics.ClientEnum client = 5;
- // Error constants. See constants defined by <Biometric>Manager. Enums won't work since errors
- // are unique to modality.
- optional int32 error_info = 6;
- // Vendor-specific error info. Valid only if acquire_info == ACQUIRED_VENDOR. These are defined
- // by the vendor and not specified by the HIDL interface.
- optional int32 error_info_vendor = 7;
- // Dictates if this message should trigger additional debugging.
- optional bool debug = 8;
- // Time spent during the authentication attempt.
- optional int64 latency_millis = 9;
-}
-
-/**
- * Logs when a system health issue is detected.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/biometrics
- */
-message BiometricSystemHealthIssueDetected {
- // Biometric modality.
- optional android.hardware.biometrics.ModalityEnum modality = 1;
- // Type of issue detected.
- optional android.hardware.biometrics.IssueEnum issue = 2;
- // Dictates if this message should trigger additional debugging.
- optional bool debug = 3;
-}
-
-/**
- * Logs when a biometric enrollment occurs.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/biometrics
- */
-message BiometricEnrolled {
- // Biometric modality that was used.
- optional android.hardware.biometrics.ModalityEnum modality = 1;
- // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java
- optional int32 user = 2;
- // The amount of time the enrollment took in milliseconds.
- optional int64 latency_millis = 3;
- // Whether or not the enrollment was successful.
- optional bool success = 4;
-}
-
-/*
- * Logs when a flag flip update occurrs. Used for mainline modules that update via flag flips.
- */
-message FlagFlipUpdateOccurred {
- // If the event is from a flag config package, specify the package name.
- optional string flag_flip_package_name = 1;
-
- // The order id of the package
- optional int64 order_id = 2;
-}
-
-/**
- * Potential experiment ids that goes with a train install.
- * Should be kept in sync with experiment_ids.proto.
- */
-message TrainExperimentIds {
- repeated int64 experiment_id = 1;
-}
-
-/*
- * Logs when a binary push state changes.
- * Logged by the installer via public api.
- */
-message BinaryPushStateChanged {
- // Name of the train.
- optional string train_name = 1;
- // Version code for a "train" of packages that need to be installed atomically
- optional int64 train_version_code = 2;
- // After installation of this package, device requires a restart.
- optional bool requires_staging = 3;
- // Rollback should be enabled for this install.
- optional bool rollback_enabled = 4;
- // Requires low latency monitoring if possible.
- optional bool requires_low_latency_monitor = 5;
-
- enum State {
- UNKNOWN = 0;
- INSTALL_REQUESTED = 1;
- INSTALL_STARTED = 2;
- INSTALL_STAGED_NOT_READY = 3;
- INSTALL_STAGED_READY = 4;
- INSTALL_SUCCESS = 5;
- // Replaced by INSTALL_FAILURE_DOWNLOAD, INSTALL_FAILURE_STATE_MISMATCH,
- // and INSTALL_FAILURE_COMMIT.
- INSTALL_FAILURE = 6 [deprecated = true];
- // This enum is for installs that are manually cancelled via the Manual Update UI.
- INSTALL_CANCELLED = 7;
- INSTALLER_ROLLBACK_REQUESTED = 8;
- INSTALLER_ROLLBACK_INITIATED = 9;
- INSTALLER_ROLLBACK_INITIATED_FAILURE = 10;
- INSTALLER_ROLLBACK_STAGED = 11;
- INSTALLER_ROLLBACK_STAGED_FAILURE = 12;
- INSTALLER_ROLLBACK_BOOT_TRIGGERED = 13;
- INSTALLER_ROLLBACK_BOOT_TRIGGERED_FAILURE = 14;
- INSTALLER_ROLLBACK_SUCCESS = 15;
- INSTALLER_ROLLBACK_FAILURE = 16;
- INSTALLER_ROLLBACK_STAGED_CANCEL_REQUESTED = 17;
- INSTALLER_ROLLBACK_STAGED_CANCEL_SUCCESS = 18;
- INSTALLER_ROLLBACK_STAGED_CANCEL_FAILURE = 19;
- INSTALL_STAGED_CANCEL_REQUESTED = 20;
- INSTALL_STAGED_CANCEL_SUCCESS = 21;
- INSTALL_STAGED_CANCEL_FAILURE = 22;
- INSTALL_FAILURE_DOWNLOAD = 23;
- INSTALL_FAILURE_STATE_MISMATCH = 24;
- INSTALL_FAILURE_COMMIT = 25;
- REBOOT_TRIGGERED = 26;
- }
- optional State state = 6;
- // Possible experiment ids for monitoring this push.
- optional TrainExperimentIds experiment_ids = 7 [(log_mode) = MODE_BYTES];
- // user id
- optional int32 user_id = 8;
- optional int32 reason = 9;
- // Whether or not this is a rollback event
- optional bool is_rollback = 10;
-}
-
-/* Test atom, is not logged anywhere */
-message TestAtomReported {
- repeated AttributionNode attribution_node = 1;
- optional int32 int_field = 2;
- optional int64 long_field = 3;
- optional float float_field = 4;
- optional string string_field = 5;
- optional bool boolean_field = 6;
- enum State {
- UNKNOWN = 0;
- OFF = 1;
- ON = 2;
- }
- optional State state = 7;
- optional TrainExperimentIds bytes_field = 8 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/** Represents USB port overheat event. */
-message UsbPortOverheatEvent {
- /* Temperature of USB port at USB plug event, in 1/10ths of degree C. */
- optional int32 plug_temperature_deci_c = 1;
-
- /* Maximum temperature of USB port during overheat event, in 1/10ths of degree C. */
- optional int32 max_temperature_deci_c = 2;
-
- /* Time between USB plug event and overheat threshold trip, in seconds. */
- optional int32 time_to_overheat_secs = 3;
-
- /* Time between overheat threshold trip and hysteresis, in seconds. */
- optional int32 time_to_hysteresis_secs = 4;
-
- /* Time between hysteresis and active mitigation ending, in seconds. */
- optional int32 time_to_inactive_secs = 5;
-};
-
-/**
- * Logs total effective full charge and discharge cycles on a battery.
- * Here are some examples of one effective cycle:
- * 1) the battery charges from 0% to 100% and drains back to 0%,
- * 2) charging from 50% to 100% and draining back to 50% twice.
- * Pulled from:
- * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
- */
-message BatteryCycleCount {
- /* Number of total charge and discharge cycles on the system battery. */
- optional int32 cycle_count = 1;
-}
-
-/**
- * Logs that external storage is mounted and information about it, the storage type (sd card/usb/
- * others), its type (public or private) and the size in bytes.
- * Pulled from:
- * StatsCompanionService
- */
-
-message ExternalStorageInfo {
-
- enum VolumeType {
- UNKNOWN = 0;
- PUBLIC = 1;
- PRIVATE = 2;
- OTHER = 3;
- }
-
- // The type of external storage.
- optional android.stats.storage.ExternalStorageType storage_type = 1;
- // Type of the volume: TYPE_PUBLIC if portable and TYPE_PRIVATE if internal.
- optional VolumeType volume_type = 2;
- // Total size of the sd card in bytes.
- optional int64 size_bytes = 3;
-}
-
-/*
- * Logs when a connection becomes available and lost.
- * Logged in StatsCompanionService.java
- */
-message ConnectivityStateChanged {
- // Id of the network.
- optional int32 net_id = 1;
-
- enum State {
- UNKNOWN = 0;
- CONNECTED = 1;
- DISCONNECTED = 2;
- }
- // Connected state of a network.
- optional State state = 2;
-}
-
-/**
- * Logs when a service starts and stops.
- * Logged from:
- * services/core/java/com/android/server/am/ActiveServices.java
- */
-message ServiceStateChanged {
-
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string package_name = 2;
-
- optional string service_name = 3;
-
- enum State {
- START = 1;
- STOP = 2;
- }
-
- optional State state = 4;
-}
-
-/**
- * Logs when a service is launched.
- * Logged from:
- * services/core/java/com/android/server/am/ActiveServices.java
- */
-message ServiceLaunchReported {
-
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string package_name = 2;
-
- optional string service_name = 3;
-}
-
-/**
- * Logs when a hidden API is used.
- *
- * Logged from:
- * libcore/libart/src/main/java/dalvik/system/VMRuntime.java
- */
-message HiddenApiUsed {
- // The uid of the app making the hidden access.
- optional int32 uid = 1 [(is_uid) = true];
-
- // Signature of the method or field accessed.
- optional string signature = 2;
-
- enum AccessMethod {
- NONE = 0;
- REFLECTION = 1;
- JNI = 2;
- LINKING = 3;
- }
-
- // Type of access.
- optional AccessMethod access_method = 3;
-
- // Whether the access was prevented or not.
- optional bool access_denied = 4;
-}
-
-/**
- * Logs user interaction with the Privacy Indicators added in Q. In particular:
- * - When user sees privacy chip
- * - When user clicks privacy chip
- * - How does the user exit the Privacy Dialog
- * Logged from:
- * packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
- */
-message PrivacyIndicatorsInteracted {
-
- enum Type {
- UNKNOWN = 0;
- CHIP_VIEWED = 1;
- CHIP_CLICKED = 2;
- DIALOG_PRIVACY_SETTINGS = 3;
- DIALOG_DISMISS = 4;
- DIALOG_LINE_ITEM = 5;
- }
-
- optional Type type = 1 [(state_field_option).exclusive_state = true];
-
- // Used if the type is LINE_ITEM
- optional string package_name = 2;
-}
-
-/**
- * Logs information about a package that is moved from the internal to external storage and vice
- * versa.
- * It logs the package name, the type of the external storage where the package is installed
- * (if moved to external storage, or UNKNOWN if moved to internal storage),
- * and the move type: if it's from internal to external or the other way around.
- *
- * Logged from:
- frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
- */
-message AppMovedStorageReported {
- enum MoveType {
- UNKNOWN = 0;
- TO_EXTERNAL = 1;
- TO_INTERNAL = 2;
- }
- // The type of the external storage.
- optional android.stats.storage.ExternalStorageType external_storage_type = 1;
- // The type of move.
- optional MoveType move_type = 2;
- // The name of the package that was moved.
- optional string package_name = 3;
-}
-
-/**
- * Logs when system server watchdog occurs.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/Watchdog.java
- */
-message SystemServerWatchdogOccurred {
- optional string subject = 1;
-}
-
-/**
- * Logs when new file added to tombstones.
- * Logged from:
- * frameworks/base/core/java/com/android/server/BootReceiver.java
- */
-message TombStoneOccurred {
-}
-
-/*
- * Information about a role request
- *
- * Logged from:
- * packages/apps/PermissionController/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java
- */
-message RoleRequestResultReported {
- // UID of application requesting the role
- optional int32 requesting_uid = 1;
-
- // Package name of application requesting the role
- optional string requesting_package_name = 2;
-
- // The role to be granted
- optional string role_name = 3;
-
- // The count of applications qualifying for the role
- optional int32 qualifying_count = 4;
-
- // UID of application current granted the role
- optional int32 current_uid = 5;
-
- // Package name of application current granted the role
- optional string current_package_name = 6;
-
- // UID of another application that user chose to grant the role to, instead of the requesting
- // application
- optional int32 granted_another_uid = 7;
-
- // Package name of another application that user chose to grant the role to, instead of the
- // requesting application
- optional string granted_another_package_name = 8;
-
- enum Result {
- UNDEFINED = 0;
- // role request was ignored
- IGNORED = 1;
- // role request was ignored because it's already granted
- IGNORED_ALREADY_GRANTED = 2;
- // role request was ignored because the application isn't qualified
- IGNORED_NOT_QUALIFIED = 3;
- // role request was ignored because user said it should be always denied
- IGNORED_USER_ALWAYS_DENIED = 4;
- // role was granted by user action
- USER_GRANTED = 5;
- // role was denied by user action
- USER_DENIED = 6;
- // role was denied by user granting another application the role
- USER_DENIED_GRANTED_ANOTHER = 7;
- // role was denied and set to be always denied by the user
- USER_DENIED_WITH_ALWAYS = 8;
- }
- // The result of the role request
- optional Result result = 9;
-}
-
-/**
- * Logs when a Vehicle Maps Service client's connection state has changed
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/stats/VmsClientLog.java
- */
-message VmsClientConnectionStateChanged {
- // The UID of the VMS client app
- optional int32 uid = 1 [(is_uid) = true];
-
- enum State {
- UNKNOWN = 0;
- // Attempting to connect to the client
- CONNECTING = 1;
- // Client connection established
- CONNECTED = 2;
- // Client connection closed unexpectedly
- DISCONNECTED = 3;
- // Client connection closed by VMS
- TERMINATED = 4;
- // Error establishing the client connection
- CONNECTION_ERROR = 5;
- }
-
- optional State state = 2;
-}
-
-message MimeTypes {
- repeated string mime_types = 1;
-}
-
-/**
- * Logs statistics regarding accesses to external storage.
- * All stats are normalized for one day period.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
- */
-message GeneralExternalStorageAccessStats {
- optional int32 uid = 1 [(is_uid) = true];
- // Total number of accesses like creation, open, delete and rename/update.
- // Includes file path and ContentResolver accesses
- optional uint32 total_accesses = 2;
- // Number of file path accesses, as opposed to file path and ContentResolver.
- optional uint32 file_path_accesses = 3;
- // Number of accesses on secondary volumes like SD cards.
- // Includes file path and ContentResolver accesses
- optional uint32 secondary_storage_accesses = 4;
- // Comma-separated list of mime types that were accessed.
- optional MimeTypes mime_types_accessed = 5;
-}
-
-/**
- * Logs when MediaProvider has successfully finished scanning a storage volume.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/scan/ModernMediaScanner.java
- */
-message MediaProviderScanOccurred {
- enum Reason {
- // Scan triggered due to unknown reason
- UNKNOWN = 0;
- // Scan triggered due to storage volume being mounted
- MOUNTED = 1;
- // Scan triggered due to explicit user action or app request
- DEMAND = 2;
- // Scan triggered due to idle maintenance
- IDLE = 3;
- }
-
- // Volume type that this event pertains to
- optional android.stats.mediaprovider.VolumeType volume_type = 1;
- // Reason why this scan was triggered
- optional Reason reason = 2;
- // Total number of files scanned
- optional int64 item_count = 3;
- // Duration of scan, normalized per file
- optional float normalized_duration_millis = 4;
- // Number of database inserts, normalized per file
- optional float normalized_insert_count = 5;
- // Number of database updates, normalized per file
- optional float normalized_update_count = 6;
- // Number of database deletes, normalized per file
- optional float normalized_delete_count = 7;
-}
-
-/**
- * Logs when an app has asked MediaProvider to delete media belonging to the user.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
- */
-message MediaContentDeleted {
- // Volume type that this event pertains to
- optional android.stats.mediaprovider.VolumeType volume_type = 1;
- // UID of app that requested deletion
- optional int32 uid = 2 [(is_uid) = true];
- // Number of items that were deleted
- optional int32 item_count = 3;
-}
-
-/**
- * Logs when an app has asked MediaProvider to grant them access to media belonging to the user.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/PermissionActivity.java
- */
-message MediaProviderPermissionRequested {
- enum Result {
- UNKNOWN = 0;
- USER_GRANTED = 1;
- AUTO_GRANTED = 2;
- USER_DENIED = 3;
- USER_DENIED_WITH_PREJUDICE = 4;
- AUTO_DENIED = 5;
- }
-
- // Volume type that this event pertains to
- optional android.stats.mediaprovider.VolumeType volume_type = 1;
- // UID of app that requested permission
- optional int32 uid = 2 [(is_uid) = true];
- // Number of items that were requested
- optional int32 item_count = 3;
- // Result of this request
- optional Result result = 4;
-}
-
-/**
- * Logs when MediaProvider has finished upgrading or downgrading its database schema.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/DatabaseHelper.java
- */
-message MediaProviderSchemaChanged {
- // Volume type that this event pertains to
- optional android.stats.mediaprovider.VolumeType volume_type = 1;
- // Old database version code
- optional int32 version_from = 2;
- // New database version code
- optional int32 version_to = 3;
- // Total number of files in database
- optional int64 item_count = 4;
- // Duration of schema change, normalized per file
- optional float normalized_duration_millis = 5;
-}
-
-/**
- * Logs when MediaProvider has finished an idle maintenance job.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
- */
-message MediaProviderIdleMaintenanceFinished {
- // Volume type that this event pertains to
- optional android.stats.mediaprovider.VolumeType volume_type = 1;
-
- // Total number of files in database
- optional int64 item_count = 2;
- // Duration of idle maintenance, normalized per file
- optional float normalized_duration_millis = 3;
- // Number of thumbnails found to be stale, normalized per file
- optional float normalized_stale_thumbnails = 4;
- // Number of items found to be expired, normalized per file
- optional float normalized_expired_media = 5;
-}
-
-/**
- * Represents boot time event with duration in ms.
- *
- * Logged from: bootstat and various system server components. Check each enums for details.
- */
-message BootTimeEventDuration {
- enum DurationEvent {
- UNKNOWN = 0;
- // Bootloader time excluding BOOTLOADER_UI_WAIT + boot complete time. Logged from bootstat.
- ABSOLUTE_BOOT_TIME = 1;
- // Bootloader's 1st stage execution time.
- // Logged from bootstat.
- BOOTLOADER_FIRST_STAGE_EXEC = 2;
- // Bootloader's 1st stage loading time.
- // Logged from bootstat.
- BOOTLOADER_FIRST_STAGE_LOAD = 3;
- // Bootloader's kernel loading time.
- // Logged from bootstat.
- BOOTLOADER_KERNEL_LOAD = 4;
- // Bootloader's 2nd stage execution time.
- // Logged from bootstat.
- BOOTLOADER_SECOND_STAGE_EXEC = 5;
- // Bootloader's 2nd stage loading time.
- // Logged from bootstat.
- BOOTLOADER_SECOND_STAGE_LOAD = 6;
- // Duration for Bootloader to show unlocked device's warning UI. This should not happen
- // for locked device.
- // Logged from bootstat.
- BOOTLOADER_UI_WAIT = 7;
- // Total time spend in bootloader. This is the sum of all BOOTLOADER_* listed above.
- // Logged from bootstat.
- BOOTLOADER_TOTAL = 8;
- // Shutdown duration inside init for the reboot before the current boot up.
- // Logged from f/b/services/.../BootReceiver.java.
- SHUTDOWN_DURATION = 9;
- // Total time for mounting of disk devices during bootup.
- // Logged from f/b/services/.../BootReceiver.java.
- MOUNT_DEFAULT_DURATION = 10;
- // Total time for early stage mounting of disk devices during bootup.
- // Logged from f/b/services/.../BootReceiver.java.
- MOUNT_EARLY_DURATION = 11;
- // Total time for late stage mounting of disk devices during bootup.
- // Logged from f/b/services/.../BootReceiver.java.
- MOUNT_LATE_DURATION = 12;
- // Average time to scan non-system app after OTA
- // Logged from f/b/services/.../PackageManagerService.java
- OTA_PACKAGE_MANAGER_INIT_TIME = 13;
- // Time to initialize Package manager after OTA
- // Logged from f/b/services/.../PackageManagerService.java
- OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME = 14;
- // Time to scan all system app from Package manager after OTA
- // Logged from f/b/services/.../PackageManagerService.java
- OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME = 15;
- // Init's total time for cold boot stage.
- // Logged from bootstat.
- COLDBOOT_WAIT = 16;
- // Init's total time for initializing selinux.
- // Logged from bootstat.
- SELINUX_INIT = 17;
- // Time since last factory reset.
- // Logged from bootstat.
- FACTORY_RESET_TIME_SINCE_RESET = 18;
- // Init's total time spent for completing the 1st stage.
- // Logged from bootstat.
- ANDROID_INIT_STAGE_1 = 19;
- }
-
- // Type of the event.
- optional DurationEvent event = 1;
- // Duration of the event in ms.
- optional int64 duration_millis = 2;
-}
-
-/**
- * Represents the start of specific boot time event during bootup in ms. This is usually a time
- * since boot-up.
- *
- * Logged from: bootstat and various system server components. Check each enums for details.
- */
-message BootTimeEventElapsedTime {
- enum ElapsedTimeEvent {
- UNKNOWN = 0;
- // Time when init starts 1st stage. Logged from bootstat.
- ANDROID_INIT_STAGE_1 = 1;
- // Time when sys.boot_completed prop is set.
- // Logged from bootstat.
- BOOT_COMPLETE = 2;
- // BOOT_COMPLETE for encrypted device.
- BOOT_COMPLETE_ENCRYPTION = 3;
- // BOOT_COMPLETE for device with no encryption.
- BOOT_COMPLETE_NO_ENCRYPTION = 4;
- // Adjusted BOOT_COMPLETE for encrypted device extracting decryption time.
- BOOT_COMPLETE_POST_DECRYPT = 5;
- // BOOT_COMPLETE after factory reset.
- FACTORY_RESET_BOOT_COMPLETE = 6;
- // BOOT_COMPLETE_NO_ENCRYPTION after factory reset.
- FACTORY_RESET_BOOT_COMPLETE_NO_ENCRYPTION = 7;
- // BOOT_COMPLETE_POST_DECRYPT after factory reset.
- FACTORY_RESET_BOOT_COMPLETE_POST_DECRYPT = 8;
- // BOOT_COMPLETE after OTA.
- OTA_BOOT_COMPLETE = 9;
- // BOOT_COMPLETE_NO_ENCRYPTION after OTA.
- OTA_BOOT_COMPLETE_NO_ENCRYPTION = 10;
- // BOOT_COMPLETE_POST_DECRYPT after OTA.
- OTA_BOOT_COMPLETE_POST_DECRYPT = 11;
- // Time when the system starts sending LOCKED_BOOT_COMPLETED broadcast.
- // Logged from f/b/services/.../UserController.java
- FRAMEWORK_LOCKED_BOOT_COMPLETED = 12;
- // Time when the system starts sending BOOT_COMPLETED broadcast.
- // Logged from f/b/services/.../UserController.java
- FRAMEWORK_BOOT_COMPLETED = 13;
- // Time when the package manager starts init.
- // Logged from f/b/services/.../SystemServer.java
- PACKAGE_MANAGER_INIT_START = 14;
- // Time when package manager is ready
- // Logged from f/b/services/.../SystemServer.java
- PACKAGE_MANAGER_INIT_READY = 15;
- // Represents the time when user has entered unlock credential for system with user pin.
- // Logged from bootstat.
- POST_DECRYPT = 16;
- // Represents the start of zygote's init.
- // Logged from zygote itself.
- ZYGOTE_INIT_START = 17;
- // Represents the start of secondary zygote's init.
- // TODO: add logging to zygote
- SECONDARY_ZYGOTE_INIT_START = 18;
- // Represents the start of system server's init.
- // Logged from f/b/services/.../SystemServer.java
- SYSTEM_SERVER_INIT_START = 19;
- // Represents the completion of system server's init.
- // Logged from f/b/services/.../SystemServer.java
- SYSTEM_SERVER_READY = 20;
- // Represents the start of launcher during boot-up.
- // TODO: add logging
- LAUNCHER_START = 21;
- // Represents the completion of launcher's initial rendering. User can use other apps from
- // launcher from this point.
- // TODO: add logging
- LAUNCHER_SHOWN = 22;
- }
-
- // Type of the event.
- optional ElapsedTimeEvent event = 1;
- // Time since bootup for the event.
- // It should be acquired from SystemClock elapsedRealtime() call or equivalent.
- optional int64 time_millis = 2;
-}
-
-/**
- * Boot time events with UTC time.
- *
- * Logged from: bootstat and various system server components. Check each enums for details.
- */
-message BootTimeEventUtcTime {
- enum UtcTimeEvent {
- UNKNOWN = 0;
- // Time of the bootstat's marking of 1st boot after the last factory reset.
- // Logged from bootstat.
- FACTORY_RESET_RESET_TIME = 1;
- // The time when bootstat records FACTORY_RESET_* events. This is close to
- // BOOT_COMPLETE time for the current bootup.
- // Logged from bootstat.
- FACTORY_RESET_CURRENT_TIME = 2;
- // DUplicate of FACTORY_RESET_RESET_TIME added for debugging purpose.
- // Logged from bootstat.
- FACTORY_RESET_RECORD_VALUE = 3;
- }
-
- // Type of the event.
- optional UtcTimeEvent event = 1;
- // UTC time for the event.
- optional int64 utc_time_secs = 2;
-}
-
-/**
- * Boot time events representing specific error code during bootup.
- * Meaning of error code can be different per each event type.
- *
- * Logged from: bootstat and various system server components. Check each enums for details.
- */
-message BootTimeEventErrorCode {
- enum ErrorCodeEvent {
- UNKNOWN = 0;
- // Linux error code for time() call to get the current UTC time.
- // Logged from bootstat.
- FACTORY_RESET_CURRENT_TIME_FAILURE = 1;
- // Represents UmountStat before the reboot for the current boot up. Error codes defined
- // as UMOUNT_STAT_* from init/reboot.cpp.
- // Logged from f/b/services/.../BootReceiver.java.
- SHUTDOWN_UMOUNT_STAT = 2;
- // Reprepsents fie system mounting error code of /data partition for the current boot.
- // Error codes defined as combination of FsStatFlags from system/core/fs_mgr/fs_mgr.cpp.
- // Logged from f/b/services/.../BootReceiver.java.
- FS_MGR_FS_STAT_DATA_PARTITION = 3;
- }
-
- // Type of the event.
- optional ErrorCodeEvent event = 1;
- // error code defined per each event type.
- // For example, this can have a value of FsStatFlags.FS_STAT_FULL_MOUNT_FAILED for the event of
- // FS_MGR_FS_STAT.
- optional int32 error_code = 2;
-}
-
-/**
- * Collects Virtual A/B statistics related to the use of dm-snapshot performed
- * after an OTA.
- *
- * Logged from:
- * - system/update_engine/cleanup_previous_update_action.cc
- */
-message SnapshotMergeReported {
- // Keep in sync with
- // system/core/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
- enum UpdateState {
- // No update or merge is in progress.
- NONE = 0;
- // An update is applying; snapshots may already exist.
- INITIATED = 1;
- // An update is pending, but has not been successfully booted yet.
- UNVERIFIED = 2;
- // The kernel is merging in the background.
- MERGING = 3;
- // Post-merge cleanup steps could not be completed due to a transient
- // error, but the next reboot will finish any pending operations.
- MERGE_NEEDS_REBOOT = 4;
- // Merging is complete, and needs to be acknowledged.
- MERGE_COMPLETED = 5;
- // Merging failed due to an unrecoverable error.
- MERGE_FAILED = 6;
- // The update was implicitly cancelled, either by a rollback or a flash
- // operation via fastboot. This state can only be returned by WaitForMerge.
- CANCELLED = 7;
- };
-
- // Status of the update after the merge attempts.
- optional UpdateState final_state = 1;
-
- // Time to complete a merge operation in milliseconds.
- // A negative value corresponds to the case in which the merge operation
- // was interrupted and resumed (e.g. in case of a system reboot during the
- // merge).
- optional int64 duration_millis = 2;
-
- // Number of reboots that occurred after issuing and before completing the
- // merge of all the snapshot devices.
- optional int32 intermediate_reboots = 3;
-
- // The device has been upgraded to Virtual A/B.
- optional bool is_vab_retrofit = 4;
-
- // Space that has been temporarily allocated in the /data partition
- // containing the dm-snapshot's copy-on-write data generated during a
- // Virtual A/B update.
- optional int64 cow_file_size_bytes = 5;
-}
-
-/**
- * Event representing when BlobStoreManager.Session#commit() is called
- *
- * Logged from:
- * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
- */
-message BlobCommitted {
- // Uid of the Blob committer
- optional int32 uid = 1 [(is_uid) = true];
-
- // Id of the Blob committed
- optional int64 blob_id = 2;
-
- // Size of the Blob
- optional int64 size = 3;
-
- enum Result {
- UNKNOWN = 0;
- // Commit Succeeded
- SUCCESS = 1;
- // Commit Failed: Error occurred during commit
- ERROR_DURING_COMMIT = 2;
- // Commit Failed: Digest of the data did not match Blob digest
- DIGEST_MISMATCH = 3;
- // Commit Failed: Allowed count limit exceeded
- COUNT_LIMIT_EXCEEDED = 4;
- }
- optional Result result = 4;
-}
-
-/**
- * Event representing when BlobStoreManager#acquireLease() is called
- *
- * Logged from:
- * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
- */
-message BlobLeased{
- // Uid of the Blob leasee
- optional int32 uid = 1 [(is_uid) = true];
-
- // Id of the Blob leased or 0 if the Blob does not exist
- optional int64 blob_id = 2;
-
- // Size of the Blob or 0 if the Blob does not exist
- optional int64 size = 3;
-
- enum Result {
- UNKNOWN = 0;
- // Lease Succeeded
- SUCCESS = 1;
- // Lease Failed: Blob does not exist
- BLOB_DNE = 2;
- // Lease Failed: Leasee does not have access to the Blob
- ACCESS_NOT_ALLOWED = 3;
- // Lease Failed: Leasee requested an invalid expiry duration
- LEASE_EXPIRY_INVALID = 4;
- // Lease Failed: Leasee has exceeded the total data lease limit
- DATA_SIZE_LIMIT_EXCEEDED = 5;
- // Leasee Failed: Allowed count limit exceeded
- COUNT_LIMIT_EXCEEDED = 6;
- }
- optional Result result = 4;
-}
-
-/**
- * Event representing when BlobStoreManager#openBlob() is called
- *
- * Logged from:
- * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
- */
-message BlobOpened{
- // Uid of the Blob opener
- optional int32 uid = 1 [(is_uid) = true];
-
- // Id of the Blob opened or 0 if the Blob does not exist
- optional int64 blob_id = 2;
-
- // Size of the Blob or 0 if the Blob does not exist
- optional int64 size = 3;
-
- enum Result {
- UNKNOWN = 0;
- // Open Succeeded
- SUCCESS = 1;
- // Open Failed: Blob does not exist
- BLOB_DNE = 2;
- // Open Failed: Opener does not have access to the Blob
- ACCESS_NOT_ALLOWED = 3;
- }
- optional Result result = 4;
-}
-
-//////////////////////////////////////////////////////////////////////
-// Pulled atoms below this line //
-//////////////////////////////////////////////////////////////////////
-
-/**
- * Pulls bytes transferred via wifi (Sum of foreground and background usage).
- *
- * Pulled from:
- * StatsCompanionService (using BatteryStats to get which interfaces are wifi)
- */
-message WifiBytesTransfer {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional int64 rx_bytes = 2;
-
- optional int64 rx_packets = 3;
-
- optional int64 tx_bytes = 4;
-
- optional int64 tx_packets = 5;
-}
-
-/**
- * Pulls bytes transferred via wifi (separated by foreground and background usage).
- *
- * Pulled from:
- * StatsCompanionService (using BatteryStats to get which interfaces are wifi)
- */
-message WifiBytesTransferByFgBg {
- optional int32 uid = 1 [(is_uid) = true];
-
- // 1 denotes foreground and 0 denotes background. This is called Set in NetworkStats.
- optional bool is_foreground = 2;
-
- optional int64 rx_bytes = 3;
-
- optional int64 rx_packets = 4;
-
- optional int64 tx_bytes = 5;
-
- optional int64 tx_packets = 6;
-}
-
-/**
- * Pulls bytes transferred via mobile networks (Sum of foreground and background usage).
- *
- * Pulled from:
- * StatsCompanionService (using BatteryStats to get which interfaces are mobile data)
- */
-message MobileBytesTransfer {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional int64 rx_bytes = 2;
-
- optional int64 rx_packets = 3;
-
- optional int64 tx_bytes = 4;
-
- optional int64 tx_packets = 5;
-}
-
-/**
- * Pulls bytes transferred via mobile networks (separated by foreground and background usage).
- *
- * Pulled from:
- * StatsCompanionService (using BatteryStats to get which interfaces are mobile data)
- */
-message MobileBytesTransferByFgBg {
- optional int32 uid = 1 [(is_uid) = true];
-
- // 1 denotes foreground and 0 denotes background. This is called Set in
- // NetworkStats.
- optional bool is_foreground = 2;
-
- optional int64 rx_bytes = 3;
-
- optional int64 rx_packets = 4;
-
- optional int64 tx_bytes = 5;
-
- optional int64 tx_packets = 6;
-}
-
-/**
- * Used for pull network statistics via mobile|wifi networks, and sliced by interesting dimensions.
- * Note that the data is expected to be sliced into more dimensions in future. In other words,
- * the caller must not assume any row of data is one full report when filtering with a set of
- * matching conditions, because future data may represent with multiple rows what is currently
- * represented by one.
- * To avoid being broken by future slicing, callers must take care to aggregate rows even if they
- * query all the existing columns.
- *
- * Pulled from:
- * StatsPullAtomService (using NetworkStatsService to get NetworkStats)
- */
-message DataUsageBytesTransfer {
- // State of this record. Should be NetworkStats#SET_DEFAULT or NetworkStats#SET_FOREGROUND to
- // indicate the foreground state, or NetworkStats#SET_ALL to indicate the record is for all
- // states combined, not including debug states. See NetworkStats#SET_*.
- optional int32 state = 1;
-
- optional int64 rx_bytes = 2;
-
- optional int64 rx_packets = 3;
-
- optional int64 tx_bytes = 4;
-
- optional int64 tx_packets = 5;
-
- // Radio Access Technology (RAT) type of this record, should be one of
- // TelephonyManager#NETWORK_TYPE_* constants, or NetworkTemplate#NETWORK_TYPE_ALL to indicate
- // the record is for all rat types combined.
- optional int32 rat_type = 6;
-
- // Mcc/Mnc read from sim if the record is for a specific subscription, null indicates the
- // record is combined across subscriptions.
- optional string sim_mcc = 7;
- optional string sim_mnc = 8;
-
- // Allows mobile virtual network operators (MVNOs) to be identified with individual IDs.
- // See TelephonyManager#getSimCarrierId.
- optional int32 carrier_id = 9;
-
- // Enumeration of opportunistic states with an additional ALL state indicates the record is
- // combined regardless of the boolean value in its field.
- enum DataSubscriptionState {
- UNKNOWN = 0; // For server side backward compatibility.
- ALL = 1;
- OPPORTUNISTIC = 2;
- NOT_OPPORTUNISTIC = 3;
- }
- // Mark whether the subscription is an opportunistic data subscription, and ALL indicates the
- // record is combined across opportunistic data subscriptions.
- // See {@link SubscriptionManager#setOpportunistic}.
- optional DataSubscriptionState opportunistic_data_sub = 10;
-
- // Indicate whether NR is connected, server side could use this with RAT type to determine if
- // the record is for 5G NSA (Non Stand Alone) mode, where the primary cell is still LTE and
- // network allocates a secondary 5G cell so telephony reports RAT = LTE along with NR state as
- // connected.
- optional bool is_nr_connected = 11;
-}
-
-/**
- * Pulls bytes transferred via bluetooth. It is pulled from Bluetooth controller.
- *
- * Pulled from:
- * StatsCompanionService
- */
-message BluetoothBytesTransfer {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional int64 rx_bytes = 2;
-
- optional int64 tx_bytes = 3;
-}
-
-/**
- * Pulls the kernel wakelock durations. This atom is adapted from
- * android/internal/os/KernelWakelockStats.java
- *
- * Pulled from:
- * StatsCompanionService using KernelWakelockReader.
- */
-message KernelWakelock {
- optional string name = 1;
-
- optional int32 count = 2;
-
- optional int32 version = 3;
-
- optional int64 time_micros = 4;
-}
-
-/**
- * Pulls low power state information. If power.stats HAL is not available, this
- * includes platform and subsystem sleep state information,
- * PowerStatePlatformSleepState, PowerStateVoter or PowerStateSubsystemSleepState
- * as defined in:
- * hardware/interfaces/power/1.0/types.hal
- * hardware/interfaces/power/1.1/types.hal
- * If power.stats HAL is available, this includes PowerEntityStateResidencyResult
- * as defined in:
- * hardware/interfaces/power/stats/1.0/types.hal
- */
-message SubsystemSleepState {
- // Subsystem name
- optional string subsystem_name = 1;
- // For PlatformLowPowerStats (hal 1.0), this is the voter name, which could be empty.
- // For SubsystemLowPowerStats (hal 1.1), this is the sleep state name.
- // For PowerEntityStateResidencyResult (hal power/stats/1.0) this is the
- // powerEntityStateName from the corresponding PowerEntityStateInfo.
- optional string subname = 2;
- // The number of times it entered, or voted for entering the sleep state
- optional uint64 count = 3;
- // The length of time spent in, or spent voting for, the sleep state
- optional uint64 time_millis = 4;
-}
-
-/**
- * Pulls on-device power measurement information.
- * Data defined by hardware/interfaces/power/stats/1.0/types.hal.
- * Pulled from:
- * frameworks/base/cmds/statsd/src/external/PowerStatsPuller.cpp
- */
-message OnDevicePowerMeasurement {
- // Name of the subsystem (to which the rail belongs).
- optional string subsystem_name = 1;
-
- // Rail name. The rail lies within the subsystem.
- optional string rail_name = 2;
-
- // Time (in ms since boot) at which the rail energy value was measured.
- // This may differ slightly from the time that statsd logs this information.
- optional uint64 measurement_timestamp_millis = 3;
-
- // Accumulated energy used via the rail since device boot in uWs.
- optional uint64 energy_microwatt_secs = 4;
-}
-
-/**
- * Pulls Cpu time per frequency.
- * Pulls the time the cpu spend on the frequency index. Frequency index
- * starts from highest to lowest. The value should be monotonically
- * increasing since boot. However, if there is a cpu
- * hotplug event, the value would be reset as well.
- */
-message CpuTimePerFreq {
- optional uint32 cluster = 1;
- optional uint32 freq_index = 2;
- optional uint64 time_millis = 3;
-}
-
-/**
- * Pulls Cpu Time Per Uid.
- * Note that isolated process uid time should be attributed to host uids.
- */
-message CpuTimePerUid {
- optional int32 uid = 1 [(is_uid) = true];
- optional uint64 user_time_micros = 2;
- optional uint64 sys_time_micros = 3;
-}
-
-/**
- * Pulls Cpu Time Per Uid per frequency.
- * Note that isolated process uid time should be attributed to host uids.
- * For each uid, we order the time by descending frequencies.
- */
-message CpuTimePerUidFreq {
- optional int32 uid = 1 [(is_uid) = true];
- optional uint32 freq_index = 2;
- optional uint64 time_millis = 3;
-}
-
-/**
- * Pulls Wifi Controller Activity Energy Info
- */
-message WifiActivityInfo {
- // timestamp(wall clock) of record creation
- optional uint64 timestamp_millis = 1;
- // stack reported state
- // TODO: replace this with proto enum
- optional int32 stack_state = 2;
- // tx time in millis
- optional uint64 controller_tx_time_millis = 3;
- // rx time in millis
- optional uint64 controller_rx_time_millis = 4;
- // idle time in millis
- optional uint64 controller_idle_time_millis = 5;
- // product of current(mA), voltage(V) and time(ms)
- optional uint64 controller_energy_used = 6;
-}
-
-/**
- * Pulls Modem Activity Energy Info
- */
-message ModemActivityInfo {
- // timestamp(wall clock) of record creation
- optional uint64 timestamp_millis = 1;
- // sleep time in millis.
- optional uint64 sleep_time_millis = 2;
- // idle time in millis
- optional uint64 controller_idle_time_millis = 3;
- /**
- * Tx power index
- * index 0 = tx_power < 0dBm
- * index 1 = 0dBm < tx_power < 5dBm
- * index 2 = 5dBm < tx_power < 15dBm
- * index 3 = 15dBm < tx_power < 20dBm
- * index 4 = tx_power > 20dBm
- */
- // tx time in ms at power level 0
- optional uint64 controller_tx_time_pl0_millis = 4;
- // tx time in ms at power level 1
- optional uint64 controller_tx_time_pl1_millis = 5;
- // tx time in ms at power level 2
- optional uint64 controller_tx_time_pl2_millis = 6;
- // tx time in ms at power level 3
- optional uint64 controller_tx_time_pl3_millis = 7;
- // tx time in ms at power level 4
- optional uint64 controller_tx_time_pl4_millis = 8;
- // rx time in ms at power level 5
- optional uint64 controller_rx_time_millis = 9;
- // product of current(mA), voltage(V) and time(ms)
- optional uint64 energy_used = 10 [deprecated=true];
-}
-
-/**
- * Pulls Bluetooth Activity Energy Info
- * Note: BluetoothBytesTransfer is pulled at the same time from the controller.
- */
-message BluetoothActivityInfo {
- // timestamp(wall clock) of record creation
- optional uint64 timestamp_millis = 1;
- // bluetooth stack state
- optional int32 bluetooth_stack_state = 2;
- // tx time in millis
- optional uint64 controller_tx_time_millis = 3;
- // rx time in millis
- optional uint64 controller_rx_time_millis = 4;
- // idle time in millis
- optional uint64 controller_idle_time_millis = 5;
- // product of current(mA), voltage(V) and time(ms)
- optional uint64 energy_used = 6;
-}
-
-/*
- * Logs the memory stats for a process.
- *
- * Pulled from StatsCompanionService for all managed processes (from ActivityManagerService).
- */
-message ProcessMemoryState {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name.
- // Usually package name, "system" for system server.
- // Provided by ActivityManagerService.
- optional string process_name = 2;
-
- // Current OOM score adjustment. Value read from ProcessRecord.
- optional int32 oom_adj_score = 3;
-
- // # of page-faults
- optional int64 page_fault = 4;
-
- // # of major page-faults
- optional int64 page_major_fault = 5;
-
- // RSS
- // Value is read from memory.stat, field total_rss if per-app memory
- // cgroups are enabled. Otherwise, value from /proc/pid/stat.
- optional int64 rss_in_bytes = 6;
-
- // CACHE
- // Value is read from memory.stat, field total_cache if per-app memory
- // cgroups are enabled. Otherwise, 0.
- optional int64 cache_in_bytes = 7;
-
- // SWAP
- // Value is read from memory.stat, field total_swap if per-app memory
- // cgroups are enabled. Otherwise, 0.
- optional int64 swap_in_bytes = 8;
-
- // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always -1.
- optional int64 rss_high_watermark_in_bytes = 9 [deprecated = true];
-
- // Deprecated: use ProcessMemorySnapshot atom instead. Always -1.
- optional int64 start_time_nanos = 10 [deprecated = true];
-
- // Deprecated: use ProcessMemorySnapshot atom instead. Always -1.
- optional int32 anon_rss_and_swap_in_kilobytes = 11 [deprecated = true];
-}
-
-/*
- * Logs the memory high-water mark for a process.
- *
- * Pulled from StatsCompanionService for all managed processes (from ActivityManagerServie)
- * and for selected native processes.
- *
- * Pulling this atom resets high-water mark counters for all processes.
- */
-message ProcessMemoryHighWaterMark {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name.
- // Usually package name or process cmdline.
- // Provided by ActivityManagerService or read from /proc/PID/cmdline.
- optional string process_name = 2;
-
- // Deprecated: use rss_high_water_mark_in_kilobytes instead. This field is
- // computed by converting kilobytes to bytes.
- optional int64 rss_high_water_mark_in_bytes = 3 [deprecated = true];
-
- // RSS high-water mark. Peak RSS usage of the process. Read from the VmHWM field in
- // /proc/PID/status.
- optional int32 rss_high_water_mark_in_kilobytes = 4;
-}
-
-/*
- * Logs the memory stats for a process.
- *
- * Pulled from StatsCompanionService for all managed processes (from ActivityManagerService)
- * and for selected native processes.
- */
-message ProcessMemorySnapshot {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name.
- // Usually package name or process cmdline.
- // Provided by ActivityManagerService or read from /proc/PID/cmdline.
- optional string process_name = 2;
-
- // The pid of the process.
- // Allows to disambiguate instances of the process.
- optional int32 pid = 3;
-
- // The current OOM score adjustment value.
- // Read from ProcessRecord for managed processes.
- // Placeholder -1001 (OOM_SCORE_ADJ_MIN - 1, outside of allowed range) for native ones.
- optional int32 oom_score_adj = 4;
-
- // The current RSS of the process.
- // VmRSS from /proc/pid/status.
- optional int32 rss_in_kilobytes = 5;
-
- // The current anon RSS of the process.
- // RssAnon from /proc/pid/status.
- optional int32 anon_rss_in_kilobytes = 6;
-
- // The current swap size of the process.
- // VmSwap from /proc/pid/status.
- optional int32 swap_in_kilobytes = 7;
-
- // The sum of rss_in_kilobytes and swap_in_kilobytes.
- optional int32 anon_rss_and_swap_in_kilobytes = 8;
-}
-
-/*
- * Elapsed real time from SystemClock.
- */
-message SystemElapsedRealtime {
- optional uint64 time_millis = 1;
-}
-
-/*
- * Up time from SystemClock.
- */
-message SystemUptime {
- // Milliseconds since the system was booted.
- // This clock stops when the system enters deep sleep (CPU off, display dark, device waiting
- // for external input).
- // It is not affected by clock scaling, idle, or other power saving mechanisms.
- optional uint64 uptime_millis = 1;
-}
-
-/*
- * Reads from /proc/uid_concurrent_active_time which has the format:
- * active: X (X is # cores)
- * [uid0]: [time-0] [time-1] [time-2] ... (# entries = # cores)
- * [uid1]: [time-0] [time-1] [time-2] ... ...
- * ...
- * Time-N means the CPU time a UID spent running concurrently with N other processes.
- * The file contains a monotonically increasing count of time for a single boot.
- */
-message CpuActiveTime {
- optional int32 uid = 1 [(is_uid) = true];
- optional uint64 time_millis = 2;
-}
-
-/**
- * Reads from /proc/uid_concurrent_policy_time which has the format:
- * policy0: X policy4: Y (there are X cores on policy0, Y cores on policy4)
- * [uid0]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ...
- * [uid1]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ...
- * ...
- * Time-X-Y means the time a UID spent on clusterX running concurrently with Y other processes.
- * The file contains a monotonically increasing count of time for a single boot.
- */
-message CpuClusterTime {
- optional int32 uid = 1 [(is_uid) = true];
- optional int32 cluster_index = 2;
- optional uint64 time_millis = 3;
-}
-
-/*
- * Pulls free disk space, for data, system partition and temporary directory.
- */
-message DiskSpace {
- // available bytes in data partition
- optional uint64 data_available_bytes = 1;
- // available bytes in system partition
- optional uint64 system_available_bytes = 2;
- // available bytes in download cache or temp directories
- optional uint64 temp_available_bytes = 3;
-}
-
-/**
- * Pulls battery coulomb counter, which is the remaining battery charge in uAh.
- *
- * Pulled from StatsCompanionService.java
- */
-message RemainingBatteryCapacity {
- optional int32 charge_micro_ampere_hour = 1;
-}
-
-/**
- * Pulls battery capacity, which is the battery capacity when full in uAh.
- * Pulled from:
- * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
- */
-message FullBatteryCapacity {
- optional int32 capacity_micro_ampere_hour = 1;
-}
-
-/**
- * Pulls battery voltage.
- * Pulled from:
- * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
- */
-message BatteryVoltage {
- // The voltage of the battery, in millivolts.
- optional int32 voltage_millivolt = 1;
-}
-
-/**
- * Pulls battery level (percent full, from 0 to 100).
- *
- * Pulled from:
- * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
- */
-message BatteryLevel {
- // Battery level. Should be in [0, 100].
- optional int32 battery_level = 1;
-}
-
-/**
- * Pulls the temperature of various parts of the device.
- * The units are tenths of a degree Celsius. Eg: 30.3C is reported as 303.
- *
- * Pulled from StatsCompanionService.java
- */
-message Temperature {
- // The type of temperature being reported. Eg. CPU, GPU, SKIN, BATTERY, BCL_.
- optional android.os.TemperatureTypeEnum sensor_location = 1;
-
- // The name of the temperature source. Eg. CPU0
- optional string sensor_name = 2;
-
- // Temperature in tenths of a degree C.
- // For BCL, it is decimillivolt, decimilliamps, and percentage * 10.
- optional int32 temperature_deci_celsius = 3;
-
- // Relative severity of the throttling, see enum definition.
- optional android.os.ThrottlingSeverityEnum severity = 4;
-}
-
-/**
- * Pulls the statistics of calls to Binder.
- *
- * Binder stats will be reset every time the data is pulled. It means it can only be pulled by one
- * config on the device.
- *
- * Next tag: 15
- */
-message BinderCalls {
- // UID of the process responsible for the binder transaction. It will be set if the process
- // executing the binder transaction attribute the transaction to another uid using
- // Binder.setThreadWorkSource().
- //
- // If not set, the value will be -1.
- optional int32 uid = 1 [(is_uid) = true];
- // UID of the process executing the binder transaction.
- optional int32 direct_caller_uid = 14;
- // Fully qualified class name of the API call.
- //
- // This is a system server class name.
- //
- // TODO(gaillard): figure out if binder call stats includes data from isolated uids, if a uid
- // gets recycled and we have isolated uids, we might attribute the data incorrectly.
- // TODO(gaillard): there is a high dimensions cardinality, figure out if we should drop the less
- // commonly used APIs.
- optional string service_class_name = 2;
- // Method name of the API call. It can also be a transaction code if we cannot
- // resolve it to a name. See Binder#getTransactionName.
- //
- // This is a system server method name.
- optional string service_method_name = 3;
- // Total number of API calls.
- optional int64 call_count = 4;
- // True if the screen was interactive PowerManager#isInteractive at the end of the call.
- optional bool screen_interactive = 13;
- // Total number of API calls we have data recorded for. If we collected data for all the calls,
- // call_count will be equal to recorded_call_count.
- //
- // If recorded_call_count is different than call_count, it means data collection has been
- // sampled. All the fields below will be sampled in this case.
- optional int64 recorded_call_count = 12;
- // Number of exceptions thrown by the API.
- optional int64 recorded_exception_count = 5;
- // Total latency of all API calls.
- // Average can be computed using total_latency_micros / recorded_call_count.
- optional int64 recorded_total_latency_micros = 6;
- // Maximum latency of one API call.
- optional int64 recorded_max_latency_micros = 7;
- // Total CPU usage of all API calls.
- // Average can be computed using total_cpu_micros / recorded_call_count.
- // Total can be computed using total_cpu_micros / recorded_call_count * call_count.
- optional int64 recorded_total_cpu_micros = 8;
- // Maximum CPU usage of one API call.
- optional int64 recorded_max_cpu_micros = 9;
- // Maximum parcel reply size of one API call.
- optional int64 recorded_max_reply_size_bytes = 10;
- // Maximum parcel request size of one API call.
- optional int64 recorded_max_request_size_bytes = 11;
-}
-
-/**
- * Pulls the statistics of exceptions during calls to Binder.
- *
- * Binder stats are cumulative from boot unless somebody reset the data using
- * > adb shell dumpsys binder_calls_stats --reset
- */
-message BinderCallsExceptions {
- // Exception class name, e.g. java.lang.IllegalArgumentException.
- //
- // This is an exception class name thrown by the system server.
- optional string exception_class_name = 1;
- // Total number of exceptions.
- optional int64 exception_count = 2;
-}
-
-/**
- * Pulls the statistics of message dispatching on HandlerThreads.
- *
- * Looper stats will be reset every time the data is pulled. It means it can only be pulled by one
- * config on the device.
- *
- * Next tag: 11
- */
-message LooperStats {
- // The uid that made a call to the System Server and caused the message to be enqueued.
- optional int32 uid = 1 [(is_uid) = true];
-
- // Fully qualified class name of the handler target class.
- //
- // This field does not contain PII. This is a system server class name.
- optional string handler_class_name = 2;
-
- // The name of the thread that runs the Looper.
- //
- // This field does not contain PII. This is a system server thread name.
- optional string looper_thread_name = 3;
-
- // The name of the dispatched message.
- //
- // This field does not contain PII. This is a system server constant or class
- // name.
- optional string message_name = 4;
-
- // Total number of successfully dispatched messages.
- optional int64 message_count = 5;
-
- // Total number of messages that failed dispatching.
- optional int64 exception_count = 6;
-
- // Total number of processed messages we have data recorded for. If we
- // collected data for all the messages, message_count will be equal to
- // recorded_message_count.
- //
- // If recorded_message_count is different than message_count, it means data
- // collection has been sampled. The fields below will be sampled in this case.
- optional int64 recorded_message_count = 7;
-
- // Total latency of all processed messages.
- // Average can be computed using recorded_total_latency_micros /
- // recorded_message_count.
- optional int64 recorded_total_latency_micros = 8;
-
- // Total CPU usage of all processed message.
- // Average can be computed using recorded_total_cpu_micros /
- // recorded_message_count. Total can be computed using
- // recorded_total_cpu_micros / recorded_message_count * message_count.
- optional int64 recorded_total_cpu_micros = 9;
-
- // True if the screen was interactive PowerManager#isInteractive at the end of the call.
- optional bool screen_interactive = 10;
-
- // Max recorded CPU usage of all processed messages.
- optional int64 recorded_max_cpu_micros = 11;
-
- // Max recorded latency of all processed messages.
- optional int64 recorded_max_latency_micros = 12;
-
- // Total number of messages we tracked the dispatching delay for. If we
- // collected data for all the messages, message_count will be equal to
- // recorded_delay_message_count.
- //
- // If recorded_delay_message_count is different than message_count, it means data
- // collection has been sampled or/and not all messages specified the target dispatch time.
- // The fields below will be sampled in this case.
- optional int64 recorded_delay_message_count = 13;
-
- // Total dispatching delay of all processed messages.
- // Calculated as a difference between the target dispatching time (Message.when)
- // and the actual dispatching time.
- // Average can be computed using recorded_total_delay_millis / recorded_delay_message_count.
- optional int64 recorded_total_delay_millis = 14;
-
- // Max dispatching delay of all processed messages.
- // Calculated as a difference between the target dispatching time (Message.when)
- // and the actual dispatching time.
- optional int64 recorded_max_delay_millis = 15;
-}
-
-/**
- * Pulls disk information, such as write speed and latency.
- */
-message DiskStats {
- // Time taken to open, write 512B to, and close a file.
- // -1 if error performing the check.
- optional int64 data_write_latency_millis = 1;
-
- optional bool file_based_encryption = 2;
-
- // Recent disk write speed in kB/s.
- // -1 if error querying storageed.
- // 0 if data is unavailable.
- optional int32 recent_disk_write_speed = 3;
-}
-
-
-/**
- * Free and total bytes of the Data, Cache, and System partition.
- */
-message DirectoryUsage {
- enum Directory {
- UNKNOWN = 0;
- DATA = 1;
- CACHE = 2;
- SYSTEM = 3;
- }
- optional Directory directory = 1;
- optional int64 free_bytes = 2;
- optional int64 total_bytes = 3;
-}
-
-
-/**
- * Size of an application: apk size, data size, and cache size.
- * Reads from a cached file produced daily by DiskStatsLoggingService.java.
- * Information is only reported for apps with the primary user (user 0).
- * Sizes are aggregated by package name.
- */
-message AppSize {
- // Including uids will involve modifying diskstats logic.
- optional string package_name = 1;
- // App size in bytes. -1 if unavailable.
- optional int64 app_size_bytes = 2;
- // App data size in bytes. -1 if unavailable.
- optional int64 app_data_size_bytes = 3;
- // App cache size in bytes. -1 if unavailable.
- optional int64 app_cache_size_bytes = 4;
- // Time that the cache file was produced.
- // Uses System.currentTimeMillis(), which is wall clock time.
- optional int64 cache_time_millis = 5;
-}
-
-
-/**
- * Size of a particular category. Eg: photos, videos.
- * Reads from a cached file produced daily by DiskStatsLoggingService.java.
- */
-message CategorySize {
- enum Category {
- UNKNOWN = 0;
- APP_SIZE = 1;
- APP_DATA_SIZE = 2;
- APP_CACHE_SIZE = 3;
- PHOTOS = 4;
- VIDEOS = 5;
- AUDIO = 6;
- DOWNLOADS = 7;
- SYSTEM = 8;
- OTHER = 9;
- }
- optional Category category = 1;
- // Category size in bytes.
- optional int64 size_bytes = 2;
- // Time that the cache file was produced.
- // Uses System.currentTimeMillis(), which is wall clock time.
- optional int64 cache_time_millis = 3;
-}
-
-/**
- * Pulls per uid I/O stats. The stats are cumulative since boot.
- *
- * Read/write bytes are I/O events from a storage device
- * Read/write chars are data requested by read/write syscalls, and can be
- * satisfied by caching.
- *
- * Pulled from StatsCompanionService, which reads proc/uid_io/stats.
- */
-message DiskIo {
- optional int32 uid = 1 [(is_uid) = true];
- optional int64 fg_chars_read = 2;
- optional int64 fg_chars_write = 3;
- optional int64 fg_bytes_read = 4;
- optional int64 fg_bytes_write = 5;
- optional int64 bg_chars_read = 6;
- optional int64 bg_chars_write = 7;
- optional int64 bg_bytes_read = 8;
- optional int64 bg_bytes_write = 9;
- optional int64 fg_fsync = 10;
- optional int64 bg_fsync= 11;
-}
-
-
-/**
- * Pulls the number of fingerprints for each user.
- *
- * Pulled from StatsCompanionService, which queries <Biometric>Manager.
- */
-message NumFingerprintsEnrolled {
- // The associated user. Eg: 0 for owners, 10+ for others.
- // Defined in android/os/UserHandle.java
- optional int32 user = 1;
- // Number of fingerprints registered to that user.
- optional int32 num_fingerprints_enrolled = 2;
-}
-
-/**
- * Pulls the number of faces for each user.
- *
- * Pulled from StatsCompanionService, which queries <Biometric>Manager.
- */
-message NumFacesEnrolled {
- // The associated user. Eg: 0 for owners, 10+ for others.
- // Defined in android/os/UserHandle.java
- optional int32 user = 1;
- // Number of faces registered to that user.
- optional int32 num_faces_enrolled = 2;
-}
-/**
- * A mapping of role holder -> role
- */
-message RoleHolder {
- // uid of the role holder
- optional int32 uid = 1 [(is_uid) = true];
-
- // package name of the role holder
- optional string package_name = 2;
-
- // the role held
- optional string role = 3;
-}
-
-message AggStats {
- // These are all in byte resolution.
- optional int64 min = 1 [deprecated = true];
- optional int64 average = 2 [deprecated = true];
- optional int64 max = 3 [deprecated = true];
-
- // These are all in kilobyte resolution. Can fit in int32, so smaller on the wire than the above
- // int64 fields.
- optional int32 mean_kb = 4;
- optional int32 max_kb = 5;
-}
-
-// A reduced subset of process states; reducing the number of possible states allows more
-// aggressive device-side aggregation of statistics and hence reduces metric upload size.
-enum ProcessStateAggregated {
- PROCESS_STATE_UNKNOWN = 0;
- // Persistent system process.
- PROCESS_STATE_PERSISTENT = 1;
- // Top activity; actually any visible activity.
- PROCESS_STATE_TOP = 2;
- // Process binding to top or a foreground service.
- PROCESS_STATE_BOUND_TOP_OR_FGS = 3;
- // Processing running a foreground service.
- PROCESS_STATE_FGS = 4;
- // Important foreground process (ime, wallpaper, etc).
- PROCESS_STATE_IMPORTANT_FOREGROUND = 5;
- // Important background process.
- PROCESS_STATE_BACKGROUND = 6;
- // Process running a receiver.
- PROCESS_STATE_RECEIVER = 7;
- // All kinds of cached processes.
- PROCESS_STATE_CACHED = 8;
-}
-
-// Next tag: 13
-message ProcessStatsStateProto {
- optional android.service.procstats.ScreenState screen_state = 1;
-
- optional android.service.procstats.MemoryState memory_state = 2 [deprecated = true];
-
- // this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
- // and not frameworks/base/core/java/android/app/ActivityManager.java
- optional android.service.procstats.ProcessState process_state = 3 [deprecated = true];
-
- optional ProcessStateAggregated process_state_aggregated = 10;
-
- // Millisecond uptime duration spent in this state
- optional int64 duration_millis = 4 [deprecated = true];
- // Same as above, but with minute resolution so it fits into an int32.
- optional int32 duration_minutes = 11;
-
- // Millisecond elapsed realtime duration spent in this state
- optional int64 realtime_duration_millis = 9 [deprecated = true];
- // Same as above, but with minute resolution so it fits into an int32.
- optional int32 realtime_duration_minutes = 12;
-
- // # of samples taken
- optional int32 sample_size = 5;
-
- // PSS is memory reserved for this process
- optional AggStats pss = 6 [deprecated = true];
-
- // USS is memory shared between processes, divided evenly for accounting
- optional AggStats uss = 7 [deprecated = true];
-
- // RSS is memory resident for this process
- optional AggStats rss = 8;
-}
-
-// Next Tag: 8
-message ProcessStatsProto {
- // Name of process.
- optional string process = 1;
-
- // Uid of the process.
- optional int32 uid = 2 [(is_uid) = true];
-
- // Information about how often kills occurred
- message Kill {
- // Count of excessive CPU kills
- optional int32 cpu = 1;
-
- // Count of kills when cached
- optional int32 cached = 2;
-
- // PSS stats during cached kill
- optional AggStats cached_pss = 3;
- }
- optional Kill kill = 3 [deprecated = true];
-
- // Time and memory spent in various states.
- repeated ProcessStatsStateProto states = 5;
-
- // Total time process has been running... screen_state, memory_state, and process_state
- // will not be set.
- optional ProcessStatsStateProto total_running_state = 6;
-
- // Association data for this process in this state;
- // each entry here is one association.
- repeated ProcessStatsAssociationProto assocs = 7;
-}
-
-// Next Tag: 6
-message ProcessStatsAssociationProto {
- // Procss Name of the associated process (client process of service binding)
- optional string assoc_process_name = 1;
-
- // Package Name of the associated package (client package of service binding)
- optional string assoc_package_name = 2 [deprecated = true];
-
- // UID of the associated process/package (client package of service binding)
- optional int32 assoc_uid = 5 [(is_uid) = true];
-
- // Total count of the times this association (service binding) appeared.
- optional int32 total_count = 3;
-
- // Uptime total duration in seconds this association (service binding) was around.
- optional int32 total_duration_secs = 4;
-}
-
-message PackageServiceOperationStatsProto {
- // Operate enum: Started, Foreground, Bound, Executing
- optional android.service.procstats.ServiceOperationState operation = 1;
-
- // Number of times the service was in this operation.
- optional int32 count = 2;
-
- // Information about a state the service can be in.
- message StateStats {
- // Screen state enum.
- optional android.service.procstats.ScreenState screen_state = 1;
- // Memory state enum.
- optional android.service.procstats.MemoryState memory_state = 2;
-
- // duration in milliseconds.
- optional int64 duration_millis = 3;
- // Millisecond elapsed realtime duration spent in this state
- optional int64 realtime_duration_millis = 4;
- }
- repeated StateStats state_stats = 3;
-}
-
-message PackageServiceStatsProto {
- // Name of service component.
- optional string service_name = 1;
-
- // The operation stats.
- // The package_name, package_uid, package_version, service_name will not be set to save space.
- repeated PackageServiceOperationStatsProto operation_stats = 2;
-}
-
-message PackageAssociationSourceProcessStatsProto {
- // Uid of the process.
- optional int32 process_uid = 1;
- // Process name.
- optional string process_name = 2;
- // Package name.
- optional string package_name = 7;
- // Total count of the times this association appeared.
- optional int32 total_count = 3;
-
- // Millisecond uptime total duration this association was around.
- optional int64 total_duration_millis = 4;
-
- // Total count of the times this association became actively impacting its target process.
- optional int32 active_count = 5;
-
- // Information on one source in this association.
- message StateStats {
- // Process state enum.
- optional android.service.procstats.ProcessState process_state = 1;
- // Millisecond uptime duration spent in this state
- optional int64 duration_millis = 2;
- // Millisecond elapsed realtime duration spent in this state
- optional int64 realtime_duration_mmillis = 3;
- }
- repeated StateStats active_state_stats = 6;
-}
-
-message PackageAssociationProcessStatsProto {
- // Name of the target component.
- optional string component_name = 1;
- // Information on one source in this association.
- repeated PackageAssociationSourceProcessStatsProto sources = 2;
-}
-
-
-message ProcessStatsPackageProto {
- // Name of package.
- optional string package = 1;
-
- // Uid of the package.
- optional int32 uid = 2;
-
- // Version of the package.
- optional int64 version = 3;
-
- // Stats for each process running with the package loaded in to it.
- repeated ProcessStatsProto process_stats = 4;
-
- // Stats for each of the package's services.
- repeated PackageServiceStatsProto service_stats = 5;
-
- // Stats for each association with the package.
- repeated PackageAssociationProcessStatsProto association_stats = 6;
-}
-
-message ProcessStatsSectionProto {
- // Elapsed realtime at start of report.
- optional int64 start_realtime_millis = 1;
-
- // Elapsed realtime at end of report.
- optional int64 end_realtime_millis = 2;
-
- // CPU uptime at start of report.
- optional int64 start_uptime_millis = 3;
-
- // CPU uptime at end of report.
- optional int64 end_uptime_millis = 4;
-
- // System runtime library. e.g. "libdvm.so", "libart.so".
- optional string runtime = 5;
-
- // whether kernel reports swapped pss.
- optional bool has_swapped_pss = 6;
-
- // Data completeness. e.g. "complete", "partial", shutdown", or "sysprops".
- enum Status {
- STATUS_UNKNOWN = 0;
- STATUS_COMPLETE = 1;
- STATUS_PARTIAL = 2;
- STATUS_SHUTDOWN = 3;
- STATUS_SYSPROPS = 4;
- }
- repeated Status status = 7;
-
- // Number of pages available of various types and sizes, representation fragmentation.
- repeated ProcessStatsAvailablePagesProto available_pages = 10;
-
- // Stats for each process.
- repeated ProcessStatsProto process_stats = 8;
-
- // Stats for each package.
- repeated ProcessStatsPackageProto package_stats = 9;
-}
-
-message ProcessStatsAvailablePagesProto {
- // Node these pages are in (as per /proc/pagetypeinfo)
- optional int32 node = 1;
-
- // Zone these pages are in (as per /proc/pagetypeinfo)
- optional string zone = 2;
-
- // Label for the type of these pages (as per /proc/pagetypeinfo)
- optional string label = 3;
-
- // Distribution of number of pages available by order size. First entry in array is
- // order 0, second is order 1, etc. Each order increase is a doubling of page size.
- repeated int32 pages_per_order = 4;
-}
-
-/**
- * Pulled from ProcessStatsService.java
- */
-message ProcStats {
- optional ProcessStatsSectionProto proc_stats_section = 1;
- // Data pulled from device into this is sometimes sharded across multiple atoms to work around
- // a size limit. When this happens, this shard ID will contain an increasing 1-indexed integer
- // with the number of this shard.
- optional int32 shard_id = 2;
-}
-
-/**
- * Pulled from ProcessStatsService.java
- */
-message ProcStatsPkgProc {
- optional ProcessStatsSectionProto proc_stats_section = 1;
-}
-
-// Next Tag: 2
-message PackageRemoteViewInfoProto {
- optional string package_name = 1;
- // add per-package additional info here (like channels)
-}
-
-// Next Tag: 2
-message NotificationRemoteViewsProto {
- repeated PackageRemoteViewInfoProto package_remote_view_info = 1;
-}
-
-/**
- * Pulled from NotificationManagerService.java
- */
-message NotificationRemoteViews {
- optional NotificationRemoteViewsProto notification_remote_views = 1;
-}
-
-/**
- * Atom that contains a list of a package's preferences, pulled from NotificationManagerService.java
- */
-message PackageNotificationPreferences {
- // Uid under which the package is installed.
- optional int32 uid = 1 [(is_uid) = true];
- // Notification importance, which specifies when and how a notification is displayed.
- // Specified under core/java/android/app/NotificationManager.java.
- optional int32 importance = 2;
- // Lockscreen visibility as set by the user.
- optional int32 visibility = 3;
- // Bitfield mask indicating what fields were locked by the user (see LockableAppfields in
- // PreferencesHelper.java)
- optional int32 user_locked_fields = 4;
-}
-
-/**
- * Atom that contains a list of a package's channel preferences, pulled from
- * NotificationManagerService.java.
- */
-message PackageNotificationChannelPreferences {
- // Uid under which the package is installed.
- optional int32 uid = 1 [(is_uid) = true];
- // Channel's ID. Should always be available.
- optional string channel_id = 2;
- // Channel's name. Should always be available.
- optional string channel_name = 3;
- // Channel's description. Optionally set by the channel creator.
- optional string description = 4;
- // Notification importance, which specifies when and how a notification is displayed. Specified
- // under core/java/android/app/NotificationManager.java.
- optional int32 importance = 5;
- // Bitmask representing which fields have been set by the user. See field bitmask descriptions
- // at core/java/android/app/NotificationChannel.java
- optional int32 user_locked_fields = 6;
- // Indicates if the channel was deleted by the app.
- optional bool is_deleted = 7;
- // Indicates if the channel was marked as a conversation by the app.
- optional bool is_conversation = 8;
- // Indicates if the channel is a conversation that was demoted by the user.
- optional bool is_demoted_conversation = 9;
- // Indicates if the channel is a conversation that was marked as important by the user.
- optional bool is_important_conversation = 10;
-}
-
-/**
- * Atom that represents an item in the list of Do Not Disturb rules, pulled from
- * NotificationManagerService.java.
- */
-message DNDModeProto {
- enum Mode {
- ROOT_CONFIG = -1; // Used to distinguish the config (one per user) from the rules.
- ZEN_MODE_OFF = 0;
- ZEN_MODE_IMPORTANT_INTERRUPTIONS = 1;
- ZEN_MODE_NO_INTERRUPTIONS = 2;
- ZEN_MODE_ALARMS = 3;
- }
- optional int32 user = 1; // Android user ID (0, 1, 10, ...)
- optional bool enabled = 2; // true for ROOT_CONFIG if a manualRule is enabled
- optional bool channels_bypassing = 3; // only valid for ROOT_CONFIG
- optional Mode zen_mode = 4;
- // id is one of the system default rule IDs, or empty
- // May also be "MANUAL_RULE" to indicate app-activation of the manual rule.
- optional string id = 5;
- optional int32 uid = 6 [(is_uid) = true]; // currently only SYSTEM_UID or 0 for other
- optional DNDPolicyProto policy = 7;
-}
-
-/**
- * Atom that represents a Do Not Disturb policy, an optional detail proto for DNDModeProto.
- */
-message DNDPolicyProto {
- enum State {
- STATE_UNSET = 0;
- STATE_ALLOW = 1;
- STATE_DISALLOW = 2;
- }
- optional State calls = 1;
- optional State repeat_callers = 2;
- optional State messages = 3;
- optional State conversations = 4;
- optional State reminders = 5;
- optional State events = 6;
- optional State alarms = 7;
- optional State media = 8;
- optional State system = 9;
- optional State fullscreen = 10;
- optional State lights = 11;
- optional State peek = 12;
- optional State status_bar = 13;
- optional State badge = 14;
- optional State ambient = 15;
- optional State notification_list = 16;
-
- enum PeopleType {
- PEOPLE_UNSET = 0;
- PEOPLE_ANYONE = 1;
- PEOPLE_CONTACTS = 2;
- PEOPLE_STARRED = 3;
- PEOPLE_NONE = 4;
- }
-
- optional PeopleType allow_calls_from = 17;
- optional PeopleType allow_messages_from = 18;
-
- enum ConversationType {
- CONV_UNSET = 0;
- CONV_ANYONE = 1;
- CONV_IMPORTANT = 2;
- CONV_NONE = 3;
- }
-
- optional ConversationType allow_conversations_from = 19;
-}
-
-/**
- * Atom that contains a list of a package's channel group preferences, pulled from
- * NotificationManagerService.java.
- */
-message PackageNotificationChannelGroupPreferences {
- // Uid under which the package is installed.
- optional int32 uid = 1 [(is_uid) = true];
- // Channel Group's ID. Should always be available.
- optional string group_id = 2;
- // Channel Group's name. Should always be available.
- optional string group_name = 3;
- // Channel Group's description. Optionally set by group creator.
- optional string description = 4;
- // Indicates if notifications from this channel group are blocked.
- optional bool is_blocked = 5;
- // Bitmask representing which fields have been set by the user. See field bitmask descriptions
- // at core/java/android/app/NotificationChannelGroup.java
- optional int32 user_locked_fields = 6;
-}
-
-message PowerProfileProto {
- optional double cpu_suspend = 1;
-
- optional double cpu_idle = 2;
-
- optional double cpu_active = 3;
-
- message CpuCluster {
- optional int32 id = 1;
- optional double cluster_power = 2;
- optional int32 cores = 3;
- repeated int64 speed = 4;
- repeated double core_power = 5;
- }
-
- repeated CpuCluster cpu_cluster = 40;
-
- optional double wifi_scan = 4;
-
- optional double wifi_on = 5;
-
- optional double wifi_active = 6;
-
- optional double wifi_controller_idle = 7;
-
- optional double wifi_controller_rx = 8;
-
- optional double wifi_controller_tx = 9;
-
- repeated double wifi_controller_tx_levels = 10;
-
- optional double wifi_controller_operating_voltage = 11;
-
- optional double bluetooth_controller_idle = 12;
-
- optional double bluetooth_controller_rx = 13;
-
- optional double bluetooth_controller_tx = 14;
-
- optional double bluetooth_controller_operating_voltage = 15;
-
- optional double modem_controller_sleep = 16;
-
- optional double modem_controller_idle = 17;
-
- optional double modem_controller_rx = 18;
-
- repeated double modem_controller_tx = 19;
-
- optional double modem_controller_operating_voltage = 20;
-
- optional double gps_on = 21;
-
- repeated double gps_signal_quality_based = 22;
-
- optional double gps_operating_voltage = 23;
-
- optional double bluetooth_on = 24;
-
- optional double bluetooth_active = 25;
-
- optional double bluetooth_at_cmd = 26;
-
- optional double ambient_display = 27;
-
- optional double screen_on = 28;
-
- optional double radio_on = 29;
-
- optional double radio_scanning = 30;
-
- optional double radio_active = 31;
-
- optional double screen_full = 32;
-
- optional double audio = 33;
-
- optional double video = 34;
-
- optional double flashlight = 35;
-
- optional double memory = 36;
-
- optional double camera = 37;
-
- optional double wifi_batched_scan = 38;
-
- optional double battery_capacity = 39;
-}
-
-/**
- * power_profile.xml and other constants for power model calculations.
- * Pulled from PowerProfile.java
- */
-message PowerProfile {
- optional PowerProfileProto power_profile = 1;
-}
-
-/**
- * Logs when a user restriction was added or removed.
- *
- * Logged from:
- * frameworks/base/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
- */
-message UserRestrictionChanged {
- // The raw string of the user restriction as defined in UserManager.
- // Allowed values are defined in UserRestrictionsUtils#USER_RESTRICTIONS.
- optional string restriction = 1;
- // Whether the restriction is enabled or disabled.
- optional bool enabled = 2;
-}
-
-/**
- * Pulls process user time and system time. Puller takes a snapshot of all pids
- * in the system and returns cpu stats for those that are working at the time.
- * Dead pids will be dropped. Kernel processes are excluded.
- * Min cool-down is 5 sec.
- */
-message ProcessCpuTime {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string process_name = 2;
- // Process cpu time in user space, cumulative from boot/process start
- optional int64 user_time_millis = 3;
- // Process cpu time in system space, cumulative from boot/process start
- optional int64 system_time_millis = 4;
-}
-
-/**
- * Pulls the CPU usage for each thread.
- *
- * Read from /proc/$PID/task/$TID/time_in_state files.
- *
- * TODO(mishaw): This is an experimental atom. Issues with big/little CPU frequencies, and
- * time_in_state files not being present on some phones, have not been addressed. These should be
- * considered before a public release.
- */
-message CpuTimePerThreadFreq {
- // UID that owns the process.
- optional int32 uid = 1 [(is_uid) = true];
- // ID of the process.
- optional int32 process_id = 2;
- // ID of the thread.
- optional int32 thread_id = 3;
- // Name of the process taken from `/proc/$PID/cmdline`.
- optional string process_name = 4;
- // Name of the thread taken from `/proc/$PID/task/$TID/comm`
- optional string thread_name = 5;
-
- // Report eight different frequencies, and how much time is spent in each frequency. Frequencies
- // are given in KHz, and time is given in milliseconds since the thread started. All eight
- // frequencies are given here as the alternative is sending eight separate atoms. This method
- // significantly reduces the amount of data created
- optional int32 frequency1_khz = 6;
- optional int32 time1_millis = 7;
- optional int32 frequency2_khz = 8;
- optional int32 time2_millis = 9;
- optional int32 frequency3_khz = 10;
- optional int32 time3_millis = 11;
- optional int32 frequency4_khz = 12;
- optional int32 time4_millis = 13;
- optional int32 frequency5_khz = 14;
- optional int32 time5_millis = 15;
- optional int32 frequency6_khz = 16;
- optional int32 time6_millis = 17;
- optional int32 frequency7_khz = 18;
- optional int32 time7_millis = 19;
- optional int32 frequency8_khz = 20;
- optional int32 time8_millis = 21;
-}
-
-/**
- * Pulls information about the device's build.
- */
-message BuildInformation {
- // Build.FINGERPRINT. A string that uniquely identifies this build. Do not parse.
- // E.g. may be composed of the brand, product, device, release, id, incremental, type, and tags.
- optional string fingerprint = 1;
-
- // Build.BRAND. The consumer-visible brand with which the product/hardware will be associated.
- optional string brand = 2;
-
- // Build.PRODUCT. The name of the overall product.
- optional string product = 3;
-
- // Build.DEVICE. The name of the industrial design.
- optional string device = 4;
-
- // Build.VERSION.RELEASE. The user-visible version string. E.g., "1.0" or "3.4b5" or "bananas".
- optional string version_release = 5;
-
- // Build.ID. E.g. a label like "M4-rc20".
- optional string id = 6;
-
- // Build.VERSION.INCREMENTAL. The internal value used by the underlying source control to
- // represent this build.
- optional string version_incremental = 7;
-
- // Build.TYPE. The type of build, like "user" or "eng".
- optional string type = 8;
-
- // Build.TAGS. Comma-separated tags describing the build, like "unsigned,debug".
- optional string tags = 9;
-}
-
-/**
- * Logs information about mismatched caller for content capture.
- *
- * Logged from:
- * frameworks/base/core/java/android/service/contentcapture/ContentCaptureService.java
- */
-message ContentCaptureCallerMismatchReported {
- optional string intended_package = 1;
- optional string calling_package = 2;
-}
-
-/**
- * Logs information about content capture service events.
- *
- * Logged from:
- * frameworks/base/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureMetricsLogger.java
- */
-message ContentCaptureServiceEvents {
- // The type of event.
- enum Event {
- UNKNOWN = 0;
- ON_CONNECTED = 1;
- ON_DISCONNECTED = 2;
- SET_WHITELIST = 3;
- SET_DISABLED = 4;
- ON_USER_DATA_REMOVED = 5;
- ON_DATA_SHARE_REQUEST = 6;
- ACCEPT_DATA_SHARE_REQUEST = 7;
- REJECT_DATA_SHARE_REQUEST = 8;
- DATA_SHARE_WRITE_FINISHED = 9;
- DATA_SHARE_ERROR_IOEXCEPTION = 10;
- DATA_SHARE_ERROR_EMPTY_DATA = 11;
- DATA_SHARE_ERROR_CLIENT_PIPE_FAIL = 12;
- DATA_SHARE_ERROR_SERVICE_PIPE_FAIL = 13;
- DATA_SHARE_ERROR_CONCURRENT_REQUEST = 14;
- DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED = 15;
- }
- optional Event event = 1;
- // component/package of content capture service.
- optional string service_info = 2;
- // component/package of target.
- // it's a concatenated list of component/package for SET_WHITELIST event
- // separated by " ".
- optional string target_info = 3;
-}
-
-/**
- * Logs information about content capture session events.
- *
- * Logged from:
- * frameworks/base/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureMetricsLogger.java
- */
-message ContentCaptureSessionEvents {
- // The type of event.
- enum Event {
- UNKNOWN = 0;
- ON_SESSION_STARTED = 1;
- ON_SESSION_FINISHED = 2;
- SESSION_NOT_CREATED = 3;
- }
- optional int32 session_id = 1;
- optional Event event = 2;
- // (n/a on session finished)
- optional int32 state_flags = 3;
- // component/package of content capture service.
- optional string service_info = 4;
- // component/package of app.
- // (n/a on session finished)
- optional string app_info = 5;
- optional bool is_child_session = 6;
-}
-
-/**
- * Logs information about session being flushed.
- *
- * Logged from:
- * frameworks/base/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureMetricsLogger.java
- */
-message ContentCaptureFlushed {
- optional int32 session_id = 1;
- // component/package of content capture service.
- optional string service_info = 2;
- // component/package of app.
- optional string app_info = 3;
- // session start/finish events
- optional int32 child_session_started = 4;
- optional int32 child_session_finished = 5;
- // count of view events.
- optional int32 view_appeared_count = 6;
- optional int32 view_disappeared_count = 7;
- optional int32 view_text_changed_count = 8;
-
- // Flush stats.
- optional int32 max_events = 9;
- optional int32 idle_flush_freq = 10;
- optional int32 text_flush_freq = 11;
- optional int32 flush_reason = 12;
-}
-
-/**
- * Pulls on-device BatteryStats power use calculations for the overall device.
- */
-message DeviceCalculatedPowerUse {
- // Power used by the device in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since
- // BatteryStats last reset (i.e. roughly since device was last significantly charged).
- // Currently, this is from BatteryStatsHelper.getComputedPower() (not getTotalPower()).
- optional int64 computed_power_nano_amp_secs = 1;
-}
-
-/**
- * Pulls on-device BatteryStats power use calculations broken down by uid.
- * This atom should be complemented by DeviceCalculatedPowerBlameOther, which contains the power use
- * that is attributed to non-uid items. They must all be included to get the total power use.
- */
-message DeviceCalculatedPowerBlameUid {
- // Uid being blamed. Note: isolated uids have already been mapped to host uid.
- optional int32 uid = 1 [(is_uid) = true];
-
- // Power used by this uid in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since
- // BatteryStats last reset (i.e. roughly since device was last significantly charged).
- optional int64 power_nano_amp_secs = 2;
-}
-
-/**
- * Pulls on-device BatteryStats power use calculations that are not due to a uid, broken down by
- * drain type.
- * This atom should be complemented by DeviceCalculatedPowerBlameUid, which contains the blame that
- * is attributed uids. They must all be included to get the total power use.
- */
-message DeviceCalculatedPowerBlameOther {
- // The type of item whose power use is being reported.
- enum DrainType {
- AMBIENT_DISPLAY = 0;
- // reserved 1; reserved "APP"; // Logged instead in DeviceCalculatedPowerBlameUid.
- BLUETOOTH = 2;
- CAMERA = 3;
- // Cell-standby
- CELL = 4;
- FLASHLIGHT = 5;
- IDLE = 6;
- MEMORY = 7;
- // Amount that total computed drain exceeded the drain estimated using the
- // battery level changes and capacity.
- OVERCOUNTED = 8;
- PHONE = 9;
- SCREEN = 10;
- // Amount that total computed drain was below the drain estimated using the
- // battery level changes and capacity.
- UNACCOUNTED = 11;
- // reserved 12; reserved "USER"; // Entire drain for a user. This is NOT supported.
- WIFI = 13;
- }
- optional DrainType drain_type = 1;
-
- // Power used by this item in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since
- // BatteryStats last reset (i.e. roughly since device was last significantly charged).
- optional int64 power_nano_amp_secs = 2;
-}
-
-/**
- * Logs device policy features.
- *
- * Logged from:
- * frameworks/base/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
- * packages/apps/ManagedProvisioning/src/com/android/managedprovisioning/
- */
-message DevicePolicyEvent {
- // The event id - unique for each event.
- optional android.stats.devicepolicy.EventId event_id = 1;
- // The admin package name.
- optional string admin_package_name = 2;
- // A generic integer parameter.
- optional int32 integer_value = 3;
- // A generic boolean parameter.
- optional bool boolean_value = 4;
- // A parameter specifying a time period in milliseconds.
- optional uint64 time_period_millis = 5;
- // A parameter specifying a list of package names, bundle extras or string parameters.
- optional android.stats.devicepolicy.StringList string_list_value = 6 [(log_mode) = MODE_BYTES];
-}
-
-/**
- * Logs when DocumentsUI is started, and how. Call this when DocumentsUI first starts up.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUILaunchReported {
- optional android.stats.docsui.LaunchAction launch_action = 1;
- optional bool has_initial_uri = 2;
- optional android.stats.docsui.MimeType mime_type = 3;
- optional android.stats.docsui.Root initial_root = 4;
-}
-
-/**
- * Logs root/app visited event in file managers/picker. Call this when the user
- * taps on root/app in hamburger menu.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIRootVisitedReported {
- optional android.stats.docsui.ContextScope scope = 1;
- optional android.stats.docsui.Root root = 2;
-}
-
-/**
- * Logs file operation stats. Call this when a file operation has completed.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIFileOperationReported {
- optional android.stats.docsui.Provider provider = 1;
- optional android.stats.docsui.FileOperation file_op = 2;
-}
-
-/**
- * Logs file operation stats. Call this when a copy/move operation has completed with a specific
- * mode.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIFileOperationCopyMoveModeReported {
- optional android.stats.docsui.FileOperation file_op = 1;
- optional android.stats.docsui.CopyMoveOpMode mode = 2;
-}
-
-
-/**
- * Logs file sub operation stats. Call this when a file operation has failed.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIFileOperationFailureReported {
- optional android.stats.docsui.Authority authority = 1;
- optional android.stats.docsui.SubFileOperation sub_op = 2;
-}
-
-/**
-* Logs the cancellation of a file operation. Call this when a job is canceled
-*
-* Logged from:
-* package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
-*/
-message DocsUIFileOperationCanceledReported {
- optional android.stats.docsui.FileOperation file_op = 1;
-}
-
-/**
- * Logs startup time in milliseconds.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIStartupMsReported {
- optional int32 startup_millis = 1;
-}
-
-/**
- * Logs the action that was started by user.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIUserActionReported {
- optional android.stats.docsui.UserAction action = 1;
-}
-
-/**
- * Logs the invalid type when invalid scoped access is requested.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/ScopedAccessMetrics.java
- */
-message DocsUIInvalidScopedAccessRequestReported {
- optional android.stats.docsui.InvalidScopedAccess type = 1;
-}
-
-/**
- * Logs the package name that launches docsui picker mode.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIPickerLaunchedFromReported {
- optional string package_name = 1;
-}
-
-/**
- * Logs the search type.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUISearchTypeReported {
- optional android.stats.docsui.SearchType search_type = 1;
-}
-
-/**
- * Logs the search mode.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUISearchModeReported {
- optional android.stats.docsui.SearchMode search_mode = 1;
-}
-
-/**
- * Logs the pick result information.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIPickResultReported {
- optional int32 total_action_count = 1;
- optional int64 duration_millis = 2;
- optional int32 file_count= 3;
- optional bool is_searching = 4;
- optional android.stats.docsui.Root picked_from = 5;
- optional android.stats.docsui.MimeType mime_type = 6;
- optional int32 repeatedly_pick_times = 7;
-}
-
-/** Logs the drag and drop of files.
-
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIDragAndDropReported {
- optional bool drag_initiated_from_docsui = 1;
-}
-
-/**
- * Logs when an app's memory is compacted.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message AppCompacted {
- // The pid of the process being compacted.
- optional int32 pid = 1;
-
- // The name of the process being compacted.
- optional string process_name = 2;
-
- // The type of compaction.
- enum Action {
- UNKNOWN = 0;
- SOME = 1;
- FULL = 2;
- PERSISTENT = 3;
- BFGS = 4;
- }
- optional Action action = 3;
-
- // Total RSS in kilobytes consumed by the process prior to compaction.
- optional int64 before_rss_total_kilobytes = 4;
-
- // File RSS in kilobytes consumed by the process prior to compaction.
- optional int64 before_rss_file_kilobytes = 5;
-
- // Anonymous RSS in kilobytes consumed by the process prior to compaction.
- optional int64 before_rss_anon_kilobytes = 6;
-
- // Swap in kilobytes consumed by the process prior to compaction.
- optional int64 before_swap_kilobytes = 7;
-
- // Total RSS in kilobytes consumed by the process after compaction.
- optional int64 after_rss_total_kilobytes = 8;
-
- // File RSS in kilobytes consumed by the process after compaction.
- optional int64 after_rss_file_kilobytes = 9;
-
- // Anonymous RSS in kilobytes consumed by the process after compaction.
- optional int64 after_rss_anon_kilobytes = 10;
-
- // Swap in kilobytes consumed by the process after compaction.
- optional int64 after_swap_kilobytes = 11;
-
- // The time taken to perform compaction in milliseconds.
- optional int64 time_to_compact_millis = 12;
-
- // The last compaction action performed for this app.
- optional Action last_action = 13;
-
- // The last time that compaction was attempted on this process in milliseconds
- // since boot, not including sleep (see SystemClock.uptimeMillis()).
- optional int64 last_compact_timestamp_ms_since_boot = 14;
-
- // The "setAdj" (i.e. previous) oom_score_adj at the time of compaction.
- optional int32 oom_score_adj = 15;
-
- // The process state at the time of compaction.
- optional android.app.ProcessStateEnum process_state = 16 [default = PROCESS_STATE_UNKNOWN];
-
- // Free ZRAM in kilobytes before compaction.
- optional int64 before_zram_free_kilobytes = 17;
-
- // Free ZRAM in kilobytes after compaction.
- optional int64 after_zram_free_kilobytes = 18;
-}
-
-/**
- * Logs when a Tethering event occurs.
- *
- */
-message NetworkTetheringReported {
- // tethering error code
- optional android.stats.connectivity.ErrorCode error_code = 1;
-
- // tethering downstream type
- optional android.stats.connectivity.DownstreamType downstream_type = 2;
-
- // transport type of upstream network
- optional android.stats.connectivity.UpstreamType upstream_type = 3;
-
- // The user type of Tethering
- optional android.stats.connectivity.UserType user_type= 4;
-}
-
-/**
- * Logs a DNS lookup operation initiated by the system resolver on behalf of an application
- * invoking native APIs such as getaddrinfo() or Java APIs such as Network#getAllByName().
- *
- * The NetworkDnsEventReported message represents the entire lookup operation, which may
- * result one or more queries to the recursive DNS resolvers. Those are individually logged
- * in DnsQueryEvents to enable computing error rates and network latency and timeouts
- * broken up by query type, transport, network interface, etc.
- */
-message NetworkDnsEventReported {
- optional android.stats.dnsresolver.EventType event_type = 1;
-
- optional android.stats.dnsresolver.ReturnCode return_code = 2;
-
- // The latency in microseconds of the entire DNS lookup operation.
- optional int32 latency_micros = 3;
-
- // Only valid for event_type = EVENT_GETADDRINFO.
- optional int32 hints_ai_flags = 4;
-
- // Flags passed to android_res_nsend() defined in multinetwork.h
- // Only valid for event_type = EVENT_RESNSEND.
- optional int32 res_nsend_flags = 5;
-
- optional android.stats.dnsresolver.NetworkType network_type = 6;
-
- // The DNS over TLS mode on a specific netId.
- optional android.stats.dnsresolver.PrivateDnsModes private_dns_modes = 7;
-
- // Additional pass-through fields opaque to statsd.
- // The DNS resolver Mainline module can add new fields here without requiring an OS update.
- optional android.stats.dnsresolver.DnsQueryEvents dns_query_events = 8 [(log_mode) = MODE_BYTES];
-
- // The sample rate of DNS stats (to statsd) is 1/sampling_rate_denom.
- optional int32 sampling_rate_denom = 9;
-}
-
-/**
- * logs the CapportApiData info
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- */
-message CapportApiData {
- // The TTL of the network connection provided by captive portal
- optional int32 remaining_ttl_secs = 1;
-
- // The limit traffic data of the network connection provided by captive portal
- optional int32 remaining_bytes = 2;
-
- // Is portal url option included in the DHCP packet (Yes, No)
- optional bool has_portal_url = 3;
-
- // Is venue info (e.g. store info, maps, flight status) included (Yes, No)
- optional bool has_venue_info = 4;
-}
-
-/**
- * logs a network Probe Event
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- */
-message ProbeEvent {
- // The probe type (http or https, or captive portal API...)
- optional android.stats.connectivity.ProbeType probe_type = 1;
-
- // The latency in microseconds of the probe event
- optional int32 latency_micros = 2;
-
- // The result of the probe event
- optional android.stats.connectivity.ProbeResult probe_result = 3;
-
- // The CaptivePortal API info
- optional CapportApiData capport_api_data = 4;
-}
-
-/**
- * log each ProbeEvent in ProbeEvents
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- */
-message ProbeEvents {
- // Record probe event during the validation
- repeated ProbeEvent probe_event = 1;
-}
-
-/**
- * The DHCP (Dynamic Host Configuration Protocol) session info
- * Logged from:
- * packages/modules/NetworkStack/src/android/net/dhcp/DhcpClient.java
- */
-message DhcpSession {
- // The DHCP Feature(s) enabled in this session
- repeated android.stats.connectivity.DhcpFeature used_features = 1;
-
- // The discover packet (re)transmit count
- optional int32 discover_count = 2;
-
- // The request packet (re)transmit count
- optional int32 request_count = 3;
-
- // The IPv4 address conflict count
- // (only be meaningful when duplicate address detection is enabled)
- optional int32 conflict_count = 4;
-
- // The DHCP packet parsing error code in this session
- // (defined in android.net.metrics.DhcpErrorEvent)
- repeated android.stats.connectivity.DhcpErrorCode error_code = 5;
-
- // The result of DHCP hostname transliteration
- optional android.stats.connectivity.HostnameTransResult ht_result = 6;
-}
-
-/**
- * Logs Network IP provisioning event
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/networkstack/metrics/NetworkIpProvisioningMetrics.java
- */
-message NetworkIpProvisioningReported {
- // Transport type (WIFI, CELLULAR, BLUETOOTH, ..)
- optional android.stats.connectivity.TransportType transport_type = 1;
-
- // The latency in microseconds of IP Provisioning over IPV4
- optional int32 ipv4_latency_micros = 2;
-
- // The latency in microseconds of IP Provisioning over IPV6
- optional int32 ipv6_latency_micros = 3;
-
- // The time duration between provisioning start and end (success or failure)
- optional int64 provisioning_duration_micros = 4;
-
- // The specific disconnect reason for this IP provisioning
- optional android.stats.connectivity.DisconnectCode disconnect_code = 5;
-
- // Log DHCP session info (Only valid for IPv4)
- optional DhcpSession dhcp_session = 6 [(log_mode) = MODE_BYTES];
-
- // The random number between 0 ~ 999 for sampling
- optional int32 random_number = 7;
-}
-
-/**
- * Logs Network DHCP Renew event
- * Logged from:
- * packages/modules/NetworkStack/src/android/net/dhcp/DhcpClient.java
- */
-message NetworkDhcpRenewReported {
- // Transport type (WIFI, CELLULAR, BLUETOOTH, ..)
- optional android.stats.connectivity.TransportType transport_type = 1;
-
- // The request packet (re)transmit count
- optional int32 request_count = 2;
-
- // The latency in microseconds of DHCP Renew
- optional int32 latency_micros = 3;
-
- // The DHCP error code is defined in android.net.metrics.DhcpErrorEvent
- optional android.stats.connectivity.DhcpErrorCode error_code = 4;
-
- // The result of DHCP renew
- optional android.stats.connectivity.DhcpRenewResult renew_result = 5;
-
- // The random number between 0 ~ 999 for sampling
- optional int32 random_number = 6;
-}
-
-/**
- * Logs Network Validation event
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- */
-message NetworkValidationReported {
- // Transport type (WIFI, CELLULAR, BLUETOOTH, ..)
- optional android.stats.connectivity.TransportType transport_type = 1;
-
- // Record each probe event
- optional ProbeEvents probe_events = 2 [(log_mode) = MODE_BYTES];
-
- // The result of the network validation
- optional android.stats.connectivity.ValidationResult validation_result = 3;
-
- // The latency in microseconds of network validation
- optional int32 latency_micros = 4;
-
- // The validation index (the first validation attempt or second, third...)
- optional int32 validation_index = 5;
-
- // The random number between 0 ~ 999 for sampling
- optional int32 random_number = 6;
-}
-
-/**
- * Logs NetworkStack Quirk event
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/networkstack/
- */
-message NetworkStackQuirkReported {
- // Transport type (WIFI, CELLULAR, BLUETOOTH, ..)
- optional android.stats.connectivity.TransportType transport_type = 1;
-
- // Record each Quirk event
- optional android.stats.connectivity.NetworkQuirkEvent event = 2;
-}
-
-/**
- * Logs when a data stall event occurs.
- *
- * Log from:
- * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- */
-message DataStallEvent {
- // Data stall evaluation type.
- // See packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- // Refer to the definition of DATA_STALL_EVALUATION_TYPE_*.
- optional int32 evaluation_type = 1;
- // See definition in data_stall_event.proto.
- optional com.android.server.connectivity.ProbeResult validation_result = 2;
- // See definition in data_stall_event.proto.
- optional android.net.NetworkCapabilitiesProto.Transport network_type = 3;
- // See definition in data_stall_event.proto.
- optional com.android.server.connectivity.WifiData wifi_info = 4 [(log_mode) = MODE_BYTES];
- // See definition in data_stall_event.proto.
- optional com.android.server.connectivity.CellularData cell_info = 5 [(log_mode) = MODE_BYTES];
- // See definition in data_stall_event.proto.
- optional com.android.server.connectivity.DnsEvent dns_event = 6 [(log_mode) = MODE_BYTES];
- // The tcp packets fail rate from the latest tcp polling.
- optional int32 tcp_fail_rate = 7;
- // Number of packets sent since the last received packet.
- optional int32 tcp_sent_since_last_recv = 8;
-}
-
-/*
- * Logs when RescueParty resets some set of experiment flags.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/RescueParty.java
- */
-message RescuePartyResetReported {
- // The rescue level of this reset. A value of 0 indicates missing or unknown level information.
- optional int32 rescue_level = 1;
-}
-
-/**
- * Logs when signed config is received from an APK, and if that config was applied successfully.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/signedconfig/SignedConfigService.java
- */
-message SignedConfigReported {
- enum Type {
- UNKNOWN_TYPE = 0;
- GLOBAL_SETTINGS = 1;
- }
- optional Type type = 1;
-
- // The final status of the signed config received.
- enum Status {
- UNKNOWN_STATUS = 0;
- APPLIED = 1;
- BASE64_FAILURE_CONFIG = 2;
- BASE64_FAILURE_SIGNATURE = 3;
- SECURITY_EXCEPTION = 4;
- INVALID_CONFIG = 5;
- OLD_CONFIG = 6;
- SIGNATURE_CHECK_FAILED = 7;
- NOT_APPLICABLE = 8;
- SIGNATURE_CHECK_FAILED_PROD_KEY_ABSENT = 9;
- }
- optional Status status = 2;
-
- // The version of the signed config processed.
- optional int32 version = 3;
-
- // The package name that the config was extracted from.
- optional string from_package = 4;
-
- enum Key {
- NO_KEY = 0;
- DEBUG = 1;
- PRODUCTION = 2;
- }
- // Which key was used to verify the config.
- optional Key verified_with = 5;
-}
-
-/*
- * Logs GNSS Network-Initiated (NI) location events.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/location/GnssLocationProvider.java
- */
-message GnssNiEventReported {
- // The type of GnssNiEvent.
- enum EventType {
- UNKNOWN = 0;
- NI_REQUEST = 1;
- NI_RESPONSE = 2;
- }
- optional EventType event_type = 1;
-
- // An ID generated by HAL to associate NI notifications and UI responses.
- optional int32 notification_id = 2;
-
- // A type which distinguishes different categories of NI request, such as VOICE, UMTS_SUPL etc.
- optional android.server.location.GnssNiType ni_type = 3;
-
- // NI requires notification.
- optional bool need_notify = 4;
-
- // NI requires verification.
- optional bool need_verify = 5;
-
- // NI requires privacy override, no notification/minimal trace.
- optional bool privacy_override = 6;
-
- // Timeout period to wait for user response. Set to 0 for no timeout limit. Specified in
- // seconds.
- optional int32 timeout = 7;
-
- // Default response when timeout.
- optional android.server.location.GnssUserResponseType default_response = 8;
-
- // String representing the requester of the network inititated location request.
- optional string requestor_id = 9;
-
- // Notification message text string representing the service(for eg. SUPL-service) who sent the
- // network initiated location request.
- optional string text = 10;
-
- // requestorId decoding scheme.
- optional android.server.location.GnssNiEncodingType requestor_id_encoding = 11;
-
- // Notification message text decoding scheme.
- optional android.server.location.GnssNiEncodingType text_encoding = 12;
-
- // True if SUPL ES is enabled.
- optional bool is_supl_es_enabled = 13;
-
- // True if GNSS location is enabled.
- optional bool is_location_enabled = 14;
-
- // GNSS NI responses which define the response in NI structures.
- optional android.server.location.GnssUserResponseType user_response = 15;
-}
-
-/**
- * Logs GNSS non-framework (NFW) location notification.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/location/GnssLocationProvider.java
- */
-message GnssNfwNotificationReported {
- // Package name of the Android proxy application representing the non-framework entity that
- // requested location. Set to empty string if unknown.
- optional string proxy_app_package_name = 1;
-
- // Protocol stack that initiated the non-framework location request.
- optional android.server.location.NfwProtocolStack protocol_stack = 2;
-
- // Name of the protocol stack if protocol_stack field is set to OTHER_PROTOCOL_STACK. Otherwise,
- // set to empty string. This field is opaque to the framework and used for logging purposes.
- optional string other_protocol_stack_name = 3;
-
- // Source initiating/receiving the location information.
- optional android.server.location.NfwRequestor requestor = 4;
-
- // Identity of the endpoint receiving the location information. For example, carrier name, OEM
- // name, SUPL SLP/E-SLP FQDN, chipset vendor name, etc. This field is opaque to the framework
- // and used for logging purposes.
- optional string requestor_id = 5;
-
- // Indicates whether location information was provided for this request.
- optional android.server.location.NfwResponseType response_type = 6;
-
- // True if the device is in user initiated emergency session.
- optional bool in_emergency_mode = 7;
-
- // True if cached location is provided.
- optional bool is_cached_location = 8;
-
- // True if proxy app permission mismatch between framework and GNSS HAL.
- optional bool is_permission_mismatched = 9;
-}
-
-/**
- * Logs GNSS configuration as defined in IGnssConfiguration.hal.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/location/GnssConfiguration.java
- */
-message GnssConfigurationReported {
- // SUPL host name.
- optional string supl_host = 1;
-
- // SUPL port number.
- optional int32 supl_port = 2;
-
- // C2K host name.
- optional string c2k_host = 3;
-
- // C2K port number.
- optional int32 c2k_port = 4;
-
- // The SUPL version requested by Carrier.
- optional int32 supl_ver = 5;
-
- // The SUPL mode.
- optional android.server.location.SuplMode supl_mode = 6;
-
- // True if NI emergency SUPL restrictions is enabled.
- optional bool supl_es = 7;
-
- // LTE Positioning Profile settings
- optional android.server.location.LppProfile lpp_profile = 8;
-
- // Positioning protocol on A-Glonass system.
- optional android.server.location.GlonassPosProtocol a_glonass_pos_protocol_select = 9;
-
- // True if emergency PDN is used. Otherwise, regular PDN is used.
- optional bool use_emergency_pdn_for_emergency_supl= 10;
-
- // Configurations of how GPS functionalities should be locked when user turns off GPS On setting.
- optional android.server.location.GpsLock gps_lock = 11;
-
- // Number of seconds to extend the emergency session duration post emergency call.
- optional int32 es_extension_sec = 12;
-
- // The full list of package names of proxy Android applications representing the non-framework
- // location access entities (on/off the device) for which the framework user has granted
- // non-framework location access permission. The package names are concatenated in one string
- // with spaces as separators.
- optional string enabled_proxy_app_package_name_list = 13;
-}
-
-/**
- * Logs when a NFC device's error occurred.
- * Logged from:
- * system/nfc/src/nfc/nfc/nfc_ncif.cc
- * packages/apps/Nfc/src/com/android/nfc/cardemulation/AidRoutingManager.java
- */
-message NfcErrorOccurred {
- enum Type {
- UNKNOWN = 0;
- CMD_TIMEOUT = 1;
- ERROR_NOTIFICATION = 2;
- AID_OVERFLOW = 3;
- }
- optional Type type = 1;
- // If it's nci cmd timeout, log the timeout command.
- optional uint32 nci_cmd = 2;
-
- optional uint32 error_ntf_status_code = 3;
-}
-
-/**
- * Logs when a NFC device's state changed event
- * Logged from:
- * packages/apps/Nfc/src/com/android/nfc/NfcService.java
- */
-message NfcStateChanged {
- enum State {
- UNKNOWN = 0;
- OFF = 1;
- ON = 2;
- ON_LOCKED = 3; // Secure Nfc enabled.
- CRASH_RESTART = 4; // NfcService watchdog timeout restart.
- }
- optional State state = 1;
-}
-
-/**
- * Logs when a NFC Beam Transaction occurred.
- * Logged from:
- * packages/apps/Nfc/src/com/android/nfc/P2pLinkManager.java
- */
-message NfcBeamOccurred {
- enum Operation {
- UNKNOWN = 0;
- SEND = 1;
- RECEIVE = 2;
- }
- optional Operation operation = 1;
-}
-
-/**
- * Logs when a NFC Card Emulation Transaction occurred.
- * Logged from:
- * packages/apps/Nfc/src/com/android/nfc/cardemulation/HostEmulationManager.java
- * packages/apps/Nfc/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java
- */
-message NfcCardemulationOccurred {
- enum Category {
- UNKNOWN = 0;
- HCE_PAYMENT = 1;
- HCE_OTHER = 2;
- OFFHOST = 3;
- }
- // Transaction belongs to HCE payment or HCE other category, or offhost.
- optional Category category = 1;
- // SeName from transaction: SIMx, eSEx, HCE, HCEF.
- optional string se_name = 2;
-}
-
-/**
- * Logs when a NFC Tag event occurred.
- * Logged from:
- * packages/apps/Nfc/src/com/android/nfc/NfcDispatcher.java
- */
-message NfcTagOccurred {
- enum Type {
- UNKNOWN = 0;
- URL = 1;
- BT_PAIRING = 2;
- PROVISION = 3;
- WIFI_CONNECT = 4;
- APP_LAUNCH = 5;
- OTHERS = 6;
- }
- optional Type type = 1;
-}
-
-/**
- * Logs when Hce transaction triggered
- * Logged from:
- * system/nfc/src/nfc/nfc/nfc_ncif.cc
- */
-message NfcHceTransactionOccurred {
- // The latency period(in microseconds) it took for the first HCE data
- // exchange.
- optional uint32 latency_micros = 1;
-}
-
-/**
- * Logs when SecureElement state event changed
- * Logged from:
- * packages/apps/SecureElement/src/com/android/se/Terminal.java
- */
-message SeStateChanged {
- enum State {
- UNKNOWN = 0;
- INITIALIZED = 1;
- DISCONNECTED = 2;
- CONNECTED = 3;
- HALCRASH = 4;
- }
- optional State state = 1;
-
- optional string state_change_reason = 2;
- // SIMx or eSEx.
- optional string terminal = 3;
-}
-
-/**
- * Information about a permission grant request
- */
-message PermissionGrantRequestResultReported {
- // unique value identifying an API call. A API call might result in multiple of these atoms
- optional int64 request_id = 1;
-
- // UID of package requesting the permission grant
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package requesting the permission grant
- optional string package_name = 3;
-
- // The permission to be granted
- optional string permission_name = 4;
-
- // If the permission was explicitly requested via the API or added by the system
- optional bool is_implicit = 5;
-
- enum Result {
- UNDEFINED = 0;
- // permission request was ignored
- IGNORED = 1;
- // permission request was ignored because it was user fixed
- IGNORED_USER_FIXED = 2;
- // permission request was ignored because it was policy fixed
- IGNORED_POLICY_FIXED = 3;
- // permission was granted by user action
- USER_GRANTED = 4;
- // permission was automatically granted
- AUTO_GRANTED = 5;
- // permission was denied by user action
- USER_DENIED = 6;
- // permission was denied with prejudice by the user
- USER_DENIED_WITH_PREJUDICE = 7;
- // permission was automatically denied
- AUTO_DENIED = 8;
- // permission request was ignored because permission is restricted
- IGNORED_RESTRICTED_PERMISSION = 9;
- // one time permission was granted by user action
- USER_GRANTED_ONE_TIME = 10;
- // user ignored request by leaving the request screen without choosing any option
- USER_IGNORED = 11;
- // user granted the permission after being linked to settings
- USER_GRANTED_IN_SETTINGS = 12;
- // user denied the permission after being linked to settings
- USER_DENIED_IN_SETTINGS = 13;
- // user denied the permission with prejudice after being linked to settings
- USER_DENIED_WITH_PREJUDICE_IN_SETTINGS = 14;
- // permission was automatically revoked after one-time permission expired
- AUTO_ONE_TIME_PERMISSION_REVOKED = 15;
- // permission was automatically revoked for unused app
- AUTO_UNUSED_APP_PERMISSION_REVOKED = 16;
- }
- // The result of the permission grant
- optional Result result = 6;
-}
-
-/**
- * Logs when Omapi API used
- * Logged from:
- * packages/apps/SecureElement/src/com/android/se/Terminal.java
- */
-message SeOmapiReported {
- enum Operation {
- UNKNOWN = 0;
- OPEN_CHANNEL = 1;
- }
- optional Operation operation = 1;
- // SIMx or eSEx.
- optional string terminal = 2;
-
- optional string package_name = 3;
-}
-
-/**
- * Logs the dispatch latency of a broadcast during processing of BOOT_COMPLETED.
- * The dispatch latency is the dispatchClockTime - enqueueClockTime.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
- */
-message BroadcastDispatchLatencyReported {
- optional int64 dispatch_latency_millis = 1;
-}
-
-/**
- * Logs AttentionManagerService attention check result.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/attention/AttentionManagerService.java
- */
-message AttentionManagerServiceResultReported {
- // See core/java/android/service/attention/AttentionService.java
- enum AttentionCheckResult {
- UNKNOWN = 20;
- ATTENTION_SUCCESS_ABSENT = 0;
- ATTENTION_SUCCESS_PRESENT = 1;
- ATTENTION_FAILURE_UNKNOWN = 2;
- ATTENTION_FAILURE_CANCELLED = 3;
- ATTENTION_FAILURE_PREEMPTED = 4;
- ATTENTION_FAILURE_TIMED_OUT = 5;
- ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6;
- }
- optional AttentionCheckResult attention_check_result = 1 [default = UNKNOWN];
-}
-
-/**
- * Logs when an adb connection changes state.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/adb/AdbDebuggingManager.java
- */
-message AdbConnectionChanged {
- // The last time this system connected via adb, or 0 if the 'always allow' option was not
- // previously selected for this system.
- optional int64 last_connection_time_millis = 1;
-
- // The time in ms within which a subsequent connection from an 'always allow' system is allowed
- // to reconnect via adb without user interaction.
- optional int64 auth_window_millis = 2;
-
- // The state of the adb connection from frameworks/base/core/proto/android/debug/enums.proto.
- optional android.debug.AdbConnectionStateEnum state = 3;
-
- // True if the 'always allow' option was selected for this system.
- optional bool always_allow = 4;
-}
-
-/*
- * Logs the reported speech DSP status.
- *
- * Logged from:
- * Vendor audio implementation.
- */
-message SpeechDspStatReported {
- // The total Speech DSP uptime in milliseconds.
- optional int32 total_uptime_millis = 1;
- // The total Speech DSP downtime in milliseconds.
- optional int32 total_downtime_millis = 2;
- optional int32 total_crash_count = 3;
- optional int32 total_recover_count = 4;
-}
-
-/**
- * Logs USB connector contaminant status.
- *
- * Logged from: USB Service.
- */
-message UsbContaminantReported {
- optional string id = 1;
- optional android.service.usb.ContaminantPresenceStatus status = 2;
-}
-
-/**
- * This atom is for debugging purpose.
- */
-message DebugElapsedClock {
- // Monotically increasing value for each pull.
- optional int64 pull_count = 1;
- // Time from System.elapsedRealtime.
- optional int64 elapsed_clock_millis = 2;
- // Time from System.elapsedRealtime.
- optional int64 same_elapsed_clock_millis = 3;
- // Diff between current elapsed time and elapsed time from previous pull.
- optional int64 elapsed_clock_diff_millis = 4;
-
- enum Type {
- TYPE_UNKNOWN = 0;
- ALWAYS_PRESENT = 1;
- PRESENT_ON_ODD_PULLS = 2;
- }
- // Type of behavior for the pulled data.
- optional Type type = 5;
-}
-
-/**
- * This atom is for debugging purpose.
- */
-message DebugFailingElapsedClock {
- // Monotically increasing value for each pull.
- optional int64 pull_count = 1;
- // Time from System.elapsedRealtime.
- optional int64 elapsed_clock_millis = 2;
- // Time from System.elapsedRealtime.
- optional int64 same_elapsed_clock_millis = 3;
- // Diff between current elapsed time and elapsed time from previous pull.
- optional int64 elapsed_clock_diff_millis = 4;
-}
-
-/** Logs System UI bubbles event changed.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/bubbles
- */
-message BubbleUIChanged {
-
- // The app package that is posting the bubble.
- optional string package_name = 1;
-
- // The notification channel that is posting the bubble.
- optional string notification_channel = 2;
-
- // The notification id associated with the posted bubble.
- optional int32 notification_id = 3;
-
- // The position of the bubble within the bubble stack.
- optional int32 position = 4;
-
- // The total number of bubbles within the bubble stack.
- optional int32 total_number = 5;
-
- // User interactions with the bubble.
- enum Action {
- UNKNOWN = 0;
- POSTED = 1;
- UPDATED = 2;
- EXPANDED = 3;
- COLLAPSED = 4;
- DISMISSED = 5;
- STACK_DISMISSED = 6;
- STACK_MOVED = 7;
- HEADER_GO_TO_APP = 8;
- HEADER_GO_TO_SETTINGS = 9;
- PERMISSION_OPT_IN = 10;
- PERMISSION_OPT_OUT = 11;
- PERMISSION_DIALOG_SHOWN = 12;
- SWIPE_LEFT = 13;
- SWIPE_RIGHT = 14;
- STACK_EXPANDED = 15;
- FLYOUT = 16;
- }
- optional Action action = 6;
-
- // Normalized screen position of the bubble stack. The range is between 0 and 1.
- optional float normalized_x_position = 7;
- optional float normalized_y_position = 8;
-
- // Whether the bubble is unread. If it is unread, a dot is shown in the bubble stack icon.
- optional bool is_unread = 9;
-
- // Whether the bubble is an on-going one.
- optional bool is_ongoing = 10;
-
- // Whether the bubble is produced by an app running in foreground.
- // This is deprecated and the value should be ignored.
- optional bool is_foreground = 11 [deprecated = true];
-}
-
-/**
- * Logs System UI bubbles developer errors.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
- */
-message BubbleDeveloperErrorReported {
-
- // The app package that is posting the bubble.
- optional string package_name = 1;
-
- // Bubble developer error type enums.
- enum Error {
- UNKNOWN = 0;
- ACTIVITY_INFO_MISSING = 1;
- ACTIVITY_INFO_NOT_RESIZABLE = 2;
- DOCUMENT_LAUNCH_NOT_ALWAYS = 3;
- }
- optional Error error = 2 [default = UNKNOWN];
-}
-
-/**
- * Logs that a constraint for a scheduled job has changed.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/job/controllers/JobStatus.java
- */
-message ScheduledJobConstraintChanged {
- repeated AttributionNode attribution_node = 1;
-
- // Name of the job.
- optional string job_name = 2;
-
- optional com.android.server.job.ConstraintEnum constraint = 3;
-
- enum State {
- UNKNOWN = 0;
- UNSATISFIED = 1;
- SATISFIED = 2;
- }
- optional State state = 4;
-}
-
-/**
- * Logs PowerManagerService screen timeout resets (extensions) that happen when an attention check
- * returns true.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
- */
-message ScreenTimeoutExtensionReported {
- // Describes how many times in a row did the power manager reset the screen off timeout.
- optional uint32 consecutive_timeout_extended_count = 1;
-}
-
-/*
-* Logs number of milliseconds it takes to start a process.
-* The definition of app process start time is from the app launch time to
-* the time that Zygote finished forking the app process and loaded the
-* application package's java classes.
-
-* This metric is different from AppStartOccurred which is for foreground
-* activity only.
-
-* ProcessStartTime can report all processes (both foreground and background)
-* start time.
-*
-* Logged from:
-* frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
-*/
-message ProcessStartTime {
- // The uid of the ProcessRecord.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process pid.
- optional int32 pid = 2;
-
- // The process name.
- // Usually package name, "system" for system server.
- // Provided by ActivityManagerService.
- optional string process_name = 3;
-
- enum StartType {
- UNKNOWN = 0;
- WARM = 1;
- HOT = 2;
- COLD = 3;
- }
-
- // The start type.
- optional StartType type = 4;
-
- // The elapsed realtime at the start of the process.
- optional int64 process_start_time_millis = 5;
-
- // Number of milliseconds it takes to reach bind application.
- optional int32 bind_application_delay_millis = 6;
-
- // Number of milliseconds it takes to finish start of the process.
- optional int32 process_start_delay_millis = 7;
-
- // hostingType field in ProcessRecord, the component type such as "activity",
- // "service", "content provider", "broadcast" or other strings.
- optional string hosting_type = 8;
-
- // hostingNameStr field in ProcessRecord. The component class name that runs
- // in this process.
- optional string hosting_name = 9;
-}
-
-/**
- * Track Media Codec usage
- * Logged from:
- * frameworks/av/media/libstagefright/MediaCodec.cpp
- * frameworks/av/services/mediaanalytics/statsd_codec.cpp
- */
-message MediametricsCodecReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.CodecData codec_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track Media Extractor (pulling video/audio streams out of containers) usage
- * Logged from:
- * frameworks/av/media/libstagefright/RemoteMediaExtractor.cpp
- * frameworks/av/services/mediaanalytics/statsd_extractor.cpp
- */
-message MediametricsExtractorReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.ExtractorData extractor_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track how we arbitrate between microphone/input requests.
- * Logged from
- * frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiopolicy.cpp
- */
-message MediametricsAudiopolicyReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.AudioPolicyData audiopolicy_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track how we arbitrate between microphone requests.
- * Logged from
- * frameworks/av/media/libaudioclient/AudioRecord.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiorecord.cpp
- */
-message MediametricsAudiorecordReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.AudioRecordData audiorecord_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track how we arbitrate between microphone/input requests.
- * Logged from
- * frameworks/av/media/libnblog/ReportPerformance.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiothread.cpp
- */
-message MediametricsAudiothreadReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.AudioThreadData audiothread_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track how we arbitrate between microphone/input requests.
- * Logged from
- * frameworks/av/media/libaudioclient/AudioTrack.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiotrack.cpp
- */
-message MediametricsAudiotrackReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.AudioTrackData audiotrack_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track information about DRM framework performance
- * Logged from
- * frameworks/av/drm/libmediadrm/DrmHal.cpp
- * frameworks/av/services/mediaanalytics/statsd_drm.cpp
- */
-message MediametricsMediadrmReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- // vendor+description tell about which DRM plugin is in use on this device
- optional string vendor = 5;
- optional string description = 6;
- // from frameworks/av/drm/libmediadrm/protos/metrics.proto
- optional bytes framework_stats = 7 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track information about the widevine DRM plugin performance
- * Logged from
- * vendor/widevine/libwvdrmengine/cdm/metrics
- * frameworks/av/services/mediaanalytics/statsd_drm.cpp
- */
-message MediametricsDrmWidevineReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional bytes vendor_specific_stats = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track information about recordings (e.g. camcorder)
- * Logged from
- * frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp
- * frameworks/av/services/mediaanalytics/statsd_recorder.cpp
- */
-message MediametricsRecorderReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.RecorderData recorder_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track Media Player usage
- * Logged from:
- * frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
- * frameworks/av/services/mediaanalytics/statsd_nuplayer.cpp
- */
-message MediametricsNuPlayerReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.NuPlayerData nuplayer_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track Legacy DRM usage
- * Logged from
- * frameworks/av/drm/drmserver/DrmManager.cpp
- */
-message MediametricsDrmManagerReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- enum Method {
- METHOD_NOT_FOUND = -1;
- GET_CONSTRAINTS = 0;
- GET_METADATA = 1;
- CAN_HANDLE = 2;
- PROCESS_DRM_INFO = 3;
- ACQUIRE_DRM_INFO = 4;
- SAVE_RIGHTS = 5;
- GET_ORIGINAL_MIME_TYPE = 6;
- GET_DRM_OBJECT_TYPE = 7;
- CHECK_RIGHTS_STATUS = 8;
- REMOVE_RIGHTS = 9;
- REMOVE_ALL_RIGHTS = 10;
- OPEN_CONVERT_SESSION = 11;
- OPEN_DECRYPT_SESSION = 12;
- }
-
- // plugin_id+description inform which Legacy DRM plugins are still in use on device
- optional string plugin_id = 5;
- optional string description = 6;
- optional Method method = 7;
- optional string mime_types = 8;
-
- optional int64 get_constraints_count = 9;
- optional int64 get_metadata_count = 10;
- optional int64 can_handle_count = 11;
- optional int64 process_drm_info_count = 12;
- optional int64 acquire_drm_info_count = 13;
- optional int64 save_rights_count = 14;
- optional int64 get_original_mime_type_count = 15;
- optional int64 get_drm_object_type_count = 16;
- optional int64 check_rights_status_count = 17;
- optional int64 remove_rights_count = 18;
- optional int64 remove_all_rights_count = 19;
- optional int64 open_convert_session_count = 20;
- optional int64 open_decrypt_session_count = 21;
-}
-
-/**
- * State of a dangerous permission requested by a package
- * Pulled from: StatsCompanionService
-*/
-message DangerousPermissionState {
- // Name of the permission
- optional string permission_name = 1;
-
- // Uid of the package
- optional int32 uid = 2 [(is_uid) = true];
-
- // Package requesting the permission
- optional string package_name = 3;
-
- // If the permission is granted to the uid
- optional bool is_granted = 4;
-
- // Permission flags as per android.content.pm.PermissionFlags
- optional int32 permission_flags = 5;
-}
-
-/**
- * Logs when a package is denied access to a device identifier based on the new access requirements.
- *
- * Logged from:
- * frameworks/base/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
- */
-message DeviceIdentifierAccessDenied {
- // The name of the package denied access to the requested device identifier.
- optional string package_name = 1;
-
- // The name of the device identifier method the package attempted to invoke.
- optional string method_name = 2;
-
- // True if the package is preinstalled.
- // Starting from Android 11, this boolean is not set and will always be false.
- optional bool is_preinstalled = 3 [deprecated = true];
-
- // True if the package is privileged.
- // Starting from Android 11, this boolean is not set and will always be false.
- optional bool is_priv_app = 4 [deprecated = true];
-}
-
-/**
- * Pulls the ongoing mainline install train version code.
- * Pulled from StatsCompanionService
- */
-message TrainInfo {
- optional int64 train_version_code = 1;
-
- optional TrainExperimentIds train_experiment_id = 2;
-
- optional string train_name = 3;
-
- enum Status {
- UNKNOWN = 0;
- INSTALL_REQUESTED = 1;
- INSTALL_STARTED = 2;
- INSTALL_STAGED_NOT_READY = 3;
- INSTALL_STAGED_READY = 4;
- INSTALL_SUCCESS = 5;
- // Replaced by INSTALL_FAILURE_DOWNLOAD, INSTALL_FAILURE_STATE_MISMATCH,
- // and INSTALL_FAILURE_COMMIT.
- INSTALL_FAILURE = 6 [deprecated = true];
- // This enum is for installs that are manually cancelled via the Manual Update UI.
- INSTALL_CANCELLED = 7;
- INSTALLER_ROLLBACK_REQUESTED = 8;
- INSTALLER_ROLLBACK_INITIATED = 9;
- INSTALLER_ROLLBACK_INITIATED_FAILURE = 10;
- INSTALLER_ROLLBACK_STAGED = 11;
- INSTALLER_ROLLBACK_STAGED_FAILURE = 12;
- INSTALLER_ROLLBACK_BOOT_TRIGGERED = 13;
- INSTALLER_ROLLBACK_BOOT_TRIGGERED_FAILURE = 14;
- INSTALLER_ROLLBACK_SUCCESS = 15;
- INSTALLER_ROLLBACK_FAILURE = 16;
- INSTALLER_ROLLBACK_STAGED_CANCEL_REQUESTED = 17;
- INSTALLER_ROLLBACK_STAGED_CANCEL_SUCCESS = 18;
- INSTALLER_ROLLBACK_STAGED_CANCEL_FAILURE = 19;
- INSTALL_STAGED_CANCEL_REQUESTED = 20;
- INSTALL_STAGED_CANCEL_SUCCESS = 21;
- INSTALL_STAGED_CANCEL_FAILURE = 22;
- INSTALL_FAILURE_DOWNLOAD = 23;
- INSTALL_FAILURE_STATE_MISMATCH = 24;
- INSTALL_FAILURE_COMMIT = 25;
- REBOOT_TRIGGERED = 26;
- }
- optional Status status = 4;
-}
-
-/**
- * Logs the gesture stage changed event.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/
- */
-message AssistGestureStageReported {
- optional android.hardware.sensor.assist.AssistGestureStageEnum gesture_stage = 1;
-}
-
-/**
- * Logs the feedback type.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/
- */
-message AssistGestureFeedbackReported {
- // Whether or not the gesture was used.
- optional android.hardware.sensor.assist.AssistGestureFeedbackEnum feedback_type = 1;
-}
-
-/**
- * Logs the progress.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/
- */
-message AssistGestureProgressReported {
- // [0,100] progress for the assist gesture.
- optional int32 progress = 1;
-}
-
-/*
- * Information about the time zone data on a device.
- */
-message TimeZoneDataInfo {
- // A version identifier for the data set on device. e.g. "2018i"
- optional string tzdb_version = 1;
-}
-
-/**
- * Logs the GPU stats global health information.
- *
- * Logged from:
- * frameworks/native/services/gpuservice/gpustats/
- */
-message GpuStatsGlobalInfo {
- // Package name of the gpu driver.
- optional string driver_package_name = 1;
-
- // Version name of the gpu driver.
- optional string driver_version_name = 2;
-
- // Version code of the gpu driver.
- optional int64 driver_version_code = 3;
-
- // Build time of the gpu driver in UTC as seconds since January 1, 1970.
- optional int64 driver_build_time = 4;
-
- // Total count of the gl driver gets loaded.
- optional int64 gl_loading_count = 5;
-
- // Total count of the gl driver fails to be loaded.
- optional int64 gl_loading_failure_count = 6;
-
- // Total count of the Vulkan driver gets loaded.
- optional int64 vk_loading_count = 7;
-
- // Total count of the Vulkan driver fails to be loaded.
- optional int64 vk_loading_failure_count = 8;
-
- // Api version of the system Vulkan driver.
- optional int32 vulkan_version = 9;
-
- // Api version of the system CPU Vulkan driver.
- optional int32 cpu_vulkan_version = 10;
-
- // Api version of the system GLES driver.
- optional int32 gles_version = 11;
-
- // Total count of the angle driver gets loaded.
- optional int64 angle_loading_count = 12;
-
- // Total count of the angle driver fails to be loaded.
- optional int64 angle_loading_failure_count = 13;
-}
-
-/**
- * GPU driver loading time info.
- */
-message GpuDriverLoadingTime {
- // List of all the driver loading times for this app. The list size is
- // capped at 50.
- repeated int64 driver_loading_time = 1;
-}
-
-/**
- * Logs the GPU stats per app health information.
- *
- * Logged from:
- * frameworks/native/services/gpuservice/gpustats/
- */
-message GpuStatsAppInfo {
- // Package name of the application that loads the gpu driver. Total number
- // of different packages is capped at 100.
- optional string app_package_name = 1;
-
- // Version code of the gpu driver this app loads.
- optional int64 driver_version_code = 2;
-
- // gl driver loading time info.
- optional GpuDriverLoadingTime gl_driver_loading_time = 3
- [(android.os.statsd.log_mode) = MODE_BYTES];
-
- // Vulkan driver loading time info.
- optional GpuDriverLoadingTime vk_driver_loading_time = 4
- [(android.os.statsd.log_mode) = MODE_BYTES];
-
- // Angle driver loading time info.
- optional GpuDriverLoadingTime angle_driver_loading_time = 5
- [(android.os.statsd.log_mode) = MODE_BYTES];
-
- // CPU Vulkan implementation is in use.
- optional bool cpu_vulkan_in_use = 6;
-
- // App is not doing pre-rotation correctly.
- optional bool false_prerotation = 7;
-
- // App creates GLESv1 context.
- optional bool gles_1_in_use = 8;
-}
-
-/*
- * Logs the size of the system ion heap.
- *
- * Pulled from StatsCompanionService.
- */
-message SystemIonHeapSize {
- // Deprecated due to limited support of ion stats in debugfs.
- // Use `IonHeapSize` instead.
- option deprecated = true;
-
- // Size of the system ion heap in bytes.
- // Read from debugfs.
- optional int64 size_in_bytes = 1;
-}
-
-/*
- * Logs the total size of the ion heap.
- *
- * Pulled from StatsCompanionService.
- */
-message IonHeapSize {
- // Total size of all ion heaps in kilobytes.
- // Read from: /sys/kernel/ion/total_heaps_kb.
- optional int32 total_size_kb = 1;
-}
-
-/*
- * Logs the per-process size of the system ion heap.
- *
- * Pulled from StatsCompanionService.
- */
-message ProcessSystemIonHeapSize {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name (from /proc/PID/cmdline).
- optional string process_name = 2;
-
- // Sum of sizes of all allocations.
- optional int32 total_size_in_kilobytes = 3;
-
- // Number of allocations.
- optional int32 allocation_count = 4;
-
- // Size of the largest allocation.
- optional int32 max_size_in_kilobytes = 5;
-}
-
-/**
- * Push network stack events.
- *
- * Log from:
- * frameworks/base/packages/NetworkStack/
- */
-message NetworkStackReported {
- // The id that indicates the event reported from NetworkStack.
- optional int32 event_id = 1;
- // The data for the reported events.
- optional android.stats.connectivity.NetworkStackEventData network_stack_event = 2 [(log_mode) = MODE_BYTES];
-}
-
-/**
- * Logs the apps that are installed on the external storage.
- * Pulled from:
- * StatsCompanionService
- */
-message AppsOnExternalStorageInfo {
- // The type of the external storage.
- optional android.stats.storage.ExternalStorageType external_storage_type = 1;
- // The name of the package that is installed on the external storage.
- optional string package_name = 2;
-}
-
-/**
- * Logs the settings related to Face.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/stats
- */
-message FaceSettings {
- // Whether or not face unlock is allowed on Keyguard.
- optional bool unlock_keyguard_enabled = 1;
- // Whether or not face unlock dismisses the Keyguard.
- optional bool unlock_dismisses_keyguard = 2;
- // Whether or not face unlock requires attention.
- optional bool unlock_attention_required = 3;
- // Whether or not face unlock is allowed for apps (through BiometricPrompt).
- optional bool unlock_app_enabled = 4;
- // Whether or not face unlock always requires user confirmation.
- optional bool unlock_always_require_confirmation = 5;
- // Whether or not a diverse set of poses are required during enrollment.
- optional bool unlock_diversity_required = 6;
-}
-
-/**
- * Logs cooling devices maintained by the kernel.
- *
- * Pulled from StatsCompanionService.java
- */
-message CoolingDevice {
- // The type of cooling device being reported. Eg. CPU, GPU...
- optional android.os.CoolingTypeEnum device_location = 1;
- // The name of the cooling device source. Eg. CPU0
- optional string device_name = 2;
- // Current throttle state of the cooling device. The value can any unsigned
- // integer between 0 and max_state defined in its driver. 0 means device is
- // not in throttling, higher value means deeper throttling.
- optional int32 state = 3;
-}
-
-/**
- * Intelligence has several counter-type events that don't warrant a
- * full separate atom. These are primarily API call counters but also include
- * counters for feature usage and specific failure modes.
- *
- * Logged from the Intelligence mainline module.
- */
-message IntelligenceEventReported {
- // The event type.
- optional android.stats.intelligence.EventType event_id = 1;
- // Success, failure.
- optional android.stats.intelligence.Status status = 2;
- // How many times the event occured (to report a batch of high frequency events).
- optional int32 count = 3;
- // How long the event took (sum of durations if count > 1)
- optional int64 duration_millis = 4;
-}
-
-/**
- * Logs when Car Power state changed.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/CarStatsLog.java
- */
-message CarPowerStateChanged {
- // States come from CpmsState in CarPowerManagementService.java.
- enum State {
- WAIT_FOR_VHAL = 0;
- ON = 1;
- SHUTDOWN_PREPARE = 2;
- WAIT_FOR_FINISH = 3;
- SUSPEND = 4;
- SIMULATE_SLEEP = 5;
- }
- optional State state = 1;
-}
-
-/**
- * Logs when Car User Hal is requested to switch/create/remove user.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalModifyUserRequestReported {
- // Request id for the request.
- optional int32 request_id = 1;
- // Request type.
- enum RequestType {
- UNKNOWN = 0;
- // Car user manager requested user switch.
- SWITCH_REQUEST_ANDROID = 1;
- // OEM requested User switch.
- SWITCH_REQUEST_OEM = 2;
- // Hal switch requested after android switch using activity manager.
- SWITCH_REQUEST_LEGACY = 3;
- // Create User
- CREATE_REQUEST = 4;
- // Remove User
- REMOVE_REQUEST = 5;
- }
- optional RequestType request_type = 2;
- // Android User id of the current user which can only be 0, 10, 11 and so on.
- // -1 if not available.
- optional int32 user_id = 3;
- // VHAL flags of the current user. (-1 if not available)
- optional int32 user_flags = 4;
- // Android User id of the target user for switch/create/remove. It can only
- // be 0, 10, 11 and so on. -1 if not available.
- optional int32 target_user_id = 5;
- // VHAL flags of the target user for switch/create/remove. (-1 if not available)
- optional int32 target_user_flags = 6;
- // Request timeout Milliseconds (-1 if not available)
- optional int32 timeout_millis = 7;
-}
-
-/**
- * Logs when Car User Hal responds to switch/create user request.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalModifyUserResponseReported {
- // Request id of the request associated with the response.
- optional int32 request_id = 1;
- // Car user hal callback status.
- enum CallbackStatus {
- UNKNOWN = 0;
- // Hal response was invalid.
- INVALID = 1;
- // Hal response was ok.
- OK = 2;
- // Hal timeout during set call.
- HAL_SET_TIMEOUT = 3;
- // Hal response timeout.
- HAL_RESPONSE_TIMEOUT = 4;
- // Hal responded with wrong info.
- WRONG_HAL_RESPONSE = 5;
- // Hal is processing multiple requests simultaneously.
- CONCURRENT_OPERATION = 6;
- }
- optional CallbackStatus callback_status = 2;
-
- // Hal request status for user switch/create/remove.
- enum HalRequestStatus {
- UNSPECIFIED = 0;
- // Hal request for user switch/create is successful.
- SUCCESS = 1;
- // Hal request for user switch/create failed.
- FAILURE = 2;
- }
- optional HalRequestStatus request_status = 3;
-}
-
-/**
- * Logs when post switch response is posted to Car User Hal.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalPostSwitchResponseReported {
- // Request id.
- optional int32 request_id = 1;
-
- // Android user switch status.
- enum UserSwitchStatus {
- UNKNOWN = 0;
- // Android user switch is successful.
- SUCCESS = 1;
- // Android user switch failed.
- FAILURE = 2;
- }
- optional UserSwitchStatus switch_status = 2;
-}
-
-/**
- * Logs when initial user information is requested from Car User Hal.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalInitialUserInfoRequestReported {
- // Request id for the request.
- optional int32 request_id = 1;
-
- // Request type for initial user information.
- enum InitialUserInfoRequestType {
- UNKNOWN = 0;
- // At the first time Android was booted (or after a factory reset).
- FIRST_BOOT = 1;
- // At the first time Android was booted after the system was updated.
- FIRST_BOOT_AFTER_OTA = 2;
- // When Android was booted "from scratch".
- COLD_BOOT = 3;
- // When Android was resumed after the system was suspended to memory.
- RESUME = 4;
- }
- optional InitialUserInfoRequestType request_type = 2;
- // Request timeout Milliseconds (-1 if not available)
- optional int32 timeout_millis = 3;
-}
-
-/**
- * Logs when Car User Hal responds to initial user information requests.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalInitialUserInfoResponseReported {
- // Request id of the request associated with the response.
- optional int32 request_id = 1;
- // Car user hal callback status.
- enum CallbackStatus {
- UNKNOWN = 0;
- // Hal response was invalid.
- INVALID = 1;
- // Hal response was ok.
- OK = 2;
- // Hal timeout during set call.
- HAL_SET_TIMEOUT = 3;
- // Hal response timeout.
- HAL_RESPONSE_TIMEOUT = 4;
- // Hal responded with wrong info.
- WRONG_HAL_RESPONSE = 5;
- // Hal is processing multiple requests simultaneously.
- CONCURRENT_OPERATION = 6;
- }
- optional CallbackStatus callback_status = 2;
- // Response for initial user information request.
- enum InitialUserInfoResponseAction {
- UNSPECIFIED = 0;
- // Let the Android System decide what to do.
- DEFAULT = 1;
- // Switch to an existing Android user.
- SWITCH = 2;
- // Create a new Android user (and switch to it).
- CREATE = 3;
- }
- optional InitialUserInfoResponseAction response_action = 3;
- // Android User id of the target user which can only be 0, 10, 11 and so on.
- // -1 if not available.
- optional int32 target_user = 4;
- // VHAL flags of the current user. (-1 if not available)
- optional int32 target_user_flags = 5;
- // User locales
- optional string user_locales = 6;
-}
-
-/**
- * Logs when set user association is requested from Car User Hal.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalUserAssociationRequestReported {
- // Request id for the request.
- optional int32 request_id = 1;
- // Request type.
- enum RequestType {
- UNKNOWN = 0;
- // For setting user association information.
- SET = 1;
- // For getting user association information.
- GET = 2;
- }
- optional RequestType request_type = 2;
- // Android User id of the current user which can only be 0, 10, 11 and so on.
- // -1 if not available.
- optional int32 current_user_id = 3;
- // VHAL flags of the current user. (-1 if not available)
- optional int32 current_user_flags = 4;
- // Number of the set associations requested.
- optional int32 number_associations = 5;
- // Concatenated string for the types from set associations request.
- // This is a string converted from an array of integers.
- optional string user_identification_association_types = 6;
- // Concatenated string for the values from set associations request.
- // This is a string converted from an array of integers.
- optional string user_identification_association_values = 7;
-}
-
-/**
- * Logs when Car User Hal responds to set user association requests.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalSetUserAssociationResponseReported {
- // Request id of the request associated with the response.
- optional int32 request_id = 1;
- // Car user hal callback status.
- enum CallbackStatus {
- UNKNOWN = 0;
- // Hal response was invalid.
- INVALID = 1;
- // Hal response was ok.
- OK = 2;
- // Hal timeout during set call.
- HAL_SET_TIMEOUT = 3;
- // Hal response timeout.
- HAL_RESPONSE_TIMEOUT = 4;
- // Hal responded with wrong info.
- WRONG_HAL_RESPONSE = 5;
- // Hal is processing multiple requests simultaneously.
- CONCURRENT_OPERATION = 6;
- }
- optional CallbackStatus callback_status = 2;
- // Number of the set associations in the response.
- optional int32 number_associations = 3;
- // Concatenated string for the types from set associations request.
- // This is a string converted from an array of integers.
- optional string user_identification_association_types = 4;
- // Concatenated string for the values from set associations request.
- // This is a string converted from an array of integers.
- optional string user_identification_association_values = 5;
-}
-
-/**
- * Logs whether GarageMode is entered.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/CarStatsLog.java
- */
-message GarageModeInfo {
- // Whether GarageMode is entered.
- optional bool is_garage_mode = 1;
-}
-
-/**
- * Historical app ops data per package.
- */
-message AppOps {
- // Uid of the package requesting the op
- optional int32 uid = 1 [(is_uid) = true];
-
- // Name of the package performing the op
- optional string package_name = 2;
-
- // operation id
- optional android.app.AppOpEnum op_id = 3 [default = APP_OP_NONE];
-
- // The number of times the op was granted while the app was in the
- // foreground (only for trusted requests)
- optional int64 trusted_foreground_granted_count = 4;
-
- // The number of times the op was granted while the app was in the
- // background (only for trusted requests)
- optional int64 trusted_background_granted_count = 5;
-
- // The number of times the op was rejected while the app was in the
- // foreground (only for trusted requests)
- optional int64 trusted_foreground_rejected_count = 6;
-
- // The number of times the op was rejected while the app was in the
- // background (only for trusted requests)
- optional int64 trusted_background_rejected_count = 7;
-
- // For long-running operations, total duration of the operation
- // while the app was in the foreground (only for trusted requests)
- optional int64 trusted_foreground_duration_millis = 8;
-
- // For long-running operations, total duration of the operation
- // while the app was in the background (only for trusted requests)
- optional int64 trusted_background_duration_millis = 9;
-
- // Whether AppOps is guarded by Runtime permission
- optional bool is_runtime_permission = 10;
-}
-
-/**
- * Historical app ops data per package and attribution tag.
- */
-message AttributedAppOps {
- // Uid of the package requesting the op
- optional int32 uid = 1 [(is_uid) = true];
-
- // Name of the package performing the op
- optional string package_name = 2;
-
- // tag; provided by developer when accessing related API, limited at 50 chars by API.
- // Attributions must be provided through manifest using <attribution> tag available in R and
- // above.
- optional string tag = 3;
-
- // operation id
- optional android.app.AppOpEnum op = 4 [default = APP_OP_NONE];
-
- // The number of times the op was granted while the app was in the
- // foreground (only for trusted requests)
- optional int64 trusted_foreground_granted_count = 5;
-
- // The number of times the op was granted while the app was in the
- // background (only for trusted requests)
- optional int64 trusted_background_granted_count = 6;
-
- // The number of times the op was rejected while the app was in the
- // foreground (only for trusted requests)
- optional int64 trusted_foreground_rejected_count = 7;
-
- // The number of times the op was rejected while the app was in the
- // background (only for trusted requests)
- optional int64 trusted_background_rejected_count = 8;
-
- // For long-running operations, total duration of the operation
- // while the app was in the foreground (only for trusted requests)
- optional int64 trusted_foreground_duration_millis = 9;
-
- // For long-running operations, total duration of the operation
- // while the app was in the background (only for trusted requests)
- optional int64 trusted_background_duration_millis = 10;
-
- // Whether AppOps is guarded by Runtime permission
- optional bool is_runtime_permission = 11;
-
- // Sampling rate used on device, from 0 to 100
- optional int32 sampling_rate = 12;
-}
-
-/**
- * Location Manager API Usage information(e.g. API under usage,
- * API call's parameters).
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/LocationManagerService.java
- */
-message LocationManagerApiUsageReported {
-
- // Indicating if usage starts or usage ends.
- optional android.stats.location.UsageState state = 1;
-
- // LocationManagerService's API in use.
- // We can identify which API from LocationManager is
- // invoking current LMS API by the combination of
- // API parameter(e.g. is_listener_null, is_intent_null,
- // is_location_request_null)
- optional android.stats.location.LocationManagerServiceApi api_in_use = 2;
-
- // Name of the package calling the API.
- optional string calling_package_name = 3;
-
- // Type of the location provider.
- optional android.stats.location.ProviderType provider = 4;
-
- // Quality of the location request
- optional android.stats.location.LocationRequestQuality quality = 5;
-
- // The desired interval for active location updates, in milliseconds.
- // Bucketized to reduce cardinality.
- optional android.stats.location.LocationRequestIntervalBucket bucketized_interval = 6;
-
- // Minimum distance between location updates, in meters.
- // Bucketized to reduce cardinality.
- optional android.stats.location.SmallestDisplacementBucket
- bucketized_smallest_displacement = 7;
-
- // The number of location updates.
- optional int64 num_updates = 8;
-
- // The request expiration time, in millisecond since boot.
- // Bucketized to reduce cardinality.
- optional android.stats.location.ExpirationBucket
- bucketized_expire_in = 9;
-
- // Type of Callback passed in for this API.
- optional android.stats.location.CallbackType callback_type = 10;
-
- // The radius of the central point of the alert
- // region, in meters. Only for API REQUEST_GEOFENCE.
- // Bucketized to reduce cardinality.
- optional android.stats.location.GeofenceRadiusBucket bucketized_radius = 11;
-
- // Activity Importance of API caller.
- // Categorized to 3 types that are interesting from location's perspective.
- optional android.stats.location.ActivityImportance activiy_importance = 12;
-}
-
-/**
- * Information about a permission grant or denial made by user inside ReviewPermissionsFragment
- */
-message ReviewPermissionsFragmentResultReported {
- // unique value identifying a permission group change. A permission group change might result
- // in multiple of these atoms
- optional int64 change_id = 1;
-
- // UID of package the permission belongs to
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package the permission belongs to
- optional string package_name = 3;
-
- // The permission to be granted
- optional string permission_name = 4;
-
- // The result of the permission grant
- optional bool permission_granted = 5;
-}
-
-/**
-* Information about results of permission upgrade by RuntimePermissionsUpgradeController
-* Logged from: RuntimePermissionUpdgradeController
-*/
-message RuntimePermissionsUpgradeResult {
- // Permission granted as result of upgrade
- optional string permission_name = 1;
-
- // UID of package granted permission
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package granted permission
- optional string package_name = 3;
-}
-
-/**
-* Information about a buttons presented in GrantPermissionsActivty and choice made by user
-*/
-message GrantPermissionsActivityButtonActions {
- // Permission granted as result of upgrade
- optional string permission_group_name = 1;
-
- // UID of package granted permission
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package requesting permission
- optional string package_name = 3;
-
- // Buttons presented in the dialog - bit flags, bit numbers are in accordance with
- // LABEL_ constants in GrantPermissionActivity.java
- optional int32 buttons_presented = 4;
-
- // Button clicked by user - same as bit flags in buttons_presented with only single bit set
- optional int32 button_clicked = 5;
-
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 6;
-}
-
-/**
- * Information about LocationAccessCheck notification presented to user
- */
-message LocationAccessCheckNotificationAction {
-
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // Uid of package for which location access check is presented
- optional int32 package_uid = 2;
-
- // Name of package for which location access check is presented
- optional string package_name = 3;
-
- enum Result {
- UNDEFINED = 0;
- // notification was presented to the user
- NOTIFICATION_PRESENTED = 1;
- // notification was declined by the user
- NOTIFICATION_DECLINED = 2;
- // notification was clicked by the user
- NOTIFICATION_CLICKED = 3;
- }
-
- // View / interaction recorded
- optional Result result = 4;
-}
-
-/**
- * Information about a permission grant or revoke made by user inside AppPermissionFragment
- */
-message AppPermissionFragmentActionReported {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // unique value identifying a permission group change. A permission group change might result
- // in multiple of these atoms
- optional int64 change_id = 2;
-
- // UID of package the permission belongs to
- optional int32 uid = 3 [(is_uid) = true];
-
- // Name of package the permission belongs to
- optional string package_name = 4;
-
- // The permission to be granted
- optional string permission_name = 5;
-
- // The result of the permission grant
- optional bool permission_granted = 6;
-
- // State of Permission Flags after grant as per android.content.pm.PermissionFlags
- optional int32 permission_flags = 7;
-
- enum Button {
- UNDEFINED = 0;
- // Allow button
- ALLOW = 1;
- // Deny button
- DENY = 2;
- // Ask every time button
- ASK_EVERY_TIME = 3;
- // Allow all the time button
- ALLOW_ALWAYS = 4;
- // Allow only while using the app button
- ALLOW_FOREGROUND = 5;
- // Same is Deny button but shown in while in use dialog
- DENY_FOREGROUND = 6;
- }
-
- // Button pressed in the dialog
- optional Button button_pressed = 8;
-}
-
-/**
-* Information about a AppPermissionFragment viewed by user
-*/
-message AppPermissionFragmentViewed {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 3;
-
- // Permission group viewed
- optional string permission_group_name = 4;
-}
-
-/**
-* Information about a AppPermissionGroupsFragment viewed by user. Fragment has been renamed, but
-* the log retains the old fragment name.
-*/
-message AppPermissionsFragmentViewed {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // id which identifies single view as every view might have several logging records
- // with different package information attached
- optional int64 view_id = 2;
-
- // Permission group viewed
- optional string permission_group_name = 3;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 4 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 5;
-
- // Category in which permission is included
- enum Category {
- UNDEFINED = 0;
- ALLOWED = 1;
- ALLOWED_FOREGROUND = 2;
- DENIED = 3;
- }
- optional Category category = 6;
-}
-/**
-* Information about a PermissionAppsFragment viewed by user.
-* Logged from ui/handheld/PermissionAppsFragment.java
-*/
-message PermissionAppsFragmentViewed {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // id which identifies single view as every view might have several logging records
- // with different package information attached
- optional int64 view_id = 2;
-
- // Permission group viewed
- optional string permission_group_name = 3;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 4 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 5;
-
- // Category in which app is included
- enum Category {
- UNDEFINED = 0;
- ALLOWED = 1;
- ALLOWED_FOREGROUND = 2;
- DENIED = 3;
- }
- optional Category category = 6;
-}
-
-/**
-* Log that the Auto Revoke notification has been clicked
-* Logged from ui/ManagePermissionsActivity
-*/
-message AutoRevokeNotificationClicked {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-}
-
-/**
-* Log that an app has been displayed on the auto revoke page, and lists one permission that was
-* auto revoked for it.
-* Logged from ui/handheld/AutoRevokeFragment
-*/
-message AutoRevokeFragmentAppViewed {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 3;
-
- // The name of a permission group that has been revoked
- optional string permission_group_name = 4;
-
- // The age of the app- more than three months old, or more than six months
- enum Age {
- UNDEFINED = 0;
- NEWER_BUCKET = 1;
- OLDER_BUCKET = 2;
- }
-
- // How long the app has been unused. Currently, newer bucket is 3 months, older is 6 months
- optional Age age = 5;
-}
-
-/**
-* Log that the user has interacted with an app on the auto revoke fragment
-* Logged from ui/handheld/AutoRevokeFragment
-*/
-message AutoRevokedAppInteraction {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 3;
-
- enum Action {
- UNDEFINED = 0;
- REMOVE = 1;
- OPEN = 2;
- APP_INFO = 3;
- PERMISSIONS = 4;
- REMOVE_IN_SETTINGS = 5;
- OPEN_IN_SETTINGS = 6;
- }
-
- // The action the user took to interact with the app
- optional Action action = 4;
-}
-
-/**
-* Log that the AppPermissionGroupsFragment has been interacted with for the possible purposes of
-* auto revoke, or that the auto revoke switch has been changed
-* Logged from ui/handheld/AppPermissionGroupsFragment
- */
-message AppPermissionGroupsFragmentAutoRevokeAction {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 3;
-
- enum Action {
- UNDEFINED = 0;
- OPENED_FOR_AUTO_REVOKE = 1;
- OPENED_FROM_INTENT = 2;
- SWITCH_ENABLED = 3;
- SWITCH_DISABLED = 4;
- }
-
- // The action the user took to interact with the fragment
- optional Action action = 4;
-}
-
-/**
- * Logs when there is a smart selection related event.
- * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java
- * Logged from: TextClassifierEventLogger.java
- */
-message TextSelectionEvent {
- // A session ID.
- optional string session_id = 1;
-
- // Event type of this event.
- optional android.stats.textclassifier.EventType event_type = 2;
-
- // Name of the annotator model that is involved in this event.
- optional string model_name = 3;
-
- // Type of widget that was involved in triggering this event.
- optional android.stats.textclassifier.WidgetType widget_type = 4;
-
- // Index of this event in a session.
- optional int32 event_index = 5;
-
- // Entity type that is involved.
- optional string entity_type = 6;
-
- // Relative word index of the start of the selection.
- optional int32 relative_word_start_index = 7;
-
- // Relative word (exclusive) index of the end of the selection.
- optional int32 relative_word_end_index = 8;
-
- // Relative word index of the start of the smart selection.
- optional int32 relative_suggested_word_start_index = 9;
-
- // Relative word (exclusive) index of the end of the smart selection.
- optional int32 relative_suggested_word_end_index = 10;
-
- // Name of source package.
- optional string package_name = 11;
-
- // Name of the LangID model that is involved in this event.
- optional string langid_model_name = 12;
-}
-
-/**
- * Logs when there is a smart linkify related event.
- * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java
- * Logged from: TextClassifierEventLogger.java
- */
-message TextLinkifyEvent {
- // A session ID.
- optional string session_id = 1;
-
- // Event type of this event.
- optional android.stats.textclassifier.EventType event_type = 2;
-
- // Name of the annotator model that is involved in this event.
- optional string model_name = 3;
-
- // Type of widget that was involved in triggering this event.
- optional android.stats.textclassifier.WidgetType widget_type = 4;
-
- // Index of this event in a session.
- optional int32 event_index = 5;
-
- // Entity type that is involved.
- optional string entity_type = 6;
-
- // Number of links detected.
- optional int32 num_links = 7;
-
- // The total length of all links.
- optional int32 linked_text_length = 8;
-
- // Length of input text.
- optional int32 text_length = 9;
-
- // Time spent on generating links in ms.
- optional int64 latency_millis = 10;
-
- // Name of source package.
- optional string package_name = 11;
-
- // Name of the LangID model that is involved in this event.
- optional string langid_model_name = 12;
-}
-
-/**
- * Logs when there is a conversation actions related event.
- * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java
- * Logged from: TextClassifierEventLogger.java
- */
-message ConversationActionsEvent {
- // A session ID.
- optional string session_id = 1;
-
- // Event type of this event.
- optional android.stats.textclassifier.EventType event_type = 2;
-
- // Name of the actions model that is involved in this event.
- optional string model_name = 3;
-
- // Type of widget that was involved in triggering this event.
- optional android.stats.textclassifier.WidgetType widget_type = 4;
-
- // The first entity type that is involved.
- optional string first_entity_type = 5;
-
- // The second entity type that is involved.
- optional string second_entity_type = 6;
-
- // The third entity type that is involved.
- optional string third_entity_type = 7;
-
- // The score of the first entity type.
- optional float score = 8;
-
- // Name of source package.
- optional string package_name = 9;
-
- // Name of the annotator model that is involved in this event.
- optional string annotator_model_name = 10;
-
- // Name of the LangID model that is involved in this event.
- optional string langid_model_name = 11;
-}
-
-/**
- * Logs when there is a language detection related event.
- * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java
- * Logged from: TextClassifierEventLogger.java
- */
-message LanguageDetectionEvent {
- // A session ID.
- optional string session_id = 1;
-
- // Event type of this event.
- optional android.stats.textclassifier.EventType event_type = 2;
-
- // Name of the language detection model that is involved in this event.
- optional string model_name = 3;
-
- // Type of widget that was involved in triggering this event.
- optional android.stats.textclassifier.WidgetType widget_type = 4;
-
- // Detected language.
- optional string language_tag = 5;
-
- // Score of the detected language.
- optional float score = 6;
-
- // Position of this action.
- optional int32 action_index = 7;
-
- // Name of source package.
- optional string package_name = 8;
-}
-
-/**
- * Information about an OTA update attempt by update_engine.
- * Logged from platform/system/update_engine/metrics_reporter_android.cc
- */
-message UpdateEngineUpdateAttemptReported {
- // The number of attempts for the update engine to apply a given payload.
- optional int32 attempt_number = 1;
-
- optional android.stats.otaupdate.PayloadType payload_type = 2;
-
- // The total time in minutes for the update engine to apply a given payload.
- // The time is calculated by calling clock_gettime() / CLOCK_BOOTTIME; and
- // it's increased when the system is sleeping.
- optional int32 duration_boottime_in_minutes = 3;
-
- // The total time in minutes for the update engine to apply a given payload.
- // The time is calculated by calling clock_gettime() / CLOCK_MONOTONIC_RAW;
- // and it's not increased when the system is sleeping.
- optional int32 duration_monotonic_in_minutes = 4;
-
- // The size of the payload in MiBs.
- optional int32 payload_size_mib = 5;
-
- // The attempt result reported by the update engine for an OTA update.
- optional android.stats.otaupdate.AttemptResult attempt_result = 6;
-
- // The error code reported by the update engine after an OTA update attempt
- // on A/B devices.
- optional android.stats.otaupdate.ErrorCode error_code = 7;
-
- // The build fingerprint of the source system. The value is read from a
- // system property when the device takes the update. e.g.
- // Android/aosp_sailfish/sailfish:10/QP1A.190425.004/5507117:userdebug/test-keys
- optional string source_fingerprint = 8;
-
- // Size of super partition.
- optional int64 super_partition_size_bytes = 9;
-
- // Size of current slot within the super partition.
- optional int64 slot_size_bytes = 10;
-
- // Free space available in the super partition.
- optional int64 super_free_space_bytes = 11;
-}
-
-/**
- * Information about all the attempts the device make before finishing the
- * successful update.
- * Logged from platform/system/update_engine/metrics_reporter_android.cc
- */
-message UpdateEngineSuccessfulUpdateReported {
- // The number of attempts for the update engine to apply the payload for a
- // successful update.
- optional int32 attempt_count = 1;
-
- optional android.stats.otaupdate.PayloadType payload_type = 2;
-
- optional int32 payload_size_mib = 3;
-
- // The total number of bytes downloaded by update_engine since the last
- // successful update.
- optional int32 total_bytes_downloaded_mib = 4;
-
- // The ratio in percentage of the over-downloaded bytes compared to the
- // total bytes needed to successfully install the update. e.g. 200 if we
- // download 200MiB in total for a 100MiB package.
- optional int32 download_overhead_percentage = 5;
-
- // The total time in minutes for the update engine to apply the payload for a
- // successful update.
- optional int32 total_duration_minutes = 6;
-
- // The number of reboot of the device during a successful update.
- optional int32 reboot_count = 7;
-}
-
-/**
- * Reported when the RebootEscrow HAL has attempted to recover the escrowed
- * key to indicate whether it was successful or not.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
- */
-message RebootEscrowRecoveryReported {
- optional bool successful = 1;
-}
-
-/**
- * Global display pipeline metrics reported by SurfaceFlinger.
- * Pulled from:
- * frameworks/native/services/surfaceflinger/TimeStats/TimeStats.cpp
- */
-message SurfaceflingerStatsGlobalInfo {
- // Total number of frames presented during the tracing period
- optional int64 total_frames = 1;
- // Total number of frames missed
- optional int64 missed_frames = 2;
- // Total number of frames that fell back to client composition
- optional int64 client_composition_frames = 3;
- // Total time the display was turned on
- optional int64 display_on_millis = 4;
- // Total time that was spent performing animations.
- // This is derived from the present-to-present layer histogram
- optional int64 animation_millis = 5;
- // Total number of event connections tracked by SurfaceFlinger at the time
- // of this pull. If this number grows prohibitively large, then this can
- // cause jank due to resource contention.
- optional int32 event_connection_count = 6;
- // Set of timings measured from when SurfaceFlinger began compositing a
- // frame, until the frame was requested to be presented to the display. This
- // measures SurfaceFlinger's total CPU walltime on the critical path per
- // frame.
- optional FrameTimingHistogram frame_duration = 7
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from when SurfaceFlinger first began using the
- // GPU to composite a frame, until the GPU has finished compositing that
- // frame. This measures the total additional time SurfaceFlinger needed to
- // perform due to falling back into GPU composition.
- optional FrameTimingHistogram render_engine_timing = 8
- [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Per-layer display pipeline metrics reported by SurfaceFlinger.
- * The number of layers uploaded will be restricted due to size limitations.
- * Pulled from:
- * frameworks/native/services/surfaceflinger/TimeStats/TimeStats.cpp
- */
-message SurfaceflingerStatsLayerInfo {
- // The layer for this set of metrics
- // For now we can infer that the package name is included in the layer
- // name.
- optional string layer_name = 1;
- // Total number of frames presented
- optional int64 total_frames = 2;
- // Total number of dropped frames while latching a buffer for this layer.
- optional int64 dropped_frames = 3;
- // Set of timings measured between successive presentation timestamps.
- optional FrameTimingHistogram present_to_present = 4
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from when an app queued a buffer for
- // presentation, until the buffer was actually presented to the
- // display.
- optional FrameTimingHistogram post_to_present = 5
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from when a buffer is ready to be presented,
- // until the buffer was actually presented to the display.
- optional FrameTimingHistogram acquire_to_present = 6
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from when a buffer was latched by
- // SurfaceFlinger, until the buffer was presented to the display
- optional FrameTimingHistogram latch_to_present = 7
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from the desired presentation to the actual
- // presentation time
- optional FrameTimingHistogram desired_to_present = 8
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from when an app queued a buffer for
- // presentation, until the buffer was ready to be presented.
- optional FrameTimingHistogram post_to_acquire = 9
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Frames missed latch because the acquire fence didn't fire
- optional int64 late_acquire_frames = 10;
- // Frames latched early because the desired present time was bad
- optional int64 bad_desired_present_frames = 11;
-}
-
-/**
- * Histogram of frame counts bucketed by time in milliseconds.
- * Because of size limitations, we hard-cap the number of buckets, with
- * buckets for corresponding to larger milliseconds being less precise.
- */
-message FrameTimingHistogram {
- // Timings in milliseconds that describes a set of histogram buckets
- repeated int32 time_millis_buckets = 1;
- // Number of frames that match to each time_millis, i.e. the bucket
- // contents
- // It's required that len(time_millis) == len(frame_count)
- repeated int64 frame_counts = 2;
-}
-
-/**
- * Janky event as reported by SurfaceFlinger.
- * This event is intended to be consumed by a Perfetto subscriber for
- * automated trace collection.
- *
- * Logged from:
- * frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
- */
-message DisplayJankReported {
- // Informational field for how long the janky event lasted in milliseconds
- optional int64 event_duration_millis = 1;
- // Number of frame deadlines missed, where SurfaceFlinger failed to update
- // the display on time.
- optional int32 present_deadlines_missed = 2;
-}
-
-/**
- * Information about camera facing and API level usage.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/camera/CameraServiceProxy.java
- */
-message CameraActionEvent {
- // Camera session duration
- optional int64 duration_millis = 1;
-
- // Camera API level used
- optional int32 api_level = 2;
-
- // Name of client package
- optional string package_name = 3;
-
- // Camera facing
- enum Facing {
- UNKNOWN = 0;
- BACK = 1;
- FRONT = 2;
- EXTERNAL = 3;
- }
- optional Facing facing = 4;
-}
-
-/**
- * Logs when a compatibility change is affecting an app.
- *
- * Logged from:
- * frameworks/base/core/java/android/app/AppCompatCallbacks.java and
- * frameworks/base/services/core/java/com/android/server/compat/PlatformCompat.java
- */
-message AppCompatibilityChangeReported {
- // The UID of the app being affected by the compatibilty change.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The ID of the change affecting the app.
- optional int64 change_id = 2;
-
- enum State {
- UNKNOWN_STATE = 0;
- ENABLED = 1;
- DISABLED = 2;
- LOGGED = 3;
- }
-
- // The state of the change - if logged from gating whether it was enabled or disabled, or just
- // logged otherwise.
- optional State state = 3;
-
- enum Source {
- UNKNOWN_SOURCE = 0;
- APP_PROCESS = 1;
- SYSTEM_SERVER = 2;
- }
-
- // Where it was logged from.
- optional Source source = 4;
-
-}
-
-/**
- * Logged from
- * external/perfetto/src/perfetto_cmd/perfetto_cmd.cc
- */
-message PerfettoUploaded {
- enum Event {
- PERFETTO_UNDEFINED = 0;
- PERFETTO_TRACE_BEGIN = 1;
- PERFETTO_BACKGROUND_TRACE_BEGIN = 2;
- PERFETTO_ON_CONNECT = 3;
- PERFETTO_ON_TRACING_DISABLED = 4;
- PERFETTO_UPLOAD_DROPBOX_BEGIN = 5;
- PERFETTO_UPLOAD_DROPBOX_SUCCESS = 6;
- PERFETTO_UPLOAD_DROPBOX_FAILURE = 7;
- PERFETTO_UPLOAD_INCIDENT_BEGIN = 8;
- PERFETTO_UPLOAD_INCIDENT_SUCCESS = 9;
- PERFETTO_UPLOAD_INCIDENT_FAILURE = 10;
- PERFETTO_FINALIZE_TRACE_AND_EXIT = 11;
- PERFETTO_TRIGGER_BEGIN = 12;
- PERFETTO_TRIGGER_SUCCESS = 13;
- PERFETTO_TRIGGER_FAILURE = 14;
- PERFETTO_HIT_GUARDRAILS = 15;
- PERFETTO_ON_TIMEOUT = 16;
- PERFETTO_NOT_UPLOADING_EMPTY_TRACE = 17;
- }
-
- // Which stage of the pipeline we are reporting from.
- optional Event event = 1;
-
- // UUID matching the one set inside the SystemInfo trace packet.
- optional int64 trace_uuid_lsb = 2;
- optional int64 trace_uuid_msb = 3;
-}
-
-/**
- * Pulls client metrics on data transferred via Vehicle Maps Service.
- * Metrics are keyed by uid + layer.
- *
- * Pulled from:
- * packages/services/Car/service/src/com/android/car/stats/CarStatsService.java
- */
-message VmsClientStats {
- // UID of the VMS client app
- optional int32 uid = 1 [(is_uid) = true];
-
- // VMS layer definition
- optional int32 layer_type = 2;
- optional int32 layer_channel = 3;
- optional int32 layer_version = 4;
-
- // Bytes and packets sent by the client for the layer
- optional int64 tx_bytes = 5;
- optional int64 tx_packets = 6;
-
- // Bytes and packets received by the client for the layer
- optional int64 rx_bytes = 7;
- optional int64 rx_packets = 8;
-
- // Bytes and packets dropped due to client error
- optional int64 dropped_bytes = 9;
- optional int64 dropped_packets = 10;
-}
-
-/**
- * State of a dangerous permission requested by a package - sampled
- * Pulled from: StatsCompanionService.java with data obtained from PackageManager API
-*/
-message DangerousPermissionStateSampled {
- // Name of the permission
- optional string permission_name = 1;
-
- // Uid of the package
- optional int32 uid = 2 [(is_uid) = true];
-
- // If the permission is granted to the uid
- optional bool is_granted = 3;
-
- // Permission flags as per android.content.pm.PermissionFlags
- optional int32 permission_flags = 4;
-}
-
-/**
- * HWUI stats for a given app.
- */
-message GraphicsStats {
- // The package name of the app
- optional string package_name = 1;
-
- // The version code of the app
- optional int64 version_code = 2;
-
- // The start & end timestamps in UTC as
- // milliseconds since January 1, 1970
- // Compatible with java.util.Date#setTime()
- optional int64 start_millis = 3;
-
- optional int64 end_millis = 4;
-
- // HWUI renders pipeline type: GL (1) or Vulkan (2).
- enum PipelineType {
- UNKNOWN = 0;
- GL = 1;
- VULKAN = 2;
- }
-
- // HWUI renders pipeline type: GL or Vulkan.
- optional PipelineType pipeline = 5;
-
- // Distinct frame count.
- optional int32 total_frames = 6;
-
- // Number of "missed vsync" events.
- optional int32 missed_vsync_count = 7;
-
- // Number of frames in triple-buffering scenario (high input latency)
- optional int32 high_input_latency_count = 8;
-
- // Number of "slow UI thread" events.
- optional int32 slow_ui_thread_count = 9;
-
- // Number of "slow bitmap upload" events.
- optional int32 slow_bitmap_upload_count = 10;
-
- // Number of "slow draw" events.
- optional int32 slow_draw_count = 11;
-
- // Number of frames that missed their deadline (aka, visibly janked)
- optional int32 missed_deadline_count = 12;
-
- // The frame time histogram for the package
- optional FrameTimingHistogram cpu_histogram = 13
- [(android.os.statsd.log_mode) = MODE_BYTES];
-
- // The gpu frame time histogram for the package
- optional FrameTimingHistogram gpu_histogram = 14
- [(android.os.statsd.log_mode) = MODE_BYTES];
-
- // UI mainline module version.
- optional int64 version_ui_module = 15;
-
- // If true, these are HWUI stats for up to a 24h period for a given app from today.
- // If false, these are HWUI stats for a 24h period for a given app from the last complete
- // day (yesterday). Stats from yesterday stay constant, while stats from today may change as
- // more apps are running / rendering.
- optional bool is_today = 16;
-}
-
-/**
- * Message related to dangerous (runtime) app ops access
- */
-message RuntimeAppOpAccess {
- // Uid of the package accessing app op
- optional int32 uid = 1 [(is_uid) = true];
-
- // Name of the package accessing app op
- optional string package_name = 2;
-
- // deprecated - set to empty string
- optional string op_deprecated = 3 [deprecated = true];
-
- // attribution_tag; provided by developer when accessing related API, limited at 50 chars by
- // API. Attributions must be provided through manifest using <attribution> tag available in R
- // and above.
- optional string attribution_tag = 4;
-
- // message related to app op access, limited to 600 chars by API
- optional string message = 5;
-
- enum SamplingStrategy {
- DEFAULT = 0;
- UNIFORM = 1;
- RARELY_USED = 2;
- BOOT_TIME_SAMPLING = 3;
- UNIFORM_OPS = 4;
- }
-
- // sampling strategy used to collect this message
- optional SamplingStrategy sampling_strategy = 6;
-
- // operation id
- optional android.app.AppOpEnum op = 7 [default = APP_OP_NONE];
-}
-
-/*
- * Logs userspace reboot outcome and duration.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/server/BootReceiver.java
- */
-message UserspaceRebootReported {
- // Possible outcomes of userspace reboot.
- enum Outcome {
- // Default value in case platform failed to determine the outcome.
- OUTCOME_UNKNOWN = 0;
- // Userspace reboot succeeded (i.e. boot completed without a fall back to hard reboot).
- SUCCESS = 1;
- // Userspace reboot shutdown sequence was aborted.
- FAILED_SHUTDOWN_SEQUENCE_ABORTED = 2;
- // Remounting userdata into checkpointing mode failed.
- FAILED_USERDATA_REMOUNT = 3;
- // Device didn't finish booting before timeout and userspace reboot watchdog issued a hard
- // reboot.
- FAILED_USERSPACE_REBOOT_WATCHDOG_TRIGGERED = 4;
- }
- // Outcome of userspace reboot. Always set.
- optional Outcome outcome = 1;
- // Duration of userspace reboot in case it has a successful outcome.
- // Duration is measured as time between userspace reboot was initiated and until boot completed
- // (e.g. sys.boot_completed=1).
- optional int64 duration_millis = 2;
- // State of primary user's (user0) credential encryption storage.
- enum UserEncryptionState {
- // Default value.
- USER_ENCRYPTION_STATE_UNKNOWN = 0;
- // Credential encrypted storage is unlocked.
- UNLOCKED = 1;
- // Credential encrypted storage is locked.
- LOCKED = 2;
- }
- // State of primary user's encryption storage at the moment boot completed. Always set.
- optional UserEncryptionState user_encryption_state = 3;
-}
-
-/*
- * Logs integrity check information during each install.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
- */
-message IntegrityCheckResultReported {
- optional string package_name = 1;
- optional string app_certificate_hash = 2;
- optional int64 version_code = 3;
- optional string installer_package_name = 4;
- enum Response {
- UNKNOWN = 0;
- ALLOWED = 1;
- REJECTED = 2;
- FORCE_ALLOWED = 3;
- }
- optional Response response = 5;
- // An estimate on the cause of the response. This will only be populated for
- // REJECTED and FORCE_ALLOWED
- optional bool caused_by_app_cert_rule = 6;
- optional bool caused_by_installer_rule = 7;
-}
-
-/**
- * Logs the information about the rules and the provider whenever rules are
- * pushed into AppIntegrityManager.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
- */
-message IntegrityRulesPushed {
- optional bool success = 1;
- // Package name of the app that pushed the rules.
- optional string rule_provider = 2;
- // Version string of arbitrary format provided by the rule provider to
- // identify the rules.
- optional string rule_version = 3;
-}
-
-/**
- * Logs when a cell broadcast message is received on the device.
- *
- * Logged from Cell Broadcast module and platform:
- * packages/modules/CellBroadcastService/src/com/android/cellbroadcastservice/
- * packages/apps/CellBroadcastReceiver/
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java
- */
-message CellBroadcastMessageReported {
- // The type of Cell Broadcast message
- enum CbType {
- UNKNOWN_TYPE = 0;
- GSM = 1;
- CDMA = 2;
- CDMA_SPC = 3;
- }
-
- // The parts of the cell broadcast message pipeline
- enum ReportSource {
- UNKNOWN_SOURCE = 0;
- FRAMEWORK = 1;
- CB_SERVICE = 2;
- CB_RECEIVER_APP = 3;
- }
-
- // GSM, CDMA, CDMA-SCP
- optional CbType type = 1;
-
- // The source of the report
- optional ReportSource source = 2;
-}
-
-/**
- * Logs when a cell broadcast message is filtered out, or otherwise intentionally not sent to CBR.
- *
- * Logged from CellBroadcastService module:
- * packages/modules/CellBroadcastService/src/com/android/cellbroadcastservice/
- */
-message CellBroadcastMessageFiltered {
- enum FilterReason {
- NOT_FILTERED = 0;
- DUPLICATE_MESSAGE = 1;
- GEOFENCED_MESSAGE = 2;
- AREA_INFO_MESSAGE = 3;
- }
-
- // GSM, CDMA, CDMA-SCP
- optional CellBroadcastMessageReported.CbType type = 1;
-
- // The source of the report
- optional FilterReason filter = 2;
-}
-
-/**
- * Logs when an error occurs while handling a cell broadcast message;
- *
- * Logged from CellBroadcastService module:
- * packages/modules/CellBroadcastService/src/com/android/cellbroadcastservice/
- */
-message CellBroadcastMessageError {
- // The type of error raised when trying to handle a cell broadcast message
- enum ErrorType {
- UNKNOWN_TYPE = 0;
- CDMA_DECODING_ERROR = 1;
- CDMA_SCP_EMPTY = 2;
- CDMA_SCP_HANDLING_ERROR = 3;
- GSM_INVALID_HEADER_LENGTH = 4;
- GSM_UNSUPPORTED_HEADER_MESSAGE_TYPE = 5;
- GSM_UNSUPPORTED_HEADER_DATA_CODING_SCHEME = 6;
- GSM_INVALID_PDU = 7;
- GSM_INVALID_GEO_FENCING_DATA = 8;
- GSM_UMTS_INVALID_WAC = 9;
- FAILED_TO_INSERT_TO_DB = 10;
- UNEXPECTED_GEOMETRY_FROM_FWK = 11;
- UNEXPECTED_GSM_MESSAGE_TYPE_FROM_FWK = 12;
- UNEXPECTED_CDMA_MESSAGE_TYPE_FROM_FWK = 13;
- UNEXPECTED_CDMA_SCP_MESSAGE_TYPE_FROM_FWK = 14;
- NO_CONNECTION_TO_CB_SERVICE = 15;
- }
-
- // What kind of error occurred
- optional ErrorType type = 1;
-
- // Exception message (or log message) associated with the error (max 1000 chars)
- optional string exception_message = 2;
-}
-
-/**
- * Logs when a tune occurs through device's Frontend.
- * This is atom ID 276.
- *
- * Logged from:
- * frameworks/base/media/java/android/media/tv/tuner/Tuner.java
- */
-message TvTunerStateChanged {
- enum State {
- UNKNOWN = 0;
- TUNING = 1; // Signal is tuned
- LOCKED = 2; // the signal is locked
- NOT_LOCKED = 3; // the signal isn’t locked.
- SIGNAL_LOST = 4; // the signal was locked, but is lost now.
- SCANNING = 5; // the signal is scanned
- SCAN_STOPPED = 6; // the scan is stopped.
- }
- // The uid of the application that sent this custom atom.
- optional int32 uid = 1 [(is_uid) = true];
- // new state
- optional State state = 2;
-}
-
-/**
- * Logs the status of a dvr playback or record.
- * This is atom ID 279.
- *
- * Logged from:
- * frameworks/base/media/java/android/media/tv/tuner/dvr
- */
-message TvTunerDvrStatus {
- enum Type {
- UNKNOWN_TYPE = 0;
- PLAYBACK = 1; // is a playback
- RECORD = 2; // is a record
- }
- enum State {
- UNKNOWN_STATE = 0;
- STARTED = 1; // DVR is started
- STOPPED = 2; // DVR is stopped
- }
- // The uid of the application that sent this custom atom.
- optional int32 uid = 1 [(is_uid) = true];
- // DVR type
- optional Type type = 2;
- // DVR state
- optional State state = 3;
- // Identify the segment of a record or playback
- optional int32 segment_id = 4;
- // indicate how many overflow or underflow happened between started to stopped
- optional int32 overflow_underflow_count = 5;
-}
-
-/**
- * Logs when a cas session opened through MediaCas.
- * This is atom ID 280.
- *
- * Logged from:
- * frameworks/base/media/java/android/media/MediaCas.java
- */
-message TvCasSessionOpenStatus {
- enum State {
- UNKNOWN = 0;
- SUCCEEDED = 1; // indicate that the session is opened successfully.
- FAILED = 2; // indicate that the session isn’t opened successfully.
- }
- // The uid of the application that sent this custom atom.
- optional int32 uid = 1 [(is_uid) = true];
- // Cas system Id
- optional int32 cas_system_id = 2;
- // State of the session
- optional State state = 3;
-}
-
-/**
- * Logs for ContactsProvider general usage.
- * This is atom ID 301.
- *
- * Logged from:
- * packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java
- */
-message ContactsProviderStatusReported {
- enum ApiType {
- UNKNOWN_API = 0;
- QUERY = 1;
- // INSERT includes insert and bulkInsert, and inserts triggered by applyBatch.
- INSERT = 2;
- // UPDATE and DELETE includes update/delete and the ones triggered by applyBatch.
- UPDATE = 3;
- DELETE = 4;
- }
-
- enum ResultType {
- UNKNOWN_RESULT = 0;
- SUCCESS = 1;
- FAIL = 2;
- ILLEGAL_ARGUMENT = 3;
- UNSUPPORTED_OPERATION = 4;
- }
-
- enum CallerType {
- UNSPECIFIED_CALLER_TYPE = 0;
- CALLER_IS_SYNC_ADAPTER = 1;
- CALLER_IS_NOT_SYNC_ADAPTER = 2;
- }
-
- optional ApiType api_type = 1;
- // Defined in
- // packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java
- optional int32 uri_type = 2;
- optional CallerType caller_type = 3;
- optional ResultType result_type = 4;
- optional int32 result_count = 5;
- optional int64 latency_micros = 6;
-}
-
-/**
- * Logs when an app is frozen or unfrozen.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/CachedAppOptimizer.java
- */
-message AppFreezeChanged {
- // The type of event.
- enum Action {
- UNKNOWN = 0;
- FREEZE_APP = 1;
- UNFREEZE_APP = 2;
- }
- optional Action action = 1;
-
- // Pid of the process being frozen.
- optional int32 pid = 2;
-
- // Name of the process being frozen.
- optional string process_name = 3;
-
- // Time since last unfrozen.
- optional int64 time_unfrozen_millis = 4;
-}
-
-/**
- * Pulls information for a single voice call.
- *
- * Each pull creates multiple atoms, one for each call. The sequence is randomized when pulled.
- *
- * Pulled from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
- */
-message VoiceCallSession {
- // Bearer (IMS or CS) when the call started.
- optional android.telephony.CallBearerEnum bearer_at_start = 1;
-
- // Bearer (IMS or CS) when the call ended.
- // The bearer may change during the call, e.g. due to SRVCC.
- optional android.telephony.CallBearerEnum bearer_at_end = 2;
-
- // Direction of the call (incoming or outgoing).
- optional android.telephony.CallDirectionEnum direction = 3;
-
- // Time spent setting up the call.
- optional android.telephony.CallSetupDurationEnum setup_duration = 4;
-
- // Whether the call ended before the setup was completed.
- optional bool setup_failed = 5;
-
- // IMS reason code or CS disconnect cause.
- // For IMS, see: frameworks/base/telephony/java/android/telephony/ims/ImsReasonInfo.java
- // For CS, see: frameworks/base/telephony/java/android/telephony/DisconnectCause.java
- optional int32 disconnect_reason_code = 6;
-
- // IMS extra code or CS precise disconnect cause.
- // For IMS, this code is vendor-specific
- // For CS, see: frameworks/base/telephony/java/android/telephony/PreciseDisconnectCause.java
- optional int32 disconnect_extra_code = 7;
-
- // IMS extra message or CS vendor cause.
- optional string disconnect_extra_message = 8;
-
- // Radio access technology (RAT) used when call started.
- optional android.telephony.NetworkTypeEnum rat_at_start = 9;
-
- // Radio access technology (RAT) used when call terminated.
- optional android.telephony.NetworkTypeEnum rat_at_end = 10;
-
- // Number of times RAT changed during the call.
- optional int64 rat_switch_count = 11;
-
- // A bitmask of all codecs used during the call.
- // See: frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
- optional int64 codec_bitmask = 12;
-
- // Number of other calls going on during call setup, for the same SIM slot.
- optional int32 concurrent_call_count_at_start = 13;
-
- // Number of other calls going on during call termination, for the same SIM slot.
- optional int32 concurrent_call_count_at_end = 14;
-
- // Index of the SIM is used, 0 for single-SIM devices.
- optional int32 sim_slot_index = 15;
-
- // Whether the device was in multi-SIM mode (with multiple active SIM profiles).
- optional bool is_multi_sim = 16;
-
- // Whether the call was made with an eSIM profile.
- optional bool is_esim = 17;
-
- // Carrier ID of the SIM card.
- // See https://source.android.com/devices/tech/config/carrierid.
- optional int32 carrier_id = 18;
-
- // Whether an SRVCC has been completed successfully for this call.
- optional bool srvcc_completed = 19;
-
- // Number of SRVCC failures.
- optional int64 srvcc_failure_count = 20;
-
- // Number of SRVCC cancellations.
- optional int64 srvcc_cancellation_count = 21;
-
- // Whether the Real-Time Text (RTT) was ever used in the call (rather than whether RTT was
- // enabled in the dialer's settings).
- optional bool rtt_enabled = 22;
-
- // Whether this was an emergency call.
- optional bool is_emergency = 23;
-
- // Whether the call was performed while roaming.
- optional bool is_roaming = 24;
-
- // A random number used as the dimension field to pull multiple atoms.
- optional int32 dimension = 25;
-}
-
-/**
- * Pulls voice call radio access technology (RAT) usage.
- *
- * Each pull creates multiple atoms, one for each carrier/RAT, the order of which is irrelevant to
- * time. The atom will be skipped if not enough data is available.
- *
- * Pulled from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
- */
-message VoiceCallRatUsage {
- // Carrier ID (https://source.android.com/devices/tech/config/carrierid).
- optional int32 carrier_id = 1;
-
- // Radio access technology.
- optional android.telephony.NetworkTypeEnum rat = 2;
-
- // Total duration that voice calls spent on this carrier and RAT.
- optional int64 total_duration_seconds = 3;
-
- // Total number of calls using this carrier and RAT.
- // A call is counted once even if it used the RAT multiple times.
- optional int64 call_count = 4;
-}
-
-/**
- * Pulls the number of active SIM slots and SIMs/eSIM profiles.
- *
- * Pulled from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
- */
-message SimSlotState {
- // Number of active SIM slots (both physical and eSIM profiles) in the device.
- optional int32 active_slot_count = 1;
-
- // Number of SIM cards (both physical and active eSIM profiles).
- // This number is always equal to or less than the number of active SIM slots.
- optional int32 sim_count = 2;
-
- // Number of active eSIM profiles.
- // This number is always equal to or less than the number of SIMs.
- optional int32 esim_count = 3;
-}
-
-/**
- * Pulls supported cellular radio access technologies.
- *
- * This atom reports the capabilities of the device, rather than the network it has access to.
- *
- * Pulled from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
- */
-message SupportedRadioAccessFamily {
- // A bitmask of supported radio technologies.
- // See android.telephony.TelephonyManager.NetworkTypeBitMask.
- optional int64 network_type_bitmask = 1;
-}
-
-/**
- * Logs gnss stats from location service provider
- *
- * Pulled from:
- * frameworks/base/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
- */
-
-message GnssStats {
- // Number of location reports since boot
- optional int64 location_reports = 1;
-
- // Total pulled reports of Location failures since boot
- optional int64 location_failure_reports = 2;
-
- // Number of time to first fix reports since boot
- optional int64 time_to_first_fix_reports = 3;
-
- // Total pulled reported time to first fix (in milli-seconds) since boot
- optional int64 time_to_first_fix_millis = 4;
-
- // Number of position accuracy reports since boot
- optional int64 position_accuracy_reports = 5;
-
- // Total pulled reported position accuracy (in meters) since boot
- optional int64 position_accuracy_meters = 6;
-
- // Number of top 4 average CN0 reports since boot
- optional int64 top_four_average_cn0_reports = 7;
-
- // Total pulled reported of top 4 average CN0 (dB-mHz) since boot
- optional int64 top_four_average_cn0_db_mhz = 8;
-
- // Number of l5 top 4 average CN0 reports since boot
- optional int64 l5_top_four_average_cn0_reports = 9;
-
- // Total pulled reported of l5 top 4 average CN0 (dB-mHz) since boot
- optional int64 l5_top_four_average_cn0_db_mhz = 10;
-
- // Total number of sv status messages reports since boot
- optional int64 sv_status_reports = 11;
-
- // Total number of sv status messages reports, where sv is used in fix since boot
- optional int64 sv_status_reports_used_in_fix = 12;
-
- // Total number of L5 sv status messages reports since boot
- optional int64 l5_sv_status_reports = 13;
-
- // Total number of L5 sv status messages reports, where sv is used in fix since boot
- optional int64 l5_sv_status_reports_used_in_fix = 14;
-}
-
-/**
- * Logs when an app is moved to a different standby bucket.
- *
- * Logged from:
- * frameworks/base/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
- */
-message AppStandbyBucketChanged {
- optional string package_name = 1;
-
- // Should be 0, 10, 11, 12, etc. where 0 is the owner. See UserHandle for more documentation.
- optional int32 user_id = 2;
-
- // These enum values match the constants defined in UsageStatsManager.java.
- enum Bucket {
- BUCKET_UNKNOWN = 0;
- BUCKET_EXEMPTED = 5;
- BUCKET_ACTIVE = 10;
- BUCKET_WORKING_SET = 20;
- BUCKET_FREQUENT = 30;
- BUCKET_RARE = 40;
- BUCKET_RESTRICTED = 45;
- BUCKET_NEVER = 50;
- }
- optional Bucket bucket = 3;
-
- enum MainReason {
- MAIN_UNKNOWN = 0;
- MAIN_DEFAULT = 0x0100;
- MAIN_TIMEOUT = 0x0200;
- MAIN_USAGE = 0x0300;
- MAIN_FORCED_BY_USER = 0x0400;
- MAIN_PREDICTED = 0x0500;
- MAIN_FORCED_BY_SYSTEM = 0x0600;
- }
- optional MainReason main_reason = 4;
-
- // A more detailed reason for the standby bucket change. The sub reason name is dependent on
- // the main reason. Values are one of the REASON_SUB_XXX constants defined in
- // UsageStatsManager.java.
- optional int32 sub_reason = 5;
-}
-
-/**
-* Reports a started sharesheet transaction.
-*
-* Logged from:
-* frameworks/base/core/java/com/android/internal/app/ChooserActivity.java
-*/
-message SharesheetStarted {
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
- // The calling app's package name.
- optional string package_name = 2;
- // An identifier to tie together multiple logs relating to the same share event
- optional int32 instance_id = 3;
- // The mime type of the share
- optional string mime_type = 4;
- // The number of direct targets the calling app is providing that will be shown.
- optional int32 num_app_provided_direct_targets = 5;
- // The number of app targets the calling app is providing that will be shown.
- optional int32 num_app_provided_app_targets = 6;
- // True if the share originates from the workprofile
- optional bool is_workprofile = 7;
-
- enum SharesheetPreviewType { // Constants from ChooserActivity.java
- CONTENT_PREVIEW_TYPE_UNKNOWN = 0; // Default for proto 2 / 3 compatibility.
- CONTENT_PREVIEW_IMAGE = 1; // The preview shown in the sharesheet is an image.
- CONTENT_PREVIEW_FILE = 2; // The preview shown in the sharesheet is a file.
- CONTENT_PREVIEW_TEXT = 3; // The preview shown in the sharesheet is text.
- }
- // How the sharesheet preview is presented.
- optional SharesheetPreviewType preview_type = 8;
-
- enum ResolverActivityIntent { // Intents handled by ResolverActivity.java
- INTENT_DEFAULT = 0;
- INTENT_ACTION_VIEW = 1;
- INTENT_ACTION_EDIT = 2;
- INTENT_ACTION_SEND = 3;
- INTENT_ACTION_SENDTO = 4;
- INTENT_ACTION_SEND_MULTIPLE = 5;
- INTENT_ACTION_IMAGE_CAPTURE = 6;
- INTENT_ACTION_MAIN = 7;
- }
- // The intent being processed (only SEND and SEND_MULTIPLE are system sharesheet)
- optional ResolverActivityIntent intent_type = 9;
-}
-
-/**
- * Reports a ranking selection event.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/app/ChooserActivity.java (sharesheet)
- */
-message RankingSelected {
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
- // The relevant app's package name (can be source or picked package).
- optional string package_name = 2;
- // An identifier to tie together multiple logs relating to the same share event.
- optional int32 instance_id = 3;
- // Which of the ranked targets got picked, default starting position 0.
- optional int32 position_picked = 4;
-}
-
-/**
- * Logs when TvSettings UI is interacted at.
- *
- * Logged from: packages/apps/TvSettings
- */
-message TvSettingsUIInteracted {
-
- /** The UI action category */
- optional android.app.tvsettings.Action action = 1;
-
- /** The ID of the entry that the users actioned on */
- optional android.app.tvsettings.ItemId item_id = 2;
-}
-
-/**
- * Logs information about a package installation using package installer V2 APIs.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/pm/PackageInstallerSession.java
- */
-message PackageInstallerV2Reported {
- // Whether this installation uses Incremental File System
- optional bool is_incremental = 1;
- // Name of the package that is intended to be installed
- optional string package_name = 2;
- // The duration between when the install was requested to when the install has completed
- optional int64 duration_millis = 3;
- // Installation result in final integer, which are SystemApi's.
- // Return_code 1 indicates success.
- // For full list, see frameworks/base/core/java/android/content/pm/PackageManager.java
- optional int32 return_code = 4;
- // Total size of the APKs installed for this package
- optional int64 apks_size_bytes = 5;
-}
-
-/**
- * Logs settings provider values.
- *
- * Use DeviceConfig.getProperties to get a list Setting key, query the data from content provider,
- * then write the value to proto.
- *
- */
-message SettingSnapshot {
-
- // Setting key
- optional string name = 1;
-
- enum SettingsValueType {
- NOTASSIGNED = 0;
- ASSIGNED_BOOL_TYPE = 1;
- ASSIGNED_INT_TYPE = 2;
- ASSIGNED_FLOAT_TYPE = 3;
- ASSIGNED_STRING_TYPE = 4;
- };
- // Setting value type
- optional SettingsValueType type = 2;
-
- optional bool bool_value = 3;
-
- optional int32 int_value = 4;
-
- optional float float_value = 5;
-
- optional string str_value = 6;
-
- // Android user index. 0 for primary user, 10, 11 for secondary or profile user
- optional int32 user_id = 7;
-}
-
-/**
- * An event logged to indicate that a user journey is about to be performed. This atom includes
- * relevant information about the users involved in the journey. A UserLifecycleEventOccurred event
- * will immediately follow this atom which will describe the event(s) and its state.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/UserController.java
- * frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java
- */
-message UserLifecycleJourneyReported {
- // An identifier to track a chain of user lifecycle events occurring (referenced in the
- // UserLifecycleEventOccurred atom)
- optional int64 session_id = 1;
-
- // Indicates what type of user journey this session is related to
- enum Journey {
- UNKNOWN = 0; // Undefined user lifecycle journey
- USER_SWITCH_UI = 1; // A user switch journey where a UI is shown
- USER_SWITCH_FG = 2; // A user switch journey without a UI shown
- USER_START = 3; // A user start journey
- USER_CREATE = 4; // A user creation journey
- }
- optional Journey journey = 2;
- // Which user the journey is originating from - could be -1 for certain phases (eg USER_CREATE)
- // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest)
- optional int32 origin_user = 3;
- // Which user the journey is targeting
- // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest)
- optional int32 target_user = 4;
-
- // What is the user type of the target user
- // These should be in sync with USER_TYPE_* flags defined in UserManager.java
- enum UserType {
- TYPE_UNKNOWN = 0;
- FULL_SYSTEM = 1;
- FULL_SECONDARY = 2;
- FULL_GUEST = 3;
- FULL_DEMO = 4;
- FULL_RESTRICTED = 5;
- PROFILE_MANAGED = 6;
- SYSTEM_HEADLESS = 7;
- }
- optional UserType user_type = 5;
- // What are the flags attached to the target user
- optional int32 user_flags = 6;
-}
-
-/**
- * An event logged when a specific user lifecycle event is performed. These events should be
- * correlated with a UserLifecycleJourneyReported atom via the session_id.
- * Note: journeys can span over multiple events, hence some events may share a single session id.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/UserController.java
- * frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java
- */
-message UserLifecycleEventOccurred {
- // An id which links back to user details (reported in the UserLifecycleJourneyReported atom)
- optional int64 session_id = 1;
- // The target user for this event (same as target_user in the UserLifecycleJourneyReported atom)
- // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest)
- optional int32 user_id = 2;
-
- enum Event {
- UNKNOWN = 0; // Indicates that the associated user journey timed-out or resulted in an error
- SWITCH_USER = 1; // Indicates that this is a user switch event
- START_USER = 2; // Indicates that this is a user start event
- CREATE_USER = 3; // Indicates that this is a user create event
- USER_RUNNING_LOCKED = 4; // Indicates that user is running in locked state
- UNLOCKING_USER = 5; // Indicates that this is a user unlocking event
- UNLOCKED_USER = 6; // Indicates that this is a user unlocked event
- }
- optional Event event = 3;
-
- enum State {
- NONE = 0; // Indicates the associated event has no start/end defined
- BEGIN = 1;
- FINISH = 2;
- }
- optional State state = 4; // Represents the state of an event (beginning/ending)
-}
-
-/**
- * Logs when accessibility shortcut clicked.
- *
- * Logged from:
- * frameworks/base/services/accessibility/java/com/android/server/accessibility
- */
-message AccessibilityShortcutReported {
- // The accessibility feature(including installed a11y service, framework a11y feature,
- // and installed a11y activity) package name that is assigned to the accessibility shortcut.
- optional string package_name = 1;
-
- // The definition of the accessibility shortcut.
- // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto.
- optional android.stats.accessibility.ShortcutType shortcut_type = 2;
-
- // The definition of the service status.
- // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto.
- optional android.stats.accessibility.ServiceStatus service_status = 3;
-}
-
-/**
- * Logs when accessibility service status changed.
- *
- * Logged from:
- * packages/apps/Settings/src/com/android/settings/accessibility
- */
-message AccessibilityServiceReported {
- // The accessibility service package name.
- optional string package_name = 1;
-
- // The definition of the service status.
- // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto.
- optional android.stats.accessibility.ServiceStatus service_status = 2;
-}
-
-/**
- * Logs when display wake up.
- *
- * Logged from:
- * services/core/java/com/android/server/power/Notifier.java
- */
-
-message DisplayWakeReported {
- // Wake_up_reason code
- // If LOWORD(wake_up_reason) = 0
- // reference to HIWORD(wake_up_reason) PowerManager.WAKE_REASON_XXX
- // else reference wake_up_reason to
- // services/core/java/com/android/server/power/Notifier.java#onWakeUp
- optional int32 wake_up_reason = 1;
-}
-
-/**
- * Logs app usage events.
- */
-message AppUsageEventOccurred {
- optional int32 uid = 1 [(is_uid) = true];
- optional string package_name = 2;
- optional string class_name = 3;
-
- enum EventType {
- NONE = 0;
- MOVE_TO_FOREGROUND = 1;
- MOVE_TO_BACKGROUND = 2;
- }
- optional EventType event_type = 4;
-}
-
-/*
- * Quality metrics logged when EVS cameras are active.
- *
- * Logged from:
- * packages/services/Car/evs/manager/1.1/Enumerator.cpp
- */
-message EvsUsageStatsReported {
-
- // Camera identifier to distinguish the source camera device. This is not
- // globally unique and therefore cannot be used to identify the user and/or
- // the device.
- optional int32 device_id = 1;
-
- // Peak number of clients during the service
- optional int32 peak_num_clients = 2;
-
- // Number of erroneous events during the service
- optional int32 num_errors = 3;
-
- // Round trip latency of the very first frame
- optional int64 first_latency_millis = 4;
-
- // Average frame round trip latency
- optional float avg_latency_millis = 5;
-
- // Peak frame round trip latency
- optional int64 peak_latency_millis = 6;
-
- // Total number of frames received
- optional int64 total_frames = 7;
-
- // Number of frames ignored
- optional int64 ignored_frames = 8;
-
- // Number of dropped frames to synchronize camera devices
- optional int64 dropped_frames_to_sync = 9;
-
- // The duration of the service
- optional int64 duration_millis = 10;
-}
-
-/**
- * Logs audio power usage stats.
- *
- * Pushed from:
- * frameworks/av/services/mediametrics/AudioPowerUsage.cpp
- */
-message AudioPowerUsageDataReported {
- /**
- * Device used for input/output
- *
- * All audio devices please refer to below file:
- * system/media/audio/include/system/audio-base.h
- *
- * Define our own enum values because we don't report all audio devices.
- * Currently, we only report built-in audio devices such as handset, speaker,
- * built-in mics, common audio devices such as wired headset, usb headset
- * and bluetooth devices.
- */
- enum AudioDevice {
- OUTPUT_EARPIECE = 0x1; // handset
- OUTPUT_SPEAKER = 0x2; // dual speaker
- OUTPUT_WIRED_HEADSET = 0x4; // 3.5mm headset
- OUTPUT_USB_HEADSET = 0x8; // usb headset
- OUTPUT_BLUETOOTH_SCO = 0x10; // bluetooth sco
- OUTPUT_BLUETOOTH_A2DP = 0x20; // a2dp
- OUTPUT_SPEAKER_SAFE = 0x40; // bottom speaker
-
- INPUT_DEVICE_BIT = 0x40000000; // non-negative positive int32.
- INPUT_BUILTIN_MIC = 0x40000001; // buildin mic
- INPUT_BUILTIN_BACK_MIC = 0x40000002; // buildin back mic
- INPUT_WIRED_HEADSET_MIC = 0x40000004; // 3.5mm headset mic
- INPUT_USB_HEADSET_MIC = 0x40000008; // usb headset mic
- INPUT_BLUETOOTH_SCO = 0x40000010; // bluetooth sco mic
- }
- optional AudioDevice audio_device = 1;
-
- // Duration of the audio in seconds
- optional int32 duration_secs = 2;
-
- // Average volume (0 ... 1.0)
- optional float average_volume = 3;
-
- enum AudioType {
- UNKNOWN_TYPE = 0;
- VOICE_CALL_TYPE = 1; // voice call
- VOIP_CALL_TYPE = 2; // voip call, including uplink and downlink
- MEDIA_TYPE = 3; // music and system sound
- RINGTONE_NOTIFICATION_TYPE = 4; // ringtone and notification
- ALARM_TYPE = 5; // alarm type
- // record type
- CAMCORDER_TYPE = 6; // camcorder
- RECORD_TYPE = 7; // other recording
- }
- optional AudioType type = 4;
-}
-
-/**
- * Pulls bytes transferred over WiFi and mobile networks sliced by uid, is_metered, and tag.
- *
- * Pulled from:
- * StatsPullAtomService, which uses NetworkStatsService to query NetworkStats.
- */
-message BytesTransferByTagAndMetered {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional bool is_metered = 2;
-
- optional int32 tag = 3;
-
- optional int64 rx_bytes = 4;
-
- optional int64 rx_packets = 5;
-
- optional int64 tx_bytes = 6;
-
- optional int64 tx_packets = 7;
-}
-
-/*
- * Logs when the Media Output Switcher finishes a media switch operation.
- *
- * Logged from:
- * packages/apps/Settings/src/com/android/settings/media/MediaOutputSliceWorker.java
- */
-message MediaOutputOpSwitchReported {
- // Source medium type before switching.
- optional android.app.settings.mediaoutput.MediumType source = 1;
-
- // Target medium type after switching.
- optional android.app.settings.mediaoutput.MediumType target = 2;
-
- // The result of switching.
- optional android.app.settings.mediaoutput.SwitchResult result = 3;
-
- // The detail code of a switching result.
- optional android.app.settings.mediaoutput.SubResult subresult = 4;
-
- /*
- * The package name of a pre-installed app, whose media session is being switched.
- */
- optional string media_session_package_name = 5;
-
- // The amount of available wired devices when a switching is being performed.
- optional int32 available_wired_device_count = 6;
-
- // The amount of available Bluetooth devices a switching is being performed.
- optional int32 available_bt_device_count = 7;
-
- // The amount of available remote devices when a switching is being performed.
- optional int32 available_remote_device_count = 8;
-
- // The amount of applied devices within a remote dynamic group after a switching is done.
- optional int32 applied_device_count_within_remote_group = 9;
-}
-
-/**
- * Logs when the Assistant is invoked.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
- */
-message AssistantInvocationReported {
-
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
-
- // The registered Assistant's uid and package (as for UiEventReported).
- optional int32 uid = 2 [(is_uid) = true];
- optional string package_name = 3;
-
- // An identifier used to disambiguate which logs refer to a particular invocation of the
- // Assistant (as for UiEventReported).
- optional int32 instance_id = 4;
-
- // The state of the device at the time of invocation.
- enum DeviceState {
- UNKNOWN_DEVICE_STATE = 0;
- AOD1 = 1;
- AOD2 = 2;
- BOUNCER = 3;
- UNLOCKED_LOCKSCREEN = 4;
- LAUNCHER_HOME = 5;
- LAUNCHER_OVERVIEW = 6;
- LAUNCHER_ALL_APPS = 7;
- APP_DEFAULT = 8;
- APP_IMMERSIVE = 9;
- APP_FULLSCREEN = 10;
- }
- optional DeviceState device_state = 5;
-
- // Whether the Assistant handles were showing at the time of invocation.
- optional bool assistant_handles_showing = 6;
-}
-
-/**
- * Logs when an AudioRecord finishes running on an audio device
- *
- * Logged from:
- * frameworks/av/services/mediametrics/AudioAnalytics.cpp
- */
-message MediametricsAudioRecordDeviceUsageReported {
- // The devices connected to this AudioRecord.
- // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2".
- // See lookup<INPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- // See audio_device_t in system/media/audio/include/system/audio-base.h
- optional string devices = 1;
-
- // The name of the remote device attached to the device, typically available for USB or BT.
- // This may be empty for a fixed device, or separated by "|" if more than one.
- optional string device_names = 2;
-
- // The amount of time spent in the device as measured by the active track in AudioFlinger.
- optional int64 device_time_nanos = 3;
-
- // The audio data format used for encoding.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t
- optional string encoding = 4;
-
- // The client-server buffer framecount.
- // The framecount is generally between 960 - 48000 for PCM encoding.
- // The framecount represents raw buffer size in bytes for non-PCM encoding.
- optional int32 frame_count = 5;
-
- // The number of audio intervals (contiguous, continuous playbacks).
- optional int32 interval_count = 6;
-
- // The sample rate of the AudioRecord.
- // A number generally between 8000-96000 (frames per second).
- optional int32 sample_rate = 7;
-
- // The audio input flags used to construct the AudioRecord.
- // A string OR from system/media/audio/include/system/audio-base.h audio_input_flags_t
- optional string flags = 8;
-
- // The santized package name of the audio client associated with the AudioRecord.
- // See getSanitizedPackageNameAndVersionCode() in
- // frameworks/av/services/mediametrics/MediaMetricsService.cpp
- optional string package_name = 9;
-
- // The selected device id (nonzero if a non-default device is selected)
- optional int32 selected_device_id = 10;
-
- // The caller of the AudioRecord.
- // See lookup<CALLER_NAME>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- optional string caller = 11;
-
- // The audio source for AudioRecord.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_source_t
- optional string source = 12;
-}
-
-/**
- * Logs when an AudioThread finishes running on an audio device
- *
- * Logged from:
- * frameworks/av/services/mediametrics/AudioAnalytics.cpp
- */
-message MediametricsAudioThreadDeviceUsageReported {
- // The devices connected to this audio thread.
- // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2".
- // (for record threads):
- // See lookup<INPUT_DEVICE> in frameworks/av/services/mediametrics/AudioTypes.cpp
- // (for playback threads):
- // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- // See audio_device_t in system/media/audio/include/system/audio-base.h
- optional string devices = 1;
-
- // The name of the remote device attached to the device, typically available for USB or BT.
- // This may be empty for a fixed device, or separated by "|" if more than one.
- optional string device_names = 2;
-
- // The amount of time spent in the device as measured by the active track in AudioFlinger.
- optional int64 device_time_nanos = 3;
-
- // The audio data format used for encoding.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t
- optional string encoding = 4;
-
- // The framecount of the buffer delivered to (or from) the HAL.
- // The framecount is generally ~960 for PCM encoding.
- // The framecount represents raw buffer size in bytes for non-PCM encoding.
- optional int32 frame_count = 5;
-
- // The number of audio intervals (contiguous, continuous playbacks).
- optional int32 interval_count = 6;
-
- // The sample rate of the audio thread.
- // A number generally between 8000-96000 (frames per second).
- optional int32 sample_rate = 7;
-
- // The audio flags used to construct the thread
- // (for record threads):
- // A string OR from system/media/audio/include/system/audio-base.h audio_input_flags_t
- // (for playback threads):
- // A string OR from system/media/audio/include/system/audio-base.h audio_output_flags_t
- optional string flags = 8;
-
- // The number of underruns encountered for a playback thread or the
- // number of overruns encountered for a capture thread.
- optional int32 xruns = 9;
-
- // The type of thread
- // A thread type enumeration from
- // frameworks/av/mediametrics/services/Translate.h
- optional string type = 10;
-}
-
-/**
- * Logs when an AudioTrack finishes running on an audio device
- *
- * Logged from:
- * frameworks/av/services/mediametrics/AudioAnalytics.cpp
- */
-message MediametricsAudioTrackDeviceUsageReported {
- // The output devices connected to this AudioTrack.
- // A string OR of various output device categories, e.g. "DEVICE1|DEVICE2".
- // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- // See audio_device_t in system/media/audio/include/system/audio-base.h
- optional string devices = 1;
-
- // The name of the remote device attached to the device, typically available for USB or BT.
- // This may be empty for a fixed device, or separated by "|" if more than one.
- optional string device_names = 2;
-
- // The amount of time spent in the device as measured by the active track in AudioFlinger.
- optional int64 device_time_nanos = 3;
-
- // The audio data format used for encoding.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t
- optional string encoding = 4;
-
- // The client-server buffer framecount.
- // The framecount is generally between 960 - 48000 for PCM encoding.
- // The framecount represents raw buffer size in bytes for non-PCM encoding.
- // A static track (see traits) may have a very large framecount.
- optional int32 frame_count = 5;
-
- // The number of audio intervals (contiguous, continuous playbacks).
- optional int32 interval_count = 6;
-
- // The sample rate of the AudioTrack.
- // A number generally between 8000-96000 (frames per second).
- optional int32 sample_rate = 7;
-
- // The audio flags used to construct the AudioTrack.
- // A string OR from system/media/audio/include/system/audio-base.h audio_output_flags_t
- optional string flags = 8;
-
- // The number of underruns encountered.
- optional int32 xruns = 9;
-
- // The santized package name of the audio client associated with the AudioTrack.
- // See getSanitizedPackageNameAndVersionCode() in
- // frameworks/av/services/mediametrics/MediaMetricsService.cpp
- optional string package_name = 10;
-
- // The latency of the last sample in the buffer in milliseconds.
- optional float device_latency_millis = 11;
-
- // The startup time in milliseconds from start() to sample played.
- optional float device_startup_millis = 12;
-
- // The average volume of the track on the device [ 0.f - 1.f ]
- optional float device_volume = 13;
-
- // The selected device id (nonzero if a non-default device is selected)
- optional int32 selected_device_id = 14;
-
- // The stream_type category for the AudioTrack.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_stream_type_t
- optional string stream_type = 15;
-
- // The usage for the AudioTrack.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_usage_t
- optional string usage = 16;
-
- // The content type of the AudioTrack.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_content_type_t
- optional string content_type = 17;
-
- // The caller of the AudioTrack.
- // See lookup<CALLER_NAME>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- optional string caller = 18;
-
- // The traits of the AudioTrack.
- // A string OR of different traits, may be empty string.
- // Only "static" is supported for R.
- // See lookup<TRACK_TRAITS>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- optional string traits = 19;
-}
-
-/**
- * Logs the status of an audio device connection attempt.
- *
- * Logged from:
- * frameworks/av/services/mediametrics/AudioAnalytics.cpp
- */
-message MediametricsAudioDeviceConnectionReported {
- // The input devices represented by this report.
- // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2".
- // See lookup<INPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- // See audio_device_t in system/media/audio/include/system/audio-base.h
- optional string input_devices = 1;
-
- // The output devices represented by this report.
- // A string OR of various output device categories.
- // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- // See audio_device_t in system/media/audio/include/system/audio-base.h
- optional string output_devices = 2;
-
- // The name of the remote device attached to the device, typically available for USB or BT.
- // This may be empty for a fixed device, or separated by "|" if more than one.
- optional string device_names = 3;
-
- // The result of the audio device connection.
- // 0 indicates success: connection verified.
- // 1 indicates unknown: connection not verified or not known if diverted properly.
- // Other values indicate specific status.
- // See DeviceConnectionResult in frameworks/av/services/mediametrics/AudioTypes.h
- optional int32 result = 4;
-
- // Average milliseconds of time to connect
- optional float time_to_connect_millis = 5;
-
- // Number of connections if aggregated statistics, otherwise 1.
- optional int32 connection_count = 6;
-}
-
-/**
- * Logs: i) creation of different types of cryptographic keys in the keystore,
- * ii) operations performed using the keys,
- * iii) attestation of the keys
- * Logged from: system/security/keystore/key_event_log_handler.cpp
- */
-message KeystoreKeyEventReported {
-
- enum Algorithm {
- /** Asymmetric algorithms. */
- RSA = 1;
- // 2 removed, do not reuse.
- EC = 3;
- /** Block cipher algorithms */
- AES = 32;
- TRIPLE_DES = 33;
- /** MAC algorithms */
- HMAC = 128;
- };
- /** Algorithm associated with the key */
- optional Algorithm algorithm = 1;
-
- /** Size of the key */
- optional int32 key_size = 2;
-
- enum KeyOrigin {
- /** Generated in keymaster. Should not exist outside the TEE. */
- GENERATED = 0;
- /** Derived inside keymaster. Likely exists off-device. */
- DERIVED = 1;
- /** Imported into keymaster. Existed as cleartext in Android. */
- IMPORTED = 2;
- /** Keymaster did not record origin. */
- UNKNOWN = 3;
- /** Securely imported into Keymaster. */
- SECURELY_IMPORTED = 4;
- };
- /* Logs whether the key was generated, imported, securely imported, or derived.*/
- optional KeyOrigin key_origin = 3;
-
- enum HardwareAuthenticatorType {
- NONE = 0;
- PASSWORD = 1;
- FINGERPRINT = 2;
- // Additional entries must be powers of 2.
- };
- /**
- * What auth types does this key require? If none,
- * then no auth required.
- */
- optional HardwareAuthenticatorType user_auth_type = 4;
-
- /**
- * If user authentication is required, is the requirement time based? If it
- * is not time based then this field will not be used and the key is per
- * operation. Per operation keys must be user authenticated on each usage.
- */
- optional int32 user_auth_key_timeout_secs = 5;
-
- /**
- * padding mode, digest, block_mode and purpose should ideally be repeated
- * fields. However, since statsd does not support repeated fields in
- * pushed atoms, they are represented using bitmaps.
- */
-
- /** Track which padding mode is being used.*/
- optional int32 padding_mode_bitmap = 6;
-
- /** Track which digest is being used. */
- optional int32 digest_bitmap = 7;
-
- /** Track what block mode is being used (for encryption). */
- optional int32 block_mode_bitmap = 8;
-
- /** Track what purpose is this key serving. */
- optional int32 purpose_bitmap = 9;
-
- enum EcCurve {
- P_224 = 0;
- P_256 = 1;
- P_384 = 2;
- P_521 = 3;
- };
- /** Which ec curve was selected if elliptic curve cryptography is in use **/
- optional EcCurve ec_curve = 10;
-
- enum KeyBlobUsageRequirements {
- STANDALONE = 0;
- REQUIRES_FILE_SYSTEM = 1;
- };
- /** Standalone or is a file system required */
- optional KeyBlobUsageRequirements key_blob_usage_reqs = 11;
-
- enum Type {
- key_operation = 0;
- key_creation = 1;
- key_attestation = 2;
- }
- /** Key creation event, operation event or attestation event? */
- optional Type type = 12;
-
- /** Was the key creation, operation, or attestation successful? */
- optional bool was_successful = 13;
-
- /** Response code or error code */
- optional int32 error_code = 14;
-}
-
-// Blob Committer stats
-// Keep in sync between:
-// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto
-// frameworks/base/cmds/statsd/src/atoms.proto
-message BlobCommitterProto {
- // Committer app's uid
- optional int32 uid = 1 [(is_uid) = true];
-
- // Unix epoch timestamp of the commit in milliseconds
- optional int64 commit_timestamp_millis = 2;
-
- // Flags of what access types the committer has set for the Blob
- optional int32 access_mode = 3;
-
- // Number of packages that have been whitelisted for ACCESS_TYPE_WHITELIST
- optional int32 num_whitelisted_package = 4;
-}
-
-// Blob Leasee stats
-// Keep in sync between:
-// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto
-// frameworks/base/cmds/statsd/src/atoms.proto
-message BlobLeaseeProto {
- // Leasee app's uid
- optional int32 uid = 1 [(is_uid) = true];
-
- // Unix epoch timestamp for lease expiration in milliseconds
- optional int64 lease_expiry_timestamp_millis = 2;
-}
-
-// List of Blob Committers
-// Keep in sync between:
-// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto
-// frameworks/base/cmds/statsd/src/atoms.proto
-message BlobCommitterListProto {
- repeated BlobCommitterProto committer = 1;
-}
-
-// List of Blob Leasees
-// Keep in sync between:
-// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto
-// frameworks/base/cmds/statsd/src/atoms.proto
-message BlobLeaseeListProto {
- repeated BlobLeaseeProto leasee = 1;
-}
-
-/**
- * Logs the current state of a Blob committed with BlobStoreManager
- *
- * Pulled from:
- * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
- */
-message BlobInfo {
- // Id of the Blob
- optional int64 blob_id = 1;
-
- // Size of the Blob data
- optional int64 size = 2;
-
- // Unix epoch timestamp of the Blob's expiration in milliseconds
- optional int64 expiry_timestamp_millis = 3;
-
- // List of committers of this Blob
- optional BlobCommitterListProto committers = 4;
-
- // List of leasees of this Blob
- optional BlobLeaseeListProto leasees = 5;
-}
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
deleted file mode 100644
index e9875ba..0000000
--- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-#include "CombinationConditionTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-using std::vector;
-
-CombinationConditionTracker::CombinationConditionTracker(const int64_t& id, const int index)
- : ConditionTracker(id, index) {
- VLOG("creating CombinationConditionTracker %lld", (long long)mConditionId);
-}
-
-CombinationConditionTracker::~CombinationConditionTracker() {
- VLOG("~CombinationConditionTracker() %lld", (long long)mConditionId);
-}
-
-bool CombinationConditionTracker::init(const vector<Predicate>& allConditionConfig,
- const vector<sp<ConditionTracker>>& allConditionTrackers,
- const unordered_map<int64_t, int>& conditionIdIndexMap,
- vector<bool>& stack,
- vector<ConditionState>& initialConditionCache) {
- VLOG("Combination predicate init() %lld", (long long)mConditionId);
- if (mInitialized) {
- return true;
- }
-
- // mark this node as visited in the recursion stack.
- stack[mIndex] = true;
-
- Predicate_Combination combinationCondition = allConditionConfig[mIndex].combination();
-
- if (!combinationCondition.has_operation()) {
- return false;
- }
- mLogicalOperation = combinationCondition.operation();
-
- if (mLogicalOperation == LogicalOperation::NOT && combinationCondition.predicate_size() != 1) {
- return false;
- }
-
- for (auto child : combinationCondition.predicate()) {
- auto it = conditionIdIndexMap.find(child);
-
- if (it == conditionIdIndexMap.end()) {
- ALOGW("Predicate %lld not found in the config", (long long)child);
- return false;
- }
-
- int childIndex = it->second;
- const auto& childTracker = allConditionTrackers[childIndex];
- // if the child is a visited node in the recursion -> circle detected.
- if (stack[childIndex]) {
- ALOGW("Circle detected!!!");
- return false;
- }
-
- bool initChildSucceeded =
- childTracker->init(allConditionConfig, allConditionTrackers, conditionIdIndexMap,
- stack, initialConditionCache);
-
- if (!initChildSucceeded) {
- ALOGW("Child initialization failed %lld ", (long long)child);
- return false;
- } else {
- VLOG("Child initialization success %lld ", (long long)child);
- }
-
- if (allConditionTrackers[childIndex]->isSliced()) {
- setSliced(true);
- mSlicedChildren.push_back(childIndex);
- } else {
- mUnSlicedChildren.push_back(childIndex);
- }
- mChildren.push_back(childIndex);
- mTrackerIndex.insert(childTracker->getLogTrackerIndex().begin(),
- childTracker->getLogTrackerIndex().end());
- }
-
- mUnSlicedPartCondition = evaluateCombinationCondition(mUnSlicedChildren, mLogicalOperation,
- initialConditionCache);
- initialConditionCache[mIndex] =
- evaluateCombinationCondition(mChildren, mLogicalOperation, initialConditionCache);
-
- // unmark this node in the recursion stack.
- stack[mIndex] = false;
-
- mInitialized = true;
-
- return true;
-}
-
-void CombinationConditionTracker::isConditionMet(
- const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
- const bool isPartialLink,
- vector<ConditionState>& conditionCache) const {
- // So far, this is fine as there is at most one child having sliced output.
- for (const int childIndex : mChildren) {
- if (conditionCache[childIndex] == ConditionState::kNotEvaluated) {
- allConditions[childIndex]->isConditionMet(conditionParameters, allConditions,
- isPartialLink,
- conditionCache);
- }
- }
- conditionCache[mIndex] =
- evaluateCombinationCondition(mChildren, mLogicalOperation, conditionCache);
-}
-
-void CombinationConditionTracker::evaluateCondition(
- const LogEvent& event, const std::vector<MatchingState>& eventMatcherValues,
- const std::vector<sp<ConditionTracker>>& mAllConditions,
- std::vector<ConditionState>& nonSlicedConditionCache,
- std::vector<bool>& conditionChangedCache) {
- // value is up to date.
- if (nonSlicedConditionCache[mIndex] != ConditionState::kNotEvaluated) {
- return;
- }
-
- for (const int childIndex : mChildren) {
- // So far, this is fine as there is at most one child having sliced output.
- if (nonSlicedConditionCache[childIndex] == ConditionState::kNotEvaluated) {
- const sp<ConditionTracker>& child = mAllConditions[childIndex];
- child->evaluateCondition(event, eventMatcherValues, mAllConditions,
- nonSlicedConditionCache, conditionChangedCache);
- }
- }
-
- ConditionState newCondition =
- evaluateCombinationCondition(mChildren, mLogicalOperation, nonSlicedConditionCache);
- if (!mSliced) {
- bool nonSlicedChanged = (mUnSlicedPartCondition != newCondition);
- mUnSlicedPartCondition = newCondition;
-
- nonSlicedConditionCache[mIndex] = mUnSlicedPartCondition;
- conditionChangedCache[mIndex] = nonSlicedChanged;
- } else {
- mUnSlicedPartCondition = evaluateCombinationCondition(mUnSlicedChildren, mLogicalOperation,
- nonSlicedConditionCache);
-
- for (const int childIndex : mChildren) {
- // If any of the sliced condition in children condition changes, the combination
- // condition may be changed too.
- if (conditionChangedCache[childIndex]) {
- conditionChangedCache[mIndex] = true;
- break;
- }
- }
- nonSlicedConditionCache[mIndex] = newCondition;
- VLOG("CombinationPredicate %lld sliced may changed? %d", (long long)mConditionId,
- conditionChangedCache[mIndex] == true);
- }
-}
-
-bool CombinationConditionTracker::equalOutputDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensions) const {
- if (mSlicedChildren.size() != 1 ||
- mSlicedChildren.front() >= (int)allConditions.size() ||
- mLogicalOperation != LogicalOperation::AND) {
- return false;
- }
- const sp<ConditionTracker>& slicedChild = allConditions.at(mSlicedChildren.front());
- return slicedChild->equalOutputDimensions(allConditions, dimensions);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.h b/cmds/statsd/src/condition/CombinationConditionTracker.h
deleted file mode 100644
index 39ff0ab..0000000
--- a/cmds/statsd/src/condition/CombinationConditionTracker.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef COMBINATION_CONDITION_TRACKER_H
-#define COMBINATION_CONDITION_TRACKER_H
-
-#include "ConditionTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class CombinationConditionTracker : public virtual ConditionTracker {
-public:
- CombinationConditionTracker(const int64_t& id, const int index);
-
- ~CombinationConditionTracker();
-
- bool init(const std::vector<Predicate>& allConditionConfig,
- const std::vector<sp<ConditionTracker>>& allConditionTrackers,
- const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
- std::vector<ConditionState>& initialConditionCache) override;
-
- void evaluateCondition(const LogEvent& event,
- const std::vector<MatchingState>& eventMatcherValues,
- const std::vector<sp<ConditionTracker>>& mAllConditions,
- std::vector<ConditionState>& conditionCache,
- std::vector<bool>& changedCache) override;
-
- void isConditionMet(const ConditionKey& conditionParameters,
- const std::vector<sp<ConditionTracker>>& allConditions,
- const bool isPartialLink,
- std::vector<ConditionState>& conditionCache) const override;
-
- // Only one child predicate can have dimension.
- const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const override {
- for (const auto& child : mChildren) {
- auto result = allConditions[child]->getChangedToTrueDimensions(allConditions);
- if (result != nullptr) {
- return result;
- }
- }
- return nullptr;
- }
-
- // Only one child predicate can have dimension.
- const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const override {
- for (const auto& child : mChildren) {
- auto result = allConditions[child]->getChangedToFalseDimensions(allConditions);
- if (result != nullptr) {
- return result;
- }
- }
- return nullptr;
- }
-
- bool IsSimpleCondition() const override { return false; }
-
- bool IsChangedDimensionTrackable() const override {
- return mLogicalOperation == LogicalOperation::AND && mSlicedChildren.size() == 1;
- }
-
- bool equalOutputDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensions) const override;
-
- void getTrueSlicedDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- std::set<HashableDimensionKey>* dimensions) const override {
- if (mSlicedChildren.size() == 1) {
- return allConditions[mSlicedChildren.front()]->getTrueSlicedDimensions(
- allConditions, dimensions);
- }
- }
-
-
-private:
- LogicalOperation mLogicalOperation;
-
- // Store index of the children Predicates.
- // We don't store string name of the Children, because we want to get rid of the hash map to
- // map the name to object. We don't want to store smart pointers to children, because it
- // increases the risk of circular dependency and memory leak.
- std::vector<int> mChildren;
-
- std::vector<int> mSlicedChildren;
- std::vector<int> mUnSlicedChildren;
-
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // COMBINATION_CONDITION_TRACKER_H
diff --git a/cmds/statsd/src/condition/ConditionTimer.h b/cmds/statsd/src/condition/ConditionTimer.h
deleted file mode 100644
index 442bc11..0000000
--- a/cmds/statsd/src/condition/ConditionTimer.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <gtest/gtest_prod.h>
-#include <stdint.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * A simple stopwatch to time the duration of condition being true.
- *
- * The owner of the stopwatch (MetricProducer) is responsible to notify the stopwatch when condition
- * changes (start/pause), and when to start a new bucket (a new lap basically). All timestamps
- * should be elapsedRealTime in nano seconds.
- *
- * Keep the timer simple and inline everything. This class is *NOT* thread safe. Caller is
- * responsible for thread safety.
- */
-class ConditionTimer {
-public:
- explicit ConditionTimer(bool initCondition, int64_t bucketStartNs) : mCondition(initCondition) {
- if (initCondition) {
- mLastConditionTrueTimestampNs = bucketStartNs;
- }
- };
-
- // Tracks how long the condition has been stayed true in the *current* bucket.
- // When a new bucket is created, this value will be reset to 0.
- int64_t mTimerNs = 0;
-
- // Last elapsed real timestamp when condition turned to true
- // When a new bucket is created and the condition is true, then the timestamp is set
- // to be the bucket start timestamp.
- int64_t mLastConditionTrueTimestampNs = 0;
-
- bool mCondition = false;
-
- int64_t newBucketStart(int64_t nextBucketStartNs) {
- if (mCondition) {
- mTimerNs += (nextBucketStartNs - mLastConditionTrueTimestampNs);
- mLastConditionTrueTimestampNs = nextBucketStartNs;
- }
-
- int64_t temp = mTimerNs;
- mTimerNs = 0;
- return temp;
- }
-
- void onConditionChanged(bool newCondition, int64_t timestampNs) {
- if (newCondition == mCondition) {
- return;
- }
- mCondition = newCondition;
- if (newCondition) {
- mLastConditionTrueTimestampNs = timestampNs;
- } else {
- mTimerNs += (timestampNs - mLastConditionTrueTimestampNs);
- }
- }
-
- FRIEND_TEST(ConditionTimerTest, TestTimer_Inital_False);
- FRIEND_TEST(ConditionTimerTest, TestTimer_Inital_True);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h
deleted file mode 100644
index 62736c8..0000000
--- a/cmds/statsd/src/condition/ConditionTracker.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "condition/condition_util.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/LogMatchingTracker.h"
-#include "matchers/matcher_util.h"
-
-#include <utils/RefBase.h>
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class ConditionTracker : public virtual RefBase {
-public:
- ConditionTracker(const int64_t& id, const int index)
- : mConditionId(id),
- mIndex(index),
- mInitialized(false),
- mTrackerIndex(),
- mUnSlicedPartCondition(ConditionState::kUnknown),
- mSliced(false){};
-
- virtual ~ConditionTracker(){};
-
- inline const int64_t& getId() { return mConditionId; }
-
- // Initialize this ConditionTracker. This initialization is done recursively (DFS). It can also
- // be done in the constructor, but we do it separately because (1) easy to return a bool to
- // indicate whether the initialization is successful. (2) makes unit test easier.
- // allConditionConfig: the list of all Predicate config from statsd_config.
- // allConditionTrackers: the list of all ConditionTrackers (this is needed because we may also
- // need to call init() on children conditions)
- // conditionIdIndexMap: the mapping from condition id to its index.
- // stack: a bit map to keep track which nodes have been visited on the stack in the recursion.
- // initialConditionCache: tracks initial conditions of all ConditionTrackers.
- virtual bool init(const std::vector<Predicate>& allConditionConfig,
- const std::vector<sp<ConditionTracker>>& allConditionTrackers,
- const std::unordered_map<int64_t, int>& conditionIdIndexMap,
- std::vector<bool>& stack,
- std::vector<ConditionState>& initialConditionCache) = 0;
-
- // evaluate current condition given the new event.
- // event: the new log event
- // eventMatcherValues: the results of the LogMatcherTrackers. LogMatcherTrackers always process
- // event before ConditionTrackers, because ConditionTracker depends on
- // LogMatchingTrackers.
- // mAllConditions: the list of all ConditionTracker
- // conditionCache: the cached non-sliced condition of the ConditionTrackers for this new event.
- // conditionChanged: the bit map to record whether the condition has changed.
- // If the condition has dimension, then any sub condition changes will report
- // conditionChanged.
- virtual void evaluateCondition(const LogEvent& event,
- const std::vector<MatchingState>& eventMatcherValues,
- const std::vector<sp<ConditionTracker>>& mAllConditions,
- std::vector<ConditionState>& conditionCache,
- std::vector<bool>& conditionChanged) = 0;
-
- // Query the condition with parameters.
- // [conditionParameters]: a map from condition name to the HashableDimensionKey to query the
- // condition.
- // [allConditions]: all condition trackers. This is needed because the condition evaluation is
- // done recursively
- // [isPartialLink]: true if the link specified by 'conditionParameters' contains all the fields
- // in the condition tracker output dimension.
- // [conditionCache]: the cache holding the condition evaluation values.
- virtual void isConditionMet(
- const ConditionKey& conditionParameters,
- const std::vector<sp<ConditionTracker>>& allConditions,
- const bool isPartialLink,
- std::vector<ConditionState>& conditionCache) const = 0;
-
- // return the list of LogMatchingTracker index that this ConditionTracker uses.
- virtual const std::set<int>& getLogTrackerIndex() const {
- return mTrackerIndex;
- }
-
- virtual void setSliced(bool sliced) {
- mSliced = mSliced | sliced;
- }
-
- inline bool isSliced() const {
- return mSliced;
- }
-
- virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
- virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
-
- inline int64_t getConditionId() const {
- return mConditionId;
- }
-
- virtual void getTrueSlicedDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- std::set<HashableDimensionKey>* dimensions) const = 0;
-
- virtual bool IsChangedDimensionTrackable() const = 0;
-
- virtual bool IsSimpleCondition() const = 0;
-
- virtual bool equalOutputDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensions) const = 0;
-
- // Return the current condition state of the unsliced part of the condition.
- inline ConditionState getUnSlicedPartConditionState() const {
- return mUnSlicedPartCondition;
- }
-
-protected:
- const int64_t mConditionId;
-
- // the index of this condition in the manager's condition list.
- const int mIndex;
-
- // if it's properly initialized.
- bool mInitialized;
-
- // the list of LogMatchingTracker index that this ConditionTracker uses.
- std::set<int> mTrackerIndex;
-
- // This variable is only used for CombinationConditionTrackers.
- // SimpleConditionTrackers technically don't have an unsliced part because
- // they are either sliced or unsliced.
- //
- // CombinationConditionTrackers have multiple children ConditionTrackers
- // that can be a mixture of sliced or unsliced. This tracks the
- // condition of the unsliced part of the combination condition.
- ConditionState mUnSlicedPartCondition;
-
- bool mSliced;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/condition/ConditionWizard.cpp b/cmds/statsd/src/condition/ConditionWizard.cpp
deleted file mode 100644
index c542032..0000000
--- a/cmds/statsd/src/condition/ConditionWizard.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "ConditionWizard.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-ConditionState ConditionWizard::query(const int index, const ConditionKey& parameters,
- const bool isPartialLink) {
- vector<ConditionState> cache(mAllConditions.size(), ConditionState::kNotEvaluated);
-
- mAllConditions[index]->isConditionMet(
- parameters, mAllConditions, isPartialLink,
- cache);
- return cache[index];
-}
-
-const set<HashableDimensionKey>* ConditionWizard::getChangedToTrueDimensions(
- const int index) const {
- return mAllConditions[index]->getChangedToTrueDimensions(mAllConditions);
-}
-
-const set<HashableDimensionKey>* ConditionWizard::getChangedToFalseDimensions(
- const int index) const {
- return mAllConditions[index]->getChangedToFalseDimensions(mAllConditions);
-}
-
-bool ConditionWizard::IsChangedDimensionTrackable(const int index) {
- if (index >= 0 && index < (int)mAllConditions.size()) {
- return mAllConditions[index]->IsChangedDimensionTrackable();
- } else {
- return false;
- }
-}
-
-bool ConditionWizard::IsSimpleCondition(const int index) {
- if (index >= 0 && index < (int)mAllConditions.size()) {
- return mAllConditions[index]->IsSimpleCondition();
- } else {
- return false;
- }
-}
-
-bool ConditionWizard::equalOutputDimensions(const int index, const vector<Matcher>& dimensions) {
- if (index >= 0 && index < (int)mAllConditions.size()) {
- return mAllConditions[index]->equalOutputDimensions(mAllConditions, dimensions);
- } else {
- return false;
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/condition/ConditionWizard.h b/cmds/statsd/src/condition/ConditionWizard.h
deleted file mode 100644
index 8926479..0000000
--- a/cmds/statsd/src/condition/ConditionWizard.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CONDITION_WIZARD_H
-#define CONDITION_WIZARD_H
-
-#include "ConditionTracker.h"
-#include "condition_util.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Held by MetricProducer, to query a condition state with input defined in MetricConditionLink.
-class ConditionWizard : public virtual android::RefBase {
-public:
- ConditionWizard(){}; // for testing
- explicit ConditionWizard(std::vector<sp<ConditionTracker>>& conditionTrackers)
- : mAllConditions(conditionTrackers){};
-
- virtual ~ConditionWizard(){};
-
- // Query condition state, for a ConditionTracker at [conditionIndex], with [conditionParameters]
- // [conditionParameters] mapping from condition name to the HashableDimensionKey to query the
- // condition.
- // The ConditionTracker at [conditionIndex] can be a CombinationConditionTracker. In this case,
- // the conditionParameters contains the parameters for it's children SimpleConditionTrackers.
- virtual ConditionState query(const int conditionIndex, const ConditionKey& conditionParameters,
- const bool isPartialLink);
-
- virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(const int index) const;
- virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
- const int index) const;
- bool equalOutputDimensions(const int index, const vector<Matcher>& dimensions);
-
- bool IsChangedDimensionTrackable(const int index);
- bool IsSimpleCondition(const int index);
-
- ConditionState getUnSlicedPartConditionState(const int index) {
- return mAllConditions[index]->getUnSlicedPartConditionState();
- }
- void getTrueSlicedDimensions(const int index,
- std::set<HashableDimensionKey>* trueDimensions) const {
- return mAllConditions[index]->getTrueSlicedDimensions(mAllConditions, trueDimensions);
- }
-
-private:
- std::vector<sp<ConditionTracker>> mAllConditions;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // CONDITION_WIZARD_H
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
deleted file mode 100644
index efb4d49..0000000
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "SimpleConditionTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-
-SimpleConditionTracker::SimpleConditionTracker(
- const ConfigKey& key, const int64_t& id, const int index,
- const SimplePredicate& simplePredicate,
- const unordered_map<int64_t, int>& trackerNameIndexMap)
- : ConditionTracker(id, index), mConfigKey(key), mContainANYPositionInInternalDimensions(false) {
- VLOG("creating SimpleConditionTracker %lld", (long long)mConditionId);
- mCountNesting = simplePredicate.count_nesting();
-
- if (simplePredicate.has_start()) {
- auto pair = trackerNameIndexMap.find(simplePredicate.start());
- if (pair == trackerNameIndexMap.end()) {
- ALOGW("Start matcher %lld not found in the config", (long long)simplePredicate.start());
- return;
- }
- mStartLogMatcherIndex = pair->second;
- mTrackerIndex.insert(mStartLogMatcherIndex);
- } else {
- mStartLogMatcherIndex = -1;
- }
-
- if (simplePredicate.has_stop()) {
- auto pair = trackerNameIndexMap.find(simplePredicate.stop());
- if (pair == trackerNameIndexMap.end()) {
- ALOGW("Stop matcher %lld not found in the config", (long long)simplePredicate.stop());
- return;
- }
- mStopLogMatcherIndex = pair->second;
- mTrackerIndex.insert(mStopLogMatcherIndex);
- } else {
- mStopLogMatcherIndex = -1;
- }
-
- if (simplePredicate.has_stop_all()) {
- auto pair = trackerNameIndexMap.find(simplePredicate.stop_all());
- if (pair == trackerNameIndexMap.end()) {
- ALOGW("Stop all matcher %lld found in the config", (long long)simplePredicate.stop_all());
- return;
- }
- mStopAllLogMatcherIndex = pair->second;
- mTrackerIndex.insert(mStopAllLogMatcherIndex);
- } else {
- mStopAllLogMatcherIndex = -1;
- }
-
- if (simplePredicate.has_dimensions()) {
- translateFieldMatcher(simplePredicate.dimensions(), &mOutputDimensions);
- if (mOutputDimensions.size() > 0) {
- mSliced = true;
- mDimensionTag = mOutputDimensions[0].mMatcher.getTag();
- }
- mContainANYPositionInInternalDimensions = HasPositionANY(simplePredicate.dimensions());
- }
-
- if (simplePredicate.initial_value() == SimplePredicate_InitialValue_FALSE) {
- mInitialValue = ConditionState::kFalse;
- } else {
- mInitialValue = ConditionState::kUnknown;
- }
-
- mInitialized = true;
-}
-
-SimpleConditionTracker::~SimpleConditionTracker() {
- VLOG("~SimpleConditionTracker()");
-}
-
-bool SimpleConditionTracker::init(const vector<Predicate>& allConditionConfig,
- const vector<sp<ConditionTracker>>& allConditionTrackers,
- const unordered_map<int64_t, int>& conditionIdIndexMap,
- vector<bool>& stack,
- vector<ConditionState>& initialConditionCache) {
- // SimpleConditionTracker does not have dependency on other conditions, thus we just return
- // if the initialization was successful.
- initialConditionCache[mIndex] = mInitialValue;
- return mInitialized;
-}
-
-void SimpleConditionTracker::dumpState() {
- VLOG("%lld DUMP:", (long long)mConditionId);
- for (const auto& pair : mSlicedConditionState) {
- VLOG("\t%s : %d", pair.first.toString().c_str(), pair.second);
- }
-
- VLOG("Changed to true keys: \n");
- for (const auto& key : mLastChangedToTrueDimensions) {
- VLOG("%s", key.toString().c_str());
- }
- VLOG("Changed to false keys: \n");
- for (const auto& key : mLastChangedToFalseDimensions) {
- VLOG("%s", key.toString().c_str());
- }
-}
-
-void SimpleConditionTracker::handleStopAll(std::vector<ConditionState>& conditionCache,
- std::vector<bool>& conditionChangedCache) {
- // Unless the default condition is false, and there was nothing started, otherwise we have
- // triggered a condition change.
- conditionChangedCache[mIndex] =
- (mInitialValue == ConditionState::kFalse && mSlicedConditionState.empty()) ? false
- : true;
-
- for (const auto& cond : mSlicedConditionState) {
- if (cond.second > 0) {
- mLastChangedToFalseDimensions.insert(cond.first);
- }
- }
-
- // After StopAll, we know everything has stopped. From now on, default condition is false.
- mInitialValue = ConditionState::kFalse;
- mSlicedConditionState.clear();
- conditionCache[mIndex] = ConditionState::kFalse;
-}
-
-bool SimpleConditionTracker::hitGuardRail(const HashableDimensionKey& newKey) {
- if (!mSliced || mSlicedConditionState.find(newKey) != mSlicedConditionState.end()) {
- // if the condition is not sliced or the key is not new, we are good!
- return false;
- }
- // 1. Report the tuple count if the tuple count > soft limit
- if (mSlicedConditionState.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mSlicedConditionState.size() + 1;
- StatsdStats::getInstance().noteConditionDimensionSize(mConfigKey, mConditionId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("Predicate %lld dropping data for dimension key %s",
- (long long)mConditionId, newKey.toString().c_str());
- return true;
- }
- }
- return false;
-}
-
-void SimpleConditionTracker::handleConditionEvent(const HashableDimensionKey& outputKey,
- bool matchStart, ConditionState* conditionCache,
- bool* conditionChangedCache) {
- bool changed = false;
- auto outputIt = mSlicedConditionState.find(outputKey);
- ConditionState newCondition;
- if (hitGuardRail(outputKey)) {
- (*conditionChangedCache) = false;
- // Tells the caller it's evaluated.
- (*conditionCache) = ConditionState::kUnknown;
- return;
- }
- if (outputIt == mSlicedConditionState.end()) {
- // We get a new output key.
- newCondition = matchStart ? ConditionState::kTrue : ConditionState::kFalse;
- if (matchStart && mInitialValue != ConditionState::kTrue) {
- mSlicedConditionState[outputKey] = 1;
- changed = true;
- mLastChangedToTrueDimensions.insert(outputKey);
- } else if (mInitialValue != ConditionState::kFalse) {
- // it's a stop and we don't have history about it.
- // If the default condition is not false, it means this stop is valuable to us.
- mSlicedConditionState[outputKey] = 0;
- mLastChangedToFalseDimensions.insert(outputKey);
- changed = true;
- }
- } else {
- // we have history about this output key.
- auto& startedCount = outputIt->second;
- // assign the old value first.
- newCondition = startedCount > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- if (matchStart) {
- if (startedCount == 0) {
- mLastChangedToTrueDimensions.insert(outputKey);
- // This condition for this output key will change from false -> true
- changed = true;
- }
-
- // it's ok to do ++ here, even if we don't count nesting. The >1 counts will be treated
- // as 1 if not counting nesting.
- startedCount++;
- newCondition = ConditionState::kTrue;
- } else {
- // This is a stop event.
- if (startedCount > 0) {
- if (mCountNesting) {
- startedCount--;
- if (startedCount == 0) {
- newCondition = ConditionState::kFalse;
- }
- } else {
- // not counting nesting, so ignore the number of starts, stop now.
- startedCount = 0;
- newCondition = ConditionState::kFalse;
- }
- // if everything has stopped for this output key, condition true -> false;
- if (startedCount == 0) {
- mLastChangedToFalseDimensions.insert(outputKey);
- changed = true;
- }
- }
-
- // if default condition is false, it means we don't need to keep the false values.
- if (mInitialValue == ConditionState::kFalse && startedCount == 0) {
- mSlicedConditionState.erase(outputIt);
- VLOG("erase key %s", outputKey.toString().c_str());
- }
- }
- }
-
- // dump all dimensions for debugging
- if (DEBUG) {
- dumpState();
- }
-
- (*conditionChangedCache) = changed;
- (*conditionCache) = newCondition;
-
- VLOG("SimplePredicate %lld nonSlicedChange? %d", (long long)mConditionId,
- conditionChangedCache[mIndex] == true);
-}
-
-void SimpleConditionTracker::evaluateCondition(
- const LogEvent& event,
- const vector<MatchingState>& eventMatcherValues,
- const vector<sp<ConditionTracker>>& mAllConditions,
- vector<ConditionState>& conditionCache,
- vector<bool>& conditionChangedCache) {
- if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
- // it has been evaluated.
- VLOG("Yes, already evaluated, %lld %d",
- (long long)mConditionId, conditionCache[mIndex]);
- return;
- }
- mLastChangedToTrueDimensions.clear();
- mLastChangedToFalseDimensions.clear();
-
- if (mStopAllLogMatcherIndex >= 0 && mStopAllLogMatcherIndex < int(eventMatcherValues.size()) &&
- eventMatcherValues[mStopAllLogMatcherIndex] == MatchingState::kMatched) {
- handleStopAll(conditionCache, conditionChangedCache);
- return;
- }
-
- int matchedState = -1;
- // Note: The order to evaluate the following start, stop, stop_all matters.
- // The priority of overwrite is stop_all > stop > start.
- if (mStartLogMatcherIndex >= 0 &&
- eventMatcherValues[mStartLogMatcherIndex] == MatchingState::kMatched) {
- matchedState = 1;
- }
-
- if (mStopLogMatcherIndex >= 0 &&
- eventMatcherValues[mStopLogMatcherIndex] == MatchingState::kMatched) {
- matchedState = 0;
- }
-
- if (matchedState < 0) {
- // The event doesn't match this condition. So we just report existing condition values.
- conditionChangedCache[mIndex] = false;
- if (mSliced) {
- // if the condition result is sliced. The overall condition is true if any of the sliced
- // condition is true
- conditionCache[mIndex] = mInitialValue;
- for (const auto& slicedCondition : mSlicedConditionState) {
- if (slicedCondition.second > 0) {
- conditionCache[mIndex] = ConditionState::kTrue;
- break;
- }
- }
- } else {
- const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
- if (itr == mSlicedConditionState.end()) {
- // condition not sliced, but we haven't seen the matched start or stop yet. so
- // return initial value.
- conditionCache[mIndex] = mInitialValue;
- } else {
- // return the cached condition.
- conditionCache[mIndex] =
- itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- }
- }
- return;
- }
-
- ConditionState overallState = mInitialValue;
- bool overallChanged = false;
-
- if (mOutputDimensions.size() == 0) {
- handleConditionEvent(DEFAULT_DIMENSION_KEY, matchedState == 1, &overallState,
- &overallChanged);
- } else if (!mContainANYPositionInInternalDimensions) {
- HashableDimensionKey outputValue;
- filterValues(mOutputDimensions, event.getValues(), &outputValue);
-
- // If this event has multiple nodes in the attribution chain, this log event probably will
- // generate multiple dimensions. If so, we will find if the condition changes for any
- // dimension and ask the corresponding metric producer to verify whether the actual sliced
- // condition has changed or not.
- // A high level assumption is that a predicate is either sliced or unsliced. We will never
- // have both sliced and unsliced version of a predicate.
- handleConditionEvent(outputValue, matchedState == 1, &overallState, &overallChanged);
- } else {
- ALOGE("The condition tracker should not be sliced by ANY position matcher.");
- }
- conditionCache[mIndex] = overallState;
- conditionChangedCache[mIndex] = overallChanged;
-}
-
-void SimpleConditionTracker::isConditionMet(
- const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
- const bool isPartialLink,
- vector<ConditionState>& conditionCache) const {
-
- if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
- // it has been evaluated.
- VLOG("Yes, already evaluated, %lld %d",
- (long long)mConditionId, conditionCache[mIndex]);
- return;
- }
- const auto pair = conditionParameters.find(mConditionId);
-
- if (pair == conditionParameters.end()) {
- ConditionState conditionState = ConditionState::kNotEvaluated;
- conditionState = conditionState | mInitialValue;
- if (!mSliced) {
- const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
- if (itr != mSlicedConditionState.end()) {
- ConditionState sliceState =
- itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- conditionState = conditionState | sliceState;
- }
- }
- conditionCache[mIndex] = conditionState;
- return;
- }
-
- ConditionState conditionState = ConditionState::kNotEvaluated;
- const HashableDimensionKey& key = pair->second;
- if (isPartialLink) {
- // For unseen key, check whether the require dimensions are subset of sliced condition
- // output.
- conditionState = conditionState | mInitialValue;
- for (const auto& slice : mSlicedConditionState) {
- ConditionState sliceState =
- slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- if (slice.first.contains(key)) {
- conditionState = conditionState | sliceState;
- }
- }
- } else {
- auto startedCountIt = mSlicedConditionState.find(key);
- conditionState = conditionState | mInitialValue;
- if (startedCountIt != mSlicedConditionState.end()) {
- ConditionState sliceState =
- startedCountIt->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- conditionState = conditionState | sliceState;
- }
-
- }
- conditionCache[mIndex] = conditionState;
- VLOG("Predicate %lld return %d", (long long)mConditionId, conditionCache[mIndex]);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.h b/cmds/statsd/src/condition/SimpleConditionTracker.h
deleted file mode 100644
index ea7f87b..0000000
--- a/cmds/statsd/src/condition/SimpleConditionTracker.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SIMPLE_CONDITION_TRACKER_H
-#define SIMPLE_CONDITION_TRACKER_H
-
-#include <gtest/gtest_prod.h>
-#include "ConditionTracker.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class SimpleConditionTracker : public virtual ConditionTracker {
-public:
- SimpleConditionTracker(const ConfigKey& key, const int64_t& id, const int index,
- const SimplePredicate& simplePredicate,
- const std::unordered_map<int64_t, int>& trackerNameIndexMap);
-
- ~SimpleConditionTracker();
-
- bool init(const std::vector<Predicate>& allConditionConfig,
- const std::vector<sp<ConditionTracker>>& allConditionTrackers,
- const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
- std::vector<ConditionState>& initialConditionCache) override;
-
- void evaluateCondition(const LogEvent& event,
- const std::vector<MatchingState>& eventMatcherValues,
- const std::vector<sp<ConditionTracker>>& mAllConditions,
- std::vector<ConditionState>& conditionCache,
- std::vector<bool>& changedCache) override;
-
- void isConditionMet(const ConditionKey& conditionParameters,
- const std::vector<sp<ConditionTracker>>& allConditions,
- const bool isPartialLink,
- std::vector<ConditionState>& conditionCache) const override;
-
- virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const {
- if (mSliced) {
- return &mLastChangedToTrueDimensions;
- } else {
- return nullptr;
- }
- }
-
- virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const {
- if (mSliced) {
- return &mLastChangedToFalseDimensions;
- } else {
- return nullptr;
- }
- }
-
- void getTrueSlicedDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- std::set<HashableDimensionKey>* dimensions) const override {
- for (const auto& itr : mSlicedConditionState) {
- if (itr.second > 0) {
- dimensions->insert(itr.first);
- }
- }
- }
-
- bool IsChangedDimensionTrackable() const override { return true; }
-
- bool IsSimpleCondition() const override { return true; }
-
- bool equalOutputDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensions) const override {
- return equalDimensions(mOutputDimensions, dimensions);
- }
-
-private:
- const ConfigKey mConfigKey;
- // The index of the LogEventMatcher which defines the start.
- int mStartLogMatcherIndex;
-
- // The index of the LogEventMatcher which defines the end.
- int mStopLogMatcherIndex;
-
- // if the start end needs to be nested.
- bool mCountNesting;
-
- // The index of the LogEventMatcher which defines the stop all.
- int mStopAllLogMatcherIndex;
-
- ConditionState mInitialValue;
-
- std::vector<Matcher> mOutputDimensions;
-
- bool mContainANYPositionInInternalDimensions;
-
- std::set<HashableDimensionKey> mLastChangedToTrueDimensions;
- std::set<HashableDimensionKey> mLastChangedToFalseDimensions;
-
- int mDimensionTag;
-
- std::map<HashableDimensionKey, int> mSlicedConditionState;
-
- void handleStopAll(std::vector<ConditionState>& conditionCache,
- std::vector<bool>& changedCache);
-
- void handleConditionEvent(const HashableDimensionKey& outputKey, bool matchStart,
- ConditionState* conditionCache, bool* changedCache);
-
- bool hitGuardRail(const HashableDimensionKey& newKey);
-
- void dumpState();
-
- FRIEND_TEST(SimpleConditionTrackerTest, TestSlicedCondition);
- FRIEND_TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim);
- FRIEND_TEST(SimpleConditionTrackerTest, TestStopAll);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // SIMPLE_CONDITION_TRACKER_H
diff --git a/cmds/statsd/src/condition/condition_util.cpp b/cmds/statsd/src/condition/condition_util.cpp
deleted file mode 100644
index 60b8c53..0000000
--- a/cmds/statsd/src/condition/condition_util.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Log.h"
-
-#include "condition_util.h"
-
-#include "../matchers/matcher_util.h"
-#include "ConditionTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-
-ConditionState evaluateCombinationCondition(const std::vector<int>& children,
- const LogicalOperation& operation,
- const std::vector<ConditionState>& conditionCache) {
- ConditionState newCondition;
-
- bool hasUnknown = false;
- bool hasFalse = false;
- bool hasTrue = false;
-
- for (auto childIndex : children) {
- ConditionState childState = conditionCache[childIndex];
- if (childState == ConditionState::kUnknown) {
- hasUnknown = true;
- break;
- }
- if (childState == ConditionState::kFalse) {
- hasFalse = true;
- }
- if (childState == ConditionState::kTrue) {
- hasTrue = true;
- }
- }
-
- // If any child condition is in unknown state, the condition is unknown too.
- if (hasUnknown) {
- return ConditionState::kUnknown;
- }
-
- switch (operation) {
- case LogicalOperation::AND: {
- newCondition = hasFalse ? ConditionState::kFalse : ConditionState::kTrue;
- break;
- }
- case LogicalOperation::OR: {
- newCondition = hasTrue ? ConditionState::kTrue : ConditionState::kFalse;
- break;
- }
- case LogicalOperation::NOT:
- newCondition = children.empty() ? ConditionState::kUnknown :
- ((conditionCache[children[0]] == ConditionState::kFalse) ?
- ConditionState::kTrue : ConditionState::kFalse);
- break;
- case LogicalOperation::NAND:
- newCondition = hasFalse ? ConditionState::kTrue : ConditionState::kFalse;
- break;
- case LogicalOperation::NOR:
- newCondition = hasTrue ? ConditionState::kFalse : ConditionState::kTrue;
- break;
- case LogicalOperation::LOGICAL_OPERATION_UNSPECIFIED:
- newCondition = ConditionState::kFalse;
- break;
- }
- return newCondition;
-}
-
-ConditionState operator|(ConditionState l, ConditionState r) {
- return l >= r ? l : r;
-}
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/condition/condition_util.h b/cmds/statsd/src/condition/condition_util.h
deleted file mode 100644
index fed90ec..0000000
--- a/cmds/statsd/src/condition/condition_util.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CONDITION_UTIL_H
-#define CONDITION_UTIL_H
-
-#include <vector>
-#include "../matchers/matcher_util.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-enum ConditionState {
- kNotEvaluated = -2,
- kUnknown = -1,
- kFalse = 0,
- kTrue = 1,
-};
-
-ConditionState operator|(ConditionState l, ConditionState r);
-
-ConditionState evaluateCombinationCondition(const std::vector<int>& children,
- const LogicalOperation& operation,
- const std::vector<ConditionState>& conditionCache);
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // CONDITION_UTIL_H
diff --git a/cmds/statsd/src/config/ConfigKey.cpp b/cmds/statsd/src/config/ConfigKey.cpp
deleted file mode 100644
index 4a2bd27..0000000
--- a/cmds/statsd/src/config/ConfigKey.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "config/ConfigKey.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-ConfigKey::ConfigKey() {
-}
-
-ConfigKey::ConfigKey(const ConfigKey& that) : mId(that.mId), mUid(that.mUid) {
-}
-
-ConfigKey::ConfigKey(int uid, const int64_t& id) : mId(id), mUid(uid) {
-}
-
-ConfigKey::~ConfigKey() {
-}
-
-string ConfigKey::ToString() const {
- string s;
- s += "(" + std::to_string(mUid) + " " + std::to_string(mId) + ")";
- return s;
-}
-
-
-int64_t StrToInt64(const string& str) {
- char* endp;
- int64_t value;
- value = strtoll(str.c_str(), &endp, 0);
- if (endp == str.c_str() || *endp != '\0') {
- value = 0;
- }
- return value;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/config/ConfigKey.h b/cmds/statsd/src/config/ConfigKey.h
deleted file mode 100644
index 4cc9393..0000000
--- a/cmds/statsd/src/config/ConfigKey.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-#include <string>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::hash;
-using std::string;
-
-/**
- * Uniquely identifies a configuration.
- */
-class ConfigKey {
-public:
- ConfigKey();
- ConfigKey(const ConfigKey& that);
- ConfigKey(int uid, const int64_t& id);
- ~ConfigKey();
-
- inline int GetUid() const {
- return mUid;
- }
- inline const int64_t& GetId() const {
- return mId;
- }
-
- inline bool operator<(const ConfigKey& that) const {
- if (mUid < that.mUid) {
- return true;
- }
- if (mUid > that.mUid) {
- return false;
- }
- return mId < that.mId;
- };
-
- inline bool operator==(const ConfigKey& that) const {
- return mUid == that.mUid && mId == that.mId;
- };
-
- string ToString() const;
-
-private:
- int64_t mId;
- int mUid;
-};
-
-int64_t StrToInt64(const string& str);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-/**
- * A hash function for ConfigKey so it can be used for unordered_map/set.
- * Unfortunately this has to go in std namespace because C++ is fun!
- */
-namespace std {
-
-using android::os::statsd::ConfigKey;
-
-template <>
-struct hash<ConfigKey> {
- std::size_t operator()(const ConfigKey& key) const {
- return (7 * key.GetUid()) ^ ((hash<long long>()(key.GetId())));
- }
-};
-
-} // namespace std
diff --git a/cmds/statsd/src/config/ConfigListener.cpp b/cmds/statsd/src/config/ConfigListener.cpp
deleted file mode 100644
index 21a3f16..0000000
--- a/cmds/statsd/src/config/ConfigListener.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "config/ConfigListener.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-ConfigListener::ConfigListener() {
-}
-
-ConfigListener::~ConfigListener() {
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/config/ConfigListener.h b/cmds/statsd/src/config/ConfigListener.h
deleted file mode 100644
index dcd5e52..0000000
--- a/cmds/statsd/src/config/ConfigListener.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-
-#include <utils/RefBase.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::RefBase;
-
-/**
- * Callback for different subsystems inside statsd to implement to find out
- * when a configuration has been added, updated or removed.
- */
-class ConfigListener : public virtual RefBase {
-public:
- ConfigListener();
- virtual ~ConfigListener();
-
- /**
- * A configuration was added or updated.
- */
- virtual void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config) = 0;
-
- /**
- * A configuration was removed.
- */
- virtual void OnConfigRemoved(const ConfigKey& key) = 0;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
deleted file mode 100644
index bbae3fe..0000000
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "config/ConfigManager.h"
-#include "storage/StorageManager.h"
-
-#include "guardrail/StatsdStats.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "stats_log_util.h"
-
-#include <stdio.h>
-#include <vector>
-#include "android-base/stringprintf.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::pair;
-using std::string;
-using std::vector;
-
-#define STATS_SERVICE_DIR "/data/misc/stats-service"
-
-using android::base::StringPrintf;
-using std::unique_ptr;
-
-struct ConfigReceiverDeathCookie {
- ConfigReceiverDeathCookie(const wp<ConfigManager>& configManager, const ConfigKey& configKey,
- const shared_ptr<IPendingIntentRef>& pir) :
- mConfigManager(configManager), mConfigKey(configKey), mPir(pir) {
- }
-
- wp<ConfigManager> mConfigManager;
- ConfigKey mConfigKey;
- shared_ptr<IPendingIntentRef> mPir;
-};
-
-void ConfigManager::configReceiverDied(void* cookie) {
- auto cookie_ = static_cast<ConfigReceiverDeathCookie*>(cookie);
- sp<ConfigManager> thiz = cookie_->mConfigManager.promote();
- if (!thiz) {
- return;
- }
-
- ConfigKey& configKey = cookie_->mConfigKey;
- shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
-
- // Erase the mapping from the config key to the config receiver (pir) if the
- // mapping still exists.
- lock_guard<mutex> lock(thiz->mMutex);
- auto it = thiz->mConfigReceivers.find(configKey);
- if (it != thiz->mConfigReceivers.end() && it->second == pir) {
- thiz->mConfigReceivers.erase(configKey);
- }
-
- // The death recipient corresponding to this specific pir can never be
- // triggered again, so free up resources.
- delete cookie_;
-}
-
-struct ActiveConfigChangedReceiverDeathCookie {
- ActiveConfigChangedReceiverDeathCookie(const wp<ConfigManager>& configManager, const int uid,
- const shared_ptr<IPendingIntentRef>& pir) :
- mConfigManager(configManager), mUid(uid), mPir(pir) {
- }
-
- wp<ConfigManager> mConfigManager;
- int mUid;
- shared_ptr<IPendingIntentRef> mPir;
-};
-
-void ConfigManager::activeConfigChangedReceiverDied(void* cookie) {
- auto cookie_ = static_cast<ActiveConfigChangedReceiverDeathCookie*>(cookie);
- sp<ConfigManager> thiz = cookie_->mConfigManager.promote();
- if (!thiz) {
- return;
- }
-
- int uid = cookie_->mUid;
- shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
-
- // Erase the mapping from the config key to the active config changed
- // receiver (pir) if the mapping still exists.
- lock_guard<mutex> lock(thiz->mMutex);
- auto it = thiz->mActiveConfigsChangedReceivers.find(uid);
- if (it != thiz->mActiveConfigsChangedReceivers.end() && it->second == pir) {
- thiz->mActiveConfigsChangedReceivers.erase(uid);
- }
-
- // The death recipient corresponding to this specific pir can never
- // be triggered again, so free up resources.
- delete cookie_;
-}
-
-ConfigManager::ConfigManager() :
- mConfigReceiverDeathRecipient(AIBinder_DeathRecipient_new(configReceiverDied)),
- mActiveConfigChangedReceiverDeathRecipient(
- AIBinder_DeathRecipient_new(activeConfigChangedReceiverDied)) {
-}
-
-ConfigManager::~ConfigManager() {
-}
-
-void ConfigManager::Startup() {
- map<ConfigKey, StatsdConfig> configsFromDisk;
- StorageManager::readConfigFromDisk(configsFromDisk);
- for (const auto& pair : configsFromDisk) {
- UpdateConfig(pair.first, pair.second);
- }
-}
-
-void ConfigManager::StartupForTest() {
- // Dummy function to avoid reading configs from disks for tests.
-}
-
-void ConfigManager::AddListener(const sp<ConfigListener>& listener) {
- lock_guard<mutex> lock(mMutex);
- mListeners.push_back(listener);
-}
-
-void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& config) {
- vector<sp<ConfigListener>> broadcastList;
- {
- lock_guard <mutex> lock(mMutex);
-
- const int numBytes = config.ByteSize();
- vector<uint8_t> buffer(numBytes);
- config.SerializeToArray(&buffer[0], numBytes);
-
- auto uidIt = mConfigs.find(key.GetUid());
- // GuardRail: Limit the number of configs per uid.
- if (uidIt != mConfigs.end()) {
- auto it = uidIt->second.find(key);
- if (it == uidIt->second.end() &&
- uidIt->second.size() >= StatsdStats::kMaxConfigCountPerUid) {
- ALOGE("ConfigManager: uid %d has exceeded the config count limit", key.GetUid());
- return;
- }
- }
-
- // Check if it's a duplicate config.
- if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end() &&
- StorageManager::hasIdenticalConfig(key, buffer)) {
- // This is a duplicate config.
- ALOGI("ConfigManager This is a duplicate config %s", key.ToString().c_str());
- // Update saved file on disk. We still update timestamp of file when
- // there exists a duplicate configuration to avoid garbage collection.
- update_saved_configs_locked(key, buffer, numBytes);
- return;
- }
-
- // Update saved file on disk.
- update_saved_configs_locked(key, buffer, numBytes);
-
- // Add to set.
- mConfigs[key.GetUid()].insert(key);
-
- for (const sp<ConfigListener>& listener : mListeners) {
- broadcastList.push_back(listener);
- }
- }
-
- const int64_t timestampNs = getElapsedRealtimeNs();
- // Tell everyone
- for (const sp<ConfigListener>& listener : broadcastList) {
- listener->OnConfigUpdated(timestampNs, key, config);
- }
-}
-
-void ConfigManager::SetConfigReceiver(const ConfigKey& key,
- const shared_ptr<IPendingIntentRef>& pir) {
- lock_guard<mutex> lock(mMutex);
- mConfigReceivers[key] = pir;
- AIBinder_linkToDeath(pir->asBinder().get(), mConfigReceiverDeathRecipient.get(),
- new ConfigReceiverDeathCookie(this, key, pir));
-}
-
-void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) {
- lock_guard<mutex> lock(mMutex);
- mConfigReceivers.erase(key);
-}
-
-void ConfigManager::SetActiveConfigsChangedReceiver(const int uid,
- const shared_ptr<IPendingIntentRef>& pir) {
- {
- lock_guard<mutex> lock(mMutex);
- mActiveConfigsChangedReceivers[uid] = pir;
- }
- AIBinder_linkToDeath(pir->asBinder().get(), mActiveConfigChangedReceiverDeathRecipient.get(),
- new ActiveConfigChangedReceiverDeathCookie(this, uid, pir));
-}
-
-void ConfigManager::RemoveActiveConfigsChangedReceiver(const int uid) {
- lock_guard<mutex> lock(mMutex);
- mActiveConfigsChangedReceivers.erase(uid);
-}
-
-void ConfigManager::RemoveConfig(const ConfigKey& key) {
- vector<sp<ConfigListener>> broadcastList;
- {
- lock_guard <mutex> lock(mMutex);
-
- auto uid = key.GetUid();
- auto uidIt = mConfigs.find(uid);
- if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end()) {
- // Remove from map
- uidIt->second.erase(key);
-
- for (const sp<ConfigListener>& listener : mListeners) {
- broadcastList.push_back(listener);
- }
- }
-
- // Remove from disk. There can still be a lingering file on disk so we check
- // whether or not the config was on memory.
- remove_saved_configs(key);
- }
-
- for (const sp<ConfigListener>& listener:broadcastList) {
- listener->OnConfigRemoved(key);
- }
-}
-
-void ConfigManager::remove_saved_configs(const ConfigKey& key) {
- string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
- StorageManager::deleteSuffixedFiles(STATS_SERVICE_DIR, suffix.c_str());
-}
-
-void ConfigManager::RemoveConfigs(int uid) {
- vector<ConfigKey> removed;
- vector<sp<ConfigListener>> broadcastList;
- {
- lock_guard <mutex> lock(mMutex);
-
- auto uidIt = mConfigs.find(uid);
- if (uidIt == mConfigs.end()) {
- return;
- }
-
- for (auto it = uidIt->second.begin(); it != uidIt->second.end(); ++it) {
- // Remove from map
- remove_saved_configs(*it);
- removed.push_back(*it);
- }
-
- mConfigs.erase(uidIt);
-
- for (const sp<ConfigListener>& listener : mListeners) {
- broadcastList.push_back(listener);
- }
- }
-
- // Remove separately so if they do anything in the callback they can't mess up our iteration.
- for (auto& key : removed) {
- // Tell everyone
- for (const sp<ConfigListener>& listener:broadcastList) {
- listener->OnConfigRemoved(key);
- }
- }
-}
-
-void ConfigManager::RemoveAllConfigs() {
- vector<ConfigKey> removed;
- vector<sp<ConfigListener>> broadcastList;
- {
- lock_guard <mutex> lock(mMutex);
-
- for (auto uidIt = mConfigs.begin(); uidIt != mConfigs.end();) {
- for (auto it = uidIt->second.begin(); it != uidIt->second.end();) {
- // Remove from map
- removed.push_back(*it);
- it = uidIt->second.erase(it);
- }
- uidIt = mConfigs.erase(uidIt);
- }
-
- for (const sp<ConfigListener>& listener : mListeners) {
- broadcastList.push_back(listener);
- }
- }
-
- // Remove separately so if they do anything in the callback they can't mess up our iteration.
- for (auto& key : removed) {
- // Tell everyone
- for (const sp<ConfigListener>& listener:broadcastList) {
- listener->OnConfigRemoved(key);
- }
- }
-}
-
-vector<ConfigKey> ConfigManager::GetAllConfigKeys() const {
- lock_guard<mutex> lock(mMutex);
-
- vector<ConfigKey> ret;
- for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
- for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
- ret.push_back(*it);
- }
- }
- return ret;
-}
-
-const shared_ptr<IPendingIntentRef> ConfigManager::GetConfigReceiver(const ConfigKey& key) const {
- lock_guard<mutex> lock(mMutex);
-
- auto it = mConfigReceivers.find(key);
- if (it == mConfigReceivers.end()) {
- return nullptr;
- } else {
- return it->second;
- }
-}
-
-const shared_ptr<IPendingIntentRef> ConfigManager::GetActiveConfigsChangedReceiver(const int uid)
- const {
- lock_guard<mutex> lock(mMutex);
-
- auto it = mActiveConfigsChangedReceivers.find(uid);
- if (it == mActiveConfigsChangedReceivers.end()) {
- return nullptr;
- } else {
- return it->second;
- }
-}
-
-void ConfigManager::Dump(FILE* out) {
- lock_guard<mutex> lock(mMutex);
-
- fprintf(out, "CONFIGURATIONS\n");
- fprintf(out, " uid name\n");
- for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
- for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
- fprintf(out, " %6d %lld\n", it->GetUid(), (long long)it->GetId());
- auto receiverIt = mConfigReceivers.find(*it);
- if (receiverIt != mConfigReceivers.end()) {
- fprintf(out, " -> received by PendingIntent as binder\n");
- }
- }
- }
-}
-
-void ConfigManager::update_saved_configs_locked(const ConfigKey& key,
- const vector<uint8_t>& buffer,
- const int numBytes) {
- // If there is a pre-existing config with same key we should first delete it.
- remove_saved_configs(key);
-
- // Then we save the latest config.
- string file_name =
- StringPrintf("%s/%ld_%d_%lld", STATS_SERVICE_DIR, time(nullptr),
- key.GetUid(), (long long)key.GetId());
- StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h
deleted file mode 100644
index 40146b1..0000000
--- a/cmds/statsd/src/config/ConfigManager.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-#include "config/ConfigListener.h"
-
-#include <aidl/android/os/IPendingIntentRef.h>
-#include <mutex>
-#include <string>
-
-#include <stdio.h>
-
-using aidl::android::os::IPendingIntentRef;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Keeps track of which configurations have been set from various sources.
- */
-class ConfigManager : public virtual android::RefBase {
-public:
- ConfigManager();
- virtual ~ConfigManager();
-
- /**
- * Initialize ConfigListener by reading from disk and get updates.
- */
- void Startup();
-
- /*
- * Dummy initializer for tests.
- */
- void StartupForTest();
-
- /**
- * Someone else wants to know about the configs.
- */
- void AddListener(const sp<ConfigListener>& listener);
-
- /**
- * A configuration was added or updated.
- *
- * Reports this to listeners.
- */
- void UpdateConfig(const ConfigKey& key, const StatsdConfig& data);
-
- /**
- * Sets the broadcast receiver for a configuration key.
- */
- void SetConfigReceiver(const ConfigKey& key, const shared_ptr<IPendingIntentRef>& pir);
-
- /**
- * Returns the package name and class name representing the broadcast receiver for this config.
- */
- const shared_ptr<IPendingIntentRef> GetConfigReceiver(const ConfigKey& key) const;
-
- /**
- * Returns all config keys registered.
- */
- std::vector<ConfigKey> GetAllConfigKeys() const;
-
- /**
- * Erase any broadcast receiver associated with this config key.
- */
- void RemoveConfigReceiver(const ConfigKey& key);
-
- /**
- * Sets the broadcast receiver that is notified whenever the list of active configs
- * changes for this uid.
- */
- void SetActiveConfigsChangedReceiver(const int uid, const shared_ptr<IPendingIntentRef>& pir);
-
- /**
- * Returns the broadcast receiver for active configs changed for this uid.
- */
-
- const shared_ptr<IPendingIntentRef> GetActiveConfigsChangedReceiver(const int uid) const;
-
- /**
- * Erase any active configs changed broadcast receiver associated with this uid.
- */
- void RemoveActiveConfigsChangedReceiver(const int uid);
-
- /**
- * A configuration was removed.
- *
- * Reports this to listeners.
- */
- void RemoveConfig(const ConfigKey& key);
-
- /**
- * Remove all of the configs for the given uid.
- */
- void RemoveConfigs(int uid);
-
- /**
- * Remove all of the configs from memory.
- */
- void RemoveAllConfigs();
-
- /**
- * Text dump of our state for debugging.
- */
- void Dump(FILE* out);
-
-private:
- mutable std::mutex mMutex;
-
- /**
- * Save the configs to disk.
- */
- void update_saved_configs_locked(const ConfigKey& key,
- const std::vector<uint8_t>& buffer,
- const int numBytes);
-
- /**
- * Remove saved configs from disk.
- */
- void remove_saved_configs(const ConfigKey& key);
-
- /**
- * Maps from uid to the config keys that have been set.
- */
- std::map<int, std::set<ConfigKey>> mConfigs;
-
- /**
- * Each config key can be subscribed by up to one receiver, specified as IPendingIntentRef.
- */
- std::map<ConfigKey, shared_ptr<IPendingIntentRef>> mConfigReceivers;
-
- /**
- * Each uid can be subscribed by up to one receiver to notify that the list of active configs
- * for this uid has changed. The receiver is specified as IPendingIntentRef.
- */
- std::map<int, shared_ptr<IPendingIntentRef>> mActiveConfigsChangedReceivers;
-
- /**
- * The ConfigListeners that will be told about changes.
- */
- std::vector<sp<ConfigListener>> mListeners;
-
- // Death recipients that are triggered when the host process holding an
- // IPendingIntentRef dies.
- ::ndk::ScopedAIBinder_DeathRecipient mConfigReceiverDeathRecipient;
- ::ndk::ScopedAIBinder_DeathRecipient mActiveConfigChangedReceiverDeathRecipient;
-
- /**
- * Death recipient callback that is called when a config receiver dies.
- * The cookie is a pointer to a ConfigReceiverDeathCookie.
- */
- static void configReceiverDied(void* cookie);
-
- /**
- * Death recipient callback that is called when an active config changed
- * receiver dies. The cookie is a pointer to an
- * ActiveConfigChangedReceiverDeathCookie.
- */
- static void activeConfigChangedReceiverDied(void* cookie);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/experiment_ids.proto b/cmds/statsd/src/experiment_ids.proto
deleted file mode 100644
index c203631..0000000
--- a/cmds/statsd/src/experiment_ids.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.internal.os";
-option java_outer_classname = "ExperimentIdsProto";
-
-// StatsLogProcessor uses the proto to parse experiment ids from
-// BinaryPushStateChanged atoms. This needs to be in sync with
-// TrainExperimentIds in atoms.proto.
-message ExperimentIds {
- repeated int64 experiment_id = 1;
-}
diff --git a/cmds/statsd/src/external/Perfetto.cpp b/cmds/statsd/src/external/Perfetto.cpp
deleted file mode 100644
index 85b660e..0000000
--- a/cmds/statsd/src/external/Perfetto.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "config/ConfigKey.h"
-#include "Log.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alert
-
-#include <android-base/unique_fd.h>
-#include <inttypes.h>
-#include <sys/wait.h>
-
-#include <string>
-
-namespace {
-const char kDropboxTag[] = "perfetto";
-}
-
-namespace android {
-namespace os {
-namespace statsd {
-
-bool CollectPerfettoTraceAndUploadToDropbox(const PerfettoDetails& config,
- int64_t subscription_id,
- int64_t alert_id,
- const ConfigKey& configKey) {
- VLOG("Starting trace collection through perfetto");
-
- if (!config.has_trace_config()) {
- ALOGE("The perfetto trace config is empty, aborting");
- return false;
- }
-
- char subscriptionId[25];
- char alertId[25];
- char configId[25];
- char configUid[25];
- snprintf(subscriptionId, sizeof(subscriptionId), "%" PRId64, subscription_id);
- snprintf(alertId, sizeof(alertId), "%" PRId64, alert_id);
- snprintf(configId, sizeof(configId), "%" PRId64, configKey.GetId());
- snprintf(configUid, sizeof(configUid), "%d", configKey.GetUid());
-
- android::base::unique_fd readPipe;
- android::base::unique_fd writePipe;
- if (!android::base::Pipe(&readPipe, &writePipe)) {
- ALOGE("pipe() failed while calling the Perfetto client: %s", strerror(errno));
- return false;
- }
-
- pid_t pid = fork();
- if (pid < 0) {
- ALOGE("fork() failed while calling the Perfetto client: %s", strerror(errno));
- return false;
- }
-
- if (pid == 0) {
- // Child process.
-
- // No malloc calls or library calls after this point. Remember that even
- // ALOGx (aka android_printLog()) can use dynamic memory for vsprintf().
-
- writePipe.reset(); // Close the write end (owned by the main process).
-
- // Replace stdin with |readPipe| so the main process can write into it.
- if (dup2(readPipe.get(), STDIN_FILENO) < 0) _exit(1);
- readPipe.reset();
-
- // Replace stdout/stderr with /dev/null and close any other file
- // descriptor. This is to avoid SELinux complaining about perfetto
- // trying to access files accidentally left open by statsd (i.e. files
- // that have been opened without the O_CLOEXEC flag).
- int devNullFd = open("/dev/null", O_RDWR | O_CLOEXEC);
- if (dup2(devNullFd, STDOUT_FILENO) < 0) _exit(2);
- if (dup2(devNullFd, STDERR_FILENO) < 0) _exit(3);
- close(devNullFd);
- for (int i = 0; i < 1024; i++) {
- if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO) close(i);
- }
-
- execl("/system/bin/perfetto", "perfetto", "--background", "--config", "-", "--dropbox",
- kDropboxTag, "--alert-id", alertId, "--config-id", configId, "--config-uid",
- configUid, "--subscription-id", subscriptionId, nullptr);
-
- // execl() doesn't return in case of success, if we get here something
- // failed.
- _exit(4);
- }
-
- // Main process.
-
- readPipe.reset(); // Close the read end (owned by the child process).
-
- // Using fdopen() because fwrite() has the right logic to chunking write()
- // over a pipe (see __sfvwrite()).
- FILE* writePipeStream = android::base::Fdopen(std::move(writePipe), "wb");
- if (!writePipeStream) {
- ALOGE("fdopen() failed while calling the Perfetto client: %s", strerror(errno));
- return false;
- }
-
- const std::string& cfgProto = config.trace_config();
- size_t bytesWritten = fwrite(cfgProto.data(), 1, cfgProto.size(), writePipeStream);
- fclose(writePipeStream);
- if (bytesWritten != cfgProto.size() || cfgProto.size() == 0) {
- ALOGE("fwrite() failed (ret: %zd) while calling the Perfetto client: %s", bytesWritten,
- strerror(errno));
- return false;
- }
-
- // This does NOT wait for the full duration of the trace. It just waits until
- // the process has read the config from stdin and detached.
- int childStatus = 0;
- waitpid(pid, &childStatus, 0);
- if (!WIFEXITED(childStatus) || WEXITSTATUS(childStatus) != 0) {
- ALOGE("Child process failed (0x%x) while calling the Perfetto client", childStatus);
- return false;
- }
-
- VLOG("CollectPerfettoTraceAndUploadToDropbox() succeeded");
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/Perfetto.h b/cmds/statsd/src/external/Perfetto.h
deleted file mode 100644
index 095782a..0000000
--- a/cmds/statsd/src/external/Perfetto.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class ConfigKey;
-class PerfettoDetails; // Declared in statsd_config.pb.h
-
-// Starts the collection of a Perfetto trace with the given |config|.
-// The trace is uploaded to Dropbox by the perfetto cmdline util once done.
-// This method returns immediately after passing the config and does NOT wait
-// for the full duration of the trace.
-bool CollectPerfettoTraceAndUploadToDropbox(const PerfettoDetails& config,
- int64_t subscription_id,
- int64_t alert_id,
- const ConfigKey& configKey);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/PullDataReceiver.h b/cmds/statsd/src/external/PullDataReceiver.h
deleted file mode 100644
index dd5c0cf..0000000
--- a/cmds/statsd/src/external/PullDataReceiver.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-#include "StatsPuller.h"
-#include "logd/LogEvent.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PullDataReceiver : virtual public RefBase{
- public:
- virtual ~PullDataReceiver() {}
- /**
- * @param data The pulled data.
- * @param pullSuccess Whether the pull succeeded. If the pull does not succeed, the data for the
- * bucket should be invalidated.
- * @param originalPullTimeNs This is when all the pulls have been initiated (elapsed time).
- */
- virtual void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
- bool pullSuccess, int64_t originalPullTimeNs) = 0;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/PullResultReceiver.cpp b/cmds/statsd/src/external/PullResultReceiver.cpp
deleted file mode 100644
index 8aa4792..0000000
--- a/cmds/statsd/src/external/PullResultReceiver.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "PullResultReceiver.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-PullResultReceiver::PullResultReceiver(
- std::function<void(int32_t, bool, const vector<StatsEventParcel>&)> pullFinishCb)
- : pullFinishCallback(std::move(pullFinishCb)) {
-}
-
-Status PullResultReceiver::pullFinished(int32_t atomTag, bool success,
- const vector<StatsEventParcel>& output) {
- pullFinishCallback(atomTag, success, output);
- return Status::ok();
-}
-
-PullResultReceiver::~PullResultReceiver() {
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/PullResultReceiver.h b/cmds/statsd/src/external/PullResultReceiver.h
deleted file mode 100644
index ceaae80..0000000
--- a/cmds/statsd/src/external/PullResultReceiver.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <aidl/android/os/BnPullAtomResultReceiver.h>
-#include <aidl/android/util/StatsEventParcel.h>
-
-using namespace std;
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::os::BnPullAtomResultReceiver;
-using aidl::android::util::StatsEventParcel;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PullResultReceiver : public BnPullAtomResultReceiver {
-public:
- PullResultReceiver(function<void(int32_t, bool, const vector<StatsEventParcel>&)>
- pullFinishCallback);
- ~PullResultReceiver();
-
- /**
- * Binder call for finishing a pull.
- */
- Status pullFinished(int32_t atomTag, bool success,
- const vector<StatsEventParcel>& output) override;
-
-private:
- function<void(int32_t, bool, const vector<StatsEventParcel>&)> pullFinishCallback;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/PullUidProvider.h b/cmds/statsd/src/external/PullUidProvider.h
deleted file mode 100644
index 2318c50..0000000
--- a/cmds/statsd/src/external/PullUidProvider.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-
-#include "StatsPuller.h"
-#include "logd/LogEvent.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PullUidProvider : virtual public RefBase {
-public:
- virtual ~PullUidProvider() {}
-
- /**
- * @param atomId The atom for which to get the uids.
- */
- virtual vector<int32_t> getPullAtomUids(int32_t atomId) = 0;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.cpp b/cmds/statsd/src/external/StatsCallbackPuller.cpp
deleted file mode 100644
index 78e6f09..0000000
--- a/cmds/statsd/src/external/StatsCallbackPuller.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsCallbackPuller.h"
-#include "PullResultReceiver.h"
-#include "StatsPullerManager.h"
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-
-#include <aidl/android/util/StatsEventParcel.h>
-
-using namespace std;
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::util::StatsEventParcel;
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsCallbackPuller::StatsCallbackPuller(int tagId, const shared_ptr<IPullAtomCallback>& callback,
- const int64_t coolDownNs, int64_t timeoutNs,
- const vector<int> additiveFields)
- : StatsPuller(tagId, coolDownNs, timeoutNs, additiveFields), mCallback(callback) {
- VLOG("StatsCallbackPuller created for tag %d", tagId);
-}
-
-bool StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
- VLOG("StatsCallbackPuller called for tag %d", mTagId);
- if(mCallback == nullptr) {
- ALOGW("No callback registered");
- return false;
- }
-
- // Shared variables needed in the result receiver.
- shared_ptr<mutex> cv_mutex = make_shared<mutex>();
- shared_ptr<condition_variable> cv = make_shared<condition_variable>();
- shared_ptr<bool> pullFinish = make_shared<bool>(false);
- shared_ptr<bool> pullSuccess = make_shared<bool>(false);
- shared_ptr<vector<shared_ptr<LogEvent>>> sharedData =
- make_shared<vector<shared_ptr<LogEvent>>>();
-
- shared_ptr<PullResultReceiver> resultReceiver = SharedRefBase::make<PullResultReceiver>(
- [cv_mutex, cv, pullFinish, pullSuccess, sharedData](
- int32_t atomTag, bool success, const vector<StatsEventParcel>& output) {
- // This is the result of the pull, executing in a statsd binder thread.
- // The pull could have taken a long time, and we should only modify
- // data (the output param) if the pointer is in scope and the pull did not time out.
- {
- lock_guard<mutex> lk(*cv_mutex);
- for (const StatsEventParcel& parcel: output) {
- shared_ptr<LogEvent> event = make_shared<LogEvent>(/*uid=*/-1, /*pid=*/-1);
- bool valid = event->parseBuffer((uint8_t*)parcel.buffer.data(),
- parcel.buffer.size());
- if (valid) {
- sharedData->push_back(event);
- } else {
- StatsdStats::getInstance().noteAtomError(event->GetTagId(),
- /*pull=*/true);
- }
- }
- *pullSuccess = success;
- *pullFinish = true;
- }
- cv->notify_one();
- });
-
- // Initiate the pull. This is a oneway call to a different process, except
- // in unit tests. In process calls are not oneway.
- Status status = mCallback->onPullAtom(mTagId, resultReceiver);
- if (!status.isOk()) {
- StatsdStats::getInstance().notePullBinderCallFailed(mTagId);
- return false;
- }
-
- {
- unique_lock<mutex> unique_lk(*cv_mutex);
- // Wait until the pull finishes, or until the pull timeout.
- cv->wait_for(unique_lk, chrono::nanoseconds(mPullTimeoutNs),
- [pullFinish] { return *pullFinish; });
- if (!*pullFinish) {
- // Note: The parent stats puller will also note that there was a timeout and that the
- // cache should be cleared. Once we migrate all pullers to this callback, we could
- // consolidate the logic.
- return true;
- } else {
- // Only copy the data if we did not timeout and the pull was successful.
- if (*pullSuccess) {
- *data = std::move(*sharedData);
- }
- VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
- return *pullSuccess;
- }
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.h b/cmds/statsd/src/external/StatsCallbackPuller.h
deleted file mode 100644
index e82e8bb..0000000
--- a/cmds/statsd/src/external/StatsCallbackPuller.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/IPullAtomCallback.h>
-#include "StatsPuller.h"
-
-using aidl::android::os::IPullAtomCallback;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsCallbackPuller : public StatsPuller {
-public:
- explicit StatsCallbackPuller(int tagId, const shared_ptr<IPullAtomCallback>& callback,
- const int64_t coolDownNs, const int64_t timeoutNs,
- const std::vector<int> additiveFields);
-
-private:
- bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
- const shared_ptr<IPullAtomCallback> mCallback;
-
- FRIEND_TEST(StatsCallbackPullerTest, PullFail);
- FRIEND_TEST(StatsCallbackPullerTest, PullSuccess);
- FRIEND_TEST(StatsCallbackPullerTest, PullTimeout);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp
deleted file mode 100644
index bb5d0a6..0000000
--- a/cmds/statsd/src/external/StatsPuller.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsPuller.h"
-#include "StatsPullerManager.h"
-#include "guardrail/StatsdStats.h"
-#include "puller_util.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::lock_guard;
-
-sp<UidMap> StatsPuller::mUidMap = nullptr;
-void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; }
-
-StatsPuller::StatsPuller(const int tagId, const int64_t coolDownNs, const int64_t pullTimeoutNs,
- const std::vector<int> additiveFields)
- : mTagId(tagId),
- mPullTimeoutNs(pullTimeoutNs),
- mCoolDownNs(coolDownNs),
- mAdditiveFields(additiveFields),
- mLastPullTimeNs(0),
- mLastEventTimeNs(0) {
-}
-
-bool StatsPuller::Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data) {
- lock_guard<std::mutex> lock(mLock);
- const int64_t elapsedTimeNs = getElapsedRealtimeNs();
- const int64_t systemUptimeMillis = getSystemUptimeMillis();
- StatsdStats::getInstance().notePull(mTagId);
- const bool shouldUseCache =
- (mLastEventTimeNs == eventTimeNs) || (elapsedTimeNs - mLastPullTimeNs < mCoolDownNs);
- if (shouldUseCache) {
- if (mHasGoodData) {
- (*data) = mCachedData;
- StatsdStats::getInstance().notePullFromCache(mTagId);
-
- }
- return mHasGoodData;
- }
- if (mLastPullTimeNs > 0) {
- StatsdStats::getInstance().updateMinPullIntervalSec(
- mTagId, (elapsedTimeNs - mLastPullTimeNs) / NS_PER_SEC);
- }
- mCachedData.clear();
- mLastPullTimeNs = elapsedTimeNs;
- mLastEventTimeNs = eventTimeNs;
- mHasGoodData = PullInternal(&mCachedData);
- if (!mHasGoodData) {
- return mHasGoodData;
- }
- const int64_t pullElapsedDurationNs = getElapsedRealtimeNs() - elapsedTimeNs;
- const int64_t pullSystemUptimeDurationMillis = getSystemUptimeMillis() - systemUptimeMillis;
- StatsdStats::getInstance().notePullTime(mTagId, pullElapsedDurationNs);
- const bool pullTimeOut = pullElapsedDurationNs > mPullTimeoutNs;
- if (pullTimeOut) {
- // Something went wrong. Discard the data.
- mCachedData.clear();
- mHasGoodData = false;
- StatsdStats::getInstance().notePullTimeout(
- mTagId, pullSystemUptimeDurationMillis, NanoToMillis(pullElapsedDurationNs));
- ALOGW("Pull for atom %d exceeds timeout %lld nano seconds.", mTagId,
- (long long)pullElapsedDurationNs);
- return mHasGoodData;
- }
-
- if (mCachedData.size() > 0) {
- mapAndMergeIsolatedUidsToHostUid(mCachedData, mUidMap, mTagId, mAdditiveFields);
- }
-
- if (mCachedData.empty()) {
- VLOG("Data pulled is empty");
- StatsdStats::getInstance().noteEmptyData(mTagId);
- }
-
- (*data) = mCachedData;
- return mHasGoodData;
-}
-
-int StatsPuller::ForceClearCache() {
- return clearCache();
-}
-
-int StatsPuller::clearCache() {
- lock_guard<std::mutex> lock(mLock);
- return clearCacheLocked();
-}
-
-int StatsPuller::clearCacheLocked() {
- int ret = mCachedData.size();
- mCachedData.clear();
- mLastPullTimeNs = 0;
- mLastEventTimeNs = 0;
- return ret;
-}
-
-int StatsPuller::ClearCacheIfNecessary(int64_t timestampNs) {
- if (timestampNs - mLastPullTimeNs > mCoolDownNs) {
- return clearCache();
- } else {
- return 0;
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h
deleted file mode 100644
index 470d15e..0000000
--- a/cmds/statsd/src/external/StatsPuller.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <utils/RefBase.h>
-#include <mutex>
-#include <vector>
-#include "packages/UidMap.h"
-
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "puller_util.h"
-
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsPuller : public virtual RefBase {
-public:
- explicit StatsPuller(const int tagId,
- const int64_t coolDownNs = NS_PER_SEC,
- const int64_t pullTimeoutNs = StatsdStats::kPullMaxDelayNs,
- const std::vector<int> additiveFields = std::vector<int>());
-
- virtual ~StatsPuller() {}
-
- // Pulls the most recent data.
- // The data may be served from cache if consecutive pulls come within
- // predefined cooldown time.
- // Returns true if the pull was successful.
- // Returns false when
- // 1) the pull fails
- // 2) pull takes longer than mPullTimeoutNs (intrinsic to puller)
- // If a metric wants to make any change to the data, like timestamps, it
- // should make a copy as this data may be shared with multiple metrics.
- bool Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data);
-
- // Clear cache immediately
- int ForceClearCache();
-
- // Clear cache if elapsed time is more than cooldown time
- int ClearCacheIfNecessary(int64_t timestampNs);
-
- static void SetUidMap(const sp<UidMap>& uidMap);
-
- virtual void SetStatsCompanionService(
- shared_ptr<IStatsCompanionService> statsCompanionService) {};
-
-protected:
- const int mTagId;
-
- // Max time allowed to pull this atom.
- // We cannot reliably kill a pull thread. So we don't terminate the puller.
- // The data is discarded if the pull takes longer than this and mHasGoodData
- // marked as false.
- const int64_t mPullTimeoutNs = StatsdStats::kPullMaxDelayNs;
-
-private:
- mutable std::mutex mLock;
-
- // Real puller impl.
- virtual bool PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) = 0;
-
- bool mHasGoodData = false;
-
- // Minimum time before this puller does actual pull again.
- // Pullers can cause significant impact to system health and battery.
- // So that we don't pull too frequently.
- // If a pull request comes before cooldown, a cached version from previous pull
- // will be returned.
- const int64_t mCoolDownNs = 1 * NS_PER_SEC;
-
- // The field numbers of the fields that need to be summed when merging
- // isolated uid with host uid.
- const std::vector<int> mAdditiveFields;
-
- int64_t mLastPullTimeNs;
-
- // All pulls happen due to an event (app upgrade, bucket boundary, condition change, etc).
- // If multiple pulls need to be done at the same event time, we will always use the cache after
- // the first pull.
- int64_t mLastEventTimeNs;
-
- // Cache of data from last pull. If next request comes before cool down finishes,
- // cached data will be returned.
- // Cached data is cleared when
- // 1) A pull fails
- // 2) A new pull request comes after cooldown time.
- // 3) clearCache is called.
- std::vector<std::shared_ptr<LogEvent>> mCachedData;
-
- int clearCache();
-
- int clearCacheLocked();
-
- static sp<UidMap> mUidMap;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
deleted file mode 100644
index 8a9ec74..0000000
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false
-#include "Log.h"
-
-#include "StatsPullerManager.h"
-
-#include <cutils/log.h>
-#include <math.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <iostream>
-
-#include "../StatsService.h"
-#include "../logd/LogEvent.h"
-#include "../stats_log_util.h"
-#include "../statscompanion_util.h"
-#include "StatsCallbackPuller.h"
-#include "TrainInfoPuller.h"
-#include "statslog_statsd.h"
-
-using std::shared_ptr;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Stores the puller as a wp to avoid holding a reference in case it is unregistered and
-// pullAtomCallbackDied is never called.
-struct PullAtomCallbackDeathCookie {
- PullAtomCallbackDeathCookie(const wp<StatsPullerManager>& pullerManager,
- const PullerKey& pullerKey, const wp<StatsPuller>& puller) :
- mPullerManager(pullerManager), mPullerKey(pullerKey), mPuller(puller) {
- }
-
- wp<StatsPullerManager> mPullerManager;
- PullerKey mPullerKey;
- wp<StatsPuller> mPuller;
-};
-
-void StatsPullerManager::pullAtomCallbackDied(void* cookie) {
- PullAtomCallbackDeathCookie* cookie_ = static_cast<PullAtomCallbackDeathCookie*>(cookie);
- sp<StatsPullerManager> thiz = cookie_->mPullerManager.promote();
- if (!thiz) {
- return;
- }
-
- const PullerKey& pullerKey = cookie_->mPullerKey;
- wp<StatsPuller> puller = cookie_->mPuller;
-
- // Erase the mapping from the puller key to the puller if the mapping still exists.
- // Note that we are removing the StatsPuller object, which internally holds the binder
- // IPullAtomCallback. However, each new registration creates a new StatsPuller, so this works.
- lock_guard<mutex> lock(thiz->mLock);
- const auto& it = thiz->kAllPullAtomInfo.find(pullerKey);
- if (it != thiz->kAllPullAtomInfo.end() && puller != nullptr && puller == it->second) {
- StatsdStats::getInstance().notePullerCallbackRegistrationChanged(pullerKey.atomTag,
- /*registered=*/false);
- thiz->kAllPullAtomInfo.erase(pullerKey);
- }
- // The death recipient corresponding to this specific IPullAtomCallback can never
- // be triggered again, so free up resources.
- delete cookie_;
-}
-
-// Values smaller than this may require to update the alarm.
-const int64_t NO_ALARM_UPDATE = INT64_MAX;
-
-StatsPullerManager::StatsPullerManager()
- : kAllPullAtomInfo({
- // TrainInfo.
- {{.atomTag = util::TRAIN_INFO, .uid = AID_STATSD}, new TrainInfoPuller()},
- }),
- mNextPullTimeNs(NO_ALARM_UPDATE),
- mPullAtomCallbackDeathRecipient(AIBinder_DeathRecipient_new(pullAtomCallbackDied)) {
-}
-
-bool StatsPullerManager::Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
- vector<shared_ptr<LogEvent>>* data, bool useUids) {
- std::lock_guard<std::mutex> _l(mLock);
- return PullLocked(tagId, configKey, eventTimeNs, data, useUids);
-}
-
-bool StatsPullerManager::Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids) {
- std::lock_guard<std::mutex> _l(mLock);
- return PullLocked(tagId, uids, eventTimeNs, data, useUids);
-}
-
-bool StatsPullerManager::PullLocked(int tagId, const ConfigKey& configKey,
- const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data,
- bool useUids) {
- vector<int32_t> uids;
- if (useUids) {
- auto uidProviderIt = mPullUidProviders.find(configKey);
- if (uidProviderIt == mPullUidProviders.end()) {
- ALOGE("Error pulling tag %d. No pull uid provider for config key %s", tagId,
- configKey.ToString().c_str());
- StatsdStats::getInstance().notePullUidProviderNotFound(tagId);
- return false;
- }
- sp<PullUidProvider> pullUidProvider = uidProviderIt->second.promote();
- if (pullUidProvider == nullptr) {
- ALOGE("Error pulling tag %d, pull uid provider for config %s is gone.", tagId,
- configKey.ToString().c_str());
- StatsdStats::getInstance().notePullUidProviderNotFound(tagId);
- return false;
- }
- uids = pullUidProvider->getPullAtomUids(tagId);
- }
- return PullLocked(tagId, uids, eventTimeNs, data, useUids);
-}
-
-bool StatsPullerManager::PullLocked(int tagId, const vector<int32_t>& uids,
- const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data,
- bool useUids) {
- VLOG("Initiating pulling %d", tagId);
- if (useUids) {
- for (int32_t uid : uids) {
- PullerKey key = {.atomTag = tagId, .uid = uid};
- auto pullerIt = kAllPullAtomInfo.find(key);
- if (pullerIt != kAllPullAtomInfo.end()) {
- bool ret = pullerIt->second->Pull(eventTimeNs, data);
- VLOG("pulled %zu items", data->size());
- if (!ret) {
- StatsdStats::getInstance().notePullFailed(tagId);
- }
- return ret;
- }
- }
- StatsdStats::getInstance().notePullerNotFound(tagId);
- ALOGW("StatsPullerManager: Unknown tagId %d", tagId);
- return false; // Return early since we don't know what to pull.
- } else {
- PullerKey key = {.atomTag = tagId, .uid = -1};
- auto pullerIt = kAllPullAtomInfo.find(key);
- if (pullerIt != kAllPullAtomInfo.end()) {
- bool ret = pullerIt->second->Pull(eventTimeNs, data);
- VLOG("pulled %zu items", data->size());
- if (!ret) {
- StatsdStats::getInstance().notePullFailed(tagId);
- }
- return ret;
- }
- ALOGW("StatsPullerManager: Unknown tagId %d", tagId);
- return false; // Return early since we don't know what to pull.
- }
-}
-
-bool StatsPullerManager::PullerForMatcherExists(int tagId) const {
- // Pulled atoms might be registered after we parse the config, so just make sure the id is in
- // an appropriate range.
- return isVendorPulledAtom(tagId) || isPulledAtom(tagId);
-}
-
-void StatsPullerManager::updateAlarmLocked() {
- if (mNextPullTimeNs == NO_ALARM_UPDATE) {
- VLOG("No need to set alarms. Skipping");
- return;
- }
-
- // TODO(b/151045771): do not hold a lock while making a binder call
- if (mStatsCompanionService != nullptr) {
- mStatsCompanionService->setPullingAlarm(mNextPullTimeNs / 1000000);
- } else {
- VLOG("StatsCompanionService not available. Alarm not set.");
- }
- return;
-}
-
-void StatsPullerManager::SetStatsCompanionService(
- shared_ptr<IStatsCompanionService> statsCompanionService) {
- std::lock_guard<std::mutex> _l(mLock);
- shared_ptr<IStatsCompanionService> tmpForLock = mStatsCompanionService;
- mStatsCompanionService = statsCompanionService;
- for (const auto& pulledAtom : kAllPullAtomInfo) {
- pulledAtom.second->SetStatsCompanionService(statsCompanionService);
- }
- if (mStatsCompanionService != nullptr) {
- updateAlarmLocked();
- }
-}
-
-void StatsPullerManager::RegisterReceiver(int tagId, const ConfigKey& configKey,
- wp<PullDataReceiver> receiver, int64_t nextPullTimeNs,
- int64_t intervalNs) {
- std::lock_guard<std::mutex> _l(mLock);
- auto& receivers = mReceivers[{.atomTag = tagId, .configKey = configKey}];
- for (auto it = receivers.begin(); it != receivers.end(); it++) {
- if (it->receiver == receiver) {
- VLOG("Receiver already registered of %d", (int)receivers.size());
- return;
- }
- }
- ReceiverInfo receiverInfo;
- receiverInfo.receiver = receiver;
-
- // Round it to the nearest minutes. This is the limit of alarm manager.
- // In practice, we should always have larger buckets.
- int64_t roundedIntervalNs = intervalNs / NS_PER_SEC / 60 * NS_PER_SEC * 60;
- // Scheduled pulling should be at least 1 min apart.
- // This can be lower in cts tests, in which case we round it to 1 min.
- if (roundedIntervalNs < 60 * (int64_t)NS_PER_SEC) {
- roundedIntervalNs = 60 * (int64_t)NS_PER_SEC;
- }
-
- receiverInfo.intervalNs = roundedIntervalNs;
- receiverInfo.nextPullTimeNs = nextPullTimeNs;
- receivers.push_back(receiverInfo);
-
- // There is only one alarm for all pulled events. So only set it to the smallest denom.
- if (nextPullTimeNs < mNextPullTimeNs) {
- VLOG("Updating next pull time %lld", (long long)mNextPullTimeNs);
- mNextPullTimeNs = nextPullTimeNs;
- updateAlarmLocked();
- }
- VLOG("Puller for tagId %d registered of %d", tagId, (int)receivers.size());
-}
-
-void StatsPullerManager::UnRegisterReceiver(int tagId, const ConfigKey& configKey,
- wp<PullDataReceiver> receiver) {
- std::lock_guard<std::mutex> _l(mLock);
- auto receiversIt = mReceivers.find({.atomTag = tagId, .configKey = configKey});
- if (receiversIt == mReceivers.end()) {
- VLOG("Unknown pull code or no receivers: %d", tagId);
- return;
- }
- std::list<ReceiverInfo>& receivers = receiversIt->second;
- for (auto it = receivers.begin(); it != receivers.end(); it++) {
- if (receiver == it->receiver) {
- receivers.erase(it);
- VLOG("Puller for tagId %d unregistered of %d", tagId, (int)receivers.size());
- return;
- }
- }
-}
-
-void StatsPullerManager::RegisterPullUidProvider(const ConfigKey& configKey,
- wp<PullUidProvider> provider) {
- std::lock_guard<std::mutex> _l(mLock);
- mPullUidProviders[configKey] = provider;
-}
-
-void StatsPullerManager::UnregisterPullUidProvider(const ConfigKey& configKey,
- wp<PullUidProvider> provider) {
- std::lock_guard<std::mutex> _l(mLock);
- const auto& it = mPullUidProviders.find(configKey);
- if (it != mPullUidProviders.end() && it->second == provider) {
- mPullUidProviders.erase(it);
- }
-}
-
-void StatsPullerManager::OnAlarmFired(int64_t elapsedTimeNs) {
- std::lock_guard<std::mutex> _l(mLock);
- int64_t wallClockNs = getWallClockNs();
-
- int64_t minNextPullTimeNs = NO_ALARM_UPDATE;
-
- vector<pair<const ReceiverKey*, vector<ReceiverInfo*>>> needToPull;
- for (auto& pair : mReceivers) {
- vector<ReceiverInfo*> receivers;
- if (pair.second.size() != 0) {
- for (ReceiverInfo& receiverInfo : pair.second) {
- if (receiverInfo.nextPullTimeNs <= elapsedTimeNs) {
- receivers.push_back(&receiverInfo);
- } else {
- if (receiverInfo.nextPullTimeNs < minNextPullTimeNs) {
- minNextPullTimeNs = receiverInfo.nextPullTimeNs;
- }
- }
- }
- if (receivers.size() > 0) {
- needToPull.push_back(make_pair(&pair.first, receivers));
- }
- }
- }
- for (const auto& pullInfo : needToPull) {
- vector<shared_ptr<LogEvent>> data;
- bool pullSuccess = PullLocked(pullInfo.first->atomTag, pullInfo.first->configKey,
- elapsedTimeNs, &data);
- if (!pullSuccess) {
- VLOG("pull failed at %lld, will try again later", (long long)elapsedTimeNs);
- }
-
- // Convention is to mark pull atom timestamp at request time.
- // If we pull at t0, puller starts at t1, finishes at t2, and send back
- // at t3, we mark t0 as its timestamp, which should correspond to its
- // triggering event, such as condition change at t0.
- // Here the triggering event is alarm fired from AlarmManager.
- // In ValueMetricProducer and GaugeMetricProducer we do same thing
- // when pull on condition change, etc.
- for (auto& event : data) {
- event->setElapsedTimestampNs(elapsedTimeNs);
- event->setLogdWallClockTimestampNs(wallClockNs);
- }
-
- for (const auto& receiverInfo : pullInfo.second) {
- sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote();
- if (receiverPtr != nullptr) {
- receiverPtr->onDataPulled(data, pullSuccess, elapsedTimeNs);
- // We may have just come out of a coma, compute next pull time.
- int numBucketsAhead =
- (elapsedTimeNs - receiverInfo->nextPullTimeNs) / receiverInfo->intervalNs;
- receiverInfo->nextPullTimeNs += (numBucketsAhead + 1) * receiverInfo->intervalNs;
- if (receiverInfo->nextPullTimeNs < minNextPullTimeNs) {
- minNextPullTimeNs = receiverInfo->nextPullTimeNs;
- }
- } else {
- VLOG("receiver already gone.");
- }
- }
- }
-
- VLOG("mNextPullTimeNs: %lld updated to %lld", (long long)mNextPullTimeNs,
- (long long)minNextPullTimeNs);
- mNextPullTimeNs = minNextPullTimeNs;
- updateAlarmLocked();
-}
-
-int StatsPullerManager::ForceClearPullerCache() {
- int totalCleared = 0;
- for (const auto& pulledAtom : kAllPullAtomInfo) {
- totalCleared += pulledAtom.second->ForceClearCache();
- }
- return totalCleared;
-}
-
-int StatsPullerManager::ClearPullerCacheIfNecessary(int64_t timestampNs) {
- int totalCleared = 0;
- for (const auto& pulledAtom : kAllPullAtomInfo) {
- totalCleared += pulledAtom.second->ClearCacheIfNecessary(timestampNs);
- }
- return totalCleared;
-}
-
-void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t atomTag,
- const int64_t coolDownNs, const int64_t timeoutNs,
- const vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& callback,
- bool useUid) {
- std::lock_guard<std::mutex> _l(mLock);
- VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
-
- if (callback == nullptr) {
- ALOGW("SetPullAtomCallback called with null callback for atom %d.", atomTag);
- return;
- }
-
- StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
- int64_t actualCoolDownNs = coolDownNs < kMinCoolDownNs ? kMinCoolDownNs : coolDownNs;
- int64_t actualTimeoutNs = timeoutNs > kMaxTimeoutNs ? kMaxTimeoutNs : timeoutNs;
-
- sp<StatsCallbackPuller> puller = new StatsCallbackPuller(atomTag, callback, actualCoolDownNs,
- actualTimeoutNs, additiveFields);
- PullerKey key = {.atomTag = atomTag, .uid = useUid ? uid : -1};
- AIBinder_linkToDeath(callback->asBinder().get(), mPullAtomCallbackDeathRecipient.get(),
- new PullAtomCallbackDeathCookie(this, key, puller));
- kAllPullAtomInfo[key] = puller;
-}
-
-void StatsPullerManager::UnregisterPullAtomCallback(const int uid, const int32_t atomTag,
- bool useUids) {
- std::lock_guard<std::mutex> _l(mLock);
- PullerKey key = {.atomTag = atomTag, .uid = useUids ? uid : -1};
- if (kAllPullAtomInfo.find(key) != kAllPullAtomInfo.end()) {
- StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag,
- /*registered=*/false);
- kAllPullAtomInfo.erase(key);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
deleted file mode 100644
index 194a0f5..0000000
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/IPullAtomCallback.h>
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <utils/RefBase.h>
-
-#include <list>
-#include <vector>
-
-#include "PullDataReceiver.h"
-#include "PullUidProvider.h"
-#include "StatsPuller.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-
-using aidl::android::os::IPullAtomCallback;
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-typedef struct PullerKey {
- // The uid of the process that registers this puller.
- const int uid = -1;
- // The atom that this puller is for.
- const int atomTag;
-
- bool operator<(const PullerKey& that) const {
- if (uid < that.uid) {
- return true;
- }
- if (uid > that.uid) {
- return false;
- }
- return atomTag < that.atomTag;
- };
-
- bool operator==(const PullerKey& that) const {
- return uid == that.uid && atomTag == that.atomTag;
- };
-} PullerKey;
-
-class StatsPullerManager : public virtual RefBase {
-public:
- StatsPullerManager();
-
- virtual ~StatsPullerManager() {
- }
-
-
- // Registers a receiver for tagId. It will be pulled on the nextPullTimeNs
- // and then every intervalNs thereafter.
- virtual void RegisterReceiver(int tagId, const ConfigKey& configKey,
- wp<PullDataReceiver> receiver, int64_t nextPullTimeNs,
- int64_t intervalNs);
-
- // Stop listening on a tagId.
- virtual void UnRegisterReceiver(int tagId, const ConfigKey& configKey,
- wp<PullDataReceiver> receiver);
-
- // Registers a pull uid provider for the config key. When pulling atoms, it will be used to
- // determine which uids to pull from.
- virtual void RegisterPullUidProvider(const ConfigKey& configKey, wp<PullUidProvider> provider);
-
- // Unregister a pull uid provider.
- virtual void UnregisterPullUidProvider(const ConfigKey& configKey,
- wp<PullUidProvider> provider);
-
- // Verify if we know how to pull for this matcher
- bool PullerForMatcherExists(int tagId) const;
-
- void OnAlarmFired(int64_t elapsedTimeNs);
-
- // Pulls the most recent data.
- // The data may be served from cache if consecutive pulls come within
- // mCoolDownNs.
- // Returns true if the pull was successful.
- // Returns false when
- // 1) the pull fails
- // 2) pull takes longer than mPullTimeoutNs (intrinsic to puller)
- // 3) Either a PullUidProvider was not registered for the config, or the there was no puller
- // registered for any of the uids for this atom.
- // If the metric wants to make any change to the data, like timestamps, they
- // should make a copy as this data may be shared with multiple metrics.
- virtual bool Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids = true);
-
- // Same as above, but directly specify the allowed uids to pull from.
- virtual bool Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids = true);
-
- // Clear pull data cache immediately.
- int ForceClearPullerCache();
-
- // Clear pull data cache if it is beyond respective cool down time.
- int ClearPullerCacheIfNecessary(int64_t timestampNs);
-
- void SetStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService);
-
- void RegisterPullAtomCallback(const int uid, const int32_t atomTag, const int64_t coolDownNs,
- const int64_t timeoutNs, const vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& callback,
- bool useUid = true);
-
- void UnregisterPullAtomCallback(const int uid, const int32_t atomTag, bool useUids = true);
-
- std::map<const PullerKey, sp<StatsPuller>> kAllPullAtomInfo;
-
-private:
- const static int64_t kMinCoolDownNs = NS_PER_SEC;
- const static int64_t kMaxTimeoutNs = 10 * NS_PER_SEC;
- shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr;
-
- // A struct containing an atom id and a Config Key
- typedef struct ReceiverKey {
- const int atomTag;
- const ConfigKey configKey;
-
- inline bool operator<(const ReceiverKey& that) const {
- return atomTag == that.atomTag ? configKey < that.configKey : atomTag < that.atomTag;
- }
- } ReceiverKey;
-
- typedef struct {
- int64_t nextPullTimeNs;
- int64_t intervalNs;
- wp<PullDataReceiver> receiver;
- } ReceiverInfo;
-
- // mapping from Receiver Key to receivers
- std::map<ReceiverKey, std::list<ReceiverInfo>> mReceivers;
-
- // mapping from Config Key to the PullUidProvider for that config
- std::map<ConfigKey, wp<PullUidProvider>> mPullUidProviders;
-
- bool PullLocked(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids = true);
-
- bool PullLocked(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids);
-
- // locks for data receiver and StatsCompanionService changes
- std::mutex mLock;
-
- void updateAlarmLocked();
-
- int64_t mNextPullTimeNs;
-
- // Death recipient that is triggered when the process holding the IPullAtomCallback has died.
- ::ndk::ScopedAIBinder_DeathRecipient mPullAtomCallbackDeathRecipient;
-
- /**
- * Death recipient callback that is called when a pull atom callback dies.
- * The cookie is a pointer to a PullAtomCallbackDeathCookie.
- */
- static void pullAtomCallbackDied(void* cookie);
-
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
-
- FRIEND_TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/TrainInfoPuller.cpp b/cmds/statsd/src/external/TrainInfoPuller.cpp
deleted file mode 100644
index 3837f4a..0000000
--- a/cmds/statsd/src/external/TrainInfoPuller.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "external/StatsPuller.h"
-
-#include "TrainInfoPuller.h"
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-#include "statslog_statsd.h"
-#include "storage/StorageManager.h"
-
-using std::make_shared;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-TrainInfoPuller::TrainInfoPuller() :
- StatsPuller(util::TRAIN_INFO) {
-}
-
-bool TrainInfoPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
- vector<InstallTrainInfo> trainInfoList =
- StorageManager::readAllTrainInfo();
- if (trainInfoList.empty()) {
- ALOGW("Train info was empty.");
- return true;
- }
- for (InstallTrainInfo& trainInfo : trainInfoList) {
- auto event = make_shared<LogEvent>(getWallClockNs(), getElapsedRealtimeNs(), trainInfo);
- data->push_back(event);
- }
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/TrainInfoPuller.h b/cmds/statsd/src/external/TrainInfoPuller.h
deleted file mode 100644
index 615d023..0000000
--- a/cmds/statsd/src/external/TrainInfoPuller.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "StatsPuller.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Reads train info from disk.
- */
-class TrainInfoPuller : public StatsPuller {
- public:
- TrainInfoPuller();
-
- private:
- bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp
deleted file mode 100644
index aa99d00..0000000
--- a/cmds/statsd/src/external/puller_util.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "puller_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace std;
-
-/**
- * Process all data and merge isolated with host if necessary.
- * For example:
- * NetworkBytesAtom {
- * int uid = 1;
- * State process_state = 2;
- * int byte_send = 3;
- * int byte_recv = 4;
- * }
- * additive fields are {3, 4}
- * If we pulled the following events (uid1_child is an isolated uid which maps to uid1):
- * [uid1, fg, 100, 200]
- * [uid1_child, fg, 100, 200]
- * [uid1, bg, 100, 200]
- *
- * We want to merge them and results should be:
- * [uid1, fg, 200, 400]
- * [uid1, bg, 100, 200]
- *
- * All atoms should be of the same tagId. All fields should be present.
- */
-void mapAndMergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const sp<UidMap>& uidMap,
- int tagId, const vector<int>& additiveFieldsVec) {
- // Check the first LogEvent for attribution chain or a uid field as either all atoms with this
- // tagId have them or none of them do.
- std::pair<int, int> attrIndexRange;
- const bool hasAttributionChain = data[0]->hasAttributionChain(&attrIndexRange);
- bool hasUidField = (data[0]->getUidFieldIndex() != -1);
-
- if (!hasAttributionChain && !hasUidField) {
- VLOG("No uid or attribution chain to merge, atom %d", tagId);
- return;
- }
-
- // 1. Map all isolated uid in-place to host uid
- for (shared_ptr<LogEvent>& event : data) {
- if (event->GetTagId() != tagId) {
- ALOGE("Wrong atom. Expecting %d, got %d", tagId, event->GetTagId());
- return;
- }
- if (hasAttributionChain) {
- vector<FieldValue>* const fieldValues = event->getMutableValues();
- for (int i = attrIndexRange.first; i <= attrIndexRange.second; i++) {
- FieldValue& fieldValue = fieldValues->at(i);
- if (isAttributionUidField(fieldValue)) {
- const int hostUid = uidMap->getHostUidOrSelf(fieldValue.mValue.int_value);
- fieldValue.mValue.setInt(hostUid);
- }
- }
- } else {
- int uidFieldIndex = event->getUidFieldIndex();
- if (uidFieldIndex != -1) {
- Value& value = (*event->getMutableValues())[uidFieldIndex].mValue;
- const int hostUid = uidMap->getHostUidOrSelf(value.int_value);
- value.setInt(hostUid);
- } else {
- ALOGE("Malformed log, uid not found. %s", event->ToString().c_str());
- }
- }
- }
-
- // 2. sort the data, bit-wise
- sort(data.begin(), data.end(),
- [](const shared_ptr<LogEvent>& lhs, const shared_ptr<LogEvent>& rhs) {
- if (lhs->size() != rhs->size()) {
- return lhs->size() < rhs->size();
- }
- const std::vector<FieldValue>& lhsValues = lhs->getValues();
- const std::vector<FieldValue>& rhsValues = rhs->getValues();
- for (int i = 0; i < (int)lhs->size(); i++) {
- if (lhsValues[i] != rhsValues[i]) {
- return lhsValues[i] < rhsValues[i];
- }
- }
- return false;
- });
-
- vector<shared_ptr<LogEvent>> mergedData;
- const set<int> additiveFields(additiveFieldsVec.begin(), additiveFieldsVec.end());
- bool needMerge = true;
-
- // 3. do the merge.
- // The loop invariant is this: for every event, check if it differs on
- // non-additive fields, or have different attribution chain length.
- // If so, no need to merge, add itself to the result.
- // Otherwise, merge the value onto the one immediately next to it.
- for (int i = 0; i < (int)data.size() - 1; i++) {
- // Size different, must be different chains.
- if (data[i]->size() != data[i + 1]->size()) {
- mergedData.push_back(data[i]);
- continue;
- }
- vector<FieldValue>* lhsValues = data[i]->getMutableValues();
- vector<FieldValue>* rhsValues = data[i + 1]->getMutableValues();
- needMerge = true;
- for (int p = 0; p < (int)lhsValues->size(); p++) {
- if ((*lhsValues)[p] != (*rhsValues)[p]) {
- int pos = (*lhsValues)[p].mField.getPosAtDepth(0);
- // Differ on non-additive field, abort.
- if (additiveFields.find(pos) == additiveFields.end()) {
- needMerge = false;
- break;
- }
- }
- }
- if (!needMerge) {
- mergedData.push_back(data[i]);
- continue;
- }
- // This should be infrequent operation.
- for (int p = 0; p < (int)lhsValues->size(); p++) {
- int pos = (*lhsValues)[p].mField.getPosAtDepth(0);
- if (additiveFields.find(pos) != additiveFields.end()) {
- (*rhsValues)[p].mValue += (*lhsValues)[p].mValue;
- }
- }
- }
- mergedData.push_back(data.back());
-
- data.clear();
- data = mergedData;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/puller_util.h b/cmds/statsd/src/external/puller_util.h
deleted file mode 100644
index afcf68c..0000000
--- a/cmds/statsd/src/external/puller_util.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <vector>
-#include "StatsPuller.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void mapAndMergeIsolatedUidsToHostUid(std::vector<std::shared_ptr<LogEvent>>& data,
- const sp<UidMap>& uidMap, int tagId,
- const vector<int>& additiveFieldsVec);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
deleted file mode 100644
index 6e89038..0000000
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ /dev/null
@@ -1,1101 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsdStats.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include "../stats_log_util.h"
-#include "statslog_statsd.h"
-#include "storage/StorageManager.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::lock_guard;
-using std::shared_ptr;
-using std::string;
-using std::to_string;
-using std::vector;
-
-const int FIELD_ID_BEGIN_TIME = 1;
-const int FIELD_ID_END_TIME = 2;
-const int FIELD_ID_CONFIG_STATS = 3;
-const int FIELD_ID_ATOM_STATS = 7;
-const int FIELD_ID_UIDMAP_STATS = 8;
-const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
-const int FIELD_ID_PERIODIC_ALARM_STATS = 12;
-const int FIELD_ID_SYSTEM_SERVER_RESTART = 15;
-const int FIELD_ID_LOGGER_ERROR_STATS = 16;
-const int FIELD_ID_OVERFLOW = 18;
-const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL = 19;
-
-const int FIELD_ID_ATOM_STATS_TAG = 1;
-const int FIELD_ID_ATOM_STATS_COUNT = 2;
-const int FIELD_ID_ATOM_STATS_ERROR_COUNT = 3;
-
-const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
-const int FIELD_ID_PERIODIC_ALARMS_REGISTERED = 1;
-
-const int FIELD_ID_LOG_LOSS_STATS_TIME = 1;
-const int FIELD_ID_LOG_LOSS_STATS_COUNT = 2;
-const int FIELD_ID_LOG_LOSS_STATS_ERROR = 3;
-const int FIELD_ID_LOG_LOSS_STATS_TAG = 4;
-const int FIELD_ID_LOG_LOSS_STATS_UID = 5;
-const int FIELD_ID_LOG_LOSS_STATS_PID = 6;
-
-const int FIELD_ID_OVERFLOW_COUNT = 1;
-const int FIELD_ID_OVERFLOW_MAX_HISTORY = 2;
-const int FIELD_ID_OVERFLOW_MIN_HISTORY = 3;
-
-const int FIELD_ID_CONFIG_STATS_UID = 1;
-const int FIELD_ID_CONFIG_STATS_ID = 2;
-const int FIELD_ID_CONFIG_STATS_CREATION = 3;
-const int FIELD_ID_CONFIG_STATS_RESET = 19;
-const int FIELD_ID_CONFIG_STATS_DELETION = 4;
-const int FIELD_ID_CONFIG_STATS_METRIC_COUNT = 5;
-const int FIELD_ID_CONFIG_STATS_CONDITION_COUNT = 6;
-const int FIELD_ID_CONFIG_STATS_MATCHER_COUNT = 7;
-const int FIELD_ID_CONFIG_STATS_ALERT_COUNT = 8;
-const int FIELD_ID_CONFIG_STATS_VALID = 9;
-const int FIELD_ID_CONFIG_STATS_BROADCAST = 10;
-const int FIELD_ID_CONFIG_STATS_DATA_DROP_TIME = 11;
-const int FIELD_ID_CONFIG_STATS_DATA_DROP_BYTES = 21;
-const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME = 12;
-const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES = 20;
-const int FIELD_ID_CONFIG_STATS_MATCHER_STATS = 13;
-const int FIELD_ID_CONFIG_STATS_CONDITION_STATS = 14;
-const int FIELD_ID_CONFIG_STATS_METRIC_STATS = 15;
-const int FIELD_ID_CONFIG_STATS_ALERT_STATS = 16;
-const int FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS = 17;
-const int FIELD_ID_CONFIG_STATS_ANNOTATION = 18;
-const int FIELD_ID_CONFIG_STATS_ACTIVATION = 22;
-const int FIELD_ID_CONFIG_STATS_DEACTIVATION = 23;
-const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT64 = 1;
-const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT32 = 2;
-
-const int FIELD_ID_MATCHER_STATS_ID = 1;
-const int FIELD_ID_MATCHER_STATS_COUNT = 2;
-const int FIELD_ID_CONDITION_STATS_ID = 1;
-const int FIELD_ID_CONDITION_STATS_COUNT = 2;
-const int FIELD_ID_METRIC_STATS_ID = 1;
-const int FIELD_ID_METRIC_STATS_COUNT = 2;
-const int FIELD_ID_ALERT_STATS_ID = 1;
-const int FIELD_ID_ALERT_STATS_COUNT = 2;
-
-const int FIELD_ID_UID_MAP_CHANGES = 1;
-const int FIELD_ID_UID_MAP_BYTES_USED = 2;
-const int FIELD_ID_UID_MAP_DROPPED_CHANGES = 3;
-const int FIELD_ID_UID_MAP_DELETED_APPS = 4;
-
-const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID = 1;
-const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME = 2;
-
-const std::map<int, std::pair<size_t, size_t>> StatsdStats::kAtomDimensionKeySizeLimitMap = {
- {util::BINDER_CALLS, {6000, 10000}},
- {util::LOOPER_STATS, {1500, 2500}},
- {util::CPU_TIME_PER_UID_FREQ, {6000, 10000}},
-};
-
-StatsdStats::StatsdStats() {
- mPushedAtomStats.resize(kMaxPushedAtomId + 1);
- mStartTimeSec = getWallClockSec();
-}
-
-StatsdStats& StatsdStats::getInstance() {
- static StatsdStats statsInstance;
- return statsInstance;
-}
-
-void StatsdStats::addToIceBoxLocked(shared_ptr<ConfigStats>& stats) {
- // The size of mIceBox grows strictly by one at a time. It won't be > kMaxIceBoxSize.
- if (mIceBox.size() == kMaxIceBoxSize) {
- mIceBox.pop_front();
- }
- mIceBox.push_back(stats);
-}
-
-void StatsdStats::noteConfigReceived(
- const ConfigKey& key, int metricsCount, int conditionsCount, int matchersCount,
- int alertsCount, const std::list<std::pair<const int64_t, const int32_t>>& annotations,
- bool isValid) {
- lock_guard<std::mutex> lock(mLock);
- int32_t nowTimeSec = getWallClockSec();
-
- // If there is an existing config for the same key, icebox the old config.
- noteConfigRemovedInternalLocked(key);
-
- shared_ptr<ConfigStats> configStats = std::make_shared<ConfigStats>();
- configStats->uid = key.GetUid();
- configStats->id = key.GetId();
- configStats->creation_time_sec = nowTimeSec;
- configStats->metric_count = metricsCount;
- configStats->condition_count = conditionsCount;
- configStats->matcher_count = matchersCount;
- configStats->alert_count = alertsCount;
- configStats->is_valid = isValid;
- for (auto& v : annotations) {
- configStats->annotations.emplace_back(v);
- }
-
- if (isValid) {
- mConfigStats[key] = configStats;
- } else {
- configStats->deletion_time_sec = nowTimeSec;
- addToIceBoxLocked(configStats);
- }
-}
-
-void StatsdStats::noteConfigRemovedInternalLocked(const ConfigKey& key) {
- auto it = mConfigStats.find(key);
- if (it != mConfigStats.end()) {
- int32_t nowTimeSec = getWallClockSec();
- it->second->deletion_time_sec = nowTimeSec;
- addToIceBoxLocked(it->second);
- mConfigStats.erase(it);
- }
-}
-
-void StatsdStats::noteConfigRemoved(const ConfigKey& key) {
- lock_guard<std::mutex> lock(mLock);
- noteConfigRemovedInternalLocked(key);
-}
-
-void StatsdStats::noteConfigResetInternalLocked(const ConfigKey& key) {
- auto it = mConfigStats.find(key);
- if (it != mConfigStats.end()) {
- it->second->reset_time_sec = getWallClockSec();
- }
-}
-
-void StatsdStats::noteConfigReset(const ConfigKey& key) {
- lock_guard<std::mutex> lock(mLock);
- noteConfigResetInternalLocked(key);
-}
-
-void StatsdStats::noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
- int32_t lastTag, int32_t uid, int32_t pid) {
- lock_guard<std::mutex> lock(mLock);
- if (mLogLossStats.size() == kMaxLoggerErrors) {
- mLogLossStats.pop_front();
- }
- mLogLossStats.emplace_back(wallClockTimeSec, count, lastError, lastTag, uid, pid);
-}
-
-void StatsdStats::noteBroadcastSent(const ConfigKey& key) {
- noteBroadcastSent(key, getWallClockSec());
-}
-
-void StatsdStats::noteBroadcastSent(const ConfigKey& key, int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
- auto it = mConfigStats.find(key);
- if (it == mConfigStats.end()) {
- ALOGE("Config key %s not found!", key.ToString().c_str());
- return;
- }
- if (it->second->broadcast_sent_time_sec.size() == kMaxTimestampCount) {
- it->second->broadcast_sent_time_sec.pop_front();
- }
- it->second->broadcast_sent_time_sec.push_back(timeSec);
-}
-
-void StatsdStats::noteActiveStatusChanged(const ConfigKey& key, bool activated) {
- noteActiveStatusChanged(key, activated, getWallClockSec());
-}
-
-void StatsdStats::noteActiveStatusChanged(const ConfigKey& key, bool activated, int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
- auto it = mConfigStats.find(key);
- if (it == mConfigStats.end()) {
- ALOGE("Config key %s not found!", key.ToString().c_str());
- return;
- }
- auto& vec = activated ? it->second->activation_time_sec
- : it->second->deactivation_time_sec;
- if (vec.size() == kMaxTimestampCount) {
- vec.pop_front();
- }
- vec.push_back(timeSec);
-}
-
-void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid) {
- noteActivationBroadcastGuardrailHit(uid, getWallClockSec());
-}
-
-void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid, const int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
- auto& guardrailTimes = mActivationBroadcastGuardrailStats[uid];
- if (guardrailTimes.size() == kMaxTimestampCount) {
- guardrailTimes.pop_front();
- }
- guardrailTimes.push_back(timeSec);
-}
-
-void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes) {
- noteDataDropped(key, totalBytes, getWallClockSec());
-}
-
-void StatsdStats::noteEventQueueOverflow(int64_t oldestEventTimestampNs) {
- lock_guard<std::mutex> lock(mLock);
-
- mOverflowCount++;
-
- int64_t history = getElapsedRealtimeNs() - oldestEventTimestampNs;
-
- if (history > mMaxQueueHistoryNs) {
- mMaxQueueHistoryNs = history;
- }
-
- if (history < mMinQueueHistoryNs) {
- mMinQueueHistoryNs = history;
- }
-}
-
-void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
- auto it = mConfigStats.find(key);
- if (it == mConfigStats.end()) {
- ALOGE("Config key %s not found!", key.ToString().c_str());
- return;
- }
- if (it->second->data_drop_time_sec.size() == kMaxTimestampCount) {
- it->second->data_drop_time_sec.pop_front();
- it->second->data_drop_bytes.pop_front();
- }
- it->second->data_drop_time_sec.push_back(timeSec);
- it->second->data_drop_bytes.push_back(totalBytes);
-}
-
-void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes) {
- noteMetricsReportSent(key, num_bytes, getWallClockSec());
-}
-
-void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes,
- int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
- auto it = mConfigStats.find(key);
- if (it == mConfigStats.end()) {
- ALOGE("Config key %s not found!", key.ToString().c_str());
- return;
- }
- if (it->second->dump_report_stats.size() == kMaxTimestampCount) {
- it->second->dump_report_stats.pop_front();
- }
- it->second->dump_report_stats.push_back(std::make_pair(timeSec, num_bytes));
-}
-
-void StatsdStats::noteUidMapDropped(int deltas) {
- lock_guard<std::mutex> lock(mLock);
- mUidMapStats.dropped_changes += mUidMapStats.dropped_changes + deltas;
-}
-
-void StatsdStats::noteUidMapAppDeletionDropped() {
- lock_guard<std::mutex> lock(mLock);
- mUidMapStats.deleted_apps++;
-}
-
-void StatsdStats::setUidMapChanges(int changes) {
- lock_guard<std::mutex> lock(mLock);
- mUidMapStats.changes = changes;
-}
-
-void StatsdStats::setCurrentUidMapMemory(int bytes) {
- lock_guard<std::mutex> lock(mLock);
- mUidMapStats.bytes_used = bytes;
-}
-
-void StatsdStats::noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size) {
- lock_guard<std::mutex> lock(mLock);
- // if name doesn't exist before, it will create the key with count 0.
- auto statsIt = mConfigStats.find(key);
- if (statsIt == mConfigStats.end()) {
- return;
- }
-
- auto& conditionSizeMap = statsIt->second->condition_stats;
- if (size > conditionSizeMap[id]) {
- conditionSizeMap[id] = size;
- }
-}
-
-void StatsdStats::noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size) {
- lock_guard<std::mutex> lock(mLock);
- // if name doesn't exist before, it will create the key with count 0.
- auto statsIt = mConfigStats.find(key);
- if (statsIt == mConfigStats.end()) {
- return;
- }
- auto& metricsDimensionMap = statsIt->second->metric_stats;
- if (size > metricsDimensionMap[id]) {
- metricsDimensionMap[id] = size;
- }
-}
-
-void StatsdStats::noteMetricDimensionInConditionSize(
- const ConfigKey& key, const int64_t& id, int size) {
- lock_guard<std::mutex> lock(mLock);
- // if name doesn't exist before, it will create the key with count 0.
- auto statsIt = mConfigStats.find(key);
- if (statsIt == mConfigStats.end()) {
- return;
- }
- auto& metricsDimensionMap = statsIt->second->metric_dimension_in_condition_stats;
- if (size > metricsDimensionMap[id]) {
- metricsDimensionMap[id] = size;
- }
-}
-
-void StatsdStats::noteMatcherMatched(const ConfigKey& key, const int64_t& id) {
- lock_guard<std::mutex> lock(mLock);
-
- auto statsIt = mConfigStats.find(key);
- if (statsIt == mConfigStats.end()) {
- return;
- }
- statsIt->second->matcher_stats[id]++;
-}
-
-void StatsdStats::noteAnomalyDeclared(const ConfigKey& key, const int64_t& id) {
- lock_guard<std::mutex> lock(mLock);
- auto statsIt = mConfigStats.find(key);
- if (statsIt == mConfigStats.end()) {
- return;
- }
- statsIt->second->alert_stats[id]++;
-}
-
-void StatsdStats::noteRegisteredAnomalyAlarmChanged() {
- lock_guard<std::mutex> lock(mLock);
- mAnomalyAlarmRegisteredStats++;
-}
-
-void StatsdStats::noteRegisteredPeriodicAlarmChanged() {
- lock_guard<std::mutex> lock(mLock);
- mPeriodicAlarmRegisteredStats++;
-}
-
-void StatsdStats::updateMinPullIntervalSec(int pullAtomId, long intervalSec) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].minPullIntervalSec =
- std::min(mPulledAtomStats[pullAtomId].minPullIntervalSec, intervalSec);
-}
-
-void StatsdStats::notePull(int pullAtomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].totalPull++;
-}
-
-void StatsdStats::notePullFromCache(int pullAtomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].totalPullFromCache++;
-}
-
-void StatsdStats::notePullTime(int pullAtomId, int64_t pullTimeNs) {
- lock_guard<std::mutex> lock(mLock);
- auto& pullStats = mPulledAtomStats[pullAtomId];
- pullStats.maxPullTimeNs = std::max(pullStats.maxPullTimeNs, pullTimeNs);
- pullStats.avgPullTimeNs = (pullStats.avgPullTimeNs * pullStats.numPullTime + pullTimeNs) /
- (pullStats.numPullTime + 1);
- pullStats.numPullTime += 1;
-}
-
-void StatsdStats::notePullDelay(int pullAtomId, int64_t pullDelayNs) {
- lock_guard<std::mutex> lock(mLock);
- auto& pullStats = mPulledAtomStats[pullAtomId];
- pullStats.maxPullDelayNs = std::max(pullStats.maxPullDelayNs, pullDelayNs);
- pullStats.avgPullDelayNs =
- (pullStats.avgPullDelayNs * pullStats.numPullDelay + pullDelayNs) /
- (pullStats.numPullDelay + 1);
- pullStats.numPullDelay += 1;
-}
-
-void StatsdStats::notePullDataError(int pullAtomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].dataError++;
-}
-
-void StatsdStats::notePullTimeout(int pullAtomId,
- int64_t pullUptimeMillis,
- int64_t pullElapsedMillis) {
- lock_guard<std::mutex> lock(mLock);
- PulledAtomStats& pulledAtomStats = mPulledAtomStats[pullAtomId];
- pulledAtomStats.pullTimeout++;
-
- if (pulledAtomStats.pullTimeoutMetadata.size() == kMaxTimestampCount) {
- pulledAtomStats.pullTimeoutMetadata.pop_front();
- }
-
- pulledAtomStats.pullTimeoutMetadata.emplace_back(pullUptimeMillis, pullElapsedMillis);
-}
-
-void StatsdStats::notePullExceedMaxDelay(int pullAtomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].pullExceedMaxDelay++;
-}
-
-void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
-
- if (atomId <= kMaxPushedAtomId) {
- mPushedAtomStats[atomId]++;
- } else {
- if (mNonPlatformPushedAtomStats.size() < kMaxNonPlatformPushedAtoms) {
- mNonPlatformPushedAtomStats[atomId]++;
- }
- }
-}
-
-void StatsdStats::noteSystemServerRestart(int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
-
- if (mSystemServerRestartSec.size() == kMaxSystemServerRestarts) {
- mSystemServerRestartSec.pop_front();
- }
- mSystemServerRestartSec.push_back(timeSec);
-}
-
-void StatsdStats::notePullFailed(int atomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[atomId].pullFailed++;
-}
-
-void StatsdStats::notePullUidProviderNotFound(int atomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[atomId].pullUidProviderNotFound++;
-}
-
-void StatsdStats::notePullerNotFound(int atomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[atomId].pullerNotFound++;
-}
-
-void StatsdStats::notePullBinderCallFailed(int atomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[atomId].binderCallFailCount++;
-}
-
-void StatsdStats::noteEmptyData(int atomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[atomId].emptyData++;
-}
-
-void StatsdStats::notePullerCallbackRegistrationChanged(int atomId, bool registered) {
- lock_guard<std::mutex> lock(mLock);
- if (registered) {
- mPulledAtomStats[atomId].registeredCount++;
- } else {
- mPulledAtomStats[atomId].unregisteredCount++;
- }
-}
-
-void StatsdStats::noteHardDimensionLimitReached(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).hardDimensionLimitReached++;
-}
-
-void StatsdStats::noteLateLogEventSkipped(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).lateLogEventSkipped++;
-}
-
-void StatsdStats::noteSkippedForwardBuckets(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).skippedForwardBuckets++;
-}
-
-void StatsdStats::noteBadValueType(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).badValueType++;
-}
-
-void StatsdStats::noteBucketDropped(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).bucketDropped++;
-}
-
-void StatsdStats::noteBucketUnknownCondition(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).bucketUnknownCondition++;
-}
-
-void StatsdStats::noteConditionChangeInNextBucket(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).conditionChangeInNextBucket++;
-}
-
-void StatsdStats::noteInvalidatedBucket(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).invalidatedBucket++;
-}
-
-void StatsdStats::noteBucketCount(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).bucketCount++;
-}
-
-void StatsdStats::noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs) {
- lock_guard<std::mutex> lock(mLock);
- AtomMetricStats& pullStats = getAtomMetricStats(metricId);
- pullStats.maxBucketBoundaryDelayNs =
- std::max(pullStats.maxBucketBoundaryDelayNs, timeDelayNs);
- pullStats.minBucketBoundaryDelayNs =
- std::min(pullStats.minBucketBoundaryDelayNs, timeDelayNs);
-}
-
-void StatsdStats::noteAtomError(int atomTag, bool pull) {
- lock_guard<std::mutex> lock(mLock);
- if (pull) {
- mPulledAtomStats[atomTag].atomErrorCount++;
- return;
- }
-
- bool present = (mPushedAtomErrorStats.find(atomTag) != mPushedAtomErrorStats.end());
- bool full = (mPushedAtomErrorStats.size() >= (size_t)kMaxPushedAtomErrorStatsSize);
- if (!full || present) {
- mPushedAtomErrorStats[atomTag]++;
- }
-}
-
-StatsdStats::AtomMetricStats& StatsdStats::getAtomMetricStats(int64_t metricId) {
- auto atomMetricStatsIter = mAtomMetricStats.find(metricId);
- if (atomMetricStatsIter != mAtomMetricStats.end()) {
- return atomMetricStatsIter->second;
- }
- auto emplaceResult = mAtomMetricStats.emplace(metricId, AtomMetricStats());
- return emplaceResult.first->second;
-}
-
-void StatsdStats::reset() {
- lock_guard<std::mutex> lock(mLock);
- resetInternalLocked();
-}
-
-void StatsdStats::resetInternalLocked() {
- // Reset the historical data, but keep the active ConfigStats
- mStartTimeSec = getWallClockSec();
- mIceBox.clear();
- std::fill(mPushedAtomStats.begin(), mPushedAtomStats.end(), 0);
- mNonPlatformPushedAtomStats.clear();
- mAnomalyAlarmRegisteredStats = 0;
- mPeriodicAlarmRegisteredStats = 0;
- mSystemServerRestartSec.clear();
- mLogLossStats.clear();
- mOverflowCount = 0;
- mMinQueueHistoryNs = kInt64Max;
- mMaxQueueHistoryNs = 0;
- for (auto& config : mConfigStats) {
- config.second->broadcast_sent_time_sec.clear();
- config.second->activation_time_sec.clear();
- config.second->deactivation_time_sec.clear();
- config.second->data_drop_time_sec.clear();
- config.second->data_drop_bytes.clear();
- config.second->dump_report_stats.clear();
- config.second->annotations.clear();
- config.second->matcher_stats.clear();
- config.second->condition_stats.clear();
- config.second->metric_stats.clear();
- config.second->metric_dimension_in_condition_stats.clear();
- config.second->alert_stats.clear();
- }
- for (auto& pullStats : mPulledAtomStats) {
- pullStats.second.totalPull = 0;
- pullStats.second.totalPullFromCache = 0;
- pullStats.second.minPullIntervalSec = LONG_MAX;
- pullStats.second.avgPullTimeNs = 0;
- pullStats.second.maxPullTimeNs = 0;
- pullStats.second.numPullTime = 0;
- pullStats.second.avgPullDelayNs = 0;
- pullStats.second.maxPullDelayNs = 0;
- pullStats.second.numPullDelay = 0;
- pullStats.second.dataError = 0;
- pullStats.second.pullTimeout = 0;
- pullStats.second.pullExceedMaxDelay = 0;
- pullStats.second.pullFailed = 0;
- pullStats.second.pullUidProviderNotFound = 0;
- pullStats.second.pullerNotFound = 0;
- pullStats.second.registeredCount = 0;
- pullStats.second.unregisteredCount = 0;
- pullStats.second.atomErrorCount = 0;
- pullStats.second.binderCallFailCount = 0;
- pullStats.second.pullTimeoutMetadata.clear();
- }
- mAtomMetricStats.clear();
- mActivationBroadcastGuardrailStats.clear();
- mPushedAtomErrorStats.clear();
-}
-
-string buildTimeString(int64_t timeSec) {
- time_t t = timeSec;
- struct tm* tm = localtime(&t);
- char timeBuffer[80];
- strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p", tm);
- return string(timeBuffer);
-}
-
-int StatsdStats::getPushedAtomErrors(int atomId) const {
- const auto& it = mPushedAtomErrorStats.find(atomId);
- if (it != mPushedAtomErrorStats.end()) {
- return it->second;
- } else {
- return 0;
- }
-}
-
-void StatsdStats::dumpStats(int out) const {
- lock_guard<std::mutex> lock(mLock);
- time_t t = mStartTimeSec;
- struct tm* tm = localtime(&t);
- char timeBuffer[80];
- strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm);
- dprintf(out, "Stats collection start second: %s\n", timeBuffer);
- dprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size());
- for (const auto& configStats : mIceBox) {
- dprintf(out,
- "Config {%d_%lld}: creation=%d, deletion=%d, reset=%d, #metric=%d, #condition=%d, "
- "#matcher=%d, #alert=%d, valid=%d\n",
- configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
- configStats->deletion_time_sec, configStats->reset_time_sec,
- configStats->metric_count, configStats->condition_count, configStats->matcher_count,
- configStats->alert_count, configStats->is_valid);
-
- for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
- dprintf(out, "\tbroadcast time: %d\n", broadcastTime);
- }
-
- for (const int& activationTime : configStats->activation_time_sec) {
- dprintf(out, "\tactivation time: %d\n", activationTime);
- }
-
- for (const int& deactivationTime : configStats->deactivation_time_sec) {
- dprintf(out, "\tdeactivation time: %d\n", deactivationTime);
- }
-
- auto dropTimePtr = configStats->data_drop_time_sec.begin();
- auto dropBytesPtr = configStats->data_drop_bytes.begin();
- for (int i = 0; i < (int)configStats->data_drop_time_sec.size();
- i++, dropTimePtr++, dropBytesPtr++) {
- dprintf(out, "\tdata drop time: %d with size %lld", *dropTimePtr,
- (long long)*dropBytesPtr);
- }
- }
- dprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size());
- for (auto& pair : mConfigStats) {
- auto& configStats = pair.second;
- dprintf(out,
- "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
- "#matcher=%d, #alert=%d, valid=%d\n",
- configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
- configStats->deletion_time_sec, configStats->metric_count,
- configStats->condition_count, configStats->matcher_count, configStats->alert_count,
- configStats->is_valid);
- for (const auto& annotation : configStats->annotations) {
- dprintf(out, "\tannotation: %lld, %d\n", (long long)annotation.first,
- annotation.second);
- }
-
- for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
- dprintf(out, "\tbroadcast time: %s(%lld)\n", buildTimeString(broadcastTime).c_str(),
- (long long)broadcastTime);
- }
-
- for (const int& activationTime : configStats->activation_time_sec) {
- dprintf(out, "\tactivation time: %d\n", activationTime);
- }
-
- for (const int& deactivationTime : configStats->deactivation_time_sec) {
- dprintf(out, "\tdeactivation time: %d\n", deactivationTime);
- }
-
- auto dropTimePtr = configStats->data_drop_time_sec.begin();
- auto dropBytesPtr = configStats->data_drop_bytes.begin();
- for (int i = 0; i < (int)configStats->data_drop_time_sec.size();
- i++, dropTimePtr++, dropBytesPtr++) {
- dprintf(out, "\tdata drop time: %s(%lld) with %lld bytes\n",
- buildTimeString(*dropTimePtr).c_str(), (long long)*dropTimePtr,
- (long long)*dropBytesPtr);
- }
-
- for (const auto& dump : configStats->dump_report_stats) {
- dprintf(out, "\tdump report time: %s(%lld) bytes: %lld\n",
- buildTimeString(dump.first).c_str(), (long long)dump.first,
- (long long)dump.second);
- }
-
- for (const auto& stats : pair.second->matcher_stats) {
- dprintf(out, "matcher %lld matched %d times\n", (long long)stats.first, stats.second);
- }
-
- for (const auto& stats : pair.second->condition_stats) {
- dprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first,
- stats.second);
- }
-
- for (const auto& stats : pair.second->condition_stats) {
- dprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first,
- stats.second);
- }
-
- for (const auto& stats : pair.second->alert_stats) {
- dprintf(out, "alert %lld declared %d times\n", (long long)stats.first, stats.second);
- }
- }
- dprintf(out, "********Disk Usage stats***********\n");
- StorageManager::printStats(out);
- dprintf(out, "********Pushed Atom stats***********\n");
- const size_t atomCounts = mPushedAtomStats.size();
- for (size_t i = 2; i < atomCounts; i++) {
- if (mPushedAtomStats[i] > 0) {
- dprintf(out, "Atom %zu->(total count)%d, (error count)%d\n", i, mPushedAtomStats[i],
- getPushedAtomErrors((int)i));
- }
- }
- for (const auto& pair : mNonPlatformPushedAtomStats) {
- dprintf(out, "Atom %d->(total count)%d, (error count)%d\n", pair.first, pair.second,
- getPushedAtomErrors(pair.first));
- }
-
- dprintf(out, "********Pulled Atom stats***********\n");
- for (const auto& pair : mPulledAtomStats) {
- dprintf(out,
- "Atom %d->(total pull)%ld, (pull from cache)%ld, "
- "(pull failed)%ld, (min pull interval)%ld \n"
- " (average pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay "
- "nanos)%lld, "
- " (max pull delay nanos)%lld, (data error)%ld\n"
- " (pull timeout)%ld, (pull exceed max delay)%ld"
- " (no uid provider count)%ld, (no puller found count)%ld\n"
- " (registered count) %ld, (unregistered count) %ld"
- " (atom error count) %d\n",
- (int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache,
- (long)pair.second.pullFailed, (long)pair.second.minPullIntervalSec,
- (long long)pair.second.avgPullTimeNs, (long long)pair.second.maxPullTimeNs,
- (long long)pair.second.avgPullDelayNs, (long long)pair.second.maxPullDelayNs,
- pair.second.dataError, pair.second.pullTimeout, pair.second.pullExceedMaxDelay,
- pair.second.pullUidProviderNotFound, pair.second.pullerNotFound,
- pair.second.registeredCount, pair.second.unregisteredCount,
- pair.second.atomErrorCount);
- if (pair.second.pullTimeoutMetadata.size() > 0) {
- string uptimeMillis = "(pull timeout system uptime millis) ";
- string pullTimeoutMillis = "(pull timeout elapsed time millis) ";
- for (const auto& stats : pair.second.pullTimeoutMetadata) {
- uptimeMillis.append(to_string(stats.pullTimeoutUptimeMillis)).append(",");;
- pullTimeoutMillis.append(to_string(stats.pullTimeoutElapsedMillis)).append(",");
- }
- uptimeMillis.pop_back();
- uptimeMillis.push_back('\n');
- pullTimeoutMillis.pop_back();
- pullTimeoutMillis.push_back('\n');
- dprintf(out, "%s", uptimeMillis.c_str());
- dprintf(out, "%s", pullTimeoutMillis.c_str());
- }
- }
-
- if (mAnomalyAlarmRegisteredStats > 0) {
- dprintf(out, "********AnomalyAlarmStats stats***********\n");
- dprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats);
- }
-
- if (mPeriodicAlarmRegisteredStats > 0) {
- dprintf(out, "********SubscriberAlarmStats stats***********\n");
- dprintf(out, "Subscriber alarm registrations: %d\n", mPeriodicAlarmRegisteredStats);
- }
-
- dprintf(out, "UID map stats: bytes=%d, changes=%d, deleted=%d, changes lost=%d\n",
- mUidMapStats.bytes_used, mUidMapStats.changes, mUidMapStats.deleted_apps,
- mUidMapStats.dropped_changes);
-
- for (const auto& restart : mSystemServerRestartSec) {
- dprintf(out, "System server restarts at %s(%lld)\n", buildTimeString(restart).c_str(),
- (long long)restart);
- }
-
- for (const auto& loss : mLogLossStats) {
- dprintf(out,
- "Log loss: %lld (wall clock sec) - %d (count), %d (last error), %d (last tag), %d "
- "(uid), %d (pid)\n",
- (long long)loss.mWallClockSec, loss.mCount, loss.mLastError, loss.mLastTag,
- loss.mUid, loss.mPid);
- }
-
- dprintf(out, "Event queue overflow: %d; MaxHistoryNs: %lld; MinHistoryNs: %lld\n",
- mOverflowCount, (long long)mMaxQueueHistoryNs, (long long)mMinQueueHistoryNs);
-
- if (mActivationBroadcastGuardrailStats.size() > 0) {
- dprintf(out, "********mActivationBroadcastGuardrail stats***********\n");
- for (const auto& pair: mActivationBroadcastGuardrailStats) {
- dprintf(out, "Uid %d: Times: ", pair.first);
- for (const auto& guardrailHitTime : pair.second) {
- dprintf(out, "%d ", guardrailHitTime);
- }
- }
- dprintf(out, "\n");
- }
-}
-
-void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* proto) {
- uint64_t token =
- proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_UID, configStats.uid);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ID, (long long)configStats.id);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CREATION, configStats.creation_time_sec);
- if (configStats.reset_time_sec != 0) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_RESET, configStats.reset_time_sec);
- }
- if (configStats.deletion_time_sec != 0) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DELETION,
- configStats.deletion_time_sec);
- }
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_METRIC_COUNT, configStats.metric_count);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CONDITION_COUNT,
- configStats.condition_count);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_MATCHER_COUNT, configStats.matcher_count);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ALERT_COUNT, configStats.alert_count);
- proto->write(FIELD_TYPE_BOOL | FIELD_ID_CONFIG_STATS_VALID, configStats.is_valid);
-
- for (const auto& broadcast : configStats.broadcast_sent_time_sec) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_BROADCAST | FIELD_COUNT_REPEATED,
- broadcast);
- }
-
- for (const auto& activation : configStats.activation_time_sec) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ACTIVATION | FIELD_COUNT_REPEATED,
- activation);
- }
-
- for (const auto& deactivation : configStats.deactivation_time_sec) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DEACTIVATION | FIELD_COUNT_REPEATED,
- deactivation);
- }
-
- for (const auto& drop_time : configStats.data_drop_time_sec) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DATA_DROP_TIME | FIELD_COUNT_REPEATED,
- drop_time);
- }
-
- for (const auto& drop_bytes : configStats.data_drop_bytes) {
- proto->write(
- FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_DATA_DROP_BYTES | FIELD_COUNT_REPEATED,
- (long long)drop_bytes);
- }
-
- for (const auto& dump : configStats.dump_report_stats) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME |
- FIELD_COUNT_REPEATED,
- dump.first);
- }
-
- for (const auto& dump : configStats.dump_report_stats) {
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES |
- FIELD_COUNT_REPEATED,
- (long long)dump.second);
- }
-
- for (const auto& annotation : configStats.annotations) {
- uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_ANNOTATION);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT64,
- (long long)annotation.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT32, annotation.second);
- proto->end(token);
- }
-
- for (const auto& pair : configStats.matcher_stats) {
- uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_MATCHER_STATS);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_MATCHER_STATS_ID, (long long)pair.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_MATCHER_STATS_COUNT, pair.second);
- proto->end(tmpToken);
- }
-
- for (const auto& pair : configStats.condition_stats) {
- uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_CONDITION_STATS);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_STATS_ID, (long long)pair.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONDITION_STATS_COUNT, pair.second);
- proto->end(tmpToken);
- }
-
- for (const auto& pair : configStats.metric_stats) {
- uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_METRIC_STATS);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
- proto->end(tmpToken);
- }
- for (const auto& pair : configStats.metric_dimension_in_condition_stats) {
- uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
- proto->end(tmpToken);
- }
-
- for (const auto& pair : configStats.alert_stats) {
- uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_ALERT_STATS);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_STATS_ID, (long long)pair.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_ALERT_STATS_COUNT, pair.second);
- proto->end(tmpToken);
- }
-
- proto->end(token);
-}
-
-void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
- lock_guard<std::mutex> lock(mLock);
-
- ProtoOutputStream proto;
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)getWallClockSec());
-
- for (const auto& configStats : mIceBox) {
- addConfigStatsToProto(*configStats, &proto);
- }
-
- for (auto& pair : mConfigStats) {
- addConfigStatsToProto(*(pair.second), &proto);
- }
-
- const size_t atomCounts = mPushedAtomStats.size();
- for (size_t i = 2; i < atomCounts; i++) {
- if (mPushedAtomStats[i] > 0) {
- uint64_t token =
- proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, (int32_t)i);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, mPushedAtomStats[i]);
- int errors = getPushedAtomErrors(i);
- if (errors > 0) {
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_ERROR_COUNT, errors);
- }
- proto.end(token);
- }
- }
-
- for (const auto& pair : mNonPlatformPushedAtomStats) {
- uint64_t token =
- proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, pair.first);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, pair.second);
- int errors = getPushedAtomErrors(pair.first);
- if (errors > 0) {
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_ERROR_COUNT, errors);
- }
- proto.end(token);
- }
-
- for (const auto& pair : mPulledAtomStats) {
- android::os::statsd::writePullerStatsToStream(pair, &proto);
- }
-
- for (const auto& pair : mAtomMetricStats) {
- android::os::statsd::writeAtomMetricStatsToStream(pair, &proto);
- }
-
- if (mAnomalyAlarmRegisteredStats > 0) {
- uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED,
- mAnomalyAlarmRegisteredStats);
- proto.end(token);
- }
-
- if (mPeriodicAlarmRegisteredStats > 0) {
- uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_PERIODIC_ALARM_STATS);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_PERIODIC_ALARMS_REGISTERED,
- mPeriodicAlarmRegisteredStats);
- proto.end(token);
- }
-
- uint64_t uidMapToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_CHANGES, mUidMapStats.changes);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_BYTES_USED, mUidMapStats.bytes_used);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DROPPED_CHANGES, mUidMapStats.dropped_changes);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DELETED_APPS, mUidMapStats.deleted_apps);
- proto.end(uidMapToken);
-
- for (const auto& error : mLogLossStats) {
- uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_LOGGER_ERROR_STATS |
- FIELD_COUNT_REPEATED);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TIME, error.mWallClockSec);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_COUNT, error.mCount);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_ERROR, error.mLastError);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TAG, error.mLastTag);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_UID, error.mUid);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_PID, error.mPid);
- proto.end(token);
- }
-
- if (mOverflowCount > 0) {
- uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_OVERFLOW);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_OVERFLOW_COUNT, (int32_t)mOverflowCount);
- proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MAX_HISTORY,
- (long long)mMaxQueueHistoryNs);
- proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MIN_HISTORY,
- (long long)mMinQueueHistoryNs);
- proto.end(token);
- }
-
- for (const auto& restart : mSystemServerRestartSec) {
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_SYSTEM_SERVER_RESTART | FIELD_COUNT_REPEATED,
- restart);
- }
-
- for (const auto& pair: mActivationBroadcastGuardrailStats) {
- uint64_t token = proto.start(FIELD_TYPE_MESSAGE |
- FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL |
- FIELD_COUNT_REPEATED);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID,
- (int32_t) pair.first);
- for (const auto& guardrailHitTime : pair.second) {
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME |
- FIELD_COUNT_REPEATED,
- guardrailHitTime);
- }
- proto.end(token);
- }
-
- output->clear();
- size_t bufferSize = proto.size();
- output->resize(bufferSize);
-
- size_t pos = 0;
- sp<android::util::ProtoReader> reader = proto.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((*output)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- if (reset) {
- resetInternalLocked();
- }
-
- VLOG("reset=%d, returned proto size %lu", reset, (unsigned long)bufferSize);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
deleted file mode 100644
index 0050484..0000000
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include "config/ConfigKey.h"
-
-#include <gtest/gtest_prod.h>
-#include <log/log_time.h>
-#include <list>
-#include <mutex>
-#include <string>
-#include <vector>
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct ConfigStats {
- int32_t uid;
- int64_t id;
- int32_t creation_time_sec;
- int32_t deletion_time_sec = 0;
- int32_t reset_time_sec = 0;
- int32_t metric_count;
- int32_t condition_count;
- int32_t matcher_count;
- int32_t alert_count;
- bool is_valid;
-
- std::list<int32_t> broadcast_sent_time_sec;
-
- // Times at which this config is activated.
- std::list<int32_t> activation_time_sec;
-
- // Times at which this config is deactivated.
- std::list<int32_t> deactivation_time_sec;
-
- std::list<int32_t> data_drop_time_sec;
- // Number of bytes dropped at corresponding time.
- std::list<int64_t> data_drop_bytes;
- std::list<std::pair<int32_t, int64_t>> dump_report_stats;
-
- // Stores how many times a matcher have been matched. The map size is capped by kMaxConfigCount.
- std::map<const int64_t, int> matcher_stats;
-
- // Stores the number of output tuple of condition trackers when it's bigger than
- // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
- // it means some data has been dropped. The map size is capped by kMaxConfigCount.
- std::map<const int64_t, int> condition_stats;
-
- // Stores the number of output tuple of metric producers when it's bigger than
- // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
- // it means some data has been dropped. The map size is capped by kMaxConfigCount.
- std::map<const int64_t, int> metric_stats;
-
- // Stores the max number of output tuple of dimensions in condition across dimensions in what
- // when it's bigger than kDimensionKeySizeSoftLimit. When you see the number is
- // kDimensionKeySizeHardLimit +1, it means some data has been dropped. The map size is capped by
- // kMaxConfigCount.
- std::map<const int64_t, int> metric_dimension_in_condition_stats;
-
- // Stores the number of times an anomaly detection alert has been declared.
- // The map size is capped by kMaxConfigCount.
- std::map<const int64_t, int> alert_stats;
-
- // Stores the config ID for each sub-config used.
- std::list<std::pair<const int64_t, const int32_t>> annotations;
-};
-
-struct UidMapStats {
- int32_t changes;
- int32_t bytes_used;
- int32_t dropped_changes;
- int32_t deleted_apps = 0;
-};
-
-// Keeps track of stats of statsd.
-// Single instance shared across the process. All public methods are thread safe.
-class StatsdStats {
-public:
- static StatsdStats& getInstance();
- ~StatsdStats(){};
-
- const static int kDimensionKeySizeSoftLimit = 500;
- const static int kDimensionKeySizeHardLimit = 800;
-
- // Per atom dimension key size limit
- static const std::map<int, std::pair<size_t, size_t>> kAtomDimensionKeySizeLimitMap;
-
- const static int kMaxConfigCountPerUid = 20;
- const static int kMaxAlertCountPerConfig = 100;
- const static int kMaxConditionCountPerConfig = 300;
- const static int kMaxMetricCountPerConfig = 1000;
- const static int kMaxMatcherCountPerConfig = 800;
-
- // The max number of old config stats we keep.
- const static int kMaxIceBoxSize = 20;
-
- const static int kMaxLoggerErrors = 20;
-
- const static int kMaxSystemServerRestarts = 20;
-
- const static int kMaxTimestampCount = 20;
-
- const static int kMaxLogSourceCount = 50;
-
- const static int kMaxPullAtomPackages = 100;
-
- // Max memory allowed for storing metrics per configuration. If this limit is exceeded, statsd
- // drops the metrics data in memory.
- static const size_t kMaxMetricsBytesPerConfig = 2 * 1024 * 1024;
-
- // Soft memory limit per configuration. Once this limit is exceeded, we begin notifying the
- // data subscriber that it's time to call getData.
- static const size_t kBytesPerConfigTriggerGetData = 192 * 1024;
-
- // Cap the UID map's memory usage to this. This should be fairly high since the UID information
- // is critical for understanding the metrics.
- const static size_t kMaxBytesUsedUidMap = 50 * 1024;
-
- // The number of deleted apps that are stored in the uid map.
- const static int kMaxDeletedAppsInUidMap = 100;
-
- /* Minimum period between two broadcasts in nanoseconds. */
- static const int64_t kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
-
- /* Min period between two checks of byte size per config key in nanoseconds. */
- static const int64_t kMinByteSizeCheckPeriodNs = 60 * NS_PER_SEC;
-
- /* Minimum period between two activation broadcasts in nanoseconds. */
- static const int64_t kMinActivationBroadcastPeriodNs = 10 * NS_PER_SEC;
-
- // Maximum age (30 days) that files on disk can exist in seconds.
- static const int kMaxAgeSecond = 60 * 60 * 24 * 30;
-
- // Maximum age (2 days) that local history files on disk can exist in seconds.
- static const int kMaxLocalHistoryAgeSecond = 60 * 60 * 24 * 2;
-
- // Maximum number of files (1000) that can be in stats directory on disk.
- static const int kMaxFileNumber = 1000;
-
- // Maximum size of all files that can be written to stats directory on disk.
- static const int kMaxFileSize = 50 * 1024 * 1024;
-
- // How long to try to clear puller cache from last time
- static const long kPullerCacheClearIntervalSec = 1;
-
- // Max time to do a pull.
- static const int64_t kPullMaxDelayNs = 30 * NS_PER_SEC;
-
- // Maximum number of pushed atoms statsd stats will track above kMaxPushedAtomId.
- static const int kMaxNonPlatformPushedAtoms = 100;
-
- // Maximum atom id value that we consider a platform pushed atom.
- // This should be updated once highest pushed atom id in atoms.proto approaches this value.
- static const int kMaxPushedAtomId = 500;
-
- // Atom id that is the start of the pulled atoms.
- static const int kPullAtomStartTag = 10000;
-
- // Atom id that is the start of vendor atoms.
- static const int kVendorAtomStartTag = 100000;
-
- // Vendor pulled atom start id.
- static const int32_t kVendorPulledAtomStartTag = 150000;
-
- // Beginning of range for timestamp truncation.
- static const int32_t kTimestampTruncationStartTag = 300000;
-
- // End of range for timestamp truncation.
- static const int32_t kTimestampTruncationEndTag = 304999;
-
- // Max accepted atom id.
- static const int32_t kMaxAtomTag = 200000;
-
- static const int64_t kInt64Max = 0x7fffffffffffffffLL;
-
- static const int32_t kMaxLoggedBucketDropEvents = 10;
-
- /**
- * Report a new config has been received and report the static stats about the config.
- *
- * The static stats include: the count of metrics, conditions, matchers, and alerts.
- * If the config is not valid, this config stats will be put into icebox immediately.
- */
- void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
- int matchersCount, int alertCount,
- const std::list<std::pair<const int64_t, const int32_t>>& annotations,
- bool isValid);
- /**
- * Report a config has been removed.
- */
- void noteConfigRemoved(const ConfigKey& key);
- /**
- * Report a config has been reset when ttl expires.
- */
- void noteConfigReset(const ConfigKey& key);
-
- /**
- * Report a broadcast has been sent to a config owner to collect the data.
- */
- void noteBroadcastSent(const ConfigKey& key);
-
- /**
- * Report that a config has become activated or deactivated.
- * This can be different from whether or not a broadcast is sent if the
- * guardrail prevented the broadcast from being sent.
- */
- void noteActiveStatusChanged(const ConfigKey& key, bool activate);
-
- /**
- * Report a config's metrics data has been dropped.
- */
- void noteDataDropped(const ConfigKey& key, const size_t totalBytes);
-
- /**
- * Report metrics data report has been sent.
- *
- * The report may be requested via StatsManager API, or through adb cmd.
- */
- void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes);
-
- /**
- * Report the size of output tuple of a condition.
- *
- * Note: only report when the condition has an output dimension, and the tuple
- * count > kDimensionKeySizeSoftLimit.
- *
- * [key]: The config key that this condition belongs to.
- * [id]: The id of the condition.
- * [size]: The output tuple size.
- */
- void noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size);
-
- /**
- * Report the size of output tuple of a metric.
- *
- * Note: only report when the metric has an output dimension, and the tuple
- * count > kDimensionKeySizeSoftLimit.
- *
- * [key]: The config key that this metric belongs to.
- * [id]: The id of the metric.
- * [size]: The output tuple size.
- */
- void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
-
- /**
- * Report the max size of output tuple of dimension in condition across dimensions in what.
- *
- * Note: only report when the metric has an output dimension in condition, and the max tuple
- * count > kDimensionKeySizeSoftLimit.
- *
- * [key]: The config key that this metric belongs to.
- * [id]: The id of the metric.
- * [size]: The output tuple size.
- */
- void noteMetricDimensionInConditionSize(const ConfigKey& key, const int64_t& id, int size);
-
- /**
- * Report a matcher has been matched.
- *
- * [key]: The config key that this matcher belongs to.
- * [id]: The id of the matcher.
- */
- void noteMatcherMatched(const ConfigKey& key, const int64_t& id);
-
- /**
- * Report that an anomaly detection alert has been declared.
- *
- * [key]: The config key that this alert belongs to.
- * [id]: The id of the alert.
- */
- void noteAnomalyDeclared(const ConfigKey& key, const int64_t& id);
-
- /**
- * Report an atom event has been logged.
- */
- void noteAtomLogged(int atomId, int32_t timeSec);
-
- /**
- * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
- */
- void noteRegisteredAnomalyAlarmChanged();
-
- /**
- * Report that statsd modified the periodic alarm registered with StatsCompanionService.
- */
- void noteRegisteredPeriodicAlarmChanged();
-
- /**
- * Records the number of delta entries that are being dropped from the uid map.
- */
- void noteUidMapDropped(int deltas);
-
- /**
- * Records that an app was deleted (from statsd's map).
- */
- void noteUidMapAppDeletionDropped();
-
- /**
- * Updates the number of changes currently stored in the uid map.
- */
- void setUidMapChanges(int changes);
- void setCurrentUidMapMemory(int bytes);
-
- /*
- * Updates minimum interval between pulls for an pulled atom.
- */
- void updateMinPullIntervalSec(int pullAtomId, long intervalSec);
-
- /*
- * Notes an atom is pulled.
- */
- void notePull(int pullAtomId);
-
- /*
- * Notes an atom is served from puller cache.
- */
- void notePullFromCache(int pullAtomId);
-
- /*
- * Notify data error for pulled atom.
- */
- void notePullDataError(int pullAtomId);
-
- /*
- * Records time for actual pulling, not including those served from cache and not including
- * statsd processing delays.
- */
- void notePullTime(int pullAtomId, int64_t pullTimeNs);
-
- /*
- * Records pull delay for a pulled atom, including those served from cache and including statsd
- * processing delays.
- */
- void notePullDelay(int pullAtomId, int64_t pullDelayNs);
-
- /*
- * Records pull exceeds timeout for the puller.
- */
- void notePullTimeout(int pullAtomId, int64_t pullUptimeMillis, int64_t pullElapsedMillis);
-
- /*
- * Records pull exceeds max delay for a metric.
- */
- void notePullExceedMaxDelay(int pullAtomId);
-
- /*
- * Records when system server restarts.
- */
- void noteSystemServerRestart(int32_t timeSec);
-
- /**
- * Records statsd skipped an event.
- */
- void noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
- int32_t lastAtomTag, int32_t uid, int32_t pid);
-
- /**
- * Records that the pull of an atom has failed. Eg, if the client indicated the pull failed, if
- * the pull timed out, or if the outgoing binder call failed.
- * This count will only increment if the puller was actually invoked.
- *
- * It does not include a pull not occurring due to not finding the appropriate
- * puller. These cases are covered in other counts.
- */
- void notePullFailed(int atomId);
-
- /**
- * Records that the pull of an atom has failed due to not having a uid provider.
- */
- void notePullUidProviderNotFound(int atomId);
-
- /**
- * Records that the pull of an atom has failed due not finding a puller registered by a
- * trusted uid.
- */
- void notePullerNotFound(int atomId);
-
- /**
- * Records that the pull has failed due to the outgoing binder call failing.
- */
- void notePullBinderCallFailed(int atomId);
-
- /**
- * A pull with no data occurred
- */
- void noteEmptyData(int atomId);
-
- /**
- * Records that a puller callback for the given atomId was registered or unregistered.
- *
- * @param registered True if the callback was registered, false if was unregistered.
- */
- void notePullerCallbackRegistrationChanged(int atomId, bool registered);
-
- /**
- * Hard limit was reached in the cardinality of an atom
- */
- void noteHardDimensionLimitReached(int64_t metricId);
-
- /**
- * A log event was too late, arrived in the wrong bucket and was skipped
- */
- void noteLateLogEventSkipped(int64_t metricId);
-
- /**
- * Buckets were skipped as time elapsed without any data for them
- */
- void noteSkippedForwardBuckets(int64_t metricId);
-
- /**
- * An unsupported value type was received
- */
- void noteBadValueType(int64_t metricId);
-
- /**
- * Buckets were dropped due to reclaim memory.
- */
- void noteBucketDropped(int64_t metricId);
-
- /**
- * A condition change was too late, arrived in the wrong bucket and was skipped
- */
- void noteConditionChangeInNextBucket(int64_t metricId);
-
- /**
- * A bucket has been tagged as invalid.
- */
- void noteInvalidatedBucket(int64_t metricId);
-
- /**
- * Tracks the total number of buckets (include skipped/invalid buckets).
- */
- void noteBucketCount(int64_t metricId);
-
- /**
- * For pulls at bucket boundaries, it represents the misalignment between the real timestamp and
- * the end of the bucket.
- */
- void noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs);
-
- /**
- * Number of buckets with unknown condition.
- */
- void noteBucketUnknownCondition(int64_t metricId);
-
- /* Reports one event has been dropped due to queue overflow, and the oldest event timestamp in
- * the queue */
- void noteEventQueueOverflow(int64_t oldestEventTimestampNs);
-
- /**
- * Reports that the activation broadcast guardrail was hit for this uid. Namely, the broadcast
- * should have been sent, but instead was skipped due to hitting the guardrail.
- */
- void noteActivationBroadcastGuardrailHit(const int uid);
-
- /**
- * Reports that an atom is erroneous or cannot be parsed successfully by
- * statsd. An atom tag of 0 indicates that the client did not supply the
- * atom id within the encoding.
- *
- * For pushed atoms only, this call should be preceded by a call to
- * noteAtomLogged.
- */
- void noteAtomError(int atomTag, bool pull=false);
-
- /**
- * Reset the historical stats. Including all stats in icebox, and the tracked stats about
- * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
- * to collect stats after reset() has been called.
- */
- void reset();
-
- /**
- * Output the stats in protobuf binary format to [buffer].
- *
- * [reset]: whether to clear the historical stats after the call.
- */
- void dumpStats(std::vector<uint8_t>* buffer, bool reset);
-
- /**
- * Output statsd stats in human readable format to [out] file descriptor.
- */
- void dumpStats(int outFd) const;
-
- typedef struct PullTimeoutMetadata {
- int64_t pullTimeoutUptimeMillis;
- int64_t pullTimeoutElapsedMillis;
- PullTimeoutMetadata(int64_t uptimeMillis, int64_t elapsedMillis) :
- pullTimeoutUptimeMillis(uptimeMillis),
- pullTimeoutElapsedMillis(elapsedMillis) {/* do nothing */}
- } PullTimeoutMetadata;
-
- typedef struct {
- long totalPull = 0;
- long totalPullFromCache = 0;
- long minPullIntervalSec = LONG_MAX;
- int64_t avgPullTimeNs = 0;
- int64_t maxPullTimeNs = 0;
- long numPullTime = 0;
- int64_t avgPullDelayNs = 0;
- int64_t maxPullDelayNs = 0;
- long numPullDelay = 0;
- long dataError = 0;
- long pullTimeout = 0;
- long pullExceedMaxDelay = 0;
- long pullFailed = 0;
- long pullUidProviderNotFound = 0;
- long pullerNotFound = 0;
- long emptyData = 0;
- long registeredCount = 0;
- long unregisteredCount = 0;
- int32_t atomErrorCount = 0;
- long binderCallFailCount = 0;
- std::list<PullTimeoutMetadata> pullTimeoutMetadata;
- } PulledAtomStats;
-
- typedef struct {
- long hardDimensionLimitReached = 0;
- long lateLogEventSkipped = 0;
- long skippedForwardBuckets = 0;
- long badValueType = 0;
- long conditionChangeInNextBucket = 0;
- long invalidatedBucket = 0;
- long bucketDropped = 0;
- int64_t minBucketBoundaryDelayNs = 0;
- int64_t maxBucketBoundaryDelayNs = 0;
- long bucketUnknownCondition = 0;
- long bucketCount = 0;
- } AtomMetricStats;
-
-private:
- StatsdStats();
-
- mutable std::mutex mLock;
-
- int32_t mStartTimeSec;
-
- // Track the number of dropped entries used by the uid map.
- UidMapStats mUidMapStats;
-
- // The stats about the configs that are still in use.
- // The map size is capped by kMaxConfigCount.
- std::map<const ConfigKey, std::shared_ptr<ConfigStats>> mConfigStats;
-
- // Stores the stats for the configs that are no longer in use.
- // The size of the vector is capped by kMaxIceBoxSize.
- std::list<const std::shared_ptr<ConfigStats>> mIceBox;
-
- // Stores the number of times a pushed atom is logged.
- // The size of the vector is the largest pushed atom id in atoms.proto + 1. Atoms
- // out of that range will be put in mNonPlatformPushedAtomStats.
- // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
- std::vector<int> mPushedAtomStats;
-
- // Stores the number of times a pushed atom is logged for atom ids above kMaxPushedAtomId.
- // The max size of the map is kMaxNonPlatformPushedAtoms.
- std::unordered_map<int, int> mNonPlatformPushedAtomStats;
-
- // Maps PullAtomId to its stats. The size is capped by the puller atom counts.
- std::map<int, PulledAtomStats> mPulledAtomStats;
-
- // Stores the number of times a pushed atom was logged erroneously. The
- // corresponding counts for pulled atoms are stored in PulledAtomStats.
- // The max size of this map is kMaxAtomErrorsStatsSize.
- std::map<int, int> mPushedAtomErrorStats;
- int kMaxPushedAtomErrorStatsSize = 100;
-
- // Maps metric ID to its stats. The size is capped by the number of metrics.
- std::map<int64_t, AtomMetricStats> mAtomMetricStats;
-
- // Maps uids to times when the activation changed broadcast not sent due to hitting the
- // guardrail. The size is capped by the number of configs, and up to 20 times per uid.
- std::map<int, std::list<int32_t>> mActivationBroadcastGuardrailStats;
-
- struct LogLossStats {
- LogLossStats(int32_t sec, int32_t count, int32_t error, int32_t tag, int32_t uid,
- int32_t pid)
- : mWallClockSec(sec),
- mCount(count),
- mLastError(error),
- mLastTag(tag),
- mUid(uid),
- mPid(pid) {
- }
- int32_t mWallClockSec;
- int32_t mCount;
- // error code defined in linux/errno.h
- int32_t mLastError;
- int32_t mLastTag;
- int32_t mUid;
- int32_t mPid;
- };
-
- // Max of {(now - oldestEventTimestamp) when overflow happens}.
- // This number is helpful to understand how SLOW statsd can be.
- int64_t mMaxQueueHistoryNs = 0;
-
- // Min of {(now - oldestEventTimestamp) when overflow happens}.
- // This number is helpful to understand how FAST the events floods to statsd.
- int64_t mMinQueueHistoryNs = kInt64Max;
-
- // Total number of events that are lost due to queue overflow.
- int32_t mOverflowCount = 0;
-
- // Timestamps when we detect log loss, and the number of logs lost.
- std::list<LogLossStats> mLogLossStats;
-
- std::list<int32_t> mSystemServerRestartSec;
-
- // Stores the number of times statsd modified the anomaly alarm registered with
- // StatsCompanionService.
- int mAnomalyAlarmRegisteredStats = 0;
-
- // Stores the number of times statsd registers the periodic alarm changes
- int mPeriodicAlarmRegisteredStats = 0;
-
- void noteConfigResetInternalLocked(const ConfigKey& key);
-
- void noteConfigRemovedInternalLocked(const ConfigKey& key);
-
- void resetInternalLocked();
-
- void noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec);
-
- void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes, int32_t timeSec);
-
- void noteBroadcastSent(const ConfigKey& key, int32_t timeSec);
-
- void noteActiveStatusChanged(const ConfigKey& key, bool activate, int32_t timeSec);
-
- void noteActivationBroadcastGuardrailHit(const int uid, int32_t timeSec);
-
- void addToIceBoxLocked(std::shared_ptr<ConfigStats>& stats);
-
- int getPushedAtomErrors(int atomId) const;
-
- /**
- * Get a reference to AtomMetricStats for a metric. If none exists, create it. The reference
- * will live as long as `this`.
- */
- StatsdStats::AtomMetricStats& getAtomMetricStats(int64_t metricId);
-
- FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
- FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
- FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
- FRIEND_TEST(StatsdStatsTest, TestSubStats);
- FRIEND_TEST(StatsdStatsTest, TestAtomLog);
- FRIEND_TEST(StatsdStatsTest, TestNonPlatformAtomLog);
- FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
- FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
- FRIEND_TEST(StatsdStatsTest, TestSystemServerCrash);
- FRIEND_TEST(StatsdStatsTest, TestPullAtomStats);
- FRIEND_TEST(StatsdStatsTest, TestAtomMetricsStats);
- FRIEND_TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit);
- FRIEND_TEST(StatsdStatsTest, TestAtomErrorStats);
-
- FRIEND_TEST(StatsLogProcessorTest, InvalidConfigRemoved);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/hash.cpp b/cmds/statsd/src/hash.cpp
deleted file mode 100644
index 543a748..0000000
--- a/cmds/statsd/src/hash.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "hash.h"
-
-#ifndef FALLTHROUGH_INTENDED
-#define FALLTHROUGH_INTENDED [[fallthrough]]
-#endif
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-// Lower-level versions of Get... that read directly from a character buffer
-// without any bounds checking.
-inline uint32_t DecodeFixed32(const char *ptr) {
- return ((static_cast<uint32_t>(static_cast<unsigned char>(ptr[0]))) |
- (static_cast<uint32_t>(static_cast<unsigned char>(ptr[1])) << 8) |
- (static_cast<uint32_t>(static_cast<unsigned char>(ptr[2])) << 16) |
- (static_cast<uint32_t>(static_cast<unsigned char>(ptr[3])) << 24));
-}
-
-inline uint64_t DecodeFixed64(const char* ptr) {
- uint64_t lo = DecodeFixed32(ptr);
- uint64_t hi = DecodeFixed32(ptr + 4);
- return (hi << 32) | lo;
-}
-
-// 0xff is in case char is signed.
-static inline uint32_t ByteAs32(char c) { return static_cast<uint32_t>(c) & 0xff; }
-static inline uint64_t ByteAs64(char c) { return static_cast<uint64_t>(c) & 0xff; }
-
-} // namespace
-
-uint32_t Hash32(const char *data, size_t n, uint32_t seed) {
- // 'm' and 'r' are mixing constants generated offline.
- // They're not really 'magic', they just happen to work well.
- const uint32_t m = 0x5bd1e995;
- const int r = 24;
-
- // Initialize the hash to a 'random' value
- uint32_t h = static_cast<uint32_t>(seed ^ n);
-
- // Mix 4 bytes at a time into the hash
- while (n >= 4) {
- uint32_t k = DecodeFixed32(data);
- k *= m;
- k ^= k >> r;
- k *= m;
- h *= m;
- h ^= k;
- data += 4;
- n -= 4;
- }
-
- // Handle the last few bytes of the input array
- switch (n) {
- case 3:
- h ^= ByteAs32(data[2]) << 16;
- FALLTHROUGH_INTENDED;
- case 2:
- h ^= ByteAs32(data[1]) << 8;
- FALLTHROUGH_INTENDED;
- case 1:
- h ^= ByteAs32(data[0]);
- h *= m;
- }
-
- // Do a few final mixes of the hash to ensure the last few
- // bytes are well-incorporated.
- h ^= h >> 13;
- h *= m;
- h ^= h >> 15;
- return h;
-}
-
-uint64_t Hash64(const char* data, size_t n, uint64_t seed) {
- const uint64_t m = 0xc6a4a7935bd1e995;
- const int r = 47;
-
- uint64_t h = seed ^ (n * m);
-
- while (n >= 8) {
- uint64_t k = DecodeFixed64(data);
- data += 8;
- n -= 8;
-
- k *= m;
- k ^= k >> r;
- k *= m;
-
- h ^= k;
- h *= m;
- }
-
- switch (n) {
- case 7:
- h ^= ByteAs64(data[6]) << 48;
- FALLTHROUGH_INTENDED;
- case 6:
- h ^= ByteAs64(data[5]) << 40;
- FALLTHROUGH_INTENDED;
- case 5:
- h ^= ByteAs64(data[4]) << 32;
- FALLTHROUGH_INTENDED;
- case 4:
- h ^= ByteAs64(data[3]) << 24;
- FALLTHROUGH_INTENDED;
- case 3:
- h ^= ByteAs64(data[2]) << 16;
- FALLTHROUGH_INTENDED;
- case 2:
- h ^= ByteAs64(data[1]) << 8;
- FALLTHROUGH_INTENDED;
- case 1:
- h ^= ByteAs64(data[0]);
- h *= m;
- }
-
- h ^= h >> r;
- h *= m;
- h ^= h >> r;
-
- return h;
-}
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/hash.h b/cmds/statsd/src/hash.h
deleted file mode 100644
index cfe869f..0000000
--- a/cmds/statsd/src/hash.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-extern uint32_t Hash32(const char *data, size_t n, uint32_t seed);
-extern uint64_t Hash64(const char* data, size_t n, uint64_t seed);
-
-inline uint32_t Hash32(const char *data, size_t n) {
- return Hash32(data, n, 0xBEEF);
-}
-
-inline uint32_t Hash32(const std::string &input) {
- return Hash32(input.data(), input.size());
-}
-
-inline uint64_t Hash64(const char* data, size_t n) {
- return Hash64(data, n, 0xDECAFCAFFE);
-}
-
-inline uint64_t Hash64(const std::string& str) {
- return Hash64(str.data(), str.size());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
deleted file mode 100644
index f56fa62..0000000
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "logd/LogEvent.h"
-
-#include <android-base/stringprintf.h>
-#include <android/binder_ibinder.h>
-#include <private/android_filesystem_config.h>
-
-#include "annotations.h"
-#include "stats_log_util.h"
-#include "statslog_statsd.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for TrainInfo experiment id serialization
-const int FIELD_ID_EXPERIMENT_ID = 1;
-
-using namespace android::util;
-using android::base::StringPrintf;
-using android::util::ProtoOutputStream;
-using std::string;
-using std::vector;
-
-// stats_event.h socket types. Keep in sync.
-/* ERRORS */
-#define ERROR_NO_TIMESTAMP 0x1
-#define ERROR_NO_ATOM_ID 0x2
-#define ERROR_OVERFLOW 0x4
-#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8
-#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10
-#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20
-#define ERROR_INVALID_ANNOTATION_ID 0x40
-#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80
-#define ERROR_TOO_MANY_ANNOTATIONS 0x100
-#define ERROR_TOO_MANY_FIELDS 0x200
-#define ERROR_INVALID_VALUE_TYPE 0x400
-#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
-
-/* TYPE IDS */
-#define INT32_TYPE 0x00
-#define INT64_TYPE 0x01
-#define STRING_TYPE 0x02
-#define LIST_TYPE 0x03
-#define FLOAT_TYPE 0x04
-#define BOOL_TYPE 0x05
-#define BYTE_ARRAY_TYPE 0x06
-#define OBJECT_TYPE 0x07
-#define KEY_VALUE_PAIRS_TYPE 0x08
-#define ATTRIBUTION_CHAIN_TYPE 0x09
-#define ERROR_TYPE 0x0F
-
-LogEvent::LogEvent(int32_t uid, int32_t pid)
- : mLogdTimestampNs(time(nullptr)), mLogUid(uid), mLogPid(pid) {
-}
-
-LogEvent::LogEvent(const string& trainName, int64_t trainVersionCode, bool requiresStaging,
- bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state,
- const std::vector<uint8_t>& experimentIds, int32_t userId) {
- mLogdTimestampNs = getWallClockNs();
- mElapsedTimestampNs = getElapsedRealtimeNs();
- mTagId = util::BINARY_PUSH_STATE_CHANGED;
- mLogUid = AIBinder_getCallingUid();
- mLogPid = AIBinder_getCallingPid();
-
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)), Value(trainName)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainVersionCode)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value((int)requiresStaging)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value((int)rollbackEnabled)));
- mValues.push_back(
- FieldValue(Field(mTagId, getSimpleField(5)), Value((int)requiresLowLatencyMonitor)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(6)), Value(state)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(7)), Value(experimentIds)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(8)), Value(userId)));
-}
-
-LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
- const InstallTrainInfo& trainInfo) {
- mLogdTimestampNs = wallClockTimestampNs;
- mElapsedTimestampNs = elapsedTimestampNs;
- mTagId = util::TRAIN_INFO;
-
- mValues.push_back(
- FieldValue(Field(mTagId, getSimpleField(1)), Value(trainInfo.trainVersionCode)));
- std::vector<uint8_t> experimentIdsProto;
- writeExperimentIdsToProto(trainInfo.experimentIds, &experimentIdsProto);
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(experimentIdsProto)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value(trainInfo.trainName)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value(trainInfo.status)));
-}
-
-void LogEvent::parseInt32(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t value = readNextValue<int32_t>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseInt64(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int64_t value = readNextValue<int64_t>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseString(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t numBytes = readNextValue<int32_t>();
- if ((uint32_t)numBytes > mRemainingLen) {
- mValid = false;
- return;
- }
-
- string value = string((char*)mBuf, numBytes);
- mBuf += numBytes;
- mRemainingLen -= numBytes;
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseFloat(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- float value = readNextValue<float>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseBool(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- // cast to int32_t because FieldValue does not support bools
- int32_t value = (int32_t)readNextValue<uint8_t>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseByteArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t numBytes = readNextValue<int32_t>();
- if ((uint32_t)numBytes > mRemainingLen) {
- mValid = false;
- return;
- }
-
- vector<uint8_t> value(mBuf, mBuf + numBytes);
- mBuf += numBytes;
- mRemainingLen -= numBytes;
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t numPairs = readNextValue<uint8_t>();
-
- for (pos[1] = 1; pos[1] <= numPairs; pos[1]++) {
- last[1] = (pos[1] == numPairs);
-
- // parse key
- pos[2] = 1;
- parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-
- // parse value
- last[2] = true;
-
- uint8_t typeInfo = readNextValue<uint8_t>();
- switch (getTypeId(typeInfo)) {
- case INT32_TYPE:
- pos[2] = 2; // pos[2] determined by index of type in KeyValuePair in atoms.proto
- parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- case INT64_TYPE:
- pos[2] = 3;
- parseInt64(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- case STRING_TYPE:
- pos[2] = 4;
- parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- case FLOAT_TYPE:
- pos[2] = 5;
- parseFloat(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- default:
- mValid = false;
- }
- }
-
- parseAnnotations(numAnnotations);
-
- pos[1] = pos[2] = 1;
- last[1] = last[2] = false;
-}
-
-void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last,
- uint8_t numAnnotations) {
- const unsigned int firstUidInChainIndex = mValues.size();
- const int32_t numNodes = readNextValue<uint8_t>();
- for (pos[1] = 1; pos[1] <= numNodes; pos[1]++) {
- last[1] = (pos[1] == numNodes);
-
- // parse uid
- pos[2] = 1;
- parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-
- // parse tag
- pos[2] = 2;
- last[2] = true;
- parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- }
- // Check if at least one node was successfully parsed.
- if (mValues.size() - 1 > firstUidInChainIndex) {
- mAttributionChainStartIndex = static_cast<int8_t>(firstUidInChainIndex);
- mAttributionChainEndIndex = static_cast<int8_t>(mValues.size() - 1);
- }
-
- parseAnnotations(numAnnotations, firstUidInChainIndex);
-
- pos[1] = pos[2] = 1;
- last[1] = last[2] = false;
-}
-
-// Assumes that mValues is not empty
-bool LogEvent::checkPreviousValueType(Type expected) {
- return mValues[mValues.size() - 1].mValue.getType() == expected;
-}
-
-void LogEvent::parseIsUidAnnotation(uint8_t annotationType) {
- if (mValues.empty() || !checkPreviousValueType(INT) || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- bool isUid = readNextValue<uint8_t>();
- if (isUid) mUidFieldIndex = static_cast<int8_t>(mValues.size() - 1);
- mValues[mValues.size() - 1].mAnnotations.setUidField(isUid);
-}
-
-void LogEvent::parseTruncateTimestampAnnotation(uint8_t annotationType) {
- if (!mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- mTruncateTimestamp = readNextValue<uint8_t>();
-}
-
-void LogEvent::parsePrimaryFieldAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- const bool primaryField = readNextValue<uint8_t>();
- mValues[mValues.size() - 1].mAnnotations.setPrimaryField(primaryField);
-}
-
-void LogEvent::parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType,
- int firstUidInChainIndex) {
- if (mValues.empty() || annotationType != BOOL_TYPE || -1 == firstUidInChainIndex) {
- mValid = false;
- return;
- }
-
- const bool primaryField = readNextValue<uint8_t>();
- mValues[firstUidInChainIndex].mAnnotations.setPrimaryField(primaryField);
-}
-
-void LogEvent::parseExclusiveStateAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- const bool exclusiveState = readNextValue<uint8_t>();
- mExclusiveStateFieldIndex = static_cast<int8_t>(mValues.size() - 1);
- mValues[getExclusiveStateFieldIndex()].mAnnotations.setExclusiveState(exclusiveState);
-}
-
-void LogEvent::parseTriggerStateResetAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != INT32_TYPE) {
- mValid = false;
- return;
- }
-
- mResetState = readNextValue<int32_t>();
-}
-
-void LogEvent::parseStateNestedAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- bool nested = readNextValue<uint8_t>();
- mValues[mValues.size() - 1].mAnnotations.setNested(nested);
-}
-
-// firstUidInChainIndex is a default parameter that is only needed when parsing
-// annotations for attribution chains.
-void LogEvent::parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex) {
- for (uint8_t i = 0; i < numAnnotations; i++) {
- uint8_t annotationId = readNextValue<uint8_t>();
- uint8_t annotationType = readNextValue<uint8_t>();
-
- switch (annotationId) {
- case ANNOTATION_ID_IS_UID:
- parseIsUidAnnotation(annotationType);
- break;
- case ANNOTATION_ID_TRUNCATE_TIMESTAMP:
- parseTruncateTimestampAnnotation(annotationType);
- break;
- case ANNOTATION_ID_PRIMARY_FIELD:
- parsePrimaryFieldAnnotation(annotationType);
- break;
- case ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID:
- parsePrimaryFieldFirstUidAnnotation(annotationType, firstUidInChainIndex);
- break;
- case ANNOTATION_ID_EXCLUSIVE_STATE:
- parseExclusiveStateAnnotation(annotationType);
- break;
- case ANNOTATION_ID_TRIGGER_STATE_RESET:
- parseTriggerStateResetAnnotation(annotationType);
- break;
- case ANNOTATION_ID_STATE_NESTED:
- parseStateNestedAnnotation(annotationType);
- break;
- default:
- mValid = false;
- return;
- }
- }
-}
-
-// This parsing logic is tied to the encoding scheme used in StatsEvent.java and
-// stats_event.c
-bool LogEvent::parseBuffer(uint8_t* buf, size_t len) {
- mBuf = buf;
- mRemainingLen = (uint32_t)len;
-
- int32_t pos[] = {1, 1, 1};
- bool last[] = {false, false, false};
-
- // Beginning of buffer is OBJECT_TYPE | NUM_FIELDS | TIMESTAMP | ATOM_ID
- uint8_t typeInfo = readNextValue<uint8_t>();
- if (getTypeId(typeInfo) != OBJECT_TYPE) mValid = false;
-
- uint8_t numElements = readNextValue<uint8_t>();
- if (numElements < 2 || numElements > 127) mValid = false;
-
- typeInfo = readNextValue<uint8_t>();
- if (getTypeId(typeInfo) != INT64_TYPE) mValid = false;
- mElapsedTimestampNs = readNextValue<int64_t>();
- numElements--;
-
- typeInfo = readNextValue<uint8_t>();
- if (getTypeId(typeInfo) != INT32_TYPE) mValid = false;
- mTagId = readNextValue<int32_t>();
- numElements--;
- parseAnnotations(getNumAnnotations(typeInfo)); // atom-level annotations
-
- for (pos[0] = 1; pos[0] <= numElements && mValid; pos[0]++) {
- last[0] = (pos[0] == numElements);
-
- typeInfo = readNextValue<uint8_t>();
- uint8_t typeId = getTypeId(typeInfo);
-
- switch (typeId) {
- case BOOL_TYPE:
- parseBool(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case INT32_TYPE:
- parseInt32(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case INT64_TYPE:
- parseInt64(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case FLOAT_TYPE:
- parseFloat(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case BYTE_ARRAY_TYPE:
- parseByteArray(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case STRING_TYPE:
- parseString(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case KEY_VALUE_PAIRS_TYPE:
- parseKeyValuePairs(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case ATTRIBUTION_CHAIN_TYPE:
- parseAttributionChain(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case ERROR_TYPE:
- /* mErrorBitmask =*/ readNextValue<int32_t>();
- mValid = false;
- break;
- default:
- mValid = false;
- break;
- }
- }
-
- if (mRemainingLen != 0) mValid = false;
- mBuf = nullptr;
- return mValid;
-}
-
-uint8_t LogEvent::getTypeId(uint8_t typeInfo) {
- return typeInfo & 0x0F; // type id in lower 4 bytes
-}
-
-uint8_t LogEvent::getNumAnnotations(uint8_t typeInfo) {
- return (typeInfo >> 4) & 0x0F; // num annotations in upper 4 bytes
-}
-
-int64_t LogEvent::GetLong(size_t key, status_t* err) const {
- // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == LONG) {
- return value.mValue.long_value;
- } else if (value.mValue.getType() == INT) {
- return value.mValue.int_value;
- } else {
- *err = BAD_TYPE;
- return 0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return 0;
-}
-
-int LogEvent::GetInt(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == INT) {
- return value.mValue.int_value;
- } else {
- *err = BAD_TYPE;
- return 0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return 0;
-}
-
-const char* LogEvent::GetString(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == STRING) {
- return value.mValue.str_value.c_str();
- } else {
- *err = BAD_TYPE;
- return 0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return NULL;
-}
-
-bool LogEvent::GetBool(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == INT) {
- return value.mValue.int_value != 0;
- } else if (value.mValue.getType() == LONG) {
- return value.mValue.long_value != 0;
- } else {
- *err = BAD_TYPE;
- return false;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return false;
-}
-
-float LogEvent::GetFloat(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == FLOAT) {
- return value.mValue.float_value;
- } else {
- *err = BAD_TYPE;
- return 0.0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return 0.0;
-}
-
-std::vector<uint8_t> LogEvent::GetStorage(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == STORAGE) {
- return value.mValue.storage_value;
- } else {
- *err = BAD_TYPE;
- return vector<uint8_t>();
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return vector<uint8_t>();
-}
-
-string LogEvent::ToString() const {
- string result;
- result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs,
- (long long)mElapsedTimestampNs, mTagId);
- for (const auto& value : mValues) {
- result +=
- StringPrintf("%#x", value.mField.getField()) + "->" + value.mValue.toString() + " ";
- }
- result += " }";
- return result;
-}
-
-void LogEvent::ToProto(ProtoOutputStream& protoOutput) const {
- writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
-}
-
-bool LogEvent::hasAttributionChain(std::pair<int, int>* indexRange) const {
- if (mAttributionChainStartIndex == -1 || mAttributionChainEndIndex == -1) {
- return false;
- }
-
- if (nullptr != indexRange) {
- indexRange->first = static_cast<int>(mAttributionChainStartIndex);
- indexRange->second = static_cast<int>(mAttributionChainEndIndex);
- }
-
- return true;
-}
-
-void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds,
- std::vector<uint8_t>* protoOut) {
- ProtoOutputStream proto;
- for (const auto& expId : experimentIds) {
- proto.write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_EXPERIMENT_ID,
- (long long)expId);
- }
-
- protoOut->resize(proto.size());
- size_t pos = 0;
- sp<ProtoReader> reader = proto.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(protoOut->data() + pos, reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
deleted file mode 100644
index a5f2460..0000000
--- a/cmds/statsd/src/logd/LogEvent.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "FieldValue.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include <private/android_logger.h>
-
-#include <string>
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct InstallTrainInfo {
- int64_t trainVersionCode;
- std::string trainName;
- int32_t status;
- std::vector<int64_t> experimentIds;
- bool requiresStaging;
- bool rollbackEnabled;
- bool requiresLowLatencyMonitor;
-};
-
-/**
- * This class decodes the structured, serialized encoding of an atom into a
- * vector of FieldValues.
- */
-class LogEvent {
-public:
- /**
- * \param uid user id of the logging caller
- * \param pid process id of the logging caller
- */
- explicit LogEvent(int32_t uid, int32_t pid);
-
- /**
- * Parses the atomId, timestamp, and vector of values from a buffer
- * containing the StatsEvent/AStatsEvent encoding of an atom.
- *
- * \param buf a buffer that begins at the start of the serialized atom (it
- * should not include the android_log_header_t or the StatsEventTag)
- * \param len size of the buffer
- *
- * \return success of the initialization
- */
- bool parseBuffer(uint8_t* buf, size_t len);
-
- // Constructs a BinaryPushStateChanged LogEvent from API call.
- explicit LogEvent(const std::string& trainName, int64_t trainVersionCode, bool requiresStaging,
- bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state,
- const std::vector<uint8_t>& experimentIds, int32_t userId);
-
- explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
- const InstallTrainInfo& installTrainInfo);
-
- ~LogEvent() {}
-
- /**
- * Get the timestamp associated with this event.
- */
- inline int64_t GetLogdTimestampNs() const { return mLogdTimestampNs; }
- inline int64_t GetElapsedTimestampNs() const { return mElapsedTimestampNs; }
-
- /**
- * Get the tag for this event.
- */
- inline int GetTagId() const { return mTagId; }
-
- /**
- * Get the uid of the logging client.
- * Returns -1 if the uid is unknown/has not been set.
- */
- inline int32_t GetUid() const { return mLogUid; }
-
- /**
- * Get the pid of the logging client.
- * Returns -1 if the pid is unknown/has not been set.
- */
- inline int32_t GetPid() const { return mLogPid; }
-
- /**
- * Get the nth value, starting at 1.
- *
- * Returns BAD_INDEX if the index is larger than the number of elements.
- * Returns BAD_TYPE if the index is available but the data is the wrong type.
- */
- int64_t GetLong(size_t key, status_t* err) const;
- int GetInt(size_t key, status_t* err) const;
- const char* GetString(size_t key, status_t* err) const;
- bool GetBool(size_t key, status_t* err) const;
- float GetFloat(size_t key, status_t* err) const;
- std::vector<uint8_t> GetStorage(size_t key, status_t* err) const;
-
- /**
- * Return a string representation of this event.
- */
- std::string ToString() const;
-
- /**
- * Write this object to a ProtoOutputStream.
- */
- void ToProto(android::util::ProtoOutputStream& out) const;
-
- /**
- * Set elapsed timestamp if the original timestamp is missing.
- */
- void setElapsedTimestampNs(int64_t timestampNs) {
- mElapsedTimestampNs = timestampNs;
- }
-
- /**
- * Set the timestamp if the original logd timestamp is missing.
- */
- void setLogdWallClockTimestampNs(int64_t timestampNs) {
- mLogdTimestampNs = timestampNs;
- }
-
- inline int size() const {
- return mValues.size();
- }
-
- const std::vector<FieldValue>& getValues() const {
- return mValues;
- }
-
- std::vector<FieldValue>* getMutableValues() {
- return &mValues;
- }
-
- // Default value = false
- inline bool shouldTruncateTimestamp() const {
- return mTruncateTimestamp;
- }
-
- // Returns the index of the uid field within the FieldValues vector if the
- // uid exists. If there is no uid field, returns -1.
- //
- // If the index within the atom definition is desired, do the following:
- // int vectorIndex = LogEvent.getUidFieldIndex();
- // if (vectorIndex != -1) {
- // FieldValue& v = LogEvent.getValues()[vectorIndex];
- // int atomIndex = v.mField.getPosAtDepth(0);
- // }
- // Note that atomIndex is 1-indexed.
- inline int getUidFieldIndex() {
- return static_cast<int>(mUidFieldIndex);
- }
-
- // Returns whether this LogEvent has an AttributionChain.
- // If it does and indexRange is not a nullptr, populate indexRange with the start and end index
- // of the AttributionChain within mValues.
- bool hasAttributionChain(std::pair<int, int>* indexRange = nullptr) const;
-
- // Returns the index of the exclusive state field within the FieldValues vector if
- // an exclusive state exists. If there is no exclusive state field, returns -1.
- //
- // If the index within the atom definition is desired, do the following:
- // int vectorIndex = LogEvent.getExclusiveStateFieldIndex();
- // if (vectorIndex != -1) {
- // FieldValue& v = LogEvent.getValues()[vectorIndex];
- // int atomIndex = v.mField.getPosAtDepth(0);
- // }
- // Note that atomIndex is 1-indexed.
- inline int getExclusiveStateFieldIndex() const {
- return static_cast<int>(mExclusiveStateFieldIndex);
- }
-
- // If a reset state is not sent in the StatsEvent, returns -1. Note that a
- // reset state is sent if and only if a reset should be triggered.
- inline int getResetState() const {
- return mResetState;
- }
-
- inline LogEvent makeCopy() {
- return LogEvent(*this);
- }
-
- template <class T>
- status_t updateValue(size_t key, T& value, Type type) {
- int field = getSimpleField(key);
- for (auto& fieldValue : mValues) {
- if (fieldValue.mField.getField() == field) {
- if (fieldValue.mValue.getType() == type) {
- fieldValue.mValue = Value(value);
- return OK;
- } else {
- return BAD_TYPE;
- }
- }
- }
- return BAD_INDEX;
- }
-
- bool isValid() const {
- return mValid;
- }
-
-private:
- /**
- * Only use this if copy is absolutely needed.
- */
- LogEvent(const LogEvent&) = default;
-
- void parseInt32(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseInt64(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseString(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseFloat(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseBool(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseByteArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseAttributionChain(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-
- void parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex = -1);
- void parseIsUidAnnotation(uint8_t annotationType);
- void parseTruncateTimestampAnnotation(uint8_t annotationType);
- void parsePrimaryFieldAnnotation(uint8_t annotationType);
- void parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType, int firstUidInChainIndex);
- void parseExclusiveStateAnnotation(uint8_t annotationType);
- void parseTriggerStateResetAnnotation(uint8_t annotationType);
- void parseStateNestedAnnotation(uint8_t annotationType);
- bool checkPreviousValueType(Type expected);
-
- /**
- * The below two variables are only valid during the execution of
- * parseBuffer. There are no guarantees about the state of these variables
- * before/after.
- */
- uint8_t* mBuf;
- uint32_t mRemainingLen; // number of valid bytes left in the buffer being parsed
-
- bool mValid = true; // stores whether the event we received from the socket is valid
-
- /**
- * Side-effects:
- * If there is enough space in buffer to read value of type T
- * - move mBuf past the value that was just read
- * - decrement mRemainingLen by size of T
- * Else
- * - set mValid to false
- */
- template <class T>
- T readNextValue() {
- T value;
- if (mRemainingLen < sizeof(T)) {
- mValid = false;
- value = 0; // all primitive types can successfully cast 0
- } else {
- // When alignof(T) == 1, hopefully the compiler can optimize away
- // this conditional as always true.
- if ((reinterpret_cast<uintptr_t>(mBuf) % alignof(T)) == 0) {
- // We're properly aligned, and can safely make this assignment.
- value = *((T*)mBuf);
- } else {
- // We need to use memcpy. It's slower, but safe.
- memcpy(&value, mBuf, sizeof(T));
- }
- mBuf += sizeof(T);
- mRemainingLen -= sizeof(T);
- }
- return value;
- }
-
- template <class T>
- void addToValues(int32_t* pos, int32_t depth, T& value, bool* last) {
- Field f = Field(mTagId, pos, depth);
- // do not decorate last position at depth 0
- for (int i = 1; i < depth; i++) {
- if (last[i]) f.decorateLastPos(i);
- }
-
- Value v = Value(value);
- mValues.push_back(FieldValue(f, v));
- }
-
- uint8_t getTypeId(uint8_t typeInfo);
- uint8_t getNumAnnotations(uint8_t typeInfo);
-
- // The items are naturally sorted in DFS order as we read them. this allows us to do fast
- // matching.
- std::vector<FieldValue> mValues;
-
- // The timestamp set by the logd.
- int64_t mLogdTimestampNs;
-
- // The elapsed timestamp set by statsd log writer.
- int64_t mElapsedTimestampNs;
-
- // The atom tag of the event (defaults to 0 if client does not
- // appropriately set the atom id).
- int mTagId = 0;
-
- // The uid of the logging client (defaults to -1).
- int32_t mLogUid = -1;
-
- // The pid of the logging client (defaults to -1).
- int32_t mLogPid = -1;
-
- // Annotations
- bool mTruncateTimestamp = false;
- int mResetState = -1;
-
- // Indexes within the FieldValue vector can be stored in 7 bits because
- // that's the assumption enforced by the encoding used in FieldValue.
- int8_t mUidFieldIndex = -1;
- int8_t mAttributionChainStartIndex = -1;
- int8_t mAttributionChainEndIndex = -1;
- int8_t mExclusiveStateFieldIndex = -1;
-};
-
-void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/logd/LogEventQueue.cpp b/cmds/statsd/src/logd/LogEventQueue.cpp
deleted file mode 100644
index 146464bb..0000000
--- a/cmds/statsd/src/logd/LogEventQueue.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "LogEventQueue.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unique_lock;
-using std::unique_ptr;
-
-unique_ptr<LogEvent> LogEventQueue::waitPop() {
- std::unique_lock<std::mutex> lock(mMutex);
-
- if (mQueue.empty()) {
- mCondition.wait(lock, [this] { return !this->mQueue.empty(); });
- }
-
- unique_ptr<LogEvent> item = std::move(mQueue.front());
- mQueue.pop();
-
- return item;
-}
-
-bool LogEventQueue::push(unique_ptr<LogEvent> item, int64_t* oldestTimestampNs) {
- bool success;
- {
- std::unique_lock<std::mutex> lock(mMutex);
- if (mQueue.size() < mQueueLimit) {
- mQueue.push(std::move(item));
- success = true;
- } else {
- // safe operation as queue must not be empty.
- *oldestTimestampNs = mQueue.front()->GetElapsedTimestampNs();
- success = false;
- }
- }
-
- mCondition.notify_one();
- return success;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/logd/LogEventQueue.h b/cmds/statsd/src/logd/LogEventQueue.h
deleted file mode 100644
index 9dda3d2..0000000
--- a/cmds/statsd/src/logd/LogEventQueue.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "LogEvent.h"
-
-#include <condition_variable>
-#include <mutex>
-#include <queue>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * A zero copy thread safe queue buffer for producing and consuming LogEvent.
- */
-class LogEventQueue {
-public:
- explicit LogEventQueue(size_t maxSize) : mQueueLimit(maxSize){};
-
- /**
- * Blocking read one event from the queue.
- */
- std::unique_ptr<LogEvent> waitPop();
-
- /**
- * Puts a LogEvent ptr to the end of the queue.
- * Returns false on failure when the queue is full, and output the oldest event timestamp
- * in the queue.
- */
- bool push(std::unique_ptr<LogEvent> event, int64_t* oldestTimestampNs);
-
-private:
- const size_t mQueueLimit;
- std::condition_variable mCondition;
- std::mutex mMutex;
- std::queue<std::unique_ptr<LogEvent>> mQueue;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
deleted file mode 100644
index cd9c4e5..0000000
--- a/cmds/statsd/src/main.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsService.h"
-#include "socket/StatsSocketListener.h"
-
-#include <android/binder_interface_utils.h>
-#include <android/binder_process.h>
-#include <android/binder_manager.h>
-#include <utils/Looper.h>
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-using namespace android;
-using namespace android::os::statsd;
-using ::ndk::SharedRefBase;
-using std::shared_ptr;
-using std::make_shared;
-
-shared_ptr<StatsService> gStatsService = nullptr;
-sp<StatsSocketListener> gSocketListener = nullptr;
-
-void signalHandler(int sig) {
- if (sig == SIGPIPE) {
- // ShellSubscriber uses SIGPIPE as a signal to detect the end of the
- // client process. Don't prematurely exit(1) here. Instead, ignore the
- // signal and allow the write call to return EPIPE.
- ALOGI("statsd received SIGPIPE. Ignoring signal.");
- return;
- }
-
- if (gSocketListener != nullptr) gSocketListener->stopListener();
- if (gStatsService != nullptr) gStatsService->Terminate();
- ALOGW("statsd terminated on receiving signal %d.", sig);
- exit(1);
-}
-
-void registerSignalHandlers()
-{
- struct sigaction sa;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = signalHandler;
- sigaction(SIGPIPE, &sa, nullptr);
- sigaction(SIGHUP, &sa, nullptr);
- sigaction(SIGINT, &sa, nullptr);
- sigaction(SIGQUIT, &sa, nullptr);
- sigaction(SIGTERM, &sa, nullptr);
-}
-
-int main(int /*argc*/, char** /*argv*/) {
- // Set up the looper
- sp<Looper> looper(Looper::prepare(0 /* opts */));
-
- // Set up the binder
- ABinderProcess_setThreadPoolMaxThreadCount(9);
- ABinderProcess_startThreadPool();
-
- std::shared_ptr<LogEventQueue> eventQueue =
- std::make_shared<LogEventQueue>(2000 /*buffer limit. Buffer is NOT pre-allocated*/);
-
- // Create the service
- gStatsService = SharedRefBase::make<StatsService>(looper, eventQueue);
- // TODO(b/149582373): Set DUMP_FLAG_PROTO once libbinder_ndk supports
- // setting dumpsys priorities.
- binder_status_t status = AServiceManager_addService(gStatsService->asBinder().get(), "stats");
- if (status != STATUS_OK) {
- ALOGE("Failed to add service as AIDL service");
- return -1;
- }
-
- registerSignalHandlers();
-
- gStatsService->sayHiToStatsCompanion();
-
- gStatsService->Startup();
-
- gSocketListener = new StatsSocketListener(eventQueue);
-
- ALOGI("Statsd starts to listen to socket.");
- // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
- if (gSocketListener->startListener(600)) {
- exit(1);
- }
-
- // Loop forever -- the reports run on this thread in a handler, and the
- // binder calls remain responsive in their pool of one thread.
- while (true) {
- looper->pollAll(-1 /* timeoutMillis */);
- }
- ALOGW("statsd escaped from its loop.");
-
- return 1;
-}
diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
deleted file mode 100644
index b94a957..0000000
--- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Log.h"
-
-#include "CombinationLogMatchingTracker.h"
-#include "matchers/matcher_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-CombinationLogMatchingTracker::CombinationLogMatchingTracker(const int64_t& id, const int index)
- : LogMatchingTracker(id, index) {
-}
-
-CombinationLogMatchingTracker::~CombinationLogMatchingTracker() {
-}
-
-bool CombinationLogMatchingTracker::init(const vector<AtomMatcher>& allLogMatchers,
- const vector<sp<LogMatchingTracker>>& allTrackers,
- const unordered_map<int64_t, int>& matcherMap,
- vector<bool>& stack) {
- if (mInitialized) {
- return true;
- }
-
- // mark this node as visited in the recursion stack.
- stack[mIndex] = true;
-
- AtomMatcher_Combination matcher = allLogMatchers[mIndex].combination();
-
- // LogicalOperation is missing in the config
- if (!matcher.has_operation()) {
- return false;
- }
-
- mLogicalOperation = matcher.operation();
-
- if (mLogicalOperation == LogicalOperation::NOT && matcher.matcher_size() != 1) {
- return false;
- }
-
- for (const auto& child : matcher.matcher()) {
- auto pair = matcherMap.find(child);
- if (pair == matcherMap.end()) {
- ALOGW("Matcher %lld not found in the config", (long long)child);
- return false;
- }
-
- int childIndex = pair->second;
-
- // if the child is a visited node in the recursion -> circle detected.
- if (stack[childIndex]) {
- ALOGE("Circle detected in matcher config");
- return false;
- }
-
- if (!allTrackers[childIndex]->init(allLogMatchers, allTrackers, matcherMap, stack)) {
- ALOGW("child matcher init failed %lld", (long long)child);
- return false;
- }
-
- mChildren.push_back(childIndex);
-
- const set<int>& childTagIds = allTrackers[childIndex]->getAtomIds();
- mAtomIds.insert(childTagIds.begin(), childTagIds.end());
- }
-
- mInitialized = true;
- // unmark this node in the recursion stack.
- stack[mIndex] = false;
- return true;
-}
-
-void CombinationLogMatchingTracker::onLogEvent(const LogEvent& event,
- const vector<sp<LogMatchingTracker>>& allTrackers,
- vector<MatchingState>& matcherResults) {
- // this event has been processed.
- if (matcherResults[mIndex] != MatchingState::kNotComputed) {
- return;
- }
-
- if (mAtomIds.find(event.GetTagId()) == mAtomIds.end()) {
- matcherResults[mIndex] = MatchingState::kNotMatched;
- return;
- }
-
- // evaluate children matchers if they haven't been evaluated.
- for (const int childIndex : mChildren) {
- if (matcherResults[childIndex] == MatchingState::kNotComputed) {
- const sp<LogMatchingTracker>& child = allTrackers[childIndex];
- child->onLogEvent(event, allTrackers, matcherResults);
- }
- }
-
- bool matched = combinationMatch(mChildren, mLogicalOperation, matcherResults);
- matcherResults[mIndex] = matched ? MatchingState::kMatched : MatchingState::kNotMatched;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
deleted file mode 100644
index 55bc4605..0000000
--- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef COMBINATION_LOG_MATCHING_TRACKER_H
-#define COMBINATION_LOG_MATCHING_TRACKER_H
-
-#include <unordered_map>
-#include <vector>
-#include "LogMatchingTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Represents a AtomMatcher_Combination in the StatsdConfig.
-class CombinationLogMatchingTracker : public virtual LogMatchingTracker {
-public:
- CombinationLogMatchingTracker(const int64_t& id, const int index);
-
- bool init(const std::vector<AtomMatcher>& allLogMatchers,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- const std::unordered_map<int64_t, int>& matcherMap,
- std::vector<bool>& stack);
-
- ~CombinationLogMatchingTracker();
-
- void onLogEvent(const LogEvent& event,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- std::vector<MatchingState>& matcherResults) override;
-
-private:
- LogicalOperation mLogicalOperation;
-
- std::vector<int> mChildren;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // COMBINATION_LOG_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/EventMatcherWizard.cpp b/cmds/statsd/src/matchers/EventMatcherWizard.cpp
deleted file mode 100644
index 025c9a8..0000000
--- a/cmds/statsd/src/matchers/EventMatcherWizard.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "EventMatcherWizard.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-MatchingState EventMatcherWizard::matchLogEvent(const LogEvent& event, int matcher_index) {
- if (matcher_index < 0 || matcher_index >= (int)mAllEventMatchers.size()) {
- return MatchingState::kNotComputed;
- }
- vector<MatchingState> matcherCache(mAllEventMatchers.size(), MatchingState::kNotComputed);
- mAllEventMatchers[matcher_index]->onLogEvent(event, mAllEventMatchers, matcherCache);
- return matcherCache[matcher_index];
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/matchers/EventMatcherWizard.h b/cmds/statsd/src/matchers/EventMatcherWizard.h
deleted file mode 100644
index 57ec2b3..0000000
--- a/cmds/statsd/src/matchers/EventMatcherWizard.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "LogMatchingTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class EventMatcherWizard : public virtual android::RefBase {
-public:
- EventMatcherWizard(){}; // for testing
- EventMatcherWizard(const std::vector<sp<LogMatchingTracker>>& eventTrackers)
- : mAllEventMatchers(eventTrackers){};
-
- virtual ~EventMatcherWizard(){};
-
- MatchingState matchLogEvent(const LogEvent& event, int matcher_index);
-
-private:
- std::vector<sp<LogMatchingTracker>> mAllEventMatchers;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/matchers/LogMatchingTracker.h b/cmds/statsd/src/matchers/LogMatchingTracker.h
deleted file mode 100644
index 88ab4e6..0000000
--- a/cmds/statsd/src/matchers/LogMatchingTracker.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef LOG_MATCHING_TRACKER_H
-#define LOG_MATCHING_TRACKER_H
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "logd/LogEvent.h"
-#include "matchers/matcher_util.h"
-
-#include <utils/RefBase.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class LogMatchingTracker : public virtual RefBase {
-public:
- LogMatchingTracker(const int64_t& id, const int index)
- : mId(id), mIndex(index), mInitialized(false){};
-
- virtual ~LogMatchingTracker(){};
-
- // Initialize this LogMatchingTracker.
- // allLogMatchers: the list of the AtomMatcher proto config. This is needed because we don't
- // store the proto object in memory. We only need it during initilization.
- // allTrackers: the list of the LogMatchingTracker objects. It's a one-to-one mapping with
- // allLogMatchers. This is needed because the initialization is done recursively
- // for CombinationLogMatchingTrackers using DFS.
- // stack: a bit map to record which matcher has been visited on the stack. This is for detecting
- // circle dependency.
- virtual bool init(const std::vector<AtomMatcher>& allLogMatchers,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- const std::unordered_map<int64_t, int>& matcherMap,
- std::vector<bool>& stack) = 0;
-
- // Called when a log event comes.
- // event: the log event.
- // allTrackers: the list of all LogMatchingTrackers. This is needed because the log processing
- // is done recursively.
- // matcherResults: The cached results for all matchers for this event. Parent matchers can
- // directly access the children's matching results if they have been evaluated.
- // Otherwise, call children matchers' onLogEvent.
- virtual void onLogEvent(const LogEvent& event,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- std::vector<MatchingState>& matcherResults) = 0;
-
- // Get the tagIds that this matcher cares about. The combined collection is stored
- // in MetricMananger, so that we can pass any LogEvents that are not interest of us. It uses
- // some memory but hopefully it can save us much CPU time when there is flood of events.
- virtual const std::set<int>& getAtomIds() const {
- return mAtomIds;
- }
-
- const int64_t& getId() const {
- return mId;
- }
-
-protected:
- // Name of this matching. We don't really need the name, but it makes log message easy to debug.
- const int64_t mId;
-
- // Index of this LogMatchingTracker in MetricsManager's container.
- const int mIndex;
-
- // Whether this LogMatchingTracker has been properly initialized.
- bool mInitialized;
-
- // The collection of the event tag ids that this LogMatchingTracker cares. So we can quickly
- // return kNotMatched when we receive an event with an id not in the list. This is especially
- // useful when we have a complex CombinationLogMatcherTracker.
- std::set<int> mAtomIds;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // LOG_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
deleted file mode 100644
index 082daf5..0000000
--- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "SimpleLogMatchingTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-using std::vector;
-
-
-SimpleLogMatchingTracker::SimpleLogMatchingTracker(const int64_t& id, const int index,
- const SimpleAtomMatcher& matcher,
- const UidMap& uidMap)
- : LogMatchingTracker(id, index), mMatcher(matcher), mUidMap(uidMap) {
- if (!matcher.has_atom_id()) {
- mInitialized = false;
- } else {
- mAtomIds.insert(matcher.atom_id());
- mInitialized = true;
- }
-}
-
-SimpleLogMatchingTracker::~SimpleLogMatchingTracker() {
-}
-
-bool SimpleLogMatchingTracker::init(const vector<AtomMatcher>& allLogMatchers,
- const vector<sp<LogMatchingTracker>>& allTrackers,
- const unordered_map<int64_t, int>& matcherMap,
- vector<bool>& stack) {
- // no need to do anything.
- return mInitialized;
-}
-
-void SimpleLogMatchingTracker::onLogEvent(const LogEvent& event,
- const vector<sp<LogMatchingTracker>>& allTrackers,
- vector<MatchingState>& matcherResults) {
- if (matcherResults[mIndex] != MatchingState::kNotComputed) {
- VLOG("Matcher %lld already evaluated ", (long long)mId);
- return;
- }
-
- if (mAtomIds.find(event.GetTagId()) == mAtomIds.end()) {
- matcherResults[mIndex] = MatchingState::kNotMatched;
- return;
- }
-
- bool matched = matchesSimple(mUidMap, mMatcher, event);
- matcherResults[mIndex] = matched ? MatchingState::kMatched : MatchingState::kNotMatched;
- VLOG("Stats SimpleLogMatcher %lld matched? %d", (long long)mId, matched);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
deleted file mode 100644
index a0f6a88..0000000
--- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SIMPLE_LOG_MATCHING_TRACKER_H
-#define SIMPLE_LOG_MATCHING_TRACKER_H
-
-#include <unordered_map>
-#include <vector>
-#include "LogMatchingTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class SimpleLogMatchingTracker : public virtual LogMatchingTracker {
-public:
- SimpleLogMatchingTracker(const int64_t& id, const int index,
- const SimpleAtomMatcher& matcher,
- const UidMap& uidMap);
-
- ~SimpleLogMatchingTracker();
-
- bool init(const std::vector<AtomMatcher>& allLogMatchers,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- const std::unordered_map<int64_t, int>& matcherMap,
- std::vector<bool>& stack) override;
-
- void onLogEvent(const LogEvent& event,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- std::vector<MatchingState>& matcherResults) override;
-
-private:
- const SimpleAtomMatcher mMatcher;
- const UidMap& mUidMap;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // SIMPLE_LOG_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
deleted file mode 100644
index 2b4c6a3..0000000
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/LogMatchingTracker.h"
-#include "matchers/matcher_util.h"
-#include "stats_util.h"
-
-using std::set;
-using std::string;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-bool combinationMatch(const vector<int>& children, const LogicalOperation& operation,
- const vector<MatchingState>& matcherResults) {
- bool matched;
- switch (operation) {
- case LogicalOperation::AND: {
- matched = true;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] != MatchingState::kMatched) {
- matched = false;
- break;
- }
- }
- break;
- }
- case LogicalOperation::OR: {
- matched = false;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] == MatchingState::kMatched) {
- matched = true;
- break;
- }
- }
- break;
- }
- case LogicalOperation::NOT:
- matched = matcherResults[children[0]] == MatchingState::kNotMatched;
- break;
- case LogicalOperation::NAND:
- matched = false;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] != MatchingState::kMatched) {
- matched = true;
- break;
- }
- }
- break;
- case LogicalOperation::NOR:
- matched = true;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] == MatchingState::kMatched) {
- matched = false;
- break;
- }
- }
- break;
- case LogicalOperation::LOGICAL_OPERATION_UNSPECIFIED:
- matched = false;
- break;
- }
- return matched;
-}
-
-bool tryMatchString(const UidMap& uidMap, const FieldValue& fieldValue, const string& str_match) {
- if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) {
- int uid = fieldValue.mValue.int_value;
- auto aidIt = UidMap::sAidToUidMapping.find(str_match);
- if (aidIt != UidMap::sAidToUidMapping.end()) {
- return ((int)aidIt->second) == uid;
- }
- std::set<string> packageNames = uidMap.getAppNamesFromUid(uid, true /* normalize*/);
- return packageNames.find(str_match) != packageNames.end();
- } else if (fieldValue.mValue.getType() == STRING) {
- return fieldValue.mValue.str_value == str_match;
- }
- return false;
-}
-
-bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher,
- const vector<FieldValue>& values, int start, int end, int depth) {
- if (depth > 2) {
- ALOGE("Depth > 3 not supported");
- return false;
- }
-
- if (start >= end) {
- return false;
- }
-
- // Filter by entry field first
- int newStart = -1;
- int newEnd = end;
- // because the fields are naturally sorted in the DFS order. we can safely
- // break when pos is larger than the one we are searching for.
- for (int i = start; i < end; i++) {
- int pos = values[i].mField.getPosAtDepth(depth);
- if (pos == matcher.field()) {
- if (newStart == -1) {
- newStart = i;
- }
- newEnd = i + 1;
- } else if (pos > matcher.field()) {
- break;
- }
- }
-
- // Now we have zoomed in to a new range
- start = newStart;
- end = newEnd;
-
- if (start == -1) {
- // No such field found.
- return false;
- }
-
- vector<pair<int, int>> ranges; // the ranges are for matching ANY position
- if (matcher.has_position()) {
- // Repeated fields position is stored as a node in the path.
- depth++;
- if (depth > 2) {
- return false;
- }
- switch (matcher.position()) {
- case Position::FIRST: {
- for (int i = start; i < end; i++) {
- int pos = values[i].mField.getPosAtDepth(depth);
- if (pos != 1) {
- // Again, the log elements are stored in sorted order. so
- // once the position is > 1, we break;
- end = i;
- break;
- }
- }
- ranges.push_back(std::make_pair(start, end));
- break;
- }
- case Position::LAST: {
- // move the starting index to the first LAST field at the depth.
- for (int i = start; i < end; i++) {
- if (values[i].mField.isLastPos(depth)) {
- start = i;
- break;
- }
- }
- ranges.push_back(std::make_pair(start, end));
- break;
- }
- case Position::ANY: {
- // ANY means all the children matchers match in any of the sub trees, it's a match
- newStart = start;
- newEnd = end;
- // Here start is guaranteed to be a valid index.
- int currentPos = values[start].mField.getPosAtDepth(depth);
- // Now find all sub trees ranges.
- for (int i = start; i < end; i++) {
- int newPos = values[i].mField.getPosAtDepth(depth);
- if (newPos != currentPos) {
- ranges.push_back(std::make_pair(newStart, i));
- newStart = i;
- currentPos = newPos;
- }
- }
- ranges.push_back(std::make_pair(newStart, end));
- break;
- }
- case Position::ALL:
- ALOGE("Not supported: field matcher with ALL position.");
- break;
- case Position::POSITION_UNKNOWN:
- break;
- }
- } else {
- // No position
- ranges.push_back(std::make_pair(start, end));
- }
- // start and end are still pointing to the matched range.
- switch (matcher.value_matcher_case()) {
- case FieldValueMatcher::kMatchesTuple: {
- ++depth;
- // If any range matches all matchers, good.
- for (const auto& range : ranges) {
- bool matched = true;
- for (const auto& subMatcher : matcher.matches_tuple().field_value_matcher()) {
- if (!matchesSimple(uidMap, subMatcher, values, range.first, range.second,
- depth)) {
- matched = false;
- break;
- }
- }
- if (matched) return true;
- }
- return false;
- }
- // Finally, we get to the point of real value matching.
- // If the field matcher ends with ANY, then we have [start, end) range > 1.
- // In the following, we should return true, when ANY of the values matches.
- case FieldValueMatcher::ValueMatcherCase::kEqBool: {
- for (int i = start; i < end; i++) {
- if ((values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value != 0) == matcher.eq_bool()) ||
- (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value != 0) == matcher.eq_bool())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqString: {
- for (int i = start; i < end; i++) {
- if (tryMatchString(uidMap, values[i], matcher.eq_string())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kNeqAnyString: {
- const auto& str_list = matcher.neq_any_string();
- for (int i = start; i < end; i++) {
- bool notEqAll = true;
- for (const auto& str : str_list.str_value()) {
- if (tryMatchString(uidMap, values[i], str)) {
- notEqAll = false;
- break;
- }
- }
- if (notEqAll) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqAnyString: {
- const auto& str_list = matcher.eq_any_string();
- for (int i = start; i < end; i++) {
- for (const auto& str : str_list.str_value()) {
- if (tryMatchString(uidMap, values[i], str)) {
- return true;
- }
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (matcher.eq_int() == values[i].mValue.int_value)) {
- return true;
- }
- // eq_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (matcher.eq_int() == values[i].mValue.long_value)) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kLtInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value < matcher.lt_int())) {
- return true;
- }
- // lt_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value < matcher.lt_int())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kGtInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value > matcher.gt_int())) {
- return true;
- }
- // gt_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value > matcher.gt_int())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kLtFloat: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == FLOAT &&
- (values[i].mValue.float_value < matcher.lt_float())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kGtFloat: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == FLOAT &&
- (values[i].mValue.float_value > matcher.gt_float())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kLteInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value <= matcher.lte_int())) {
- return true;
- }
- // lte_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value <= matcher.lte_int())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kGteInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value >= matcher.gte_int())) {
- return true;
- }
- // gte_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value >= matcher.gte_int())) {
- return true;
- }
- }
- return false;
- }
- default:
- return false;
- }
-}
-
-bool matchesSimple(const UidMap& uidMap, const SimpleAtomMatcher& simpleMatcher,
- const LogEvent& event) {
- if (event.GetTagId() != simpleMatcher.atom_id()) {
- return false;
- }
-
- for (const auto& matcher : simpleMatcher.field_value_matcher()) {
- if (!matchesSimple(uidMap, matcher, event.getValues(), 0, event.getValues().size(), 0)) {
- return false;
- }
- }
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h
deleted file mode 100644
index 1ab3e87..0000000
--- a/cmds/statsd/src/matchers/matcher_util.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "logd/LogEvent.h"
-
-#include <vector>
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "packages/UidMap.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-enum MatchingState {
- kNotComputed = -1,
- kNotMatched = 0,
- kMatched = 1,
-};
-
-bool combinationMatch(const std::vector<int>& children, const LogicalOperation& operation,
- const std::vector<MatchingState>& matcherResults);
-
-bool matchesSimple(const UidMap& uidMap,
- const SimpleAtomMatcher& simpleMatcher, const LogEvent& wrapper);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metadata_util.cpp b/cmds/statsd/src/metadata_util.cpp
deleted file mode 100644
index 27ee59b..0000000
--- a/cmds/statsd/src/metadata_util.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "FieldValue.h"
-#include "metadata_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using google::protobuf::RepeatedPtrField;
-
-void writeValueToProto(metadata::FieldValue* metadataFieldValue, const Value& value) {
- std::string storage_value;
- switch (value.getType()) {
- case INT:
- metadataFieldValue->set_value_int(value.int_value);
- break;
- case LONG:
- metadataFieldValue->set_value_long(value.long_value);
- break;
- case FLOAT:
- metadataFieldValue->set_value_float(value.float_value);
- break;
- case DOUBLE:
- metadataFieldValue->set_value_double(value.double_value);
- break;
- case STRING:
- metadataFieldValue->set_value_str(value.str_value.c_str());
- break;
- case STORAGE: // byte array
- storage_value = ((char*) value.storage_value.data());
- metadataFieldValue->set_value_storage(storage_value);
- break;
- default:
- break;
- }
-}
-
-void writeMetricDimensionKeyToMetadataDimensionKey(
- const MetricDimensionKey& metricKey,
- metadata::MetricDimensionKey* metadataMetricKey) {
- for (const FieldValue& fieldValue : metricKey.getDimensionKeyInWhat().getValues()) {
- metadata::FieldValue* metadataFieldValue = metadataMetricKey->add_dimension_key_in_what();
- metadata::Field* metadataField = metadataFieldValue->mutable_field();
- metadataField->set_tag(fieldValue.mField.getTag());
- metadataField->set_field(fieldValue.mField.getField());
- writeValueToProto(metadataFieldValue, fieldValue.mValue);
- }
-
- for (const FieldValue& fieldValue : metricKey.getStateValuesKey().getValues()) {
- metadata::FieldValue* metadataFieldValue = metadataMetricKey->add_state_values_key();
- metadata::Field* metadataField = metadataFieldValue->mutable_field();
- metadataField->set_tag(fieldValue.mField.getTag());
- metadataField->set_field(fieldValue.mField.getField());
- writeValueToProto(metadataFieldValue, fieldValue.mValue);
- }
-}
-
-void writeFieldValuesFromMetadata(
- const RepeatedPtrField<metadata::FieldValue>& repeatedFieldValueList,
- std::vector<FieldValue>* fieldValues) {
- for (const metadata::FieldValue& metadataFieldValue : repeatedFieldValueList) {
- Field field(metadataFieldValue.field().tag(), metadataFieldValue.field().field());
- Value value;
- switch (metadataFieldValue.value_case()) {
- case metadata::FieldValue::ValueCase::kValueInt:
- value = Value(metadataFieldValue.value_int());
- break;
- case metadata::FieldValue::ValueCase::kValueLong:
- value = Value(metadataFieldValue.value_long());
- break;
- case metadata::FieldValue::ValueCase::kValueFloat:
- value = Value(metadataFieldValue.value_float());
- break;
- case metadata::FieldValue::ValueCase::kValueDouble:
- value = Value(metadataFieldValue.value_double());
- break;
- case metadata::FieldValue::ValueCase::kValueStr:
- value = Value(metadataFieldValue.value_str());
- break;
- case metadata::FieldValue::ValueCase::kValueStorage:
- value = Value(metadataFieldValue.value_storage());
- break;
- default:
- break;
- }
- FieldValue fieldValue(field, value);
- fieldValues->emplace_back(field, value);
- }
-}
-
-MetricDimensionKey loadMetricDimensionKeyFromProto(
- const metadata::MetricDimensionKey& metricDimensionKey) {
- std::vector<FieldValue> dimKeyInWhatFieldValues;
- writeFieldValuesFromMetadata(metricDimensionKey.dimension_key_in_what(),
- &dimKeyInWhatFieldValues);
- std::vector<FieldValue> stateValuesFieldValues;
- writeFieldValuesFromMetadata(metricDimensionKey.state_values_key(), &stateValuesFieldValues);
-
- HashableDimensionKey dimKeyInWhat(dimKeyInWhatFieldValues);
- HashableDimensionKey stateValues(stateValuesFieldValues);
- MetricDimensionKey metricKey(dimKeyInWhat, stateValues);
- return metricKey;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/metadata_util.h b/cmds/statsd/src/metadata_util.h
deleted file mode 100644
index 84a39ff..0000000
--- a/cmds/statsd/src/metadata_util.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "HashableDimensionKey.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h" // AlertMetadata
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void writeMetricDimensionKeyToMetadataDimensionKey(const MetricDimensionKey& metricKey,
- metadata::MetricDimensionKey* metadataMetricKey);
-
-MetricDimensionKey loadMetricDimensionKeyFromProto(
- const metadata::MetricDimensionKey& metricDimensionKey);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
deleted file mode 100644
index 5739612..0000000
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "CountMetricProducer.h"
-
-#include <inttypes.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include "guardrail/StatsdStats.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_COUNT_METRICS = 5;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-
-// for CountMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-// for CountMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_SLICE_BY_STATE = 6;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-// for CountBucketInfo
-const int FIELD_ID_COUNT = 3;
-const int FIELD_ID_BUCKET_NUM = 4;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
-
-CountMetricProducer::CountMetricProducer(
- const ConfigKey& key, const CountMetric& metric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
- const int64_t timeBaseNs, const int64_t startTimeNs,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
- : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
- eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap) {
- if (metric.has_bucket()) {
- mBucketSizeNs =
- TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
- } else {
- mBucketSizeNs = LLONG_MAX;
- }
-
- if (metric.has_dimensions_in_what()) {
- translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
- mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
- }
-
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
-
- if (metric.links().size() > 0) {
- for (const auto& link : metric.links()) {
- Metric2Condition mc;
- mc.conditionId = link.condition();
- translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
- translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
- mMetric2ConditionLinks.push_back(mc);
- }
- mConditionSliced = true;
- }
-
- for (const auto& stateLink : metric.state_link()) {
- Metric2State ms;
- ms.stateAtomId = stateLink.state_atom_id();
- translateFieldMatcher(stateLink.fields_in_what(), &ms.metricFields);
- translateFieldMatcher(stateLink.fields_in_state(), &ms.stateFields);
- mMetric2StateLinks.push_back(ms);
- }
-
- flushIfNeededLocked(startTimeNs);
- // Adjust start for partial bucket
- mCurrentBucketStartTimeNs = startTimeNs;
-
- VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
- (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-CountMetricProducer::~CountMetricProducer() {
- VLOG("~CountMetricProducer() called");
-}
-
-void CountMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey,
- const FieldValue& oldState, const FieldValue& newState) {
- VLOG("CountMetric %lld onStateChanged time %lld, State%d, key %s, %d -> %d",
- (long long)mMetricId, (long long)eventTimeNs, atomId, primaryKey.toString().c_str(),
- oldState.mValue.int_value, newState.mValue.int_value);
-}
-
-void CountMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
- if (mCurrentSlicedCounter == nullptr ||
- mCurrentSlicedCounter->size() == 0) {
- return;
- }
-
- fprintf(out, "CountMetric %lld dimension size %lu\n", (long long)mMetricId,
- (unsigned long)mCurrentSlicedCounter->size());
- if (verbose) {
- for (const auto& it : *mCurrentSlicedCounter) {
- fprintf(out, "\t(what)%s\t(state)%s %lld\n",
- it.first.getDimensionKeyInWhat().toString().c_str(),
- it.first.getStateValuesKey().toString().c_str(), (unsigned long long)it.second);
- }
- }
-}
-
-void CountMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTime) {
- VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-}
-
-
-void CountMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
- mPastBuckets.clear();
-}
-
-void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- if (include_current_partial_bucket) {
- flushLocked(dumpTimeNs);
- } else {
- flushIfNeededLocked(dumpTimeNs);
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
-
- if (mPastBuckets.empty()) {
- return;
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-
- // Fills the dimension path if not slicing by ALL.
- if (!mSliceByPositionALL) {
- if (!mDimensionsInWhat.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
- writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
- protoOutput->end(dimenPathToken);
- }
- }
-
- uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_COUNT_METRICS);
-
- for (const auto& counter : mPastBuckets) {
- const MetricDimensionKey& dimensionKey = counter.first;
- VLOG(" dimension key %s", dimensionKey.toString().c_str());
-
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
- // First fill dimension.
- if (mSliceByPositionALL) {
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
- protoOutput->end(dimensionToken);
- } else {
- writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
- FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
- }
- // Then fill slice_by_state.
- for (auto state : dimensionKey.getStateValuesKey().getValues()) {
- uint64_t stateToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SLICE_BY_STATE);
- writeStateToProto(state, protoOutput);
- protoOutput->end(stateToken);
- }
- // Then fill bucket_info (CountBucketInfo).
- for (const auto& bucket : counter.second) {
- uint64_t bucketInfoToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
- // Partial bucket.
- if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketStartNs));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketEndNs));
- } else {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
- (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_COUNT, (long long)bucket.mCount);
- protoOutput->end(bucketInfoToken);
- VLOG("\t bucket [%lld - %lld] count: %lld", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, (long long)bucket.mCount);
- }
- protoOutput->end(wrapperToken);
- }
-
- protoOutput->end(protoToken);
-
- if (erase_data) {
- mPastBuckets.clear();
- }
-}
-
-void CountMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
- flushIfNeededLocked(dropTimeNs);
- StatsdStats::getInstance().noteBucketDropped(mMetricId);
- mPastBuckets.clear();
-}
-
-void CountMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const int64_t eventTime) {
- VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
- mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
-}
-
-bool CountMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
- if (mCurrentSlicedCounter->find(newKey) != mCurrentSlicedCounter->end()) {
- return false;
- }
- // ===========GuardRail==============
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentSlicedCounter->size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mCurrentSlicedCounter->size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("CountMetric %lld dropping data for dimension key %s",
- (long long)mMetricId, newKey.toString().c_str());
- StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
- return true;
- }
- }
-
- return false;
-}
-
-void CountMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) {
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
- flushIfNeededLocked(eventTimeNs);
-
- if (!condition) {
- return;
- }
-
- auto it = mCurrentSlicedCounter->find(eventKey);
- if (it == mCurrentSlicedCounter->end()) {
- // ===========GuardRail==============
- if (hitGuardRailLocked(eventKey)) {
- return;
- }
- // create a counter for the new key
- (*mCurrentSlicedCounter)[eventKey] = 1;
- } else {
- // increment the existing value
- auto& count = it->second;
- count++;
- }
- for (auto& tracker : mAnomalyTrackers) {
- int64_t countWholeBucket = mCurrentSlicedCounter->find(eventKey)->second;
- auto prev = mCurrentFullCounters->find(eventKey);
- if (prev != mCurrentFullCounters->end()) {
- countWholeBucket += prev->second;
- }
- tracker->detectAndDeclareAnomaly(eventTimeNs, mCurrentBucketNum, mMetricId, eventKey,
- countWholeBucket);
- }
-
- VLOG("metric %lld %s->%lld", (long long)mMetricId, eventKey.toString().c_str(),
- (long long)(*mCurrentSlicedCounter)[eventKey]);
-}
-
-// When a new matched event comes in, we check if event falls into the current
-// bucket. If not, flush the old counter to past buckets and initialize the new bucket.
-void CountMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
- int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
- if (eventTimeNs < currentBucketEndTimeNs) {
- return;
- }
-
- // Setup the bucket start time and number.
- int64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
- int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
- flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
-
- mCurrentBucketNum += numBucketsForward;
- VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
- (long long)mCurrentBucketStartTimeNs);
-}
-
-void CountMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) {
- int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
- CountBucket info;
- info.mBucketStartNs = mCurrentBucketStartTimeNs;
- if (eventTimeNs < fullBucketEndTimeNs) {
- info.mBucketEndNs = eventTimeNs;
- } else {
- info.mBucketEndNs = fullBucketEndTimeNs;
- }
- for (const auto& counter : *mCurrentSlicedCounter) {
- info.mCount = counter.second;
- auto& bucketList = mPastBuckets[counter.first];
- bucketList.push_back(info);
- VLOG("metric %lld, dump key value: %s -> %lld", (long long)mMetricId,
- counter.first.toString().c_str(),
- (long long)counter.second);
- }
-
- // If we have finished a full bucket, then send this to anomaly tracker.
- if (eventTimeNs > fullBucketEndTimeNs) {
- // Accumulate partial buckets with current value and then send to anomaly tracker.
- if (mCurrentFullCounters->size() > 0) {
- for (const auto& keyValuePair : *mCurrentSlicedCounter) {
- (*mCurrentFullCounters)[keyValuePair.first] += keyValuePair.second;
- }
- for (auto& tracker : mAnomalyTrackers) {
- tracker->addPastBucket(mCurrentFullCounters, mCurrentBucketNum);
- }
- mCurrentFullCounters = std::make_shared<DimToValMap>();
- } else {
- // Skip aggregating the partial buckets since there's no previous partial bucket.
- for (auto& tracker : mAnomalyTrackers) {
- tracker->addPastBucket(mCurrentSlicedCounter, mCurrentBucketNum);
- }
- }
- } else {
- // Accumulate partial bucket.
- for (const auto& keyValuePair : *mCurrentSlicedCounter) {
- (*mCurrentFullCounters)[keyValuePair.first] += keyValuePair.second;
- }
- }
-
- StatsdStats::getInstance().noteBucketCount(mMetricId);
- // Only resets the counters, but doesn't setup the times nor numbers.
- // (Do not clear since the old one is still referenced in mAnomalyTrackers).
- mCurrentSlicedCounter = std::make_shared<DimToValMap>();
- mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
-}
-
-// Rough estimate of CountMetricProducer buffer stored. This number will be
-// greater than actual data size as it contains each dimension of
-// CountMetricData is duplicated.
-size_t CountMetricProducer::byteSizeLocked() const {
- size_t totalSize = 0;
- for (const auto& pair : mPastBuckets) {
- totalSize += pair.second.size() * kBucketSize;
- }
- return totalSize;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
deleted file mode 100644
index f05fb06..0000000
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef COUNT_METRIC_PRODUCER_H
-#define COUNT_METRIC_PRODUCER_H
-
-#include <android/util/ProtoOutputStream.h>
-#include <gtest/gtest_prod.h>
-
-#include <unordered_map>
-
-#include "MetricProducer.h"
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/matcher_util.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct CountBucket {
- int64_t mBucketStartNs;
- int64_t mBucketEndNs;
- int64_t mCount;
-};
-
-class CountMetricProducer : public MetricProducer {
-public:
- CountMetricProducer(
- const ConfigKey& key, const CountMetric& countMetric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
- const int64_t timeBaseNs, const int64_t startTimeNs,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap = {},
- const vector<int>& slicedStateAtoms = {},
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
- virtual ~CountMetricProducer();
-
- void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey, const FieldValue& oldState,
- const FieldValue& newState) override;
-
-protected:
- void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
-
- void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) override;
-
- void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
- // Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
- // Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
- // Internal function to calculate the current used bytes.
- size_t byteSizeLocked() const override;
-
- void dumpStatesLocked(FILE* out, bool verbose) const override;
-
- void dropDataLocked(const int64_t dropTimeNs) override;
-
- // Util function to flush the old packet.
- void flushIfNeededLocked(const int64_t& newEventTime) override;
-
- void flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) override;
-
- std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets;
-
- // The current bucket (may be a partial bucket).
- std::shared_ptr<DimToValMap> mCurrentSlicedCounter = std::make_shared<DimToValMap>();
-
- // The sum of previous partial buckets in the current full bucket (excluding the current
- // partial bucket). This is only updated while flushing the current bucket.
- std::shared_ptr<DimToValMap> mCurrentFullCounters = std::make_shared<DimToValMap>();
-
- static const size_t kBucketSize = sizeof(CountBucket{});
-
- bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
- FRIEND_TEST(CountMetricProducerTest, TestNonDimensionalEvents);
- FRIEND_TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition);
- FRIEND_TEST(CountMetricProducerTest, TestEventsWithSlicedCondition);
- FRIEND_TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced);
- FRIEND_TEST(CountMetricProducerTest, TestFirstBucket);
- FRIEND_TEST(CountMetricProducerTest, TestOneWeekTimeUnit);
-
- FRIEND_TEST(CountMetricProducerTest_PartialBucket, TestSplitInCurrentBucket);
- FRIEND_TEST(CountMetricProducerTest_PartialBucket, TestSplitInNextBucket);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // COUNT_METRIC_PRODUCER_H
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
deleted file mode 100644
index e9b0438..0000000
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false
-
-#include "Log.h"
-#include "DurationMetricProducer.h"
-#include "guardrail/StatsdStats.h"
-#include "stats_util.h"
-#include "stats_log_util.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_DURATION_METRICS = 6;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for DurationMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-// for DurationMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-const int FIELD_ID_SLICE_BY_STATE = 6;
-// for DurationBucketInfo
-const int FIELD_ID_DURATION = 3;
-const int FIELD_ID_BUCKET_NUM = 4;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
-
-DurationMetricProducer::DurationMetricProducer(
- const ConfigKey& key, const DurationMetric& metric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const size_t startIndex,
- const size_t stopIndex, const size_t stopAllIndex, const bool nesting,
- const sp<ConditionWizard>& wizard, const FieldMatcher& internalDimensions,
- const int64_t timeBaseNs, const int64_t startTimeNs,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
- : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
- eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap),
- mAggregationType(metric.aggregation_type()),
- mStartIndex(startIndex),
- mStopIndex(stopIndex),
- mStopAllIndex(stopAllIndex),
- mNested(nesting),
- mContainANYPositionInInternalDimensions(false) {
- if (metric.has_bucket()) {
- mBucketSizeNs =
- TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
- } else {
- mBucketSizeNs = LLONG_MAX;
- }
-
- if (metric.has_dimensions_in_what()) {
- translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
- mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
- }
-
- if (internalDimensions.has_field()) {
- translateFieldMatcher(internalDimensions, &mInternalDimensions);
- mContainANYPositionInInternalDimensions = HasPositionANY(internalDimensions);
- }
- if (mContainANYPositionInInternalDimensions) {
- ALOGE("Position ANY in internal dimension not supported.");
- }
- if (mContainANYPositionInDimensionsInWhat) {
- ALOGE("Position ANY in dimension_in_what not supported.");
- }
-
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
-
- if (metric.links().size() > 0) {
- for (const auto& link : metric.links()) {
- Metric2Condition mc;
- mc.conditionId = link.condition();
- translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
- translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
- mMetric2ConditionLinks.push_back(mc);
- }
- mConditionSliced = true;
- }
- mUnSlicedPartCondition = ConditionState::kUnknown;
-
- for (const auto& stateLink : metric.state_link()) {
- Metric2State ms;
- ms.stateAtomId = stateLink.state_atom_id();
- translateFieldMatcher(stateLink.fields_in_what(), &ms.metricFields);
- translateFieldMatcher(stateLink.fields_in_state(), &ms.stateFields);
- mMetric2StateLinks.push_back(ms);
- }
-
- mUseWhatDimensionAsInternalDimension = equalDimensions(mDimensionsInWhat, mInternalDimensions);
- if (mWizard != nullptr && mConditionTrackerIndex >= 0 &&
- mMetric2ConditionLinks.size() == 1) {
- mHasLinksToAllConditionDimensionsInTracker = mWizard->equalOutputDimensions(
- mConditionTrackerIndex, mMetric2ConditionLinks.begin()->conditionFields);
- }
- flushIfNeededLocked(startTimeNs);
- // Adjust start for partial bucket
- mCurrentBucketStartTimeNs = startTimeNs;
- VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
- (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-DurationMetricProducer::~DurationMetricProducer() {
- VLOG("~DurationMetric() called");
-}
-
-sp<AnomalyTracker> DurationMetricProducer::addAnomalyTracker(
- const Alert &alert, const sp<AlarmMonitor>& anomalyAlarmMonitor) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (mAggregationType == DurationMetric_AggregationType_SUM) {
- if (alert.trigger_if_sum_gt() > alert.num_buckets() * mBucketSizeNs) {
- ALOGW("invalid alert for SUM: threshold (%f) > possible recordable value (%d x %lld)",
- alert.trigger_if_sum_gt(), alert.num_buckets(), (long long)mBucketSizeNs);
- return nullptr;
- }
- }
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, mConfigKey, anomalyAlarmMonitor);
- if (anomalyTracker != nullptr) {
- mAnomalyTrackers.push_back(anomalyTracker);
- }
- return anomalyTracker;
-}
-
-void DurationMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey,
- const FieldValue& oldState,
- const FieldValue& newState) {
- // Check if this metric has a StateMap. If so, map the new state value to
- // the correct state group id.
- FieldValue newStateCopy = newState;
- mapStateValue(atomId, &newStateCopy);
-
- flushIfNeededLocked(eventTimeNs);
-
- // Each duration tracker is mapped to a different whatKey (a set of values from the
- // dimensionsInWhat fields). We notify all trackers iff the primaryKey field values from the
- // state change event are a subset of the tracker's whatKey field values.
- //
- // Ex. For a duration metric dimensioned on uid and tag:
- // DurationTracker1 whatKey = uid: 1001, tag: 1
- // DurationTracker2 whatKey = uid: 1002, tag 1
- //
- // If the state change primaryKey = uid: 1001, we only notify DurationTracker1 of a state
- // change.
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- if (!containsLinkedStateValues(whatIt.first, primaryKey, mMetric2StateLinks, atomId)) {
- continue;
- }
- whatIt.second->onStateChanged(eventTimeNs, atomId, newStateCopy);
- }
-}
-
-unique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker(
- const MetricDimensionKey& eventKey) const {
- switch (mAggregationType) {
- case DurationMetric_AggregationType_SUM:
- return make_unique<OringDurationTracker>(
- mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex, mNested,
- mCurrentBucketStartTimeNs, mCurrentBucketNum, mTimeBaseNs, mBucketSizeNs,
- mConditionSliced, mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers);
- case DurationMetric_AggregationType_MAX_SPARSE:
- return make_unique<MaxDurationTracker>(
- mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex, mNested,
- mCurrentBucketStartTimeNs, mCurrentBucketNum, mTimeBaseNs, mBucketSizeNs,
- mConditionSliced, mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers);
- }
-}
-
-// SlicedConditionChange optimization case 1:
-// 1. If combination condition, logical operation is AND, only one sliced child predicate.
-// 2. The links covers all dimension fields in the sliced child condition predicate.
-void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool condition,
- const int64_t eventTime) {
- if (mMetric2ConditionLinks.size() != 1 ||
- !mHasLinksToAllConditionDimensionsInTracker) {
- return;
- }
-
- bool currentUnSlicedPartCondition = true;
- if (!mWizard->IsSimpleCondition(mConditionTrackerIndex)) {
- ConditionState unslicedPartState =
- mWizard->getUnSlicedPartConditionState(mConditionTrackerIndex);
- // When the unsliced part is still false, return directly.
- if (mUnSlicedPartCondition == ConditionState::kFalse &&
- unslicedPartState == ConditionState::kFalse) {
- return;
- }
- mUnSlicedPartCondition = unslicedPartState;
- currentUnSlicedPartCondition = mUnSlicedPartCondition > 0;
- }
-
- auto dimensionsChangedToTrue = mWizard->getChangedToTrueDimensions(mConditionTrackerIndex);
- auto dimensionsChangedToFalse = mWizard->getChangedToFalseDimensions(mConditionTrackerIndex);
-
- // The condition change is from the unsliced predicates.
- // We need to find out the true dimensions from the sliced predicate and flip their condition
- // state based on the new unsliced condition state.
- if (dimensionsChangedToTrue == nullptr || dimensionsChangedToFalse == nullptr ||
- (dimensionsChangedToTrue->empty() && dimensionsChangedToFalse->empty())) {
- std::set<HashableDimensionKey> trueConditionDimensions;
- mWizard->getTrueSlicedDimensions(mConditionTrackerIndex, &trueConditionDimensions);
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- HashableDimensionKey linkedConditionDimensionKey;
- getDimensionForCondition(whatIt.first.getValues(), mMetric2ConditionLinks[0],
- &linkedConditionDimensionKey);
- if (trueConditionDimensions.find(linkedConditionDimensionKey) !=
- trueConditionDimensions.end()) {
- whatIt.second->onConditionChanged(currentUnSlicedPartCondition, eventTime);
- }
- }
- } else {
- // Handle the condition change from the sliced predicate.
- if (currentUnSlicedPartCondition) {
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- HashableDimensionKey linkedConditionDimensionKey;
- getDimensionForCondition(whatIt.first.getValues(), mMetric2ConditionLinks[0],
- &linkedConditionDimensionKey);
- if (dimensionsChangedToTrue->find(linkedConditionDimensionKey) !=
- dimensionsChangedToTrue->end()) {
- whatIt.second->onConditionChanged(true, eventTime);
- }
- if (dimensionsChangedToFalse->find(linkedConditionDimensionKey) !=
- dimensionsChangedToFalse->end()) {
- whatIt.second->onConditionChanged(false, eventTime);
- }
- }
- }
- }
-}
-
-void DurationMetricProducer::onSlicedConditionMayChangeInternalLocked(bool overallCondition,
- const int64_t eventTimeNs) {
- bool changeDimTrackable = mWizard->IsChangedDimensionTrackable(mConditionTrackerIndex);
- if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker) {
- onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTimeNs);
- return;
- }
-
- // Now for each of the on-going event, check if the condition has changed for them.
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- whatIt.second->onSlicedConditionMayChange(overallCondition, eventTimeNs);
- }
-}
-
-void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTime) {
- VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-
- if (!mIsActive) {
- return;
- }
-
- flushIfNeededLocked(eventTime);
-
- if (!mConditionSliced) {
- return;
- }
-
- onSlicedConditionMayChangeInternalLocked(overallCondition, eventTime);
-}
-
-void DurationMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
- MetricProducer::onActiveStateChangedLocked(eventTimeNs);
-
- if (!mConditionSliced) {
- if (ConditionState::kTrue != mCondition) {
- return;
- }
-
- if (mIsActive) {
- flushIfNeededLocked(eventTimeNs);
- }
-
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- whatIt.second->onConditionChanged(mIsActive, eventTimeNs);
- }
- } else if (mIsActive) {
- flushIfNeededLocked(eventTimeNs);
- onSlicedConditionMayChangeInternalLocked(mIsActive, eventTimeNs);
- } else { // mConditionSliced == true && !mIsActive
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- whatIt.second->onConditionChanged(mIsActive, eventTimeNs);
- }
- }
-}
-
-void DurationMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const int64_t eventTime) {
- VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
- mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
-
- if (!mIsActive) {
- return;
- }
-
- flushIfNeededLocked(eventTime);
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- whatIt.second->onConditionChanged(conditionMet, eventTime);
- }
-}
-
-void DurationMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
- flushIfNeededLocked(dropTimeNs);
- StatsdStats::getInstance().noteBucketDropped(mMetricId);
- mPastBuckets.clear();
-}
-
-void DurationMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
- flushIfNeededLocked(dumpTimeNs);
- mPastBuckets.clear();
-}
-
-void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- if (include_current_partial_bucket) {
- flushLocked(dumpTimeNs);
- } else {
- flushIfNeededLocked(dumpTimeNs);
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
- if (mPastBuckets.empty()) {
- VLOG(" Duration metric, empty return");
- return;
- }
-
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-
- if (!mSliceByPositionALL) {
- if (!mDimensionsInWhat.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
- writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
- protoOutput->end(dimenPathToken);
- }
- }
-
- uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS);
-
- VLOG("Duration metric %lld dump report now...", (long long)mMetricId);
-
- for (const auto& pair : mPastBuckets) {
- const MetricDimensionKey& dimensionKey = pair.first;
- VLOG(" dimension key %s", dimensionKey.toString().c_str());
-
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
- // First fill dimension.
- if (mSliceByPositionALL) {
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
- protoOutput->end(dimensionToken);
- } else {
- writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
- FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
- }
- // Then fill slice_by_state.
- for (auto state : dimensionKey.getStateValuesKey().getValues()) {
- uint64_t stateToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SLICE_BY_STATE);
- writeStateToProto(state, protoOutput);
- protoOutput->end(stateToken);
- }
- // Then fill bucket_info (DurationBucketInfo).
- for (const auto& bucket : pair.second) {
- uint64_t bucketInfoToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
- if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketStartNs));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketEndNs));
- } else {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
- (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DURATION, (long long)bucket.mDuration);
- protoOutput->end(bucketInfoToken);
- VLOG("\t bucket [%lld - %lld] duration: %lld", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, (long long)bucket.mDuration);
- }
-
- protoOutput->end(wrapperToken);
- }
-
- protoOutput->end(protoToken);
- if (erase_data) {
- mPastBuckets.clear();
- }
-}
-
-void DurationMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
- int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
-
- if (currentBucketEndTimeNs > eventTimeNs) {
- return;
- }
- VLOG("flushing...........");
- int numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
- int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
- flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
-
- mCurrentBucketNum += numBucketsForward;
-}
-
-void DurationMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) {
- for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin();
- whatIt != mCurrentSlicedDurationTrackerMap.end();) {
- if (whatIt->second->flushCurrentBucket(eventTimeNs, &mPastBuckets)) {
- VLOG("erase bucket for key %s", whatIt->first.toString().c_str());
- whatIt = mCurrentSlicedDurationTrackerMap.erase(whatIt);
- } else {
- ++whatIt;
- }
- }
- StatsdStats::getInstance().noteBucketCount(mMetricId);
- mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
-}
-
-void DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
- if (mCurrentSlicedDurationTrackerMap.size() == 0) {
- return;
- }
-
- fprintf(out, "DurationMetric %lld dimension size %lu\n", (long long)mMetricId,
- (unsigned long)mCurrentSlicedDurationTrackerMap.size());
- if (verbose) {
- for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- fprintf(out, "\t(what)%s\n", whatIt.first.toString().c_str());
- whatIt.second->dumpStates(out, verbose);
- }
- }
-}
-
-bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
- auto whatIt = mCurrentSlicedDurationTrackerMap.find(newKey.getDimensionKeyInWhat());
- if (whatIt == mCurrentSlicedDurationTrackerMap.end()) {
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentSlicedDurationTrackerMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mCurrentSlicedDurationTrackerMap.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(
- mConfigKey, mMetricId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("DurationMetric %lld dropping data for what dimension key %s",
- (long long)mMetricId, newKey.getDimensionKeyInWhat().toString().c_str());
- StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
- return true;
- }
- }
- }
- return false;
-}
-
-void DurationMetricProducer::handleStartEvent(const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKeys,
- bool condition, const LogEvent& event) {
- const auto& whatKey = eventKey.getDimensionKeyInWhat();
- auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatKey);
- if (whatIt == mCurrentSlicedDurationTrackerMap.end()) {
- if (hitGuardRailLocked(eventKey)) {
- return;
- }
- mCurrentSlicedDurationTrackerMap[whatKey] = createDurationTracker(eventKey);
- }
-
- auto it = mCurrentSlicedDurationTrackerMap.find(whatKey);
- if (mUseWhatDimensionAsInternalDimension) {
- it->second->noteStart(whatKey, condition, event.GetElapsedTimestampNs(), conditionKeys);
- return;
- }
-
- if (mInternalDimensions.empty()) {
- it->second->noteStart(DEFAULT_DIMENSION_KEY, condition, event.GetElapsedTimestampNs(),
- conditionKeys);
- } else {
- HashableDimensionKey dimensionKey = DEFAULT_DIMENSION_KEY;
- filterValues(mInternalDimensions, event.getValues(), &dimensionKey);
- it->second->noteStart(dimensionKey, condition, event.GetElapsedTimestampNs(),
- conditionKeys);
- }
-
-}
-
-void DurationMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKeys, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) {
- ALOGW("Not used in duration tracker.");
-}
-
-void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
- const LogEvent& event) {
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
- if (eventTimeNs < mTimeBaseNs) {
- return;
- }
-
- if (mIsActive) {
- flushIfNeededLocked(event.GetElapsedTimestampNs());
- }
-
- // Handles Stopall events.
- if (matcherIndex == mStopAllIndex) {
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- whatIt.second->noteStopAll(event.GetElapsedTimestampNs());
- }
- return;
- }
-
- HashableDimensionKey dimensionInWhat = DEFAULT_DIMENSION_KEY;
- if (!mDimensionsInWhat.empty()) {
- filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhat);
- }
-
- // Stores atom id to primary key pairs for each state atom that the metric is
- // sliced by.
- std::map<int, HashableDimensionKey> statePrimaryKeys;
-
- // For states with primary fields, use MetricStateLinks to get the primary
- // field values from the log event. These values will form a primary key
- // that will be used to query StateTracker for the correct state value.
- for (const auto& stateLink : mMetric2StateLinks) {
- getDimensionForState(event.getValues(), stateLink,
- &statePrimaryKeys[stateLink.stateAtomId]);
- }
-
- // For each sliced state, query StateTracker for the state value using
- // either the primary key from the previous step or the DEFAULT_DIMENSION_KEY.
- //
- // Expected functionality: for any case where the MetricStateLinks are
- // initialized incorrectly (ex. # of state links != # of primary fields, no
- // links are provided for a state with primary fields, links are provided
- // in the wrong order, etc.), StateTracker will simply return kStateUnknown
- // when queried using an incorrect key.
- HashableDimensionKey stateValuesKey = DEFAULT_DIMENSION_KEY;
- for (auto atomId : mSlicedStateAtoms) {
- FieldValue value;
- if (statePrimaryKeys.find(atomId) != statePrimaryKeys.end()) {
- // found a primary key for this state, query using the key
- queryStateValue(atomId, statePrimaryKeys[atomId], &value);
- } else {
- // if no MetricStateLinks exist for this state atom,
- // query using the default dimension key (empty HashableDimensionKey)
- queryStateValue(atomId, DEFAULT_DIMENSION_KEY, &value);
- }
- mapStateValue(atomId, &value);
- stateValuesKey.addValue(value);
- }
-
- // Handles Stop events.
- if (matcherIndex == mStopIndex) {
- if (mUseWhatDimensionAsInternalDimension) {
- auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
- if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
- whatIt->second->noteStop(dimensionInWhat, event.GetElapsedTimestampNs(), false);
- }
- return;
- }
-
- HashableDimensionKey internalDimensionKey = DEFAULT_DIMENSION_KEY;
- if (!mInternalDimensions.empty()) {
- filterValues(mInternalDimensions, event.getValues(), &internalDimensionKey);
- }
-
- auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
- if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
- whatIt->second->noteStop(internalDimensionKey, event.GetElapsedTimestampNs(), false);
- }
- return;
- }
-
- bool condition;
- ConditionKey conditionKey;
- if (mConditionSliced) {
- for (const auto& link : mMetric2ConditionLinks) {
- getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
- }
-
- auto conditionState =
- mWizard->query(mConditionTrackerIndex, conditionKey,
- !mHasLinksToAllConditionDimensionsInTracker);
- condition = conditionState == ConditionState::kTrue;
- } else {
- // TODO: The unknown condition state is not handled here, we should fix it.
- condition = mCondition == ConditionState::kTrue;
- }
-
- condition = condition && mIsActive;
-
- handleStartEvent(MetricDimensionKey(dimensionInWhat, stateValuesKey), conditionKey, condition,
- event);
-}
-
-size_t DurationMetricProducer::byteSizeLocked() const {
- size_t totalSize = 0;
- for (const auto& pair : mPastBuckets) {
- totalSize += pair.second.size() * kBucketSize;
- }
- return totalSize;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
deleted file mode 100644
index bfe1010..0000000
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-
-#include <unordered_map>
-
-#include <android/util/ProtoOutputStream.h>
-#include "../anomaly/DurationAnomalyTracker.h"
-#include "../condition/ConditionTracker.h"
-#include "../matchers/matcher_util.h"
-#include "MetricProducer.h"
-#include "duration_helper/DurationTracker.h"
-#include "duration_helper/MaxDurationTracker.h"
-#include "duration_helper/OringDurationTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class DurationMetricProducer : public MetricProducer {
-public:
- DurationMetricProducer(
- const ConfigKey& key, const DurationMetric& durationMetric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const size_t startIndex,
- const size_t stopIndex, const size_t stopAllIndex, const bool nesting,
- const sp<ConditionWizard>& wizard, const FieldMatcher& internalDimensions,
- const int64_t timeBaseNs, const int64_t startTimeNs,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap = {},
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap = {},
- const vector<int>& slicedStateAtoms = {},
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
- virtual ~DurationMetricProducer();
-
- sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
- const sp<AlarmMonitor>& anomalyAlarmMonitor) override;
-
- void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey, const FieldValue& oldState,
- const FieldValue& newState) override;
-
-protected:
- void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) override;
-
- void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKeys, bool condition, const LogEvent& event,
- const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
- void handleStartEvent(const MetricDimensionKey& eventKey, const ConditionKey& conditionKeys,
- bool condition, const LogEvent& event);
-
- void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) override;
-
- void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
- // Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
- // Internal interface to handle active state change.
- void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
-
- // Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
- void onSlicedConditionMayChangeInternalLocked(bool overallCondition,
- const int64_t eventTimeNs);
-
- void onSlicedConditionMayChangeLocked_opt1(bool overallCondition, const int64_t eventTime);
- void onSlicedConditionMayChangeLocked_opt2(bool overallCondition, const int64_t eventTime);
-
- // Internal function to calculate the current used bytes.
- size_t byteSizeLocked() const override;
-
- void dumpStatesLocked(FILE* out, bool verbose) const override;
-
- void dropDataLocked(const int64_t dropTimeNs) override;
-
- // Util function to flush the old packet.
- void flushIfNeededLocked(const int64_t& eventTime);
-
- void flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) override;
-
- const DurationMetric_AggregationType mAggregationType;
-
- // Index of the SimpleAtomMatcher which defines the start.
- const size_t mStartIndex;
-
- // Index of the SimpleAtomMatcher which defines the stop.
- const size_t mStopIndex;
-
- // Index of the SimpleAtomMatcher which defines the stop all for all dimensions.
- const size_t mStopAllIndex;
-
- // nest counting -- for the same key, stops must match the number of starts to make real stop
- const bool mNested;
-
- // The dimension from the atom predicate. e.g., uid, wakelock name.
- vector<Matcher> mInternalDimensions;
-
- bool mContainANYPositionInInternalDimensions;
-
- // This boolean is true iff When mInternalDimensions == mDimensionsInWhat
- bool mUseWhatDimensionAsInternalDimension;
-
- // Caches the current unsliced part condition.
- ConditionState mUnSlicedPartCondition;
-
- // Save the past buckets and we can clear when the StatsLogReport is dumped.
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>> mPastBuckets;
-
- // The duration trackers in the current bucket.
- std::unordered_map<HashableDimensionKey, std::unique_ptr<DurationTracker>>
- mCurrentSlicedDurationTrackerMap;
-
- // Helper function to create a duration tracker given the metric aggregation type.
- std::unique_ptr<DurationTracker> createDurationTracker(
- const MetricDimensionKey& eventKey) const;
-
- // This hides the base class's std::vector<sp<AnomalyTracker>> mAnomalyTrackers
- std::vector<sp<DurationAnomalyTracker>> mAnomalyTrackers;
-
- // Util function to check whether the specified dimension hits the guardrail.
- bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
- static const size_t kBucketSize = sizeof(DurationBucket{});
-
- FRIEND_TEST(DurationMetricTrackerTest, TestNoCondition);
- FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedCondition);
- FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicates);
- FRIEND_TEST(DurationMetricTrackerTest, TestFirstBucket);
-
- FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestSumDuration);
- FRIEND_TEST(DurationMetricProducerTest_PartialBucket,
- TestSumDurationWithSplitInFollowingBucket);
- FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDuration);
- FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
deleted file mode 100644
index dc0036a..0000000
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "EventMetricProducer.h"
-#include "stats_util.h"
-#include "stats_log_util.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_STRING;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_EVENT_METRICS = 4;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for EventMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-// for EventMetricData
-const int FIELD_ID_ELAPSED_TIMESTAMP_NANOS = 1;
-const int FIELD_ID_ATOMS = 2;
-
-EventMetricProducer::EventMetricProducer(
- const ConfigKey& key, const EventMetric& metric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
- const int64_t startTimeNs,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
- : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, initialConditionCache, wizard,
- eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap) {
- if (metric.links().size() > 0) {
- for (const auto& link : metric.links()) {
- Metric2Condition mc;
- mc.conditionId = link.condition();
- translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
- translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
- mMetric2ConditionLinks.push_back(mc);
- }
- mConditionSliced = true;
- }
- mProto = std::make_unique<ProtoOutputStream>();
- VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
- (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-EventMetricProducer::~EventMetricProducer() {
- VLOG("~EventMetricProducer() called");
-}
-
-void EventMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
- mProto->clear();
- StatsdStats::getInstance().noteBucketDropped(mMetricId);
-}
-
-void EventMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTime) {
-}
-
-std::unique_ptr<std::vector<uint8_t>> serializeProtoLocked(ProtoOutputStream& protoOutput) {
- size_t bufferSize = protoOutput.size();
-
- std::unique_ptr<std::vector<uint8_t>> buffer(new std::vector<uint8_t>(bufferSize));
-
- size_t pos = 0;
- sp<android::util::ProtoReader> reader = protoOutput.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((*buffer)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- return buffer;
-}
-
-void EventMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
- mProto->clear();
-}
-
-void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
- if (mProto->size() <= 0) {
- return;
- }
-
- size_t bufferSize = mProto->size();
- VLOG("metric %lld dump report now... proto size: %zu ",
- (long long)mMetricId, bufferSize);
- std::unique_ptr<std::vector<uint8_t>> buffer = serializeProtoLocked(*mProto);
-
- protoOutput->write(FIELD_TYPE_MESSAGE | FIELD_ID_EVENT_METRICS,
- reinterpret_cast<char*>(buffer.get()->data()), buffer.get()->size());
-
- if (erase_data) {
- mProto->clear();
- }
-}
-
-void EventMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const int64_t eventTime) {
- VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
- mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
-}
-
-void EventMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) {
- if (!condition) {
- return;
- }
-
- uint64_t wrapperToken =
- mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
- const int64_t elapsedTimeNs = truncateTimestampIfNecessary(event);
- mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS, (long long) elapsedTimeNs);
-
- uint64_t eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS);
- event.ToProto(*mProto);
- mProto->end(eventToken);
- mProto->end(wrapperToken);
-}
-
-size_t EventMetricProducer::byteSizeLocked() const {
- return mProto->bytesWritten();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
deleted file mode 100644
index bfb2de3..0000000
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef EVENT_METRIC_PRODUCER_H
-#define EVENT_METRIC_PRODUCER_H
-
-#include <unordered_map>
-
-#include <android/util/ProtoOutputStream.h>
-
-#include "../condition/ConditionTracker.h"
-#include "../matchers/matcher_util.h"
-#include "MetricProducer.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class EventMetricProducer : public MetricProducer {
-public:
- EventMetricProducer(
- const ConfigKey& key, const EventMetric& eventMetric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
- const int64_t startTimeNs,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap = {},
- const vector<int>& slicedStateAtoms = {},
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
- virtual ~EventMetricProducer();
-
-private:
- void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
- void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) override;
- void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
- // Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
- // Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
- void dropDataLocked(const int64_t dropTimeNs) override;
-
- // Internal function to calculate the current used bytes.
- size_t byteSizeLocked() const override;
-
- void dumpStatesLocked(FILE* out, bool verbose) const override{};
-
- // Maps to a EventMetricDataWrapper. Storing atom events in ProtoOutputStream
- // is more space efficient than storing LogEvent.
- std::unique_ptr<android::util::ProtoOutputStream> mProto;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // EVENT_METRIC_PRODUCER_H
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
deleted file mode 100644
index 020f4b6..0000000
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "../guardrail/StatsdStats.h"
-#include "GaugeMetricProducer.h"
-#include "../stats_log_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::make_shared;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_GAUGE_METRICS = 8;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for GaugeMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-const int FIELD_ID_SKIPPED = 2;
-// for SkippedBuckets
-const int FIELD_ID_SKIPPED_START_MILLIS = 3;
-const int FIELD_ID_SKIPPED_END_MILLIS = 4;
-const int FIELD_ID_SKIPPED_DROP_EVENT = 5;
-// for DumpEvent Proto
-const int FIELD_ID_BUCKET_DROP_REASON = 1;
-const int FIELD_ID_DROP_TIME = 2;
-// for GaugeMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-// for GaugeBucketInfo
-const int FIELD_ID_ATOM = 3;
-const int FIELD_ID_ELAPSED_ATOM_TIMESTAMP = 4;
-const int FIELD_ID_BUCKET_NUM = 6;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 7;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 8;
-
-GaugeMetricProducer::GaugeMetricProducer(
- const ConfigKey& key, const GaugeMetric& metric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
- const int whatMatcherIndex, const sp<EventMatcherWizard>& matcherWizard,
- const int pullTagId, const int triggerAtomId, const int atomId, const int64_t timeBaseNs,
- const int64_t startTimeNs, const sp<StatsPullerManager>& pullerManager,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap)
- : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
- eventActivationMap, eventDeactivationMap, /*slicedStateAtoms=*/{},
- /*stateGroupMap=*/{}),
- mWhatMatcherIndex(whatMatcherIndex),
- mEventMatcherWizard(matcherWizard),
- mPullerManager(pullerManager),
- mPullTagId(pullTagId),
- mTriggerAtomId(triggerAtomId),
- mAtomId(atomId),
- mIsPulled(pullTagId != -1),
- mMinBucketSizeNs(metric.min_bucket_size_nanos()),
- mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC
- : StatsdStats::kPullMaxDelayNs),
- mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
- StatsdStats::kAtomDimensionKeySizeLimitMap.end()
- ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).first
- : StatsdStats::kDimensionKeySizeSoftLimit),
- mDimensionHardLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
- StatsdStats::kAtomDimensionKeySizeLimitMap.end()
- ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second
- : StatsdStats::kDimensionKeySizeHardLimit),
- mGaugeAtomsPerDimensionLimit(metric.max_num_gauge_atoms_per_bucket()),
- mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()) {
- mCurrentSlicedBucket = std::make_shared<DimToGaugeAtomsMap>();
- mCurrentSlicedBucketForAnomaly = std::make_shared<DimToValMap>();
- int64_t bucketSizeMills = 0;
- if (metric.has_bucket()) {
- bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
- } else {
- bucketSizeMills = TimeUnitToBucketSizeInMillis(ONE_HOUR);
- }
- mBucketSizeNs = bucketSizeMills * 1000000;
-
- mSamplingType = metric.sampling_type();
- if (!metric.gauge_fields_filter().include_all()) {
- translateFieldMatcher(metric.gauge_fields_filter().fields(), &mFieldMatchers);
- }
-
- if (metric.has_dimensions_in_what()) {
- translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
- mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
- }
-
- if (metric.links().size() > 0) {
- for (const auto& link : metric.links()) {
- Metric2Condition mc;
- mc.conditionId = link.condition();
- translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
- translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
- mMetric2ConditionLinks.push_back(mc);
- }
- mConditionSliced = true;
- }
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
-
- flushIfNeededLocked(startTimeNs);
- // Kicks off the puller immediately.
- if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- mPullerManager->RegisterReceiver(mPullTagId, mConfigKey, this, getCurrentBucketEndTimeNs(),
- mBucketSizeNs);
- }
-
- // Adjust start for partial first bucket and then pull if needed
- mCurrentBucketStartTimeNs = startTimeNs;
-
- VLOG("Gauge metric %lld created. bucket size %lld start_time: %lld sliced %d",
- (long long)metric.id(), (long long)mBucketSizeNs, (long long)mTimeBaseNs,
- mConditionSliced);
-}
-
-GaugeMetricProducer::~GaugeMetricProducer() {
- VLOG("~GaugeMetricProducer() called");
- if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- mPullerManager->UnRegisterReceiver(mPullTagId, mConfigKey, this);
- }
-}
-
-void GaugeMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
- if (mCurrentSlicedBucket == nullptr ||
- mCurrentSlicedBucket->size() == 0) {
- return;
- }
-
- fprintf(out, "GaugeMetric %lld dimension size %lu\n", (long long)mMetricId,
- (unsigned long)mCurrentSlicedBucket->size());
- if (verbose) {
- for (const auto& it : *mCurrentSlicedBucket) {
- fprintf(out, "\t(what)%s\t(states)%s %d atoms\n",
- it.first.getDimensionKeyInWhat().toString().c_str(),
- it.first.getStateValuesKey().toString().c_str(), (int)it.second.size());
- }
- }
-}
-
-void GaugeMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
- flushIfNeededLocked(dumpTimeNs);
- mPastBuckets.clear();
- mSkippedBuckets.clear();
-}
-
-void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- VLOG("Gauge metric %lld report now...", (long long)mMetricId);
- if (include_current_partial_bucket) {
- flushLocked(dumpTimeNs);
- } else {
- flushIfNeededLocked(dumpTimeNs);
- }
-
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
- if (mPastBuckets.empty() && mSkippedBuckets.empty()) {
- return;
- }
-
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-
- // Fills the dimension path if not slicing by ALL.
- if (!mSliceByPositionALL) {
- if (!mDimensionsInWhat.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
- writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
- protoOutput->end(dimenPathToken);
- }
- }
-
- uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_GAUGE_METRICS);
-
- for (const auto& skippedBucket : mSkippedBuckets) {
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SKIPPED);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_START_MILLIS,
- (long long)(NanoToMillis(skippedBucket.bucketStartTimeNs)));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_END_MILLIS,
- (long long)(NanoToMillis(skippedBucket.bucketEndTimeNs)));
-
- for (const auto& dropEvent : skippedBucket.dropEvents) {
- uint64_t dropEventToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SKIPPED_DROP_EVENT);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_BUCKET_DROP_REASON, dropEvent.reason);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DROP_TIME, (long long) (NanoToMillis(dropEvent.dropTimeNs)));
- protoOutput->end(dropEventToken);
- }
- protoOutput->end(wrapperToken);
- }
-
- for (const auto& pair : mPastBuckets) {
- const MetricDimensionKey& dimensionKey = pair.first;
-
- VLOG("Gauge dimension key %s", dimensionKey.toString().c_str());
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
- // First fill dimension.
- if (mSliceByPositionALL) {
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
- protoOutput->end(dimensionToken);
- } else {
- writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
- FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
- }
-
- // Then fill bucket_info (GaugeBucketInfo).
- for (const auto& bucket : pair.second) {
- uint64_t bucketInfoToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
-
- if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketStartNs));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketEndNs));
- } else {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
- (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
- }
-
- if (!bucket.mGaugeAtoms.empty()) {
- for (const auto& atom : bucket.mGaugeAtoms) {
- uint64_t atomsToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ATOM);
- writeFieldValueTreeToStream(mAtomId, *(atom.mFields), protoOutput);
- protoOutput->end(atomsToken);
- }
- for (const auto& atom : bucket.mGaugeAtoms) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED |
- FIELD_ID_ELAPSED_ATOM_TIMESTAMP,
- (long long)atom.mElapsedTimestampNs);
- }
- }
- protoOutput->end(bucketInfoToken);
- VLOG("Gauge \t bucket [%lld - %lld] includes %d atoms.",
- (long long)bucket.mBucketStartNs, (long long)bucket.mBucketEndNs,
- (int)bucket.mGaugeAtoms.size());
- }
- protoOutput->end(wrapperToken);
- }
- protoOutput->end(protoToken);
-
-
- if (erase_data) {
- mPastBuckets.clear();
- mSkippedBuckets.clear();
- }
-}
-
-void GaugeMetricProducer::prepareFirstBucketLocked() {
- if (mIsActive && mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- pullAndMatchEventsLocked(mCurrentBucketStartTimeNs);
- }
-}
-
-void GaugeMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
- bool triggerPuller = false;
- switch(mSamplingType) {
- // When the metric wants to do random sampling and there is already one gauge atom for the
- // current bucket, do not do it again.
- case GaugeMetric::RANDOM_ONE_SAMPLE: {
- triggerPuller = mCondition == ConditionState::kTrue && mCurrentSlicedBucket->empty();
- break;
- }
- case GaugeMetric::CONDITION_CHANGE_TO_TRUE: {
- triggerPuller = mCondition == ConditionState::kTrue;
- break;
- }
- case GaugeMetric::FIRST_N_SAMPLES: {
- triggerPuller = mCondition == ConditionState::kTrue;
- break;
- }
- default:
- break;
- }
- if (!triggerPuller) {
- return;
- }
- vector<std::shared_ptr<LogEvent>> allData;
- if (!mPullerManager->Pull(mPullTagId, mConfigKey, timestampNs, &allData)) {
- ALOGE("Gauge Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
- return;
- }
- const int64_t pullDelayNs = getElapsedRealtimeNs() - timestampNs;
- StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
- if (pullDelayNs > mMaxPullDelayNs) {
- ALOGE("Pull finish too late for atom %d", mPullTagId);
- StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId);
- return;
- }
- for (const auto& data : allData) {
- LogEvent localCopy = data->makeCopy();
- localCopy.setElapsedTimestampNs(timestampNs);
- if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) ==
- MatchingState::kMatched) {
- onMatchedLogEventLocked(mWhatMatcherIndex, localCopy);
- }
- }
-}
-
-void GaugeMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
- MetricProducer::onActiveStateChangedLocked(eventTimeNs);
- if (ConditionState::kTrue != mCondition || !mIsPulled) {
- return;
- }
- if (mTriggerAtomId == -1 || (mIsActive && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE)) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
-
-}
-
-void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const int64_t eventTimeNs) {
- VLOG("GaugeMetric %lld onConditionChanged", (long long)mMetricId);
-
- mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
- if (!mIsActive) {
- return;
- }
-
- flushIfNeededLocked(eventTimeNs);
- if (mIsPulled && mTriggerAtomId == -1) {
- pullAndMatchEventsLocked(eventTimeNs);
- } // else: Push mode. No need to proactively pull the gauge data.
-}
-
-void GaugeMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTimeNs) {
- VLOG("GaugeMetric %lld onSlicedConditionMayChange overall condition %d", (long long)mMetricId,
- overallCondition);
- mCondition = overallCondition ? ConditionState::kTrue : ConditionState::kFalse;
- if (!mIsActive) {
- return;
- }
-
- flushIfNeededLocked(eventTimeNs);
- // If the condition is sliced, mCondition is true if any of the dimensions is true. And we will
- // pull for every dimension.
- if (mIsPulled && mTriggerAtomId == -1) {
- pullAndMatchEventsLocked(eventTimeNs);
- } // else: Push mode. No need to proactively pull the gauge data.
-}
-
-std::shared_ptr<vector<FieldValue>> GaugeMetricProducer::getGaugeFields(const LogEvent& event) {
- std::shared_ptr<vector<FieldValue>> gaugeFields;
- if (mFieldMatchers.size() > 0) {
- gaugeFields = std::make_shared<vector<FieldValue>>();
- filterGaugeValues(mFieldMatchers, event.getValues(), gaugeFields.get());
- } else {
- gaugeFields = std::make_shared<vector<FieldValue>>(event.getValues());
- }
- // Trim all dimension fields from output. Dimensions will appear in output report and will
- // benefit from dictionary encoding. For large pulled atoms, this can give the benefit of
- // optional repeated field.
- for (const auto& field : mDimensionsInWhat) {
- for (auto it = gaugeFields->begin(); it != gaugeFields->end();) {
- if (it->mField.matches(field)) {
- it = gaugeFields->erase(it);
- } else {
- it++;
- }
- }
- }
- return gaugeFields;
-}
-
-void GaugeMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData,
- bool pullSuccess, int64_t originalPullTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!pullSuccess || allData.size() == 0) {
- return;
- }
- const int64_t pullDelayNs = getElapsedRealtimeNs() - originalPullTimeNs;
- StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
- if (pullDelayNs > mMaxPullDelayNs) {
- ALOGE("Pull finish too late for atom %d", mPullTagId);
- StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId);
- return;
- }
- for (const auto& data : allData) {
- if (mEventMatcherWizard->matchLogEvent(
- *data, mWhatMatcherIndex) == MatchingState::kMatched) {
- onMatchedLogEventLocked(mWhatMatcherIndex, *data);
- }
- }
-}
-
-bool GaugeMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
- if (mCurrentSlicedBucket->find(newKey) != mCurrentSlicedBucket->end()) {
- return false;
- }
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentSlicedBucket->size() > mDimensionSoftLimit - 1) {
- size_t newTupleCount = mCurrentSlicedBucket->size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > mDimensionHardLimit) {
- ALOGE("GaugeMetric %lld dropping data for dimension key %s",
- (long long)mMetricId, newKey.toString().c_str());
- StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
- return true;
- }
- }
-
- return false;
-}
-
-void GaugeMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) {
- if (condition == false) {
- return;
- }
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
- if (eventTimeNs < mCurrentBucketStartTimeNs) {
- VLOG("Gauge Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
- (long long)mCurrentBucketStartTimeNs);
- return;
- }
- flushIfNeededLocked(eventTimeNs);
-
- if (mTriggerAtomId == event.GetTagId()) {
- pullAndMatchEventsLocked(eventTimeNs);
- return;
- }
-
- // When gauge metric wants to randomly sample the output atom, we just simply use the first
- // gauge in the given bucket.
- if (mCurrentSlicedBucket->find(eventKey) != mCurrentSlicedBucket->end() &&
- mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- return;
- }
- if (hitGuardRailLocked(eventKey)) {
- return;
- }
- if ((*mCurrentSlicedBucket)[eventKey].size() >= mGaugeAtomsPerDimensionLimit) {
- return;
- }
-
- const int64_t truncatedElapsedTimestampNs = truncateTimestampIfNecessary(event);
- GaugeAtom gaugeAtom(getGaugeFields(event), truncatedElapsedTimestampNs);
- (*mCurrentSlicedBucket)[eventKey].push_back(gaugeAtom);
- // Anomaly detection on gauge metric only works when there is one numeric
- // field specified.
- if (mAnomalyTrackers.size() > 0) {
- if (gaugeAtom.mFields->size() == 1) {
- const Value& value = gaugeAtom.mFields->begin()->mValue;
- long gaugeVal = 0;
- if (value.getType() == INT) {
- gaugeVal = (long)value.int_value;
- } else if (value.getType() == LONG) {
- gaugeVal = value.long_value;
- }
- for (auto& tracker : mAnomalyTrackers) {
- tracker->detectAndDeclareAnomaly(eventTimeNs, mCurrentBucketNum, mMetricId,
- eventKey, gaugeVal);
- }
- }
- }
-}
-
-void GaugeMetricProducer::updateCurrentSlicedBucketForAnomaly() {
- for (const auto& slice : *mCurrentSlicedBucket) {
- if (slice.second.empty()) {
- continue;
- }
- const Value& value = slice.second.front().mFields->front().mValue;
- long gaugeVal = 0;
- if (value.getType() == INT) {
- gaugeVal = (long)value.int_value;
- } else if (value.getType() == LONG) {
- gaugeVal = value.long_value;
- }
- (*mCurrentSlicedBucketForAnomaly)[slice.first] = gaugeVal;
- }
-}
-
-void GaugeMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
- flushIfNeededLocked(dropTimeNs);
- StatsdStats::getInstance().noteBucketDropped(mMetricId);
- mPastBuckets.clear();
-}
-
-// When a new matched event comes in, we check if event falls into the current
-// bucket. If not, flush the old counter to past buckets and initialize the new
-// bucket.
-// if data is pushed, onMatchedLogEvent will only be called through onConditionChanged() inside
-// the GaugeMetricProducer while holding the lock.
-void GaugeMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
- int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
-
- if (eventTimeNs < currentBucketEndTimeNs) {
- VLOG("Gauge eventTime is %lld, less than next bucket start time %lld",
- (long long)eventTimeNs, (long long)(mCurrentBucketStartTimeNs + mBucketSizeNs));
- return;
- }
-
- // Adjusts the bucket start and end times.
- int64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
- int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
- flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
-
- mCurrentBucketNum += numBucketsForward;
- VLOG("Gauge metric %lld: new bucket start time: %lld", (long long)mMetricId,
- (long long)mCurrentBucketStartTimeNs);
-}
-
-void GaugeMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) {
- int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
- int64_t bucketEndTime = eventTimeNs < fullBucketEndTimeNs ? eventTimeNs : fullBucketEndTimeNs;
-
- GaugeBucket info;
- info.mBucketStartNs = mCurrentBucketStartTimeNs;
- info.mBucketEndNs = bucketEndTime;
-
- // Add bucket to mPastBuckets if bucket is large enough.
- // Otherwise, drop the bucket data and add bucket metadata to mSkippedBuckets.
- bool isBucketLargeEnough = info.mBucketEndNs - mCurrentBucketStartTimeNs >= mMinBucketSizeNs;
- if (isBucketLargeEnough) {
- for (const auto& slice : *mCurrentSlicedBucket) {
- info.mGaugeAtoms = slice.second;
- auto& bucketList = mPastBuckets[slice.first];
- bucketList.push_back(info);
- VLOG("Gauge gauge metric %lld, dump key value: %s", (long long)mMetricId,
- slice.first.toString().c_str());
- }
- } else {
- mCurrentSkippedBucket.bucketStartTimeNs = mCurrentBucketStartTimeNs;
- mCurrentSkippedBucket.bucketEndTimeNs = bucketEndTime;
- if (!maxDropEventsReached()) {
- mCurrentSkippedBucket.dropEvents.emplace_back(
- buildDropEvent(eventTimeNs, BucketDropReason::BUCKET_TOO_SMALL));
- }
- mSkippedBuckets.emplace_back(mCurrentSkippedBucket);
- }
-
- // If we have anomaly trackers, we need to update the partial bucket values.
- if (mAnomalyTrackers.size() > 0) {
- updateCurrentSlicedBucketForAnomaly();
-
- if (eventTimeNs > fullBucketEndTimeNs) {
- // This is known to be a full bucket, so send this data to the anomaly tracker.
- for (auto& tracker : mAnomalyTrackers) {
- tracker->addPastBucket(mCurrentSlicedBucketForAnomaly, mCurrentBucketNum);
- }
- mCurrentSlicedBucketForAnomaly = std::make_shared<DimToValMap>();
- }
- }
-
- StatsdStats::getInstance().noteBucketCount(mMetricId);
- mCurrentSlicedBucket = std::make_shared<DimToGaugeAtomsMap>();
- mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
- mCurrentSkippedBucket.reset();
-}
-
-size_t GaugeMetricProducer::byteSizeLocked() const {
- size_t totalSize = 0;
- for (const auto& pair : mPastBuckets) {
- for (const auto& bucket : pair.second) {
- totalSize += bucket.mGaugeAtoms.size() * sizeof(GaugeAtom);
- for (const auto& atom : bucket.mGaugeAtoms) {
- if (atom.mFields != nullptr) {
- totalSize += atom.mFields->size() * sizeof(FieldValue);
- }
- }
- }
- }
- return totalSize;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
deleted file mode 100644
index 2fc772b..0000000
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <unordered_map>
-
-#include <android/util/ProtoOutputStream.h>
-#include <gtest/gtest_prod.h>
-#include "../condition/ConditionTracker.h"
-#include "../external/PullDataReceiver.h"
-#include "../external/StatsPullerManager.h"
-#include "../matchers/matcher_util.h"
-#include "../matchers/EventMatcherWizard.h"
-#include "MetricProducer.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "../stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct GaugeAtom {
- GaugeAtom(std::shared_ptr<vector<FieldValue>> fields, int64_t elapsedTimeNs)
- : mFields(fields), mElapsedTimestampNs(elapsedTimeNs) {
- }
- std::shared_ptr<vector<FieldValue>> mFields;
- int64_t mElapsedTimestampNs;
-};
-
-struct GaugeBucket {
- int64_t mBucketStartNs;
- int64_t mBucketEndNs;
- std::vector<GaugeAtom> mGaugeAtoms;
-};
-
-typedef std::unordered_map<MetricDimensionKey, std::vector<GaugeAtom>>
- DimToGaugeAtomsMap;
-
-// This gauge metric producer first register the puller to automatically pull the gauge at the
-// beginning of each bucket. If the condition is met, insert it to the bucket info. Otherwise
-// proactively pull the gauge when the condition is changed to be true. Therefore, the gauge metric
-// producer always reports the guage at the earliest time of the bucket when the condition is met.
-class GaugeMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver {
-public:
- GaugeMetricProducer(
- const ConfigKey& key, const GaugeMetric& gaugeMetric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache,
- const sp<ConditionWizard>& conditionWizard, const int whatMatcherIndex,
- const sp<EventMatcherWizard>& matcherWizard, const int pullTagId,
- const int triggerAtomId, const int atomId, const int64_t timeBaseNs,
- const int64_t startTimeNs, const sp<StatsPullerManager>& pullerManager,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap = {});
-
- virtual ~GaugeMetricProducer();
-
- // Handles when the pulled data arrives.
- void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
- bool pullSuccess, int64_t originalPullTimeNs) override;
-
- // GaugeMetric needs to immediately trigger another pull when we create the partial bucket.
- void notifyAppUpgrade(const int64_t& eventTimeNs) override {
- std::lock_guard<std::mutex> lock(mMutex);
-
- if (!mSplitBucketForAppUpgrade) {
- return;
- }
- flushLocked(eventTimeNs);
- if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- };
-
- // GaugeMetric needs to immediately trigger another pull when we create the partial bucket.
- void onStatsdInitCompleted(const int64_t& eventTimeNs) override {
- std::lock_guard<std::mutex> lock(mMutex);
-
- flushLocked(eventTimeNs);
- if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- };
-
-protected:
- void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
- void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) override;
- void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
- // Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
- // Internal interface to handle active state change.
- void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
-
- // Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
- // Internal function to calculate the current used bytes.
- size_t byteSizeLocked() const override;
-
- void dumpStatesLocked(FILE* out, bool verbose) const override;
-
- void dropDataLocked(const int64_t dropTimeNs) override;
-
- // Util function to flush the old packet.
- void flushIfNeededLocked(const int64_t& eventTime) override;
-
- void flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) override;
-
- void prepareFirstBucketLocked() override;
-
- void pullAndMatchEventsLocked(const int64_t timestampNs);
-
- const int mWhatMatcherIndex;
-
- sp<EventMatcherWizard> mEventMatcherWizard;
-
- sp<StatsPullerManager> mPullerManager;
- // tagId for pulled data. -1 if this is not pulled
- const int mPullTagId;
-
- // tagId for atoms that trigger the pulling, if any
- const int mTriggerAtomId;
-
- // tagId for output atom
- const int mAtomId;
-
- // if this is pulled metric
- const bool mIsPulled;
-
- // Save the past buckets and we can clear when the StatsLogReport is dumped.
- std::unordered_map<MetricDimensionKey, std::vector<GaugeBucket>> mPastBuckets;
-
- // The current partial bucket.
- std::shared_ptr<DimToGaugeAtomsMap> mCurrentSlicedBucket;
-
- // The current full bucket for anomaly detection. This is updated to the latest value seen for
- // this slice (ie, for partial buckets, we use the last partial bucket in this full bucket).
- std::shared_ptr<DimToValMap> mCurrentSlicedBucketForAnomaly;
-
- const int64_t mMinBucketSizeNs;
-
- // Translate Atom based bucket to single numeric value bucket for anomaly and updates the map
- // for each slice with the latest value.
- void updateCurrentSlicedBucketForAnomaly();
-
- // Whitelist of fields to report. Empty means all are reported.
- std::vector<Matcher> mFieldMatchers;
-
- GaugeMetric::SamplingType mSamplingType;
-
- const int64_t mMaxPullDelayNs;
-
- // apply a whitelist on the original input
- std::shared_ptr<vector<FieldValue>> getGaugeFields(const LogEvent& event);
-
- // Util function to check whether the specified dimension hits the guardrail.
- bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
- static const size_t kBucketSize = sizeof(GaugeBucket{});
-
- const size_t mDimensionSoftLimit;
-
- const size_t mDimensionHardLimit;
-
- const size_t mGaugeAtomsPerDimensionLimit;
-
- const bool mSplitBucketForAppUpgrade;
-
- FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition);
- FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition);
- FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition);
- FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled);
- FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection);
- FRIEND_TEST(GaugeMetricProducerTest, TestFirstBucket);
- FRIEND_TEST(GaugeMetricProducerTest, TestPullOnTrigger);
- FRIEND_TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput);
-
- FRIEND_TEST(GaugeMetricProducerTest_PartialBucket, TestPushedEvents);
- FRIEND_TEST(GaugeMetricProducerTest_PartialBucket, TestPulled);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
deleted file mode 100644
index fe143e4..0000000
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "MetricProducer.h"
-
-#include "../guardrail/StatsdStats.h"
-#include "state/StateTracker.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_ENUM;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-// for ActiveMetric
-const int FIELD_ID_ACTIVE_METRIC_ID = 1;
-const int FIELD_ID_ACTIVE_METRIC_ACTIVATION = 2;
-
-// for ActiveEventActivation
-const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_ATOM_MATCHER_INDEX = 1;
-const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS = 2;
-const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE = 3;
-
-MetricProducer::MetricProducer(
- const int64_t& metricId, const ConfigKey& key, const int64_t timeBaseNs,
- const int conditionIndex, const vector<ConditionState>& initialConditionCache,
- const sp<ConditionWizard>& wizard,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap,
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
- : mMetricId(metricId),
- mConfigKey(key),
- mTimeBaseNs(timeBaseNs),
- mCurrentBucketStartTimeNs(timeBaseNs),
- mCurrentBucketNum(0),
- mCondition(initialCondition(conditionIndex, initialConditionCache)),
- mConditionTrackerIndex(conditionIndex),
- mConditionSliced(false),
- mWizard(wizard),
- mContainANYPositionInDimensionsInWhat(false),
- mSliceByPositionALL(false),
- mHasLinksToAllConditionDimensionsInTracker(false),
- mEventActivationMap(eventActivationMap),
- mEventDeactivationMap(eventDeactivationMap),
- mIsActive(mEventActivationMap.empty()),
- mSlicedStateAtoms(slicedStateAtoms),
- mStateGroupMap(stateGroupMap) {
-}
-
-void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) {
- if (!mIsActive) {
- return;
- }
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
- // this is old event, maybe statsd restarted?
- if (eventTimeNs < mTimeBaseNs) {
- return;
- }
-
- bool condition;
- ConditionKey conditionKey;
- if (mConditionSliced) {
- for (const auto& link : mMetric2ConditionLinks) {
- getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
- }
- auto conditionState =
- mWizard->query(mConditionTrackerIndex, conditionKey,
- !mHasLinksToAllConditionDimensionsInTracker);
- condition = (conditionState == ConditionState::kTrue);
- } else {
- // TODO: The unknown condition state is not handled here, we should fix it.
- condition = mCondition == ConditionState::kTrue;
- }
-
- // Stores atom id to primary key pairs for each state atom that the metric is
- // sliced by.
- std::map<int32_t, HashableDimensionKey> statePrimaryKeys;
-
- // For states with primary fields, use MetricStateLinks to get the primary
- // field values from the log event. These values will form a primary key
- // that will be used to query StateTracker for the correct state value.
- for (const auto& stateLink : mMetric2StateLinks) {
- getDimensionForState(event.getValues(), stateLink,
- &statePrimaryKeys[stateLink.stateAtomId]);
- }
-
- // For each sliced state, query StateTracker for the state value using
- // either the primary key from the previous step or the DEFAULT_DIMENSION_KEY.
- //
- // Expected functionality: for any case where the MetricStateLinks are
- // initialized incorrectly (ex. # of state links != # of primary fields, no
- // links are provided for a state with primary fields, links are provided
- // in the wrong order, etc.), StateTracker will simply return kStateUnknown
- // when queried using an incorrect key.
- HashableDimensionKey stateValuesKey;
- for (auto atomId : mSlicedStateAtoms) {
- FieldValue value;
- if (statePrimaryKeys.find(atomId) != statePrimaryKeys.end()) {
- // found a primary key for this state, query using the key
- queryStateValue(atomId, statePrimaryKeys[atomId], &value);
- } else {
- // if no MetricStateLinks exist for this state atom,
- // query using the default dimension key (empty HashableDimensionKey)
- queryStateValue(atomId, DEFAULT_DIMENSION_KEY, &value);
- }
- mapStateValue(atomId, &value);
- stateValuesKey.addValue(value);
- }
-
- HashableDimensionKey dimensionInWhat;
- filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhat);
- MetricDimensionKey metricKey(dimensionInWhat, stateValuesKey);
- onMatchedLogEventInternalLocked(matcherIndex, metricKey, conditionKey, condition, event,
- statePrimaryKeys);
-}
-
-bool MetricProducer::evaluateActiveStateLocked(int64_t elapsedTimestampNs) {
- bool isActive = mEventActivationMap.empty();
- for (auto& it : mEventActivationMap) {
- if (it.second->state == ActivationState::kActive &&
- elapsedTimestampNs > it.second->ttl_ns + it.second->start_ns) {
- it.second->state = ActivationState::kNotActive;
- }
- if (it.second->state == ActivationState::kActive) {
- isActive = true;
- }
- }
- return isActive;
-}
-
-void MetricProducer::flushIfExpire(int64_t elapsedTimestampNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mIsActive) {
- return;
- }
- mIsActive = evaluateActiveStateLocked(elapsedTimestampNs);
- if (!mIsActive) {
- onActiveStateChangedLocked(elapsedTimestampNs);
- }
-}
-
-void MetricProducer::activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs) {
- auto it = mEventActivationMap.find(activationTrackerIndex);
- if (it == mEventActivationMap.end()) {
- return;
- }
- auto& activation = it->second;
- if (ACTIVATE_ON_BOOT == activation->activationType) {
- if (ActivationState::kNotActive == activation->state) {
- activation->state = ActivationState::kActiveOnBoot;
- }
- // If the Activation is already active or set to kActiveOnBoot, do nothing.
- return;
- }
- activation->start_ns = elapsedTimestampNs;
- activation->state = ActivationState::kActive;
- bool oldActiveState = mIsActive;
- mIsActive = true;
- if (!oldActiveState) { // Metric went from not active to active.
- onActiveStateChangedLocked(elapsedTimestampNs);
- }
-}
-
-void MetricProducer::cancelEventActivationLocked(int deactivationTrackerIndex) {
- auto it = mEventDeactivationMap.find(deactivationTrackerIndex);
- if (it == mEventDeactivationMap.end()) {
- return;
- }
- for (auto activationToCancelIt : it->second) {
- activationToCancelIt->state = ActivationState::kNotActive;
- }
-}
-
-void MetricProducer::loadActiveMetricLocked(const ActiveMetric& activeMetric,
- int64_t currentTimeNs) {
- if (mEventActivationMap.size() == 0) {
- return;
- }
- for (int i = 0; i < activeMetric.activation_size(); i++) {
- const auto& activeEventActivation = activeMetric.activation(i);
- auto it = mEventActivationMap.find(activeEventActivation.atom_matcher_index());
- if (it == mEventActivationMap.end()) {
- ALOGE("Saved event activation not found");
- continue;
- }
- auto& activation = it->second;
- // If the event activation does not have a state, assume it is active.
- if (!activeEventActivation.has_state() ||
- activeEventActivation.state() == ActiveEventActivation::ACTIVE) {
- // We don't want to change the ttl for future activations, so we set the start_ns
- // such that start_ns + ttl_ns == currentTimeNs + remaining_ttl_nanos
- activation->start_ns =
- currentTimeNs + activeEventActivation.remaining_ttl_nanos() - activation->ttl_ns;
- activation->state = ActivationState::kActive;
- mIsActive = true;
- } else if (activeEventActivation.state() == ActiveEventActivation::ACTIVATE_ON_BOOT) {
- activation->state = ActivationState::kActiveOnBoot;
- }
- }
-}
-
-void MetricProducer::writeActiveMetricToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_METRIC_ID, (long long)mMetricId);
- for (auto& it : mEventActivationMap) {
- const int atom_matcher_index = it.first;
- const std::shared_ptr<Activation>& activation = it.second;
-
- if (ActivationState::kNotActive == activation->state ||
- (ActivationState::kActive == activation->state &&
- activation->start_ns + activation->ttl_ns < currentTimeNs)) {
- continue;
- }
-
- const uint64_t activationToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ACTIVE_METRIC_ACTIVATION);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_ATOM_MATCHER_INDEX,
- atom_matcher_index);
- if (ActivationState::kActive == activation->state) {
- const int64_t remainingTtlNs =
- activation->start_ns + activation->ttl_ns - currentTimeNs;
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
- (long long)remainingTtlNs);
- proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
- ActiveEventActivation::ACTIVE);
-
- } else if (ActivationState::kActiveOnBoot == activation->state) {
- if (reason == DEVICE_SHUTDOWN || reason == TERMINATION_SIGNAL_RECEIVED) {
- proto->write(
- FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
- (long long)activation->ttl_ns);
- proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
- ActiveEventActivation::ACTIVE);
- } else if (reason == STATSCOMPANION_DIED) {
- // We are saving because of system server death, not due to a device shutdown.
- // Next time we load, we do not want to activate metrics that activate on boot.
- proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
- ActiveEventActivation::ACTIVATE_ON_BOOT);
- }
- }
- proto->end(activationToken);
- }
-}
-
-void MetricProducer::queryStateValue(const int32_t atomId, const HashableDimensionKey& queryKey,
- FieldValue* value) {
- if (!StateManager::getInstance().getStateValue(atomId, queryKey, value)) {
- value->mValue = Value(StateTracker::kStateUnknown);
- value->mField.setTag(atomId);
- ALOGW("StateTracker not found for state atom %d", atomId);
- return;
- }
-}
-
-void MetricProducer::mapStateValue(const int32_t atomId, FieldValue* value) {
- // check if there is a state map for this atom
- auto atomIt = mStateGroupMap.find(atomId);
- if (atomIt == mStateGroupMap.end()) {
- return;
- }
- auto valueIt = atomIt->second.find(value->mValue.int_value);
- if (valueIt == atomIt->second.end()) {
- // state map exists, but value was not put in a state group
- // so set mValue to kStateUnknown
- // TODO(tsaichristine): handle incomplete state maps
- value->mValue.setInt(StateTracker::kStateUnknown);
- } else {
- // set mValue to group_id
- value->mValue.setLong(valueIt->second);
- }
-}
-
-HashableDimensionKey MetricProducer::getUnknownStateKey() {
- HashableDimensionKey stateKey;
- for (auto atom : mSlicedStateAtoms) {
- FieldValue fieldValue;
- fieldValue.mField.setTag(atom);
- fieldValue.mValue.setInt(StateTracker::kStateUnknown);
- stateKey.addValue(fieldValue);
- }
- return stateKey;
-}
-
-DropEvent MetricProducer::buildDropEvent(const int64_t dropTimeNs, const BucketDropReason reason) {
- DropEvent event;
- event.reason = reason;
- event.dropTimeNs = dropTimeNs;
- return event;
-}
-
-bool MetricProducer::maxDropEventsReached() {
- return mCurrentSkippedBucket.dropEvents.size() >= StatsdStats::kMaxLoggedBucketDropEvents;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
deleted file mode 100644
index be4cd67..0000000
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef METRIC_PRODUCER_H
-#define METRIC_PRODUCER_H
-
-#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
-#include <utils/RefBase.h>
-
-#include <unordered_map>
-
-#include "HashableDimensionKey.h"
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionWizard.h"
-#include "config/ConfigKey.h"
-#include "matchers/matcher_util.h"
-#include "packages/PackageInfoListener.h"
-#include "state/StateListener.h"
-#include "state/StateManager.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Keep this in sync with DumpReportReason enum in stats_log.proto
-enum DumpReportReason {
- DEVICE_SHUTDOWN = 1,
- CONFIG_UPDATED = 2,
- CONFIG_REMOVED = 3,
- GET_DATA_CALLED = 4,
- ADB_DUMP = 5,
- CONFIG_RESET = 6,
- STATSCOMPANION_DIED = 7,
- TERMINATION_SIGNAL_RECEIVED = 8
-};
-
-// If the metric has no activation requirement, it will be active once the metric producer is
-// created.
-// If the metric needs to be activated by atoms, the metric producer will start
-// with kNotActive state, turn to kActive or kActiveOnBoot when the activation event arrives, become
-// kNotActive when it reaches the duration limit (timebomb). If the activation event arrives again
-// before or after it expires, the event producer will be re-activated and ttl will be reset.
-enum ActivationState {
- kNotActive = 0,
- kActive = 1,
- kActiveOnBoot = 2,
-};
-
-enum DumpLatency {
- // In some cases, we only have a short time range to do the dump, e.g. statsd is being killed.
- // We might be able to return all the data in this mode. For instance, pull metrics might need
- // to be pulled when the current bucket is requested.
- FAST = 1,
- // In other cases, it is fine for a dump to take more than a few milliseconds, e.g. config
- // updates.
- NO_TIME_CONSTRAINTS = 2
-};
-
-// Keep this in sync with BucketDropReason enum in stats_log.proto
-enum BucketDropReason {
- // For ValueMetric, a bucket is dropped during a dump report request iff
- // current bucket should be included, a pull is needed (pulled metric and
- // condition is true), and we are under fast time constraints.
- DUMP_REPORT_REQUESTED = 1,
- EVENT_IN_WRONG_BUCKET = 2,
- CONDITION_UNKNOWN = 3,
- PULL_FAILED = 4,
- PULL_DELAYED = 5,
- DIMENSION_GUARDRAIL_REACHED = 6,
- MULTIPLE_BUCKETS_SKIPPED = 7,
- // Not an invalid bucket case, but the bucket is dropped.
- BUCKET_TOO_SMALL = 8,
- // Not an invalid bucket case, but the bucket is skipped.
- NO_DATA = 9
-};
-
-struct Activation {
- Activation(const ActivationType& activationType, const int64_t ttlNs)
- : ttl_ns(ttlNs),
- start_ns(0),
- state(ActivationState::kNotActive),
- activationType(activationType) {}
-
- const int64_t ttl_ns;
- int64_t start_ns;
- ActivationState state;
- const ActivationType activationType;
-};
-
-struct DropEvent {
- // Reason for dropping the bucket and/or marking the bucket invalid.
- BucketDropReason reason;
- // The timestamp of the drop event.
- int64_t dropTimeNs;
-};
-
-struct SkippedBucket {
- // Start time of the dropped bucket.
- int64_t bucketStartTimeNs;
- // End time of the dropped bucket.
- int64_t bucketEndTimeNs;
- // List of events that invalidated this bucket.
- std::vector<DropEvent> dropEvents;
-
- void reset() {
- bucketStartTimeNs = 0;
- bucketEndTimeNs = 0;
- dropEvents.clear();
- }
-};
-
-// A MetricProducer is responsible for compute one single metrics, creating stats log report, and
-// writing the report to dropbox. MetricProducers should respond to package changes as required in
-// PackageInfoListener, but if none of the metrics are slicing by package name, then the update can
-// be a no-op.
-class MetricProducer : public virtual android::RefBase, public virtual StateListener {
-public:
- MetricProducer(const int64_t& metricId, const ConfigKey& key, const int64_t timeBaseNs,
- const int conditionIndex, const vector<ConditionState>& initialConditionCache,
- const sp<ConditionWizard>& wizard,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap,
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap);
-
- virtual ~MetricProducer(){};
-
- ConditionState initialCondition(const int conditionIndex,
- const vector<ConditionState>& initialConditionCache) const {
- return conditionIndex >= 0 ? initialConditionCache[conditionIndex] : ConditionState::kTrue;
- }
-
- /**
- * Force a partial bucket split on app upgrade
- */
- virtual void notifyAppUpgrade(const int64_t& eventTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- flushLocked(eventTimeNs);
- };
-
- void notifyAppRemoved(const int64_t& eventTimeNs) {
- // Force buckets to split on removal also.
- notifyAppUpgrade(eventTimeNs);
- };
-
- /**
- * Force a partial bucket split on boot complete.
- */
- virtual void onStatsdInitCompleted(const int64_t& eventTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- flushLocked(eventTimeNs);
- }
- // Consume the parsed stats log entry that already matched the "what" of the metric.
- void onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) {
- std::lock_guard<std::mutex> lock(mMutex);
- onMatchedLogEventLocked(matcherIndex, event);
- }
-
- void onConditionChanged(const bool condition, const int64_t eventTime) {
- std::lock_guard<std::mutex> lock(mMutex);
- onConditionChangedLocked(condition, eventTime);
- }
-
- void onSlicedConditionMayChange(bool overallCondition, const int64_t eventTime) {
- std::lock_guard<std::mutex> lock(mMutex);
- onSlicedConditionMayChangeLocked(overallCondition, eventTime);
- }
-
- bool isConditionSliced() const {
- std::lock_guard<std::mutex> lock(mMutex);
- return mConditionSliced;
- };
-
- void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey, const FieldValue& oldState,
- const FieldValue& newState){};
-
- // Output the metrics data to [protoOutput]. All metrics reports end with the same timestamp.
- // This method clears all the past buckets.
- void onDumpReport(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) {
- std::lock_guard<std::mutex> lock(mMutex);
- return onDumpReportLocked(dumpTimeNs, include_current_partial_bucket, erase_data,
- dumpLatency, str_set, protoOutput);
- }
-
- void clearPastBuckets(const int64_t dumpTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- return clearPastBucketsLocked(dumpTimeNs);
- }
-
- void prepareFirstBucket() {
- std::lock_guard<std::mutex> lock(mMutex);
- prepareFirstBucketLocked();
- }
-
- // Returns the memory in bytes currently used to store this metric's data. Does not change
- // state.
- size_t byteSize() const {
- std::lock_guard<std::mutex> lock(mMutex);
- return byteSizeLocked();
- }
-
- void dumpStates(FILE* out, bool verbose) const {
- std::lock_guard<std::mutex> lock(mMutex);
- dumpStatesLocked(out, verbose);
- }
-
- // Let MetricProducer drop in-memory data to save memory.
- // We still need to keep future data valid and anomaly tracking work, which means we will
- // have to flush old data, informing anomaly trackers then safely drop old data.
- // We still keep current bucket data for future metrics' validity.
- void dropData(const int64_t dropTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- dropDataLocked(dropTimeNs);
- }
-
- void loadActiveMetric(const ActiveMetric& activeMetric, int64_t currentTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- loadActiveMetricLocked(activeMetric, currentTimeNs);
- }
-
- void activate(int activationTrackerIndex, int64_t elapsedTimestampNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- activateLocked(activationTrackerIndex, elapsedTimestampNs);
- }
-
- void cancelEventActivation(int deactivationTrackerIndex) {
- std::lock_guard<std::mutex> lock(mMutex);
- cancelEventActivationLocked(deactivationTrackerIndex);
- }
-
- bool isActive() const {
- std::lock_guard<std::mutex> lock(mMutex);
- return isActiveLocked();
- }
-
- void flushIfExpire(int64_t elapsedTimestampNs);
-
- void writeActiveMetricToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
- // Start: getters/setters
- inline const int64_t& getMetricId() const {
- return mMetricId;
- }
-
- // For test only.
- inline int64_t getCurrentBucketNum() const {
- return mCurrentBucketNum;
- }
-
- int64_t getBucketSizeInNs() const {
- std::lock_guard<std::mutex> lock(mMutex);
- return mBucketSizeNs;
- }
-
- inline const std::vector<int> getSlicedStateAtoms() {
- std::lock_guard<std::mutex> lock(mMutex);
- return mSlicedStateAtoms;
- }
-
- /* If alert is valid, adds an AnomalyTracker and returns it. If invalid, returns nullptr. */
- virtual sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
- const sp<AlarmMonitor>& anomalyAlarmMonitor) {
- std::lock_guard<std::mutex> lock(mMutex);
- sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, mConfigKey);
- if (anomalyTracker != nullptr) {
- mAnomalyTrackers.push_back(anomalyTracker);
- }
- return anomalyTracker;
- }
- // End: getters/setters
-protected:
- /**
- * Flushes the current bucket if the eventTime is after the current bucket's end time.
- */
- virtual void flushIfNeededLocked(const int64_t& eventTime){};
-
- /**
- * For metrics that aggregate (ie, every metric producer except for EventMetricProducer),
- * we need to be able to flush the current buckets on demand (ie, end the current bucket and
- * start new bucket). If this function is called when eventTimeNs is greater than the current
- * bucket's end timestamp, than we flush up to the end of the latest full bucket; otherwise,
- * we assume that we want to flush a partial bucket. The bucket start timestamp and bucket
- * number are not changed by this function. This method should only be called by
- * flushIfNeededLocked or flushLocked or the app upgrade handler; the caller MUST update the
- * bucket timestamp and bucket number as needed.
- */
- virtual void flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) {};
-
- /**
- * Flushes all the data including the current partial bucket.
- */
- virtual void flushLocked(const int64_t& eventTimeNs) {
- flushIfNeededLocked(eventTimeNs);
- flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
- };
-
- /*
- * Individual metrics can implement their own business logic here. All pre-processing is done.
- *
- * [matcherIndex]: the index of the matcher which matched this event. This is interesting to
- * DurationMetric, because it has start/stop/stop_all 3 matchers.
- * [eventKey]: the extracted dimension key for the final output. if the metric doesn't have
- * dimensions, it will be DEFAULT_DIMENSION_KEY
- * [conditionKey]: the keys of conditions which should be used to query the condition for this
- * target event (from MetricConditionLink). This is passed to individual metrics
- * because DurationMetric needs it to be cached.
- * [condition]: whether condition is met. If condition is sliced, this is the result coming from
- * query with ConditionWizard; If condition is not sliced, this is the
- * nonSlicedCondition.
- * [event]: the log event, just in case the metric needs its data, e.g., EventMetric.
- */
- virtual void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) = 0;
-
- // Consume the parsed stats log entry that already matched the "what" of the metric.
- virtual void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event);
- virtual void onConditionChangedLocked(const bool condition, const int64_t eventTime) = 0;
- virtual void onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTime) = 0;
- virtual void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) = 0;
- virtual void clearPastBucketsLocked(const int64_t dumpTimeNs) = 0;
- virtual void prepareFirstBucketLocked(){};
- virtual size_t byteSizeLocked() const = 0;
- virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0;
- virtual void dropDataLocked(const int64_t dropTimeNs) = 0;
- void loadActiveMetricLocked(const ActiveMetric& activeMetric, int64_t currentTimeNs);
- void activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs);
- void cancelEventActivationLocked(int deactivationTrackerIndex);
-
- bool evaluateActiveStateLocked(int64_t elapsedTimestampNs);
-
- virtual void onActiveStateChangedLocked(const int64_t& eventTimeNs) {
- if (!mIsActive) {
- flushLocked(eventTimeNs);
- }
- }
-
- inline bool isActiveLocked() const {
- return mIsActive;
- }
-
- // Convenience to compute the current bucket's end time, which is always aligned with the
- // start time of the metric.
- int64_t getCurrentBucketEndTimeNs() const {
- return mTimeBaseNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
- }
-
- int64_t getBucketNumFromEndTimeNs(const int64_t endNs) {
- return (endNs - mTimeBaseNs) / mBucketSizeNs - 1;
- }
-
- // Query StateManager for original state value using the queryKey.
- // The field and value are output.
- void queryStateValue(const int32_t atomId, const HashableDimensionKey& queryKey,
- FieldValue* value);
-
- // If a state map exists for the given atom, replace the original state
- // value with the group id mapped to the value.
- // If no state map exists, keep the original state value.
- void mapStateValue(const int32_t atomId, FieldValue* value);
-
- // Returns a HashableDimensionKey with unknown state value for each state
- // atom.
- HashableDimensionKey getUnknownStateKey();
-
- DropEvent buildDropEvent(const int64_t dropTimeNs, const BucketDropReason reason);
-
- // Returns true if the number of drop events in the current bucket has
- // exceeded the maximum number allowed, which is currently capped at 10.
- bool maxDropEventsReached();
-
- const int64_t mMetricId;
-
- const ConfigKey mConfigKey;
-
- // The time when this metric producer was first created. The end time for the current bucket
- // can be computed from this based on mCurrentBucketNum.
- int64_t mTimeBaseNs;
-
- // Start time may not be aligned with the start of statsd if there is an app upgrade in the
- // middle of a bucket.
- int64_t mCurrentBucketStartTimeNs;
-
- // Used by anomaly detector to track which bucket we are in. This is not sent with the produced
- // report.
- int64_t mCurrentBucketNum;
-
- int64_t mBucketSizeNs;
-
- ConditionState mCondition;
-
- int mConditionTrackerIndex;
-
- bool mConditionSliced;
-
- sp<ConditionWizard> mWizard;
-
- bool mContainANYPositionInDimensionsInWhat;
-
- bool mSliceByPositionALL;
-
- vector<Matcher> mDimensionsInWhat; // The dimensions_in_what defined in statsd_config
-
- // True iff the metric to condition links cover all dimension fields in the condition tracker.
- // This field is always false for combinational condition trackers.
- bool mHasLinksToAllConditionDimensionsInTracker;
-
- std::vector<Metric2Condition> mMetric2ConditionLinks;
-
- std::vector<sp<AnomalyTracker>> mAnomalyTrackers;
-
- mutable std::mutex mMutex;
-
- // When the metric producer has multiple activations, these activations are ORed to determine
- // whether the metric producer is ready to generate metrics.
- std::unordered_map<int, std::shared_ptr<Activation>> mEventActivationMap;
-
- // Maps index of atom matcher for deactivation to a list of Activation structs.
- std::unordered_map<int, std::vector<std::shared_ptr<Activation>>> mEventDeactivationMap;
-
- bool mIsActive;
-
- // The slice_by_state atom ids defined in statsd_config.
- const std::vector<int32_t> mSlicedStateAtoms;
-
- // Maps atom ids and state values to group_ids (<atom_id, <value, group_id>>).
- const std::unordered_map<int32_t, std::unordered_map<int, int64_t>> mStateGroupMap;
-
- // MetricStateLinks defined in statsd_config that link fields in the state
- // atom to fields in the "what" atom.
- std::vector<Metric2State> mMetric2StateLinks;
-
- SkippedBucket mCurrentSkippedBucket;
- // Buckets that were invalidated and had their data dropped.
- std::vector<SkippedBucket> mSkippedBuckets;
-
- FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
- FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
- FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
-
- FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
- FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
- FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped);
- FRIEND_TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
-
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
-
- FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
- FRIEND_TEST(StatsLogProcessorTest,
- TestActivationOnBootMultipleActivationsDifferentActivationTypes);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
-
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
- FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
-
- FRIEND_TEST(MetricsManagerTest, TestInitialConditions);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // METRIC_PRODUCER_H
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
deleted file mode 100644
index 60de1a2..0000000
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ /dev/null
@@ -1,695 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "MetricsManager.h"
-
-#include <private/android_filesystem_config.h>
-
-#include "CountMetricProducer.h"
-#include "condition/CombinationConditionTracker.h"
-#include "condition/SimpleConditionTracker.h"
-#include "guardrail/StatsdStats.h"
-#include "matchers/CombinationLogMatchingTracker.h"
-#include "matchers/SimpleLogMatchingTracker.h"
-#include "metrics_manager_util.h"
-#include "state/StateManager.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "statslog_statsd.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-
-using std::set;
-using std::string;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const int FIELD_ID_METRICS = 1;
-const int FIELD_ID_ANNOTATIONS = 7;
-const int FIELD_ID_ANNOTATIONS_INT64 = 1;
-const int FIELD_ID_ANNOTATIONS_INT32 = 2;
-
-// for ActiveConfig
-const int FIELD_ID_ACTIVE_CONFIG_ID = 1;
-const int FIELD_ID_ACTIVE_CONFIG_UID = 2;
-const int FIELD_ID_ACTIVE_CONFIG_METRIC = 3;
-
-MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
- const int64_t timeBaseNs, const int64_t currentTimeNs,
- const sp<UidMap>& uidMap,
- const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& periodicAlarmMonitor)
- : mConfigKey(key),
- mUidMap(uidMap),
- mTtlNs(config.has_ttl_in_seconds() ? config.ttl_in_seconds() * NS_PER_SEC : -1),
- mTtlEndNs(-1),
- mLastReportTimeNs(currentTimeNs),
- mLastReportWallClockNs(getWallClockNs()),
- mPullerManager(pullerManager),
- mWhitelistedAtomIds(config.whitelisted_atom_ids().begin(),
- config.whitelisted_atom_ids().end()),
- mShouldPersistHistory(config.persist_locally()) {
- // Init the ttl end timestamp.
- refreshTtl(timeBaseNs);
-
- mConfigValid = initStatsdConfig(
- key, config, *uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchers, mAllConditionTrackers,
- mAllMetricProducers, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers,
- mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap,
- mActivationAtomTrackerToMetricMap, mDeactivationAtomTrackerToMetricMap,
- mAlertTrackerMap, mMetricIndexesWithActivation, mNoReportMetricIds);
-
- mHashStringsInReport = config.hash_strings_in_metric_report();
- mVersionStringsInReport = config.version_strings_in_metric_report();
- mInstallerInReport = config.installer_in_metric_report();
-
- // Init allowed pushed atom uids.
- if (config.allowed_log_source_size() == 0) {
- mConfigValid = false;
- ALOGE("Log source whitelist is empty! This config won't get any data. Suggest adding at "
- "least AID_SYSTEM and AID_STATSD to the allowed_log_source field.");
- } else {
- for (const auto& source : config.allowed_log_source()) {
- auto it = UidMap::sAidToUidMapping.find(source);
- if (it != UidMap::sAidToUidMapping.end()) {
- mAllowedUid.push_back(it->second);
- } else {
- mAllowedPkg.push_back(source);
- }
- }
-
- if (mAllowedUid.size() + mAllowedPkg.size() > StatsdStats::kMaxLogSourceCount) {
- ALOGE("Too many log sources. This is likely to be an error in the config.");
- mConfigValid = false;
- } else {
- initLogSourceWhiteList();
- }
- }
-
- // Init default allowed pull atom uids.
- int numPullPackages = 0;
- for (const string& pullSource : config.default_pull_packages()) {
- auto it = UidMap::sAidToUidMapping.find(pullSource);
- if (it != UidMap::sAidToUidMapping.end()) {
- numPullPackages++;
- mDefaultPullUids.insert(it->second);
- } else {
- ALOGE("Default pull atom packages must be in sAidToUidMapping");
- mConfigValid = false;
- }
- }
- // Init per-atom pull atom packages.
- for (const PullAtomPackages& pullAtomPackages : config.pull_atom_packages()) {
- int32_t atomId = pullAtomPackages.atom_id();
- for (const string& pullPackage : pullAtomPackages.packages()) {
- numPullPackages++;
- auto it = UidMap::sAidToUidMapping.find(pullPackage);
- if (it != UidMap::sAidToUidMapping.end()) {
- mPullAtomUids[atomId].insert(it->second);
- } else {
- mPullAtomPackages[atomId].insert(pullPackage);
- }
- }
- }
- if (numPullPackages > StatsdStats::kMaxPullAtomPackages) {
- ALOGE("Too many sources in default_pull_packages and pull_atom_packages. This is likely to "
- "be an error in the config");
- mConfigValid = false;
- } else {
- initPullAtomSources();
- }
- mPullerManager->RegisterPullUidProvider(mConfigKey, this);
-
- // Store the sub-configs used.
- for (const auto& annotation : config.annotation()) {
- mAnnotations.emplace_back(annotation.field_int64(), annotation.field_int32());
- }
-
- // Guardrail. Reject the config if it's too big.
- if (mAllMetricProducers.size() > StatsdStats::kMaxMetricCountPerConfig ||
- mAllConditionTrackers.size() > StatsdStats::kMaxConditionCountPerConfig ||
- mAllAtomMatchers.size() > StatsdStats::kMaxMatcherCountPerConfig) {
- ALOGE("This config is too big! Reject!");
- mConfigValid = false;
- }
- if (mAllAnomalyTrackers.size() > StatsdStats::kMaxAlertCountPerConfig) {
- ALOGE("This config has too many alerts! Reject!");
- mConfigValid = false;
- }
-
- mIsAlwaysActive = (mMetricIndexesWithActivation.size() != mAllMetricProducers.size()) ||
- (mAllMetricProducers.size() == 0);
- bool isActive = mIsAlwaysActive;
- for (int metric : mMetricIndexesWithActivation) {
- isActive |= mAllMetricProducers[metric]->isActive();
- }
- mIsActive = isActive;
- VLOG("mIsActive is initialized to %d", mIsActive)
-
- // no matter whether this config is valid, log it in the stats.
- StatsdStats::getInstance().noteConfigReceived(
- key, mAllMetricProducers.size(), mAllConditionTrackers.size(), mAllAtomMatchers.size(),
- mAllAnomalyTrackers.size(), mAnnotations, mConfigValid);
- // Check active
- for (const auto& metric : mAllMetricProducers) {
- if (metric->isActive()) {
- mIsActive = true;
- break;
- }
- }
-}
-
-MetricsManager::~MetricsManager() {
- for (auto it : mAllMetricProducers) {
- for (int atomId : it->getSlicedStateAtoms()) {
- StateManager::getInstance().unregisterListener(atomId, it);
- }
- }
- mPullerManager->UnregisterPullUidProvider(mConfigKey, this);
-
- VLOG("~MetricsManager()");
-}
-
-void MetricsManager::initLogSourceWhiteList() {
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- mAllowedLogSources.clear();
- mAllowedLogSources.insert(mAllowedUid.begin(), mAllowedUid.end());
-
- for (const auto& pkg : mAllowedPkg) {
- auto uids = mUidMap->getAppUid(pkg);
- mAllowedLogSources.insert(uids.begin(), uids.end());
- }
- if (DEBUG) {
- for (const auto& uid : mAllowedLogSources) {
- VLOG("Allowed uid %d", uid);
- }
- }
-}
-
-void MetricsManager::initPullAtomSources() {
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- mCombinedPullAtomUids.clear();
- for (const auto& [atomId, uids] : mPullAtomUids) {
- mCombinedPullAtomUids[atomId].insert(uids.begin(), uids.end());
- }
- for (const auto& [atomId, packages] : mPullAtomPackages) {
- for (const string& pkg : packages) {
- set<int32_t> uids = mUidMap->getAppUid(pkg);
- mCombinedPullAtomUids[atomId].insert(uids.begin(), uids.end());
- }
- }
-}
-
-bool MetricsManager::isConfigValid() const {
- return mConfigValid;
-}
-
-void MetricsManager::notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
- const int64_t version) {
- // Inform all metric producers.
- for (const auto& it : mAllMetricProducers) {
- it->notifyAppUpgrade(eventTimeNs);
- }
- // check if we care this package
- if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) != mAllowedPkg.end()) {
- // We will re-initialize the whole list because we don't want to keep the multi mapping of
- // UID<->pkg inside MetricsManager to reduce the memory usage.
- initLogSourceWhiteList();
- }
-
- for (const auto& it : mPullAtomPackages) {
- if (it.second.find(apk) != it.second.end()) {
- initPullAtomSources();
- return;
- }
- }
-}
-
-void MetricsManager::notifyAppRemoved(const int64_t& eventTimeNs, const string& apk,
- const int uid) {
- // Inform all metric producers.
- for (const auto& it : mAllMetricProducers) {
- it->notifyAppRemoved(eventTimeNs);
- }
- // check if we care this package
- if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) != mAllowedPkg.end()) {
- // We will re-initialize the whole list because we don't want to keep the multi mapping of
- // UID<->pkg inside MetricsManager to reduce the memory usage.
- initLogSourceWhiteList();
- }
-
- for (const auto& it : mPullAtomPackages) {
- if (it.second.find(apk) != it.second.end()) {
- initPullAtomSources();
- return;
- }
- }
-}
-
-void MetricsManager::onUidMapReceived(const int64_t& eventTimeNs) {
- // Purposefully don't inform metric producers on a new snapshot
- // because we don't need to flush partial buckets.
- // This occurs if a new user is added/removed or statsd crashes.
- initPullAtomSources();
-
- if (mAllowedPkg.size() == 0) {
- return;
- }
- initLogSourceWhiteList();
-}
-
-void MetricsManager::onStatsdInitCompleted(const int64_t& eventTimeNs) {
- // Inform all metric producers.
- for (const auto& it : mAllMetricProducers) {
- it->onStatsdInitCompleted(eventTimeNs);
- }
-}
-
-void MetricsManager::init() {
- for (const auto& producer : mAllMetricProducers) {
- producer->prepareFirstBucket();
- }
-}
-
-vector<int32_t> MetricsManager::getPullAtomUids(int32_t atomId) {
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- vector<int32_t> uids;
- const auto& it = mCombinedPullAtomUids.find(atomId);
- if (it != mCombinedPullAtomUids.end()) {
- uids.insert(uids.end(), it->second.begin(), it->second.end());
- }
- uids.insert(uids.end(), mDefaultPullUids.begin(), mDefaultPullUids.end());
- return uids;
-}
-
-void MetricsManager::dumpStates(FILE* out, bool verbose) {
- fprintf(out, "ConfigKey %s, allowed source:", mConfigKey.ToString().c_str());
- {
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- for (const auto& source : mAllowedLogSources) {
- fprintf(out, "%d ", source);
- }
- }
- fprintf(out, "\n");
- for (const auto& producer : mAllMetricProducers) {
- producer->dumpStates(out, verbose);
- }
-}
-
-void MetricsManager::dropData(const int64_t dropTimeNs) {
- for (const auto& producer : mAllMetricProducers) {
- producer->dropData(dropTimeNs);
- }
-}
-
-void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- VLOG("=========================Metric Reports Start==========================");
- // one StatsLogReport per MetricProduer
- for (const auto& producer : mAllMetricProducers) {
- if (mNoReportMetricIds.find(producer->getMetricId()) == mNoReportMetricIds.end()) {
- uint64_t token = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_METRICS);
- if (mHashStringsInReport) {
- producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
- dumpLatency, str_set, protoOutput);
- } else {
- producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
- dumpLatency, nullptr, protoOutput);
- }
- protoOutput->end(token);
- } else {
- producer->clearPastBuckets(dumpTimeStampNs);
- }
- }
- for (const auto& annotation : mAnnotations) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ANNOTATIONS);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ANNOTATIONS_INT64,
- (long long)annotation.first);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_ANNOTATIONS_INT32, annotation.second);
- protoOutput->end(token);
- }
-
- // Do not update the timestamps when data is not cleared to avoid timestamps from being
- // misaligned.
- if (erase_data) {
- mLastReportTimeNs = dumpTimeStampNs;
- mLastReportWallClockNs = getWallClockNs();
- }
- VLOG("=========================Metric Reports End==========================");
-}
-
-
-bool MetricsManager::checkLogCredentials(const LogEvent& event) {
- if (mWhitelistedAtomIds.find(event.GetTagId()) != mWhitelistedAtomIds.end()) {
- return true;
- }
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- if (mAllowedLogSources.find(event.GetUid()) == mAllowedLogSources.end()) {
- VLOG("log source %d not on the whitelist", event.GetUid());
- return false;
- }
- return true;
-}
-
-bool MetricsManager::eventSanityCheck(const LogEvent& event) {
- if (event.GetTagId() == util::APP_BREADCRUMB_REPORTED) {
- // Check that app breadcrumb reported fields are valid.
- status_t err = NO_ERROR;
-
- // Uid is 3rd from last field and must match the caller's uid,
- // unless that caller is statsd itself (statsd is allowed to spoof uids).
- long appHookUid = event.GetLong(event.size()-2, &err);
- if (err != NO_ERROR) {
- VLOG("APP_BREADCRUMB_REPORTED had error when parsing the uid");
- return false;
- }
-
- // Because the uid within the LogEvent may have been mapped from
- // isolated to host, map the loggerUid similarly before comparing.
- int32_t loggerUid = mUidMap->getHostUidOrSelf(event.GetUid());
- if (loggerUid != appHookUid && loggerUid != AID_STATSD) {
- VLOG("APP_BREADCRUMB_REPORTED has invalid uid: claimed %ld but caller is %d",
- appHookUid, loggerUid);
- return false;
- }
-
- // The state must be from 0,3. This part of code must be manually updated.
- long appHookState = event.GetLong(event.size(), &err);
- if (err != NO_ERROR) {
- VLOG("APP_BREADCRUMB_REPORTED had error when parsing the state field");
- return false;
- } else if (appHookState < 0 || appHookState > 3) {
- VLOG("APP_BREADCRUMB_REPORTED does not have valid state %ld", appHookState);
- return false;
- }
- } else if (event.GetTagId() == util::DAVEY_OCCURRED) {
- // Daveys can be logged from any app since they are logged in libs/hwui/JankTracker.cpp.
- // Check that the davey duration is reasonable. Max length check is for privacy.
- status_t err = NO_ERROR;
-
- // Uid is the first field provided.
- long jankUid = event.GetLong(1, &err);
- if (err != NO_ERROR) {
- VLOG("Davey occurred had error when parsing the uid");
- return false;
- }
- int32_t loggerUid = event.GetUid();
- if (loggerUid != jankUid && loggerUid != AID_STATSD) {
- VLOG("DAVEY_OCCURRED has invalid uid: claimed %ld but caller is %d", jankUid,
- loggerUid);
- return false;
- }
-
- long duration = event.GetLong(event.size(), &err);
- if (err != NO_ERROR) {
- VLOG("Davey occurred had error when parsing the duration");
- return false;
- } else if (duration > 100000) {
- VLOG("Davey duration is unreasonably long: %ld", duration);
- return false;
- }
- }
-
- return true;
-}
-
-// Consume the stats log if it's interesting to this metric.
-void MetricsManager::onLogEvent(const LogEvent& event) {
- if (!mConfigValid) {
- return;
- }
-
- if (!checkLogCredentials(event)) {
- return;
- }
-
- if (!eventSanityCheck(event)) {
- return;
- }
-
- int tagId = event.GetTagId();
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
-
- bool isActive = mIsAlwaysActive;
-
- // Set of metrics that are still active after flushing.
- unordered_set<int> activeMetricsIndices;
-
- // Update state of all metrics w/ activation conditions as of eventTimeNs.
- for (int metricIndex : mMetricIndexesWithActivation) {
- const sp<MetricProducer>& metric = mAllMetricProducers[metricIndex];
- metric->flushIfExpire(eventTimeNs);
- if (metric->isActive()) {
- // If this metric w/ activation condition is still active after
- // flushing, remember it.
- activeMetricsIndices.insert(metricIndex);
- }
- }
-
- mIsActive = isActive || !activeMetricsIndices.empty();
-
- if (mTagIds.find(tagId) == mTagIds.end()) {
- // Not interesting...
- return;
- }
-
- vector<MatchingState> matcherCache(mAllAtomMatchers.size(), MatchingState::kNotComputed);
-
- // Evaluate all atom matchers.
- for (auto& matcher : mAllAtomMatchers) {
- matcher->onLogEvent(event, mAllAtomMatchers, matcherCache);
- }
-
- // Set of metrics that received an activation cancellation.
- unordered_set<int> metricIndicesWithCanceledActivations;
-
- // Determine which metric activations received a cancellation and cancel them.
- for (const auto& it : mDeactivationAtomTrackerToMetricMap) {
- if (matcherCache[it.first] == MatchingState::kMatched) {
- for (int metricIndex : it.second) {
- mAllMetricProducers[metricIndex]->cancelEventActivation(it.first);
- metricIndicesWithCanceledActivations.insert(metricIndex);
- }
- }
- }
-
- // Determine whether any metrics are no longer active after cancelling metric activations.
- for (const int metricIndex : metricIndicesWithCanceledActivations) {
- const sp<MetricProducer>& metric = mAllMetricProducers[metricIndex];
- metric->flushIfExpire(eventTimeNs);
- if (!metric->isActive()) {
- activeMetricsIndices.erase(metricIndex);
- }
- }
-
- isActive |= !activeMetricsIndices.empty();
-
-
- // Determine which metric activations should be turned on and turn them on
- for (const auto& it : mActivationAtomTrackerToMetricMap) {
- if (matcherCache[it.first] == MatchingState::kMatched) {
- for (int metricIndex : it.second) {
- mAllMetricProducers[metricIndex]->activate(it.first, eventTimeNs);
- isActive |= mAllMetricProducers[metricIndex]->isActive();
- }
- }
- }
-
- mIsActive = isActive;
-
- // A bitmap to see which ConditionTracker needs to be re-evaluated.
- vector<bool> conditionToBeEvaluated(mAllConditionTrackers.size(), false);
-
- for (const auto& pair : mTrackerToConditionMap) {
- if (matcherCache[pair.first] == MatchingState::kMatched) {
- const auto& conditionList = pair.second;
- for (const int conditionIndex : conditionList) {
- conditionToBeEvaluated[conditionIndex] = true;
- }
- }
- }
-
- vector<ConditionState> conditionCache(mAllConditionTrackers.size(),
- ConditionState::kNotEvaluated);
- // A bitmap to track if a condition has changed value.
- vector<bool> changedCache(mAllConditionTrackers.size(), false);
- for (size_t i = 0; i < mAllConditionTrackers.size(); i++) {
- if (conditionToBeEvaluated[i] == false) {
- continue;
- }
- sp<ConditionTracker>& condition = mAllConditionTrackers[i];
- condition->evaluateCondition(event, matcherCache, mAllConditionTrackers, conditionCache,
- changedCache);
- }
-
- for (size_t i = 0; i < mAllConditionTrackers.size(); i++) {
- if (changedCache[i] == false) {
- continue;
- }
- auto pair = mConditionToMetricMap.find(i);
- if (pair != mConditionToMetricMap.end()) {
- auto& metricList = pair->second;
- for (auto metricIndex : metricList) {
- // Metric cares about non sliced condition, and it's changed.
- // Push the new condition to it directly.
- if (!mAllMetricProducers[metricIndex]->isConditionSliced()) {
- mAllMetricProducers[metricIndex]->onConditionChanged(conditionCache[i],
- eventTimeNs);
- // Metric cares about sliced conditions, and it may have changed. Send
- // notification, and the metric can query the sliced conditions that are
- // interesting to it.
- } else {
- mAllMetricProducers[metricIndex]->onSlicedConditionMayChange(conditionCache[i],
- eventTimeNs);
- }
- }
- }
- }
-
- // For matched AtomMatchers, tell relevant metrics that a matched event has come.
- for (size_t i = 0; i < mAllAtomMatchers.size(); i++) {
- if (matcherCache[i] == MatchingState::kMatched) {
- StatsdStats::getInstance().noteMatcherMatched(mConfigKey,
- mAllAtomMatchers[i]->getId());
- auto pair = mTrackerToMetricMap.find(i);
- if (pair != mTrackerToMetricMap.end()) {
- auto& metricList = pair->second;
- for (const int metricIndex : metricList) {
- // pushed metrics are never scheduled pulls
- mAllMetricProducers[metricIndex]->onMatchedLogEvent(i, event);
- }
- }
- }
- }
-}
-
-void MetricsManager::onAnomalyAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
- for (const auto& itr : mAllAnomalyTrackers) {
- itr->informAlarmsFired(timestampNs, alarmSet);
- }
-}
-
-void MetricsManager::onPeriodicAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
- for (const auto& itr : mAllPeriodicAlarmTrackers) {
- itr->informAlarmsFired(timestampNs, alarmSet);
- }
-}
-
-// Returns the total byte size of all metrics managed by a single config source.
-size_t MetricsManager::byteSize() {
- size_t totalSize = 0;
- for (const auto& metricProducer : mAllMetricProducers) {
- totalSize += metricProducer->byteSize();
- }
- return totalSize;
-}
-
-void MetricsManager::loadActiveConfig(const ActiveConfig& config, int64_t currentTimeNs) {
- if (config.metric_size() == 0) {
- ALOGW("No active metric for config %s", mConfigKey.ToString().c_str());
- return;
- }
-
- for (int i = 0; i < config.metric_size(); i++) {
- const auto& activeMetric = config.metric(i);
- for (int metricIndex : mMetricIndexesWithActivation) {
- const auto& metric = mAllMetricProducers[metricIndex];
- if (metric->getMetricId() == activeMetric.id()) {
- VLOG("Setting active metric: %lld", (long long)metric->getMetricId());
- metric->loadActiveMetric(activeMetric, currentTimeNs);
- if (!mIsActive && metric->isActive()) {
- StatsdStats::getInstance().noteActiveStatusChanged(mConfigKey,
- /*activate=*/ true);
- }
- mIsActive |= metric->isActive();
- }
- }
- }
-}
-
-void MetricsManager::writeActiveConfigToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_CONFIG_ID, (long long)mConfigKey.GetId());
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVE_CONFIG_UID, mConfigKey.GetUid());
- for (int metricIndex : mMetricIndexesWithActivation) {
- const auto& metric = mAllMetricProducers[metricIndex];
- const uint64_t metricToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ACTIVE_CONFIG_METRIC);
- metric->writeActiveMetricToProtoOutputStream(currentTimeNs, reason, proto);
- proto->end(metricToken);
- }
-}
-
-bool MetricsManager::writeMetadataToProto(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadata* statsMetadata) {
- bool metadataWritten = false;
- metadata::ConfigKey* configKey = statsMetadata->mutable_config_key();
- configKey->set_config_id(mConfigKey.GetId());
- configKey->set_uid(mConfigKey.GetUid());
- for (const auto& anomalyTracker : mAllAnomalyTrackers) {
- metadata::AlertMetadata* alertMetadata = statsMetadata->add_alert_metadata();
- bool alertWritten = anomalyTracker->writeAlertMetadataToProto(currentWallClockTimeNs,
- systemElapsedTimeNs, alertMetadata);
- if (!alertWritten) {
- statsMetadata->mutable_alert_metadata()->RemoveLast();
- }
- metadataWritten |= alertWritten;
- }
- return metadataWritten;
-}
-
-void MetricsManager::loadMetadata(const metadata::StatsMetadata& metadata,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- for (const metadata::AlertMetadata& alertMetadata : metadata.alert_metadata()) {
- int64_t alertId = alertMetadata.alert_id();
- auto it = mAlertTrackerMap.find(alertId);
- if (it == mAlertTrackerMap.end()) {
- ALOGE("No anomalyTracker found for alertId %lld", (long long) alertId);
- continue;
- }
- mAllAnomalyTrackers[it->second]->loadAlertMetadata(alertMetadata,
- currentWallClockTimeNs,
- systemElapsedTimeNs);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
deleted file mode 100644
index ad30a88..0000000
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "anomaly/AlarmMonitor.h"
-#include "anomaly/AlarmTracker.h"
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionTracker.h"
-#include "config/ConfigKey.h"
-#include "external/StatsPullerManager.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"
-#include "logd/LogEvent.h"
-#include "matchers/LogMatchingTracker.h"
-#include "metrics/MetricProducer.h"
-#include "packages/UidMap.h"
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// A MetricsManager is responsible for managing metrics from one single config source.
-class MetricsManager : public virtual android::RefBase, public virtual PullUidProvider {
-public:
- MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, const int64_t timeBaseNs,
- const int64_t currentTimeNs, const sp<UidMap>& uidMap,
- const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& periodicAlarmMonitor);
-
- virtual ~MetricsManager();
-
- // Return whether the configuration is valid.
- bool isConfigValid() const;
-
- bool checkLogCredentials(const LogEvent& event);
-
- bool eventSanityCheck(const LogEvent& event);
-
- void onLogEvent(const LogEvent& event);
-
- void onAnomalyAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
-
- void onPeriodicAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
-
- void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
- const int64_t version);
-
- void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid);
-
- void onUidMapReceived(const int64_t& eventTimeNs);
-
- void onStatsdInitCompleted(const int64_t& elapsedTimeNs);
-
- void init();
-
- vector<int32_t> getPullAtomUids(int32_t atomId) override;
-
- bool shouldWriteToDisk() const {
- return mNoReportMetricIds.size() != mAllMetricProducers.size();
- }
-
- bool shouldPersistLocalHistory() const {
- return mShouldPersistHistory;
- }
-
- void dumpStates(FILE* out, bool verbose);
-
- inline bool isInTtl(const int64_t timestampNs) const {
- return mTtlNs <= 0 || timestampNs < mTtlEndNs;
- };
-
- inline bool hashStringInReport() const {
- return mHashStringsInReport;
- };
-
- inline bool versionStringsInReport() const {
- return mVersionStringsInReport;
- };
-
- inline bool installerInReport() const {
- return mInstallerInReport;
- };
-
- void refreshTtl(const int64_t currentTimestampNs) {
- if (mTtlNs > 0) {
- mTtlEndNs = currentTimestampNs + mTtlNs;
- }
- };
-
- // Returns the elapsed realtime when this metric manager last reported metrics. If this config
- // has not yet dumped any reports, this is the time the metricsmanager was initialized.
- inline int64_t getLastReportTimeNs() const {
- return mLastReportTimeNs;
- };
-
- inline int64_t getLastReportWallClockNs() const {
- return mLastReportWallClockNs;
- };
-
- inline size_t getNumMetrics() const {
- return mAllMetricProducers.size();
- }
-
- virtual void dropData(const int64_t dropTimeNs);
-
- virtual void onDumpReport(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput);
-
- // Computes the total byte size of all metrics managed by a single config source.
- // Does not change the state.
- virtual size_t byteSize();
-
- // Returns whether or not this config is active.
- // The config is active if any metric in the config is active.
- inline bool isActive() const {
- return mIsActive;
- }
-
- void loadActiveConfig(const ActiveConfig& config, int64_t currentTimeNs);
-
- void writeActiveConfigToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
- // Returns true if at least one piece of metadata is written.
- bool writeMetadataToProto(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadata* statsMetadata);
-
- void loadMetadata(const metadata::StatsMetadata& metadata,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs);
-private:
- // For test only.
- inline int64_t getTtlEndNs() const { return mTtlEndNs; }
-
- const ConfigKey mConfigKey;
-
- sp<UidMap> mUidMap;
-
- bool mConfigValid = false;
-
- bool mHashStringsInReport = false;
- bool mVersionStringsInReport = false;
- bool mInstallerInReport = false;
-
- const int64_t mTtlNs;
- int64_t mTtlEndNs;
-
- int64_t mLastReportTimeNs;
- int64_t mLastReportWallClockNs;
-
- sp<StatsPullerManager> mPullerManager;
-
- // The uid log sources from StatsdConfig.
- std::vector<int32_t> mAllowedUid;
-
- // The pkg log sources from StatsdConfig.
- std::vector<std::string> mAllowedPkg;
-
- // The combined uid sources (after translating pkg name to uid).
- // Logs from uids that are not in the list will be ignored to avoid spamming.
- std::set<int32_t> mAllowedLogSources;
-
- // To guard access to mAllowedLogSources
- mutable std::mutex mAllowedLogSourcesMutex;
-
- const std::set<int32_t> mWhitelistedAtomIds;
-
- // We can pull any atom from these uids.
- std::set<int32_t> mDefaultPullUids;
-
- // Uids that specific atoms can pull from.
- // This is a map<atom id, set<uids>>
- std::map<int32_t, std::set<int32_t>> mPullAtomUids;
-
- // Packages that specific atoms can be pulled from.
- std::map<int32_t, std::set<std::string>> mPullAtomPackages;
-
- // All uids to pull for this atom. NOTE: Does not include the default uids for memory.
- std::map<int32_t, std::set<int32_t>> mCombinedPullAtomUids;
-
- // Contains the annotations passed in with StatsdConfig.
- std::list<std::pair<const int64_t, const int32_t>> mAnnotations;
-
- const bool mShouldPersistHistory;
-
-
- // All event tags that are interesting to my metrics.
- std::set<int> mTagIds;
-
- // We only store the sp of LogMatchingTracker, MetricProducer, and ConditionTracker in
- // MetricsManager. There are relationships between them, and the relationships are denoted by
- // index instead of pointers. The reasons for this are: (1) the relationship between them are
- // complicated, so storing index instead of pointers reduces the risk that A holds B's sp, and B
- // holds A's sp. (2) When we evaluate matcher results, or condition results, we can quickly get
- // the related results from a cache using the index.
-
- // Hold all the atom matchers from the config.
- std::vector<sp<LogMatchingTracker>> mAllAtomMatchers;
-
- // Hold all the conditions from the config.
- std::vector<sp<ConditionTracker>> mAllConditionTrackers;
-
- // Hold all metrics from the config.
- std::vector<sp<MetricProducer>> mAllMetricProducers;
-
- // Hold all alert trackers.
- std::vector<sp<AnomalyTracker>> mAllAnomalyTrackers;
-
- // Hold all periodic alarm trackers.
- std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers;
-
- // To make the log processing more efficient, we want to do as much filtering as possible
- // before we go into individual trackers and conditions to match.
-
- // 1st filter: check if the event tag id is in mTagIds.
- // 2nd filter: if it is, we parse the event because there is at least one member is interested.
- // then pass to all LogMatchingTrackers (itself also filter events by ids).
- // 3nd filter: for LogMatchingTrackers that matched this event, we pass this event to the
- // ConditionTrackers and MetricProducers that use this matcher.
- // 4th filter: for ConditionTrackers that changed value due to this event, we pass
- // new conditions to metrics that use this condition.
-
- // The following map is initialized from the statsd_config.
-
- // Maps from the index of the LogMatchingTracker to index of MetricProducer.
- std::unordered_map<int, std::vector<int>> mTrackerToMetricMap;
-
- // Maps from LogMatchingTracker to ConditionTracker
- std::unordered_map<int, std::vector<int>> mTrackerToConditionMap;
-
- // Maps from ConditionTracker to MetricProducer
- std::unordered_map<int, std::vector<int>> mConditionToMetricMap;
-
- // Maps from life span triggering event to MetricProducers.
- std::unordered_map<int, std::vector<int>> mActivationAtomTrackerToMetricMap;
-
- // Maps deactivation triggering event to MetricProducers.
- std::unordered_map<int, std::vector<int>> mDeactivationAtomTrackerToMetricMap;
-
- // Maps AlertIds to the index of the corresponding AnomalyTracker stored in mAllAnomalyTrackers.
- // The map is used in LoadMetadata to more efficiently lookup AnomalyTrackers from an AlertId.
- std::unordered_map<int64_t, int> mAlertTrackerMap;
-
- std::vector<int> mMetricIndexesWithActivation;
-
- void initLogSourceWhiteList();
-
- void initPullAtomSources();
-
- // The metrics that don't need to be uploaded or even reported.
- std::set<int64_t> mNoReportMetricIds;
-
- // The config is active if any metric in the config is active.
- bool mIsActive;
-
- // The config is always active if any metric in the config does not have an activation signal.
- bool mIsAlwaysActive;
-
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions);
- FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks);
- FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
- FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
- FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition);
- FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents);
-
- FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_load_refractory_from_disk);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-
- FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
- FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
-
- FRIEND_TEST(MetricsManagerTest, TestLogSources);
-
- FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
- FRIEND_TEST(StatsLogProcessorTest,
- TestActivationOnBootMultipleActivationsDifferentActivationTypes);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
-
- FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
- FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
-
- FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
- FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
- FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSuperset);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
-
- FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
deleted file mode 100644
index 5987a72..0000000
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ /dev/null
@@ -1,1156 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "ValueMetricProducer.h"
-#include "../guardrail/StatsdStats.h"
-#include "../stats_log_util.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_DOUBLE;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::shared_ptr;
-using std::unordered_map;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_VALUE_METRICS = 7;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for ValueMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-const int FIELD_ID_SKIPPED = 2;
-// for SkippedBuckets
-const int FIELD_ID_SKIPPED_START_MILLIS = 3;
-const int FIELD_ID_SKIPPED_END_MILLIS = 4;
-const int FIELD_ID_SKIPPED_DROP_EVENT = 5;
-// for DumpEvent Proto
-const int FIELD_ID_BUCKET_DROP_REASON = 1;
-const int FIELD_ID_DROP_TIME = 2;
-// for ValueMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-const int FIELD_ID_SLICE_BY_STATE = 6;
-// for ValueBucketInfo
-const int FIELD_ID_VALUE_INDEX = 1;
-const int FIELD_ID_VALUE_LONG = 2;
-const int FIELD_ID_VALUE_DOUBLE = 3;
-const int FIELD_ID_VALUES = 9;
-const int FIELD_ID_BUCKET_NUM = 4;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
-const int FIELD_ID_CONDITION_TRUE_NS = 10;
-
-const Value ZERO_LONG((int64_t)0);
-const Value ZERO_DOUBLE((int64_t)0);
-
-// ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently
-ValueMetricProducer::ValueMetricProducer(
- const ConfigKey& key, const ValueMetric& metric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache,
- const sp<ConditionWizard>& conditionWizard, const int whatMatcherIndex,
- const sp<EventMatcherWizard>& matcherWizard, const int pullTagId, const int64_t timeBaseNs,
- const int64_t startTimeNs, const sp<StatsPullerManager>& pullerManager,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
- : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache,
- conditionWizard, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
- stateGroupMap),
- mWhatMatcherIndex(whatMatcherIndex),
- mEventMatcherWizard(matcherWizard),
- mPullerManager(pullerManager),
- mPullTagId(pullTagId),
- mIsPulled(pullTagId != -1),
- mMinBucketSizeNs(metric.min_bucket_size_nanos()),
- mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
- StatsdStats::kAtomDimensionKeySizeLimitMap.end()
- ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).first
- : StatsdStats::kDimensionKeySizeSoftLimit),
- mDimensionHardLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
- StatsdStats::kAtomDimensionKeySizeLimitMap.end()
- ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second
- : StatsdStats::kDimensionKeySizeHardLimit),
- mUseAbsoluteValueOnReset(metric.use_absolute_value_on_reset()),
- mAggregationType(metric.aggregation_type()),
- mUseDiff(metric.has_use_diff() ? metric.use_diff() : (mIsPulled ? true : false)),
- mValueDirection(metric.value_direction()),
- mSkipZeroDiffOutput(metric.skip_zero_diff_output()),
- mUseZeroDefaultBase(metric.use_zero_default_base()),
- mHasGlobalBase(false),
- mCurrentBucketIsSkipped(false),
- mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC
- : StatsdStats::kPullMaxDelayNs),
- mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()),
- // Condition timer will be set later within the constructor after pulling events
- mConditionTimer(false, timeBaseNs) {
- int64_t bucketSizeMills = 0;
- if (metric.has_bucket()) {
- bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
- } else {
- bucketSizeMills = TimeUnitToBucketSizeInMillis(ONE_HOUR);
- }
-
- mBucketSizeNs = bucketSizeMills * 1000000;
-
- translateFieldMatcher(metric.value_field(), &mFieldMatchers);
-
- if (metric.has_dimensions_in_what()) {
- translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
- mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
- }
-
- if (metric.links().size() > 0) {
- for (const auto& link : metric.links()) {
- Metric2Condition mc;
- mc.conditionId = link.condition();
- translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
- translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
- mMetric2ConditionLinks.push_back(mc);
- }
- mConditionSliced = true;
- }
-
- for (const auto& stateLink : metric.state_link()) {
- Metric2State ms;
- ms.stateAtomId = stateLink.state_atom_id();
- translateFieldMatcher(stateLink.fields_in_what(), &ms.metricFields);
- translateFieldMatcher(stateLink.fields_in_state(), &ms.stateFields);
- mMetric2StateLinks.push_back(ms);
- }
-
- int64_t numBucketsForward = calcBucketsForwardCount(startTimeNs);
- mCurrentBucketNum += numBucketsForward;
-
- flushIfNeededLocked(startTimeNs);
-
- if (mIsPulled) {
- mPullerManager->RegisterReceiver(mPullTagId, mConfigKey, this, getCurrentBucketEndTimeNs(),
- mBucketSizeNs);
- }
-
- // Only do this for partial buckets like first bucket. All other buckets should use
- // flushIfNeeded to adjust start and end to bucket boundaries.
- // Adjust start for partial bucket
- mCurrentBucketStartTimeNs = startTimeNs;
- mConditionTimer.newBucketStart(mCurrentBucketStartTimeNs);
-
- // Now that activations are processed, start the condition timer if needed.
- mConditionTimer.onConditionChanged(mIsActive && mCondition == ConditionState::kTrue,
- mCurrentBucketStartTimeNs);
-
- VLOG("value metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
- (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-ValueMetricProducer::~ValueMetricProducer() {
- VLOG("~ValueMetricProducer() called");
- if (mIsPulled) {
- mPullerManager->UnRegisterReceiver(mPullTagId, mConfigKey, this);
- }
-}
-
-void ValueMetricProducer::onStateChanged(int64_t eventTimeNs, int32_t atomId,
- const HashableDimensionKey& primaryKey,
- const FieldValue& oldState, const FieldValue& newState) {
- VLOG("ValueMetric %lld onStateChanged time %lld, State %d, key %s, %d -> %d",
- (long long)mMetricId, (long long)eventTimeNs, atomId, primaryKey.toString().c_str(),
- oldState.mValue.int_value, newState.mValue.int_value);
-
- // If old and new states are in the same StateGroup, then we do not need to
- // pull for this state change.
- FieldValue oldStateCopy = oldState;
- FieldValue newStateCopy = newState;
- mapStateValue(atomId, &oldStateCopy);
- mapStateValue(atomId, &newStateCopy);
- if (oldStateCopy == newStateCopy) {
- return;
- }
-
- // If condition is not true or metric is not active, we do not need to pull
- // for this state change.
- if (mCondition != ConditionState::kTrue || !mIsActive) {
- return;
- }
-
- bool isEventLate = eventTimeNs < mCurrentBucketStartTimeNs;
- if (isEventLate) {
- VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
- (long long)mCurrentBucketStartTimeNs);
- invalidateCurrentBucket(eventTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
- return;
- }
- mStateChangePrimaryKey.first = atomId;
- mStateChangePrimaryKey.second = primaryKey;
- if (mIsPulled) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- mStateChangePrimaryKey.first = 0;
- mStateChangePrimaryKey.second = DEFAULT_DIMENSION_KEY;
- flushIfNeededLocked(eventTimeNs);
-}
-
-void ValueMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTime) {
- VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-}
-
-void ValueMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
- StatsdStats::getInstance().noteBucketDropped(mMetricId);
-
- // The current partial bucket is not flushed and does not require a pull,
- // so the data is still valid.
- flushIfNeededLocked(dropTimeNs);
- clearPastBucketsLocked(dropTimeNs);
-}
-
-void ValueMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
- mPastBuckets.clear();
- mSkippedBuckets.clear();
-}
-
-void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- VLOG("metric %lld dump report now...", (long long)mMetricId);
- if (include_current_partial_bucket) {
- // For pull metrics, we need to do a pull at bucket boundaries. If we do not do that the
- // current bucket will have incomplete data and the next will have the wrong snapshot to do
- // a diff against. If the condition is false, we are fine since the base data is reset and
- // we are not tracking anything.
- bool pullNeeded = mIsPulled && mCondition == ConditionState::kTrue;
- if (pullNeeded) {
- switch (dumpLatency) {
- case FAST:
- invalidateCurrentBucket(dumpTimeNs, BucketDropReason::DUMP_REPORT_REQUESTED);
- break;
- case NO_TIME_CONSTRAINTS:
- pullAndMatchEventsLocked(dumpTimeNs);
- break;
- }
- }
- flushCurrentBucketLocked(dumpTimeNs, dumpTimeNs);
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
- if (mPastBuckets.empty() && mSkippedBuckets.empty()) {
- return;
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
- // Fills the dimension path if not slicing by ALL.
- if (!mSliceByPositionALL) {
- if (!mDimensionsInWhat.empty()) {
- uint64_t dimenPathToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
- writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
- protoOutput->end(dimenPathToken);
- }
- }
-
- uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_VALUE_METRICS);
-
- for (const auto& skippedBucket : mSkippedBuckets) {
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SKIPPED);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_START_MILLIS,
- (long long)(NanoToMillis(skippedBucket.bucketStartTimeNs)));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_END_MILLIS,
- (long long)(NanoToMillis(skippedBucket.bucketEndTimeNs)));
- for (const auto& dropEvent : skippedBucket.dropEvents) {
- uint64_t dropEventToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SKIPPED_DROP_EVENT);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_BUCKET_DROP_REASON, dropEvent.reason);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DROP_TIME,
- (long long)(NanoToMillis(dropEvent.dropTimeNs)));
- ;
- protoOutput->end(dropEventToken);
- }
- protoOutput->end(wrapperToken);
- }
-
- for (const auto& pair : mPastBuckets) {
- const MetricDimensionKey& dimensionKey = pair.first;
- VLOG(" dimension key %s", dimensionKey.toString().c_str());
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
- // First fill dimension.
- if (mSliceByPositionALL) {
- uint64_t dimensionToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
- protoOutput->end(dimensionToken);
- } else {
- writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
- FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
- }
-
- // Then fill slice_by_state.
- for (auto state : dimensionKey.getStateValuesKey().getValues()) {
- uint64_t stateToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SLICE_BY_STATE);
- writeStateToProto(state, protoOutput);
- protoOutput->end(stateToken);
- }
-
- // Then fill bucket_info (ValueBucketInfo).
- for (const auto& bucket : pair.second) {
- uint64_t bucketInfoToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
-
- if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketStartNs));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketEndNs));
- } else {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
- (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
- }
- // only write the condition timer value if the metric has a condition.
- if (mConditionTrackerIndex >= 0) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_TRUE_NS,
- (long long)bucket.mConditionTrueNs);
- }
- for (int i = 0; i < (int)bucket.valueIndex.size(); i++) {
- int index = bucket.valueIndex[i];
- const Value& value = bucket.values[i];
- uint64_t valueToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_VALUES);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_VALUE_INDEX,
- index);
- if (value.getType() == LONG) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_VALUE_LONG,
- (long long)value.long_value);
- VLOG("\t bucket [%lld - %lld] value %d: %lld", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, index, (long long)value.long_value);
- } else if (value.getType() == DOUBLE) {
- protoOutput->write(FIELD_TYPE_DOUBLE | FIELD_ID_VALUE_DOUBLE,
- value.double_value);
- VLOG("\t bucket [%lld - %lld] value %d: %.2f", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, index, value.double_value);
- } else {
- VLOG("Wrong value type for ValueMetric output: %d", value.getType());
- }
- protoOutput->end(valueToken);
- }
- protoOutput->end(bucketInfoToken);
- }
- protoOutput->end(wrapperToken);
- }
- protoOutput->end(protoToken);
-
- VLOG("metric %lld dump report now...", (long long)mMetricId);
- if (erase_data) {
- mPastBuckets.clear();
- mSkippedBuckets.clear();
- }
-}
-
-void ValueMetricProducer::invalidateCurrentBucketWithoutResetBase(const int64_t dropTimeNs,
- const BucketDropReason reason) {
- if (!mCurrentBucketIsSkipped) {
- // Only report to StatsdStats once per invalid bucket.
- StatsdStats::getInstance().noteInvalidatedBucket(mMetricId);
- }
-
- skipCurrentBucket(dropTimeNs, reason);
-}
-
-void ValueMetricProducer::invalidateCurrentBucket(const int64_t dropTimeNs,
- const BucketDropReason reason) {
- invalidateCurrentBucketWithoutResetBase(dropTimeNs, reason);
- resetBase();
-}
-
-void ValueMetricProducer::skipCurrentBucket(const int64_t dropTimeNs,
- const BucketDropReason reason) {
- if (!maxDropEventsReached()) {
- mCurrentSkippedBucket.dropEvents.emplace_back(buildDropEvent(dropTimeNs, reason));
- }
- mCurrentBucketIsSkipped = true;
-}
-
-void ValueMetricProducer::resetBase() {
- for (auto& slice : mCurrentBaseInfo) {
- for (auto& baseInfo : slice.second) {
- baseInfo.hasBase = false;
- }
- }
- mHasGlobalBase = false;
-}
-
-// Handle active state change. Active state change is treated like a condition change:
-// - drop bucket if active state change event arrives too late
-// - if condition is true, pull data on active state changes
-// - ConditionTimer tracks changes based on AND of condition and active state.
-void ValueMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
- bool isEventTooLate = eventTimeNs < mCurrentBucketStartTimeNs;
- if (isEventTooLate) {
- // Drop bucket because event arrived too late, ie. we are missing data for this bucket.
- StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
- invalidateCurrentBucket(eventTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
- }
-
- // Call parent method once we've verified the validity of current bucket.
- MetricProducer::onActiveStateChangedLocked(eventTimeNs);
-
- if (ConditionState::kTrue != mCondition) {
- return;
- }
-
- // Pull on active state changes.
- if (!isEventTooLate) {
- if (mIsPulled) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- // When active state changes from true to false, clear diff base but don't
- // reset other counters as we may accumulate more value in the bucket.
- if (mUseDiff && !mIsActive) {
- resetBase();
- }
- }
-
- flushIfNeededLocked(eventTimeNs);
-
- // Let condition timer know of new active state.
- mConditionTimer.onConditionChanged(mIsActive, eventTimeNs);
-}
-
-void ValueMetricProducer::onConditionChangedLocked(const bool condition,
- const int64_t eventTimeNs) {
- ConditionState newCondition = condition ? ConditionState::kTrue : ConditionState::kFalse;
- bool isEventTooLate = eventTimeNs < mCurrentBucketStartTimeNs;
-
- // If the config is not active, skip the event.
- if (!mIsActive) {
- mCondition = isEventTooLate ? ConditionState::kUnknown : newCondition;
- return;
- }
-
- // If the event arrived late, mark the bucket as invalid and skip the event.
- if (isEventTooLate) {
- VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
- (long long)mCurrentBucketStartTimeNs);
- StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
- StatsdStats::getInstance().noteConditionChangeInNextBucket(mMetricId);
- invalidateCurrentBucket(eventTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
- mCondition = ConditionState::kUnknown;
- mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
- return;
- }
-
- // If the previous condition was unknown, mark the bucket as invalid
- // because the bucket will contain partial data. For example, the condition
- // change might happen close to the end of the bucket and we might miss a
- // lot of data.
- //
- // We still want to pull to set the base.
- if (mCondition == ConditionState::kUnknown) {
- invalidateCurrentBucket(eventTimeNs, BucketDropReason::CONDITION_UNKNOWN);
- }
-
- // Pull and match for the following condition change cases:
- // unknown/false -> true - condition changed
- // true -> false - condition changed
- // true -> true - old condition was true so we can flush the bucket at the
- // end if needed.
- //
- // We don’t need to pull for unknown -> false or false -> false.
- //
- // onConditionChangedLocked might happen on bucket boundaries if this is
- // called before #onDataPulled.
- if (mIsPulled &&
- (newCondition == ConditionState::kTrue || mCondition == ConditionState::kTrue)) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
-
- // For metrics that use diff, when condition changes from true to false,
- // clear diff base but don't reset other counts because we may accumulate
- // more value in the bucket.
- if (mUseDiff &&
- (mCondition == ConditionState::kTrue && newCondition == ConditionState::kFalse)) {
- resetBase();
- }
-
- // Update condition state after pulling.
- mCondition = newCondition;
-
- flushIfNeededLocked(eventTimeNs);
- mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
-}
-
-void ValueMetricProducer::prepareFirstBucketLocked() {
- // Kicks off the puller immediately if condition is true and diff based.
- if (mIsActive && mIsPulled && mCondition == ConditionState::kTrue && mUseDiff) {
- pullAndMatchEventsLocked(mCurrentBucketStartTimeNs);
- }
-}
-
-void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
- vector<std::shared_ptr<LogEvent>> allData;
- if (!mPullerManager->Pull(mPullTagId, mConfigKey, timestampNs, &allData)) {
- ALOGE("Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
- invalidateCurrentBucket(timestampNs, BucketDropReason::PULL_FAILED);
- return;
- }
-
- accumulateEvents(allData, timestampNs, timestampNs);
-}
-
-int64_t ValueMetricProducer::calcPreviousBucketEndTime(const int64_t currentTimeNs) {
- return mTimeBaseNs + ((currentTimeNs - mTimeBaseNs) / mBucketSizeNs) * mBucketSizeNs;
-}
-
-// By design, statsd pulls data at bucket boundaries using AlarmManager. These pulls are likely
-// to be delayed. Other events like condition changes or app upgrade which are not based on
-// AlarmManager might have arrived earlier and close the bucket.
-void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData,
- bool pullSuccess, int64_t originalPullTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (mCondition == ConditionState::kTrue) {
- // If the pull failed, we won't be able to compute a diff.
- if (!pullSuccess) {
- invalidateCurrentBucket(originalPullTimeNs, BucketDropReason::PULL_FAILED);
- } else {
- bool isEventLate = originalPullTimeNs < getCurrentBucketEndTimeNs();
- if (isEventLate) {
- // If the event is late, we are in the middle of a bucket. Just
- // process the data without trying to snap the data to the nearest bucket.
- accumulateEvents(allData, originalPullTimeNs, originalPullTimeNs);
- } else {
- // For scheduled pulled data, the effective event time is snap to the nearest
- // bucket end. In the case of waking up from a deep sleep state, we will
- // attribute to the previous bucket end. If the sleep was long but not very
- // long, we will be in the immediate next bucket. Previous bucket may get a
- // larger number as we pull at a later time than real bucket end.
- //
- // If the sleep was very long, we skip more than one bucket before sleep. In
- // this case, if the diff base will be cleared and this new data will serve as
- // new diff base.
- int64_t bucketEndTime = calcPreviousBucketEndTime(originalPullTimeNs) - 1;
- StatsdStats::getInstance().noteBucketBoundaryDelayNs(
- mMetricId, originalPullTimeNs - bucketEndTime);
- accumulateEvents(allData, originalPullTimeNs, bucketEndTime);
- }
- }
- }
-
- // We can probably flush the bucket. Since we used bucketEndTime when calling
- // #onMatchedLogEventInternalLocked, the current bucket will not have been flushed.
- flushIfNeededLocked(originalPullTimeNs);
-}
-
-void ValueMetricProducer::accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData,
- int64_t originalPullTimeNs, int64_t eventElapsedTimeNs) {
- bool isEventLate = eventElapsedTimeNs < mCurrentBucketStartTimeNs;
- if (isEventLate) {
- VLOG("Skip bucket end pull due to late arrival: %lld vs %lld",
- (long long)eventElapsedTimeNs, (long long)mCurrentBucketStartTimeNs);
- StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
- invalidateCurrentBucket(eventElapsedTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
- return;
- }
-
- const int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
- const int64_t pullDelayNs = elapsedRealtimeNs - originalPullTimeNs;
- StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
- if (pullDelayNs > mMaxPullDelayNs) {
- ALOGE("Pull finish too late for atom %d, longer than %lld", mPullTagId,
- (long long)mMaxPullDelayNs);
- StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId);
- // We are missing one pull from the bucket which means we will not have a complete view of
- // what's going on.
- invalidateCurrentBucket(eventElapsedTimeNs, BucketDropReason::PULL_DELAYED);
- return;
- }
-
- mMatchedMetricDimensionKeys.clear();
- for (const auto& data : allData) {
- LogEvent localCopy = data->makeCopy();
- if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) ==
- MatchingState::kMatched) {
- localCopy.setElapsedTimestampNs(eventElapsedTimeNs);
- onMatchedLogEventLocked(mWhatMatcherIndex, localCopy);
- }
- }
- // If a key that is:
- // 1. Tracked in mCurrentSlicedBucket and
- // 2. A superset of the current mStateChangePrimaryKey
- // was not found in the new pulled data (i.e. not in mMatchedDimensionInWhatKeys)
- // then we need to reset the base.
- for (auto& slice : mCurrentSlicedBucket) {
- const auto& whatKey = slice.first.getDimensionKeyInWhat();
- bool presentInPulledData =
- mMatchedMetricDimensionKeys.find(whatKey) != mMatchedMetricDimensionKeys.end();
- if (!presentInPulledData && whatKey.contains(mStateChangePrimaryKey.second)) {
- auto it = mCurrentBaseInfo.find(whatKey);
- for (auto& baseInfo : it->second) {
- baseInfo.hasBase = false;
- }
- }
- }
- mMatchedMetricDimensionKeys.clear();
- mHasGlobalBase = true;
-
- // If we reach the guardrail, we might have dropped some data which means the bucket is
- // incomplete.
- //
- // The base also needs to be reset. If we do not have the full data, we might
- // incorrectly compute the diff when mUseZeroDefaultBase is true since an existing key
- // might be missing from mCurrentSlicedBucket.
- if (hasReachedGuardRailLimit()) {
- invalidateCurrentBucket(eventElapsedTimeNs, BucketDropReason::DIMENSION_GUARDRAIL_REACHED);
- mCurrentSlicedBucket.clear();
- }
-}
-
-void ValueMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
- if (mCurrentSlicedBucket.size() == 0) {
- return;
- }
-
- fprintf(out, "ValueMetric %lld dimension size %lu\n", (long long)mMetricId,
- (unsigned long)mCurrentSlicedBucket.size());
- if (verbose) {
- for (const auto& it : mCurrentSlicedBucket) {
- for (const auto& interval : it.second) {
- fprintf(out, "\t(what)%s\t(states)%s (value)%s\n",
- it.first.getDimensionKeyInWhat().toString().c_str(),
- it.first.getStateValuesKey().toString().c_str(),
- interval.value.toString().c_str());
- }
- }
- }
-}
-
-bool ValueMetricProducer::hasReachedGuardRailLimit() const {
- return mCurrentSlicedBucket.size() >= mDimensionHardLimit;
-}
-
-bool ValueMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
- // ===========GuardRail==============
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentSlicedBucket.find(newKey) != mCurrentSlicedBucket.end()) {
- return false;
- }
- if (mCurrentSlicedBucket.size() > mDimensionSoftLimit - 1) {
- size_t newTupleCount = mCurrentSlicedBucket.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (hasReachedGuardRailLimit()) {
- ALOGE("ValueMetric %lld dropping data for dimension key %s", (long long)mMetricId,
- newKey.toString().c_str());
- StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
- return true;
- }
- }
-
- return false;
-}
-
-bool ValueMetricProducer::hitFullBucketGuardRailLocked(const MetricDimensionKey& newKey) {
- // ===========GuardRail==============
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentFullBucket.find(newKey) != mCurrentFullBucket.end()) {
- return false;
- }
- if (mCurrentFullBucket.size() > mDimensionSoftLimit - 1) {
- size_t newTupleCount = mCurrentFullBucket.size() + 1;
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > mDimensionHardLimit) {
- ALOGE("ValueMetric %lld dropping data for full bucket dimension key %s",
- (long long)mMetricId,
- newKey.toString().c_str());
- return true;
- }
- }
-
- return false;
-}
-
-bool getDoubleOrLong(const LogEvent& event, const Matcher& matcher, Value& ret) {
- for (const FieldValue& value : event.getValues()) {
- if (value.mField.matches(matcher)) {
- switch (value.mValue.type) {
- case INT:
- ret.setLong(value.mValue.int_value);
- break;
- case LONG:
- ret.setLong(value.mValue.long_value);
- break;
- case FLOAT:
- ret.setDouble(value.mValue.float_value);
- break;
- case DOUBLE:
- ret.setDouble(value.mValue.double_value);
- break;
- default:
- return false;
- break;
- }
- return true;
- }
- }
- return false;
-}
-
-void ValueMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) {
- auto whatKey = eventKey.getDimensionKeyInWhat();
- auto stateKey = eventKey.getStateValuesKey();
-
- // Skip this event if a state changed occurred for a different primary key.
- auto it = statePrimaryKeys.find(mStateChangePrimaryKey.first);
- // Check that both the atom id and the primary key are equal.
- if (it != statePrimaryKeys.end() && it->second != mStateChangePrimaryKey.second) {
- VLOG("ValueMetric skip event with primary key %s because state change primary key "
- "is %s",
- it->second.toString().c_str(), mStateChangePrimaryKey.second.toString().c_str());
- return;
- }
-
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
- if (eventTimeNs < mCurrentBucketStartTimeNs) {
- VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
- (long long)mCurrentBucketStartTimeNs);
- return;
- }
- mMatchedMetricDimensionKeys.insert(whatKey);
-
- if (!mIsPulled) {
- // We cannot flush without doing a pull first.
- flushIfNeededLocked(eventTimeNs);
- }
-
- // We should not accumulate the data for pushed metrics when the condition is false.
- bool shouldSkipForPushMetric = !mIsPulled && !condition;
- // For pulled metrics, there are two cases:
- // - to compute diffs, we need to process all the state changes
- // - for non-diffs metrics, we should ignore the data if the condition wasn't true. If we have a
- // state change from
- // + True -> True: we should process the data, it might be a bucket boundary
- // + True -> False: we als need to process the data.
- bool shouldSkipForPulledMetric = mIsPulled && !mUseDiff
- && mCondition != ConditionState::kTrue;
- if (shouldSkipForPushMetric || shouldSkipForPulledMetric) {
- VLOG("ValueMetric skip event because condition is false and we are not using diff (for "
- "pulled metric)");
- return;
- }
-
- if (hitGuardRailLocked(eventKey)) {
- return;
- }
-
- vector<BaseInfo>& baseInfos = mCurrentBaseInfo[whatKey];
- if (baseInfos.size() < mFieldMatchers.size()) {
- VLOG("Resizing number of intervals to %d", (int)mFieldMatchers.size());
- baseInfos.resize(mFieldMatchers.size());
- }
-
- for (BaseInfo& baseInfo : baseInfos) {
- if (!baseInfo.hasCurrentState) {
- baseInfo.currentState = getUnknownStateKey();
- baseInfo.hasCurrentState = true;
- }
- }
-
- // We need to get the intervals stored with the previous state key so we can
- // close these value intervals.
- const auto oldStateKey = baseInfos[0].currentState;
- vector<Interval>& intervals = mCurrentSlicedBucket[MetricDimensionKey(whatKey, oldStateKey)];
- if (intervals.size() < mFieldMatchers.size()) {
- VLOG("Resizing number of intervals to %d", (int)mFieldMatchers.size());
- intervals.resize(mFieldMatchers.size());
- }
-
- // We only use anomaly detection under certain cases.
- // N.B.: The anomaly detection cases were modified in order to fix an issue with value metrics
- // containing multiple values. We tried to retain all previous behaviour, but we are unsure the
- // previous behaviour was correct. At the time of the fix, anomaly detection had no owner.
- // Whoever next works on it should look into the cases where it is triggered in this function.
- // Discussion here: http://ag/6124370.
- bool useAnomalyDetection = true;
-
- for (int i = 0; i < (int)mFieldMatchers.size(); i++) {
- const Matcher& matcher = mFieldMatchers[i];
- BaseInfo& baseInfo = baseInfos[i];
- Interval& interval = intervals[i];
- interval.valueIndex = i;
- Value value;
- baseInfo.hasCurrentState = true;
- baseInfo.currentState = stateKey;
- if (!getDoubleOrLong(event, matcher, value)) {
- VLOG("Failed to get value %d from event %s", i, event.ToString().c_str());
- StatsdStats::getInstance().noteBadValueType(mMetricId);
- return;
- }
- interval.seenNewData = true;
-
- if (mUseDiff) {
- if (!baseInfo.hasBase) {
- if (mHasGlobalBase && mUseZeroDefaultBase) {
- // The bucket has global base. This key does not.
- // Optionally use zero as base.
- baseInfo.base = (value.type == LONG ? ZERO_LONG : ZERO_DOUBLE);
- baseInfo.hasBase = true;
- } else {
- // no base. just update base and return.
- baseInfo.base = value;
- baseInfo.hasBase = true;
- // If we're missing a base, do not use anomaly detection on incomplete data
- useAnomalyDetection = false;
- // Continue (instead of return) here in order to set baseInfo.base and
- // baseInfo.hasBase for other baseInfos
- continue;
- }
- }
-
- Value diff;
- switch (mValueDirection) {
- case ValueMetric::INCREASING:
- if (value >= baseInfo.base) {
- diff = value - baseInfo.base;
- } else if (mUseAbsoluteValueOnReset) {
- diff = value;
- } else {
- VLOG("Unexpected decreasing value");
- StatsdStats::getInstance().notePullDataError(mPullTagId);
- baseInfo.base = value;
- // If we've got bad data, do not use anomaly detection
- useAnomalyDetection = false;
- continue;
- }
- break;
- case ValueMetric::DECREASING:
- if (baseInfo.base >= value) {
- diff = baseInfo.base - value;
- } else if (mUseAbsoluteValueOnReset) {
- diff = value;
- } else {
- VLOG("Unexpected increasing value");
- StatsdStats::getInstance().notePullDataError(mPullTagId);
- baseInfo.base = value;
- // If we've got bad data, do not use anomaly detection
- useAnomalyDetection = false;
- continue;
- }
- break;
- case ValueMetric::ANY:
- diff = value - baseInfo.base;
- break;
- default:
- break;
- }
- baseInfo.base = value;
- value = diff;
- }
-
- if (interval.hasValue) {
- switch (mAggregationType) {
- case ValueMetric::SUM:
- // for AVG, we add up and take average when flushing the bucket
- case ValueMetric::AVG:
- interval.value += value;
- break;
- case ValueMetric::MIN:
- interval.value = std::min(value, interval.value);
- break;
- case ValueMetric::MAX:
- interval.value = std::max(value, interval.value);
- break;
- default:
- break;
- }
- } else {
- interval.value = value;
- interval.hasValue = true;
- }
- interval.sampleSize += 1;
- }
-
- // Only trigger the tracker if all intervals are correct
- if (useAnomalyDetection) {
- // TODO: propgate proper values down stream when anomaly support doubles
- long wholeBucketVal = intervals[0].value.long_value;
- auto prev = mCurrentFullBucket.find(eventKey);
- if (prev != mCurrentFullBucket.end()) {
- wholeBucketVal += prev->second;
- }
- for (auto& tracker : mAnomalyTrackers) {
- tracker->detectAndDeclareAnomaly(eventTimeNs, mCurrentBucketNum, mMetricId, eventKey,
- wholeBucketVal);
- }
- }
-}
-
-// For pulled metrics, we always need to make sure we do a pull before flushing the bucket
-// if mCondition is true!
-void ValueMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
- int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
- if (eventTimeNs < currentBucketEndTimeNs) {
- VLOG("eventTime is %lld, less than current bucket end time %lld", (long long)eventTimeNs,
- (long long)(currentBucketEndTimeNs));
- return;
- }
- int64_t numBucketsForward = calcBucketsForwardCount(eventTimeNs);
- int64_t nextBucketStartTimeNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
- flushCurrentBucketLocked(eventTimeNs, nextBucketStartTimeNs);
-}
-
-int64_t ValueMetricProducer::calcBucketsForwardCount(const int64_t& eventTimeNs) const {
- int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
- if (eventTimeNs < currentBucketEndTimeNs) {
- return 0;
- }
- return 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
-}
-
-void ValueMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) {
- if (mCondition == ConditionState::kUnknown) {
- StatsdStats::getInstance().noteBucketUnknownCondition(mMetricId);
- invalidateCurrentBucketWithoutResetBase(eventTimeNs, BucketDropReason::CONDITION_UNKNOWN);
- }
-
- VLOG("finalizing bucket for %ld, dumping %d slices", (long)mCurrentBucketStartTimeNs,
- (int)mCurrentSlicedBucket.size());
-
- int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
- int64_t bucketEndTime = fullBucketEndTimeNs;
- int64_t numBucketsForward = calcBucketsForwardCount(eventTimeNs);
-
- // Skip buckets if this is a pulled metric or a pushed metric that is diffed.
- if (numBucketsForward > 1 && (mIsPulled || mUseDiff)) {
-
- VLOG("Skipping forward %lld buckets", (long long)numBucketsForward);
- StatsdStats::getInstance().noteSkippedForwardBuckets(mMetricId);
- // Something went wrong. Maybe the device was sleeping for a long time. It is better
- // to mark the current bucket as invalid. The last pull might have been successful through.
- invalidateCurrentBucketWithoutResetBase(eventTimeNs,
- BucketDropReason::MULTIPLE_BUCKETS_SKIPPED);
- // End the bucket at the next bucket start time so the entire interval is skipped.
- bucketEndTime = nextBucketStartTimeNs;
- } else if (eventTimeNs < fullBucketEndTimeNs) {
- bucketEndTime = eventTimeNs;
- }
-
- // Close the current bucket.
- int64_t conditionTrueDuration = mConditionTimer.newBucketStart(bucketEndTime);
- bool isBucketLargeEnough = bucketEndTime - mCurrentBucketStartTimeNs >= mMinBucketSizeNs;
- if (!isBucketLargeEnough) {
- skipCurrentBucket(eventTimeNs, BucketDropReason::BUCKET_TOO_SMALL);
- }
- if (!mCurrentBucketIsSkipped) {
- bool bucketHasData = false;
- // The current bucket is large enough to keep.
- for (const auto& slice : mCurrentSlicedBucket) {
- ValueBucket bucket = buildPartialBucket(bucketEndTime, slice.second);
- bucket.mConditionTrueNs = conditionTrueDuration;
- // it will auto create new vector of ValuebucketInfo if the key is not found.
- if (bucket.valueIndex.size() > 0) {
- auto& bucketList = mPastBuckets[slice.first];
- bucketList.push_back(bucket);
- bucketHasData = true;
- }
- }
- if (!bucketHasData) {
- skipCurrentBucket(eventTimeNs, BucketDropReason::NO_DATA);
- }
- }
-
- if (mCurrentBucketIsSkipped) {
- mCurrentSkippedBucket.bucketStartTimeNs = mCurrentBucketStartTimeNs;
- mCurrentSkippedBucket.bucketEndTimeNs = bucketEndTime;
- mSkippedBuckets.emplace_back(mCurrentSkippedBucket);
- }
-
- // This means that the current bucket was not flushed before a forced bucket split.
- // This can happen if an app update or a dump report with include_current_partial_bucket is
- // requested before we get a chance to flush the bucket due to receiving new data, either from
- // the statsd socket or the StatsPullerManager.
- if (bucketEndTime < nextBucketStartTimeNs) {
- SkippedBucket bucketInGap;
- bucketInGap.bucketStartTimeNs = bucketEndTime;
- bucketInGap.bucketEndTimeNs = nextBucketStartTimeNs;
- bucketInGap.dropEvents.emplace_back(
- buildDropEvent(eventTimeNs, BucketDropReason::NO_DATA));
- mSkippedBuckets.emplace_back(bucketInGap);
- }
-
- appendToFullBucket(eventTimeNs > fullBucketEndTimeNs);
- initCurrentSlicedBucket(nextBucketStartTimeNs);
- // Update the condition timer again, in case we skipped buckets.
- mConditionTimer.newBucketStart(nextBucketStartTimeNs);
- mCurrentBucketNum += numBucketsForward;
-}
-
-ValueBucket ValueMetricProducer::buildPartialBucket(int64_t bucketEndTime,
- const std::vector<Interval>& intervals) {
- ValueBucket bucket;
- bucket.mBucketStartNs = mCurrentBucketStartTimeNs;
- bucket.mBucketEndNs = bucketEndTime;
- for (const auto& interval : intervals) {
- if (interval.hasValue) {
- // skip the output if the diff is zero
- if (mSkipZeroDiffOutput && mUseDiff && interval.value.isZero()) {
- continue;
- }
- bucket.valueIndex.push_back(interval.valueIndex);
- if (mAggregationType != ValueMetric::AVG) {
- bucket.values.push_back(interval.value);
- } else {
- double sum = interval.value.type == LONG ? (double)interval.value.long_value
- : interval.value.double_value;
- bucket.values.push_back(Value((double)sum / interval.sampleSize));
- }
- }
- }
- return bucket;
-}
-
-void ValueMetricProducer::initCurrentSlicedBucket(int64_t nextBucketStartTimeNs) {
- StatsdStats::getInstance().noteBucketCount(mMetricId);
- // Cleanup data structure to aggregate values.
- for (auto it = mCurrentSlicedBucket.begin(); it != mCurrentSlicedBucket.end();) {
- bool obsolete = true;
- for (auto& interval : it->second) {
- interval.hasValue = false;
- interval.sampleSize = 0;
- if (interval.seenNewData) {
- obsolete = false;
- }
- interval.seenNewData = false;
- }
-
- if (obsolete) {
- it = mCurrentSlicedBucket.erase(it);
- } else {
- it++;
- }
- // TODO(b/157655103): remove mCurrentBaseInfo entries when obsolete
- }
-
- mCurrentBucketIsSkipped = false;
- mCurrentSkippedBucket.reset();
-
- // If we do not have a global base when the condition is true,
- // we will have incomplete bucket for the next bucket.
- if (mUseDiff && !mHasGlobalBase && mCondition) {
- mCurrentBucketIsSkipped = false;
- }
- mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
- VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
- (long long)mCurrentBucketStartTimeNs);
-}
-
-void ValueMetricProducer::appendToFullBucket(const bool isFullBucketReached) {
- if (mCurrentBucketIsSkipped) {
- if (isFullBucketReached) {
- // If the bucket is invalid, we ignore the full bucket since it contains invalid data.
- mCurrentFullBucket.clear();
- }
- // Current bucket is invalid, we do not add it to the full bucket.
- return;
- }
-
- if (isFullBucketReached) { // If full bucket, send to anomaly tracker.
- // Accumulate partial buckets with current value and then send to anomaly tracker.
- if (mCurrentFullBucket.size() > 0) {
- for (const auto& slice : mCurrentSlicedBucket) {
- if (hitFullBucketGuardRailLocked(slice.first)) {
- continue;
- }
- // TODO: fix this when anomaly can accept double values
- auto& interval = slice.second[0];
- if (interval.hasValue) {
- mCurrentFullBucket[slice.first] += interval.value.long_value;
- }
- }
- for (const auto& slice : mCurrentFullBucket) {
- for (auto& tracker : mAnomalyTrackers) {
- if (tracker != nullptr) {
- tracker->addPastBucket(slice.first, slice.second, mCurrentBucketNum);
- }
- }
- }
- mCurrentFullBucket.clear();
- } else {
- // Skip aggregating the partial buckets since there's no previous partial bucket.
- for (const auto& slice : mCurrentSlicedBucket) {
- for (auto& tracker : mAnomalyTrackers) {
- if (tracker != nullptr) {
- // TODO: fix this when anomaly can accept double values
- auto& interval = slice.second[0];
- if (interval.hasValue) {
- tracker->addPastBucket(slice.first, interval.value.long_value,
- mCurrentBucketNum);
- }
- }
- }
- }
- }
- } else {
- // Accumulate partial bucket.
- for (const auto& slice : mCurrentSlicedBucket) {
- // TODO: fix this when anomaly can accept double values
- auto& interval = slice.second[0];
- if (interval.hasValue) {
- mCurrentFullBucket[slice.first] += interval.value.long_value;
- }
- }
- }
-}
-
-size_t ValueMetricProducer::byteSizeLocked() const {
- size_t totalSize = 0;
- for (const auto& pair : mPastBuckets) {
- totalSize += pair.second.size() * kBucketSize;
- }
- return totalSize;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
deleted file mode 100644
index b359af7..0000000
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionTimer.h"
-#include "condition/ConditionTracker.h"
-#include "external/PullDataReceiver.h"
-#include "external/StatsPullerManager.h"
-#include "matchers/EventMatcherWizard.h"
-#include "stats_log_util.h"
-#include "MetricProducer.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct ValueBucket {
- int64_t mBucketStartNs;
- int64_t mBucketEndNs;
- std::vector<int> valueIndex;
- std::vector<Value> values;
- // If the metric has no condition, then this field is just wasted.
- // When we tune statsd memory usage in the future, this is a candidate to optimize.
- int64_t mConditionTrueNs;
-};
-
-
-// Aggregates values within buckets.
-//
-// There are different events that might complete a bucket
-// - a condition change
-// - an app upgrade
-// - an alarm set to the end of the bucket
-class ValueMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver {
-public:
- ValueMetricProducer(
- const ConfigKey& key, const ValueMetric& valueMetric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache,
- const sp<ConditionWizard>& conditionWizard, const int whatMatcherIndex,
- const sp<EventMatcherWizard>& matcherWizard, const int pullTagId,
- const int64_t timeBaseNs, const int64_t startTimeNs,
- const sp<StatsPullerManager>& pullerManager,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap = {},
- const vector<int>& slicedStateAtoms = {},
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
- virtual ~ValueMetricProducer();
-
- // Process data pulled on bucket boundary.
- void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
- bool pullSuccess, int64_t originalPullTimeNs) override;
-
- // ValueMetric needs special logic if it's a pulled atom.
- void notifyAppUpgrade(const int64_t& eventTimeNs) override {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mSplitBucketForAppUpgrade) {
- return;
- }
- if (mIsPulled && mCondition == ConditionState::kTrue) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
- };
-
- // ValueMetric needs special logic if it's a pulled atom.
- void onStatsdInitCompleted(const int64_t& eventTimeNs) override {
- std::lock_guard<std::mutex> lock(mMutex);
- if (mIsPulled && mCondition == ConditionState::kTrue) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
- };
-
- void onStateChanged(int64_t eventTimeNs, int32_t atomId, const HashableDimensionKey& primaryKey,
- const FieldValue& oldState, const FieldValue& newState) override;
-
-protected:
- void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
- void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) override;
- void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
- // Internal interface to handle active state change.
- void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
-
- // Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
- // Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
- // Internal function to calculate the current used bytes.
- size_t byteSizeLocked() const override;
-
- void dumpStatesLocked(FILE* out, bool verbose) const override;
-
- // For pulled metrics, this method should only be called if a pull has be done. Else we will
- // not have complete data for the bucket.
- void flushIfNeededLocked(const int64_t& eventTime) override;
-
- // For pulled metrics, this method should only be called if a pulled have be done. Else we will
- // not have complete data for the bucket.
- void flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) override;
-
- void prepareFirstBucketLocked() override;
-
- void dropDataLocked(const int64_t dropTimeNs) override;
-
- // Calculate previous bucket end time based on current time.
- int64_t calcPreviousBucketEndTime(const int64_t currentTimeNs);
-
- // Calculate how many buckets are present between the current bucket and eventTimeNs.
- int64_t calcBucketsForwardCount(const int64_t& eventTimeNs) const;
-
- // Mark the data as invalid.
- void invalidateCurrentBucket(const int64_t dropTimeNs, const BucketDropReason reason);
-
- void invalidateCurrentBucketWithoutResetBase(const int64_t dropTimeNs,
- const BucketDropReason reason);
-
- // Skips the current bucket without notifying StatsdStats of the skipped bucket.
- // This should only be called from #flushCurrentBucketLocked. Otherwise, a future event that
- // causes the bucket to be invalidated will not notify StatsdStats.
- void skipCurrentBucket(const int64_t dropTimeNs, const BucketDropReason reason);
-
- const int mWhatMatcherIndex;
-
- sp<EventMatcherWizard> mEventMatcherWizard;
-
- sp<StatsPullerManager> mPullerManager;
-
- // Value fields for matching.
- std::vector<Matcher> mFieldMatchers;
-
- // Value fields for matching.
- std::set<HashableDimensionKey> mMatchedMetricDimensionKeys;
-
- // Holds the atom id, primary key pair from a state change.
- pair<int32_t, HashableDimensionKey> mStateChangePrimaryKey;
-
- // tagId for pulled data. -1 if this is not pulled
- const int mPullTagId;
-
- // if this is pulled metric
- const bool mIsPulled;
-
- // internal state of an ongoing aggregation bucket.
- typedef struct {
- // Index in multi value aggregation.
- int valueIndex;
- // Current value, depending on the aggregation type.
- Value value;
- // Number of samples collected.
- int sampleSize;
- // If this dimension has any non-tainted value. If not, don't report the
- // dimension.
- bool hasValue = false;
- // Whether new data is seen in the bucket.
- bool seenNewData = false;
- } Interval;
-
- typedef struct {
- // Holds current base value of the dimension. Take diff and update if necessary.
- Value base;
- // Whether there is a base to diff to.
- bool hasBase;
- // Last seen state value(s).
- HashableDimensionKey currentState;
- // Whether this dimensions in what key has a current state key.
- bool hasCurrentState;
- } BaseInfo;
-
- std::unordered_map<MetricDimensionKey, std::vector<Interval>> mCurrentSlicedBucket;
-
- std::unordered_map<HashableDimensionKey, std::vector<BaseInfo>> mCurrentBaseInfo;
-
- std::unordered_map<MetricDimensionKey, int64_t> mCurrentFullBucket;
-
- // Save the past buckets and we can clear when the StatsLogReport is dumped.
- std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>> mPastBuckets;
-
- const int64_t mMinBucketSizeNs;
-
- // Util function to check whether the specified dimension hits the guardrail.
- bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
- bool hasReachedGuardRailLimit() const;
-
- bool hitFullBucketGuardRailLocked(const MetricDimensionKey& newKey);
-
- void pullAndMatchEventsLocked(const int64_t timestampNs);
-
- void accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData,
- int64_t originalPullTimeNs, int64_t eventElapsedTimeNs);
-
- ValueBucket buildPartialBucket(int64_t bucketEndTime,
- const std::vector<Interval>& intervals);
-
- void initCurrentSlicedBucket(int64_t nextBucketStartTimeNs);
-
- void appendToFullBucket(const bool isFullBucketReached);
-
- // Reset diff base and mHasGlobalBase
- void resetBase();
-
- static const size_t kBucketSize = sizeof(ValueBucket{});
-
- const size_t mDimensionSoftLimit;
-
- const size_t mDimensionHardLimit;
-
- const bool mUseAbsoluteValueOnReset;
-
- const ValueMetric::AggregationType mAggregationType;
-
- const bool mUseDiff;
-
- const ValueMetric::ValueDirection mValueDirection;
-
- const bool mSkipZeroDiffOutput;
-
- // If true, use a zero value as base to compute the diff.
- // This is used for new keys which are present in the new data but was not
- // present in the base data.
- // The default base will only be used if we have a global base.
- const bool mUseZeroDefaultBase;
-
- // For pulled metrics, this is always set to true whenever a pull succeeds.
- // It is set to false when a pull fails, or upon condition change to false.
- // This is used to decide if we have the right base data to compute the
- // diff against.
- bool mHasGlobalBase;
-
- // This is to track whether or not the bucket is skipped for any of the reasons listed in
- // BucketDropReason, many of which make the bucket potentially invalid.
- bool mCurrentBucketIsSkipped;
-
- const int64_t mMaxPullDelayNs;
-
- const bool mSplitBucketForAppUpgrade;
-
- ConditionTimer mConditionTimer;
-
- FRIEND_TEST(ValueMetricProducerTest, TestAnomalyDetection);
- FRIEND_TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet);
- FRIEND_TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime);
- FRIEND_TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged);
- FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary);
- FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged);
- FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled);
- FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestFirstBucket);
- FRIEND_TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff);
- FRIEND_TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff);
- FRIEND_TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsNoCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateAvg);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateMax);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateMin);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateSum);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate);
- FRIEND_TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput);
- FRIEND_TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue);
- FRIEND_TEST(ValueMetricProducerTest, TestSlicedState);
- FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithMap);
- FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions);
- FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey);
- FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBase);
- FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures);
-
- FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed);
- FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed);
- FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed);
- FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit);
- FRIEND_TEST(ValueMetricProducerTest_BucketDrop,
- TestInvalidBucketWhenAccumulateEventWrongBucket);
-
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestBucketBoundariesOnPartialBucket);
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestFullBucketResetWhenLastBucketInvalid);
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated);
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPushedEvents);
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValue);
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse);
-
- friend class ValueMetricProducerTestHelper;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
deleted file mode 100644
index 8d59d13..0000000
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DURATION_TRACKER_H
-#define DURATION_TRACKER_H
-
-#include "anomaly/DurationAnomalyTracker.h"
-#include "condition/ConditionWizard.h"
-#include "config/ConfigKey.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-enum DurationState {
- kStopped = 0, // The event is stopped.
- kStarted = 1, // The event is on going.
- kPaused = 2, // The event is started, but condition is false, clock is paused. When condition
- // turns to true, kPaused will become kStarted.
-};
-
-// Hold duration information for one atom level duration in current on-going bucket.
-struct DurationInfo {
- DurationState state;
-
- // the number of starts seen.
- int32_t startCount;
-
- // most recent start time.
- int64_t lastStartTime;
- // existing duration in current bucket.
- int64_t lastDuration;
- // cache the HashableDimensionKeys we need to query the condition for this duration event.
- ConditionKey conditionKeys;
-
- DurationInfo() : state(kStopped), startCount(0), lastStartTime(0), lastDuration(0){};
-};
-
-struct DurationBucket {
- int64_t mBucketStartNs;
- int64_t mBucketEndNs;
- int64_t mDuration;
-};
-
-struct DurationValues {
- // Recorded duration for current partial bucket.
- int64_t mDuration;
-
- // Sum of past partial bucket durations in current full bucket.
- // Used for anomaly detection.
- int64_t mDurationFullBucket;
-};
-
-class DurationTracker {
-public:
- DurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
- sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
- int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs,
- int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
- const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
- : mConfigKey(key),
- mTrackerId(id),
- mEventKey(eventKey),
- mWizard(wizard),
- mConditionTrackerIndex(conditionIndex),
- mBucketSizeNs(bucketSizeNs),
- mNested(nesting),
- mCurrentBucketStartTimeNs(currentBucketStartNs),
- mDuration(0),
- mCurrentBucketNum(currentBucketNum),
- mStartTimeNs(startTimeNs),
- mConditionSliced(conditionSliced),
- mHasLinksToAllConditionDimensionsInTracker(fullLink),
- mAnomalyTrackers(anomalyTrackers){};
-
- virtual ~DurationTracker(){};
-
- virtual void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
- const ConditionKey& conditionKey) = 0;
- virtual void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
- const bool stopAll) = 0;
- virtual void noteStopAll(const int64_t eventTime) = 0;
-
- virtual void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) = 0;
- virtual void onConditionChanged(bool condition, const int64_t timestamp) = 0;
-
- virtual void onStateChanged(const int64_t timestamp, const int32_t atomId,
- const FieldValue& newState) = 0;
-
- // Flush stale buckets if needed, and return true if the tracker has no on-going duration
- // events, so that the owner can safely remove the tracker.
- virtual bool flushIfNeeded(
- int64_t timestampNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) = 0;
-
- // Should only be called during an app upgrade or from this tracker's flushIfNeeded. If from
- // an app upgrade, we assume that we're trying to form a partial bucket.
- virtual bool flushCurrentBucket(
- const int64_t& eventTimeNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) = 0;
-
- // Predict the anomaly timestamp given the current status.
- virtual int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
- const int64_t currentTimestamp) const = 0;
- // Dump internal states for debugging
- virtual void dumpStates(FILE* out, bool verbose) const = 0;
-
- virtual int64_t getCurrentStateKeyDuration() const = 0;
-
- virtual int64_t getCurrentStateKeyFullBucketDuration() const = 0;
-
- // Replace old value with new value for the given state atom.
- virtual void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState) = 0;
-
-protected:
- int64_t getCurrentBucketEndTimeNs() const {
- return mStartTimeNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
- }
-
- // Starts the anomaly alarm.
- void startAnomalyAlarm(const int64_t eventTime) {
- for (auto& anomalyTracker : mAnomalyTrackers) {
- if (anomalyTracker != nullptr) {
- const int64_t alarmTimestampNs =
- predictAnomalyTimestampNs(*anomalyTracker, eventTime);
- if (alarmTimestampNs > 0) {
- anomalyTracker->startAlarm(mEventKey, alarmTimestampNs);
- }
- }
- }
- }
-
- // Stops the anomaly alarm. If it should have already fired, declare the anomaly now.
- void stopAnomalyAlarm(const int64_t timestamp) {
- for (auto& anomalyTracker : mAnomalyTrackers) {
- if (anomalyTracker != nullptr) {
- anomalyTracker->stopAlarm(mEventKey, timestamp);
- }
- }
- }
-
- void addPastBucketToAnomalyTrackers(const MetricDimensionKey eventKey,
- const int64_t& bucketValue, const int64_t& bucketNum) {
- for (auto& anomalyTracker : mAnomalyTrackers) {
- if (anomalyTracker != nullptr) {
- anomalyTracker->addPastBucket(eventKey, bucketValue, bucketNum);
- }
- }
- }
-
- void detectAndDeclareAnomaly(const int64_t& timestamp, const int64_t& currBucketNum,
- const int64_t& currentBucketValue) {
- for (auto& anomalyTracker : mAnomalyTrackers) {
- if (anomalyTracker != nullptr) {
- anomalyTracker->detectAndDeclareAnomaly(timestamp, currBucketNum, mTrackerId,
- mEventKey, currentBucketValue);
- }
- }
- }
-
- // Convenience to compute the current bucket's end time, which is always aligned with the
- // start time of the metric.
- int64_t getCurrentBucketEndTimeNs() {
- return mStartTimeNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
- }
-
- void setEventKey(const MetricDimensionKey& eventKey) {
- mEventKey = eventKey;
- }
-
- // A reference to the DurationMetricProducer's config key.
- const ConfigKey& mConfigKey;
-
- const int64_t mTrackerId;
-
- MetricDimensionKey mEventKey;
-
- sp<ConditionWizard> mWizard;
-
- const int mConditionTrackerIndex;
-
- const int64_t mBucketSizeNs;
-
- const bool mNested;
-
- int64_t mCurrentBucketStartTimeNs;
-
- int64_t mDuration; // current recorded duration result (for partial bucket)
-
- // Recorded duration results for each state key in the current partial bucket.
- std::unordered_map<HashableDimensionKey, DurationValues> mStateKeyDurationMap;
-
- int64_t mCurrentBucketNum;
-
- const int64_t mStartTimeNs;
-
- const bool mConditionSliced;
-
- bool mHasLinksToAllConditionDimensionsInTracker;
-
- std::vector<sp<DurationAnomalyTracker>> mAnomalyTrackers;
-
- FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // DURATION_TRACKER_H
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
deleted file mode 100644
index ee4e167..0000000
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false
-
-#include "Log.h"
-#include "MaxDurationTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-MaxDurationTracker::MaxDurationTracker(const ConfigKey& key, const int64_t& id,
- const MetricDimensionKey& eventKey,
- sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
- int64_t currentBucketStartNs, int64_t currentBucketNum,
- int64_t startTimeNs, int64_t bucketSizeNs,
- bool conditionSliced, bool fullLink,
- const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
- : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs,
- currentBucketNum, startTimeNs, bucketSizeNs, conditionSliced, fullLink,
- anomalyTrackers) {
-}
-
-bool MaxDurationTracker::hitGuardRail(const HashableDimensionKey& newKey) {
- // ===========GuardRail==============
- if (mInfos.find(newKey) != mInfos.end()) {
- // if the key existed, we are good!
- return false;
- }
- // 1. Report the tuple count if the tuple count > soft limit
- if (mInfos.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mInfos.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mTrackerId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("MaxDurTracker %lld dropping data for dimension key %s",
- (long long)mTrackerId, newKey.toString().c_str());
- return true;
- }
- }
- return false;
-}
-
-void MaxDurationTracker::noteStart(const HashableDimensionKey& key, bool condition,
- const int64_t eventTime, const ConditionKey& conditionKey) {
- // this will construct a new DurationInfo if this key didn't exist.
- if (hitGuardRail(key)) {
- return;
- }
-
- DurationInfo& duration = mInfos[key];
- if (mConditionSliced) {
- duration.conditionKeys = conditionKey;
- }
- VLOG("MaxDuration: key %s start condition %d", key.toString().c_str(), condition);
-
- switch (duration.state) {
- case kStarted:
- duration.startCount++;
- break;
- case kPaused:
- duration.startCount++;
- break;
- case kStopped:
- if (!condition) {
- // event started, but we need to wait for the condition to become true.
- duration.state = DurationState::kPaused;
- } else {
- duration.state = DurationState::kStarted;
- duration.lastStartTime = eventTime;
- startAnomalyAlarm(eventTime);
- }
- duration.startCount = 1;
- break;
- }
-}
-
-void MaxDurationTracker::noteStop(const HashableDimensionKey& key, const int64_t eventTime,
- bool forceStop) {
- VLOG("MaxDuration: key %s stop", key.toString().c_str());
- if (mInfos.find(key) == mInfos.end()) {
- // we didn't see a start event before. do nothing.
- return;
- }
- DurationInfo& duration = mInfos[key];
-
- switch (duration.state) {
- case DurationState::kStopped:
- // already stopped, do nothing.
- break;
- case DurationState::kStarted: {
- duration.startCount--;
- if (forceStop || !mNested || duration.startCount <= 0) {
- stopAnomalyAlarm(eventTime);
- duration.state = DurationState::kStopped;
- int64_t durationTime = eventTime - duration.lastStartTime;
- VLOG("Max, key %s, Stop %lld %lld %lld", key.toString().c_str(),
- (long long)duration.lastStartTime, (long long)eventTime,
- (long long)durationTime);
- duration.lastDuration += durationTime;
- if (anyStarted()) {
- // In case any other dimensions are still started, we need to keep the alarm
- // set.
- startAnomalyAlarm(eventTime);
- }
- VLOG(" record duration: %lld ", (long long)duration.lastDuration);
- }
- break;
- }
- case DurationState::kPaused: {
- duration.startCount--;
- if (forceStop || !mNested || duration.startCount <= 0) {
- duration.state = DurationState::kStopped;
- }
- break;
- }
- }
-
- if (duration.lastDuration > mDuration) {
- mDuration = duration.lastDuration;
- VLOG("Max: new max duration: %lld", (long long)mDuration);
- }
- // Once an atom duration ends, we erase it. Next time, if we see another atom event with the
- // same name, they are still considered as different atom durations.
- if (duration.state == DurationState::kStopped) {
- mInfos.erase(key);
- }
-}
-
-bool MaxDurationTracker::anyStarted() {
- for (auto& pair : mInfos) {
- if (pair.second.state == kStarted) {
- return true;
- }
- }
- return false;
-}
-
-void MaxDurationTracker::noteStopAll(const int64_t eventTime) {
- std::set<HashableDimensionKey> keys;
- for (const auto& pair : mInfos) {
- keys.insert(pair.first);
- }
- for (auto& key : keys) {
- noteStop(key, eventTime, true);
- }
-}
-
-bool MaxDurationTracker::flushCurrentBucket(
- const int64_t& eventTimeNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) {
- VLOG("MaxDurationTracker flushing.....");
-
- // adjust the bucket start time
- int numBucketsForward = 0;
- int64_t fullBucketEnd = getCurrentBucketEndTimeNs();
- int64_t currentBucketEndTimeNs;
- if (eventTimeNs >= fullBucketEnd) {
- numBucketsForward = 1 + (eventTimeNs - fullBucketEnd) / mBucketSizeNs;
- currentBucketEndTimeNs = fullBucketEnd;
- } else {
- // This must be a partial bucket.
- currentBucketEndTimeNs = eventTimeNs;
- }
-
- bool hasPendingEvent =
- false; // has either a kStarted or kPaused event across bucket boundaries
- // meaning we need to carry them over to the new bucket.
- for (auto it = mInfos.begin(); it != mInfos.end();) {
- if (it->second.state == DurationState::kStopped) {
- // No need to keep buckets for events that were stopped before.
- it = mInfos.erase(it);
- } else {
- ++it;
- hasPendingEvent = true;
- }
- }
-
- // mDuration is updated in noteStop to the maximum duration that ended in the current bucket.
- if (mDuration != 0) {
- DurationBucket info;
- info.mBucketStartNs = mCurrentBucketStartTimeNs;
- info.mBucketEndNs = currentBucketEndTimeNs;
- info.mDuration = mDuration;
- (*output)[mEventKey].push_back(info);
- VLOG(" final duration for last bucket: %lld", (long long)mDuration);
- }
-
- if (numBucketsForward > 0) {
- mCurrentBucketStartTimeNs = fullBucketEnd + (numBucketsForward - 1) * mBucketSizeNs;
- mCurrentBucketNum += numBucketsForward;
- } else { // We must be forming a partial bucket.
- mCurrentBucketStartTimeNs = eventTimeNs;
- }
-
- mDuration = 0;
- // If this tracker has no pending events, tell owner to remove.
- return !hasPendingEvent;
-}
-
-bool MaxDurationTracker::flushIfNeeded(
- int64_t eventTimeNs, unordered_map<MetricDimensionKey, vector<DurationBucket>>* output) {
- if (eventTimeNs < getCurrentBucketEndTimeNs()) {
- return false;
- }
- return flushCurrentBucket(eventTimeNs, output);
-}
-
-void MaxDurationTracker::onSlicedConditionMayChange(bool overallCondition,
- const int64_t timestamp) {
- // Now for each of the on-going event, check if the condition has changed for them.
- for (auto& pair : mInfos) {
- if (pair.second.state == kStopped) {
- continue;
- }
- ConditionState conditionState = mWizard->query(
- mConditionTrackerIndex, pair.second.conditionKeys,
- !mHasLinksToAllConditionDimensionsInTracker);
- bool conditionMet = (conditionState == ConditionState::kTrue);
-
- VLOG("key: %s, condition: %d", pair.first.toString().c_str(), conditionMet);
- noteConditionChanged(pair.first, conditionMet, timestamp);
- }
-}
-
-void MaxDurationTracker::onStateChanged(const int64_t timestamp, const int32_t atomId,
- const FieldValue& newState) {
- ALOGE("MaxDurationTracker does not handle sliced state changes.");
-}
-
-void MaxDurationTracker::onConditionChanged(bool condition, const int64_t timestamp) {
- for (auto& pair : mInfos) {
- noteConditionChanged(pair.first, condition, timestamp);
- }
-}
-
-void MaxDurationTracker::noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
- const int64_t timestamp) {
- auto it = mInfos.find(key);
- if (it == mInfos.end()) {
- return;
- }
-
- switch (it->second.state) {
- case kStarted:
- // If condition becomes false, kStarted -> kPaused. Record the current duration and
- // stop anomaly alarm.
- if (!conditionMet) {
- stopAnomalyAlarm(timestamp);
- it->second.state = DurationState::kPaused;
- it->second.lastDuration += (timestamp - it->second.lastStartTime);
- if (anyStarted()) {
- // In case any other dimensions are still started, we need to set the alarm.
- startAnomalyAlarm(timestamp);
- }
- VLOG("MaxDurationTracker Key: %s Started->Paused ", key.toString().c_str());
- }
- break;
- case kStopped:
- // Nothing to do if it's stopped.
- break;
- case kPaused:
- // If condition becomes true, kPaused -> kStarted. and the start time is the condition
- // change time.
- if (conditionMet) {
- it->second.state = DurationState::kStarted;
- it->second.lastStartTime = timestamp;
- startAnomalyAlarm(timestamp);
- VLOG("MaxDurationTracker Key: %s Paused->Started", key.toString().c_str());
- }
- break;
- }
- // Note that we don't update mDuration here since it's only updated during noteStop.
-}
-
-int64_t MaxDurationTracker::predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
- const int64_t currentTimestamp) const {
- // The allowed time we can continue in the current state is the
- // (anomaly threshold) - max(elapsed time of the started mInfos).
- int64_t maxElapsed = 0;
- for (auto it = mInfos.begin(); it != mInfos.end(); ++it) {
- if (it->second.state == DurationState::kStarted) {
- int64_t duration =
- it->second.lastDuration + (currentTimestamp - it->second.lastStartTime);
- if (duration > maxElapsed) {
- maxElapsed = duration;
- }
- }
- }
- int64_t anomalyTimeNs = currentTimestamp + anomalyTracker.getAnomalyThreshold() - maxElapsed;
- int64_t refractoryEndNs = anomalyTracker.getRefractoryPeriodEndsSec(mEventKey) * NS_PER_SEC;
- return std::max(anomalyTimeNs, refractoryEndNs);
-}
-
-void MaxDurationTracker::dumpStates(FILE* out, bool verbose) const {
- fprintf(out, "\t\t sub-durations %lu\n", (unsigned long)mInfos.size());
- fprintf(out, "\t\t current duration %lld\n", (long long)mDuration);
-}
-
-int64_t MaxDurationTracker::getCurrentStateKeyDuration() const {
- ALOGE("MaxDurationTracker does not handle sliced state changes.");
- return -1;
-}
-
-int64_t MaxDurationTracker::getCurrentStateKeyFullBucketDuration() const {
- ALOGE("MaxDurationTracker does not handle sliced state changes.");
- return -1;
-}
-
-void MaxDurationTracker::updateCurrentStateKey(const int32_t atomId, const FieldValue& newState) {
- ALOGE("MaxDurationTracker does not handle sliced state changes.");
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
deleted file mode 100644
index 2891c6e..0000000
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MAX_DURATION_TRACKER_H
-#define MAX_DURATION_TRACKER_H
-
-#include "DurationTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Tracks a pool of atom durations, and output the max duration for each bucket.
-// To get max duration, we need to keep track of each individual durations, and compare them when
-// they stop or bucket expires.
-class MaxDurationTracker : public DurationTracker {
-public:
- MaxDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
- sp<ConditionWizard> wizard, int conditionIndex,
- bool nesting,
- int64_t currentBucketStartNs, int64_t currentBucketNum,
- int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
- bool fullLink,
- const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
-
- MaxDurationTracker(const MaxDurationTracker& tracker) = default;
-
- void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
- const ConditionKey& conditionKey) override;
- void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
- const bool stopAll) override;
- void noteStopAll(const int64_t eventTime) override;
-
- bool flushIfNeeded(
- int64_t timestampNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
- bool flushCurrentBucket(
- const int64_t& eventTimeNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>*) override;
-
- void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) override;
- void onConditionChanged(bool condition, const int64_t timestamp) override;
-
- void onStateChanged(const int64_t timestamp, const int32_t atomId,
- const FieldValue& newState) override;
-
- int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
- const int64_t currentTimestamp) const override;
- void dumpStates(FILE* out, bool verbose) const override;
-
- int64_t getCurrentStateKeyDuration() const override;
-
- int64_t getCurrentStateKeyFullBucketDuration() const override;
-
- void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState);
-
-private:
- // Returns true if at least one of the mInfos is started.
- bool anyStarted();
-
- std::unordered_map<HashableDimensionKey, DurationInfo> mInfos;
-
- void noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
- const int64_t timestamp);
-
- // return true if we should not allow newKey to be tracked because we are above the threshold
- bool hitGuardRail(const HashableDimensionKey& newKey);
-
- FRIEND_TEST(MaxDurationTrackerTest, TestSimpleMaxDuration);
- FRIEND_TEST(MaxDurationTrackerTest, TestCrossBucketBoundary);
- FRIEND_TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition);
- FRIEND_TEST(MaxDurationTrackerTest, TestStopAll);
- FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyDetection);
- FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // MAX_DURATION_TRACKER_H
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
deleted file mode 100644
index 0d49bbc..0000000
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false
-#include "Log.h"
-#include "OringDurationTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::pair;
-
-OringDurationTracker::OringDurationTracker(
- const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
- sp<ConditionWizard> wizard, int conditionIndex, bool nesting, int64_t currentBucketStartNs,
- int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
- bool fullLink, const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
- : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs,
- currentBucketNum, startTimeNs, bucketSizeNs, conditionSliced, fullLink,
- anomalyTrackers),
- mStarted(),
- mPaused() {
- mLastStartTime = 0;
-}
-
-bool OringDurationTracker::hitGuardRail(const HashableDimensionKey& newKey) {
- // ===========GuardRail==============
- // 1. Report the tuple count if the tuple count > soft limit
- if (mConditionKeyMap.find(newKey) != mConditionKeyMap.end()) {
- return false;
- }
- if (mConditionKeyMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mConditionKeyMap.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mTrackerId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("OringDurTracker %lld dropping data for dimension key %s",
- (long long)mTrackerId, newKey.toString().c_str());
- return true;
- }
- }
- return false;
-}
-
-void OringDurationTracker::noteStart(const HashableDimensionKey& key, bool condition,
- const int64_t eventTime, const ConditionKey& conditionKey) {
- if (hitGuardRail(key)) {
- return;
- }
- if (condition) {
- if (mStarted.size() == 0) {
- mLastStartTime = eventTime;
- VLOG("record first start....");
- startAnomalyAlarm(eventTime);
- }
- mStarted[key]++;
- } else {
- mPaused[key]++;
- }
-
- if (mConditionSliced && mConditionKeyMap.find(key) == mConditionKeyMap.end()) {
- mConditionKeyMap[key] = conditionKey;
- }
- VLOG("Oring: %s start, condition %d", key.toString().c_str(), condition);
-}
-
-void OringDurationTracker::noteStop(const HashableDimensionKey& key, const int64_t timestamp,
- const bool stopAll) {
- VLOG("Oring: %s stop", key.toString().c_str());
- auto it = mStarted.find(key);
- if (it != mStarted.end()) {
- (it->second)--;
- if (stopAll || !mNested || it->second <= 0) {
- mStarted.erase(it);
- mConditionKeyMap.erase(key);
- }
- if (mStarted.empty()) {
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
- (timestamp - mLastStartTime);
- detectAndDeclareAnomaly(
- timestamp, mCurrentBucketNum,
- getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
- VLOG("record duration %lld, total duration %lld for state key %s",
- (long long)timestamp - mLastStartTime, (long long)getCurrentStateKeyDuration(),
- mEventKey.getStateValuesKey().toString().c_str());
- }
- }
-
- auto pausedIt = mPaused.find(key);
- if (pausedIt != mPaused.end()) {
- (pausedIt->second)--;
- if (stopAll || !mNested || pausedIt->second <= 0) {
- mPaused.erase(pausedIt);
- mConditionKeyMap.erase(key);
- }
- }
- if (mStarted.empty()) {
- stopAnomalyAlarm(timestamp);
- }
-}
-
-void OringDurationTracker::noteStopAll(const int64_t timestamp) {
- if (!mStarted.empty()) {
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
- (timestamp - mLastStartTime);
- VLOG("Oring Stop all: record duration %lld, total duration %lld for state key %s",
- (long long)timestamp - mLastStartTime, (long long)getCurrentStateKeyDuration(),
- mEventKey.getStateValuesKey().toString().c_str());
- detectAndDeclareAnomaly(
- timestamp, mCurrentBucketNum,
- getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
- }
-
- stopAnomalyAlarm(timestamp);
- mStarted.clear();
- mPaused.clear();
- mConditionKeyMap.clear();
-}
-
-bool OringDurationTracker::flushCurrentBucket(
- const int64_t& eventTimeNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) {
- VLOG("OringDurationTracker Flushing.............");
-
- // Note that we have to mimic the bucket time changes we do in the
- // MetricProducer#notifyAppUpgrade.
-
- int numBucketsForward = 0;
- int64_t fullBucketEnd = getCurrentBucketEndTimeNs();
- int64_t currentBucketEndTimeNs;
-
- if (eventTimeNs >= fullBucketEnd) {
- numBucketsForward = 1 + (eventTimeNs - fullBucketEnd) / mBucketSizeNs;
- currentBucketEndTimeNs = fullBucketEnd;
- } else {
- // This must be a partial bucket.
- currentBucketEndTimeNs = eventTimeNs;
- }
-
- // Process the current bucket.
- if (mStarted.size() > 0) {
- // Calculate the duration for the current state key.
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
- (currentBucketEndTimeNs - mLastStartTime);
- }
- // Store DurationBucket info for each whatKey, stateKey pair.
- // Note: The whatKey stored in mEventKey is constant for each DurationTracker, while the
- // stateKey stored in mEventKey is only the current stateKey. mStateKeyDurationMap is used to
- // store durations for each stateKey, so we need to flush the bucket by creating a
- // DurationBucket for each stateKey.
- for (auto& durationIt : mStateKeyDurationMap) {
- if (durationIt.second.mDuration > 0) {
- DurationBucket current_info;
- current_info.mBucketStartNs = mCurrentBucketStartTimeNs;
- current_info.mBucketEndNs = currentBucketEndTimeNs;
- current_info.mDuration = durationIt.second.mDuration;
- (*output)[MetricDimensionKey(mEventKey.getDimensionKeyInWhat(), durationIt.first)]
- .push_back(current_info);
-
- durationIt.second.mDurationFullBucket += durationIt.second.mDuration;
- VLOG(" duration: %lld", (long long)current_info.mDuration);
- }
-
- if (eventTimeNs > fullBucketEnd) {
- // End of full bucket, can send to anomaly tracker now.
- addPastBucketToAnomalyTrackers(
- MetricDimensionKey(mEventKey.getDimensionKeyInWhat(), durationIt.first),
- getCurrentStateKeyFullBucketDuration(), mCurrentBucketNum);
- durationIt.second.mDurationFullBucket = 0;
- }
- durationIt.second.mDuration = 0;
- }
-
- if (mStarted.size() > 0) {
- for (int i = 1; i < numBucketsForward; i++) {
- DurationBucket info;
- info.mBucketStartNs = fullBucketEnd + mBucketSizeNs * (i - 1);
- info.mBucketEndNs = info.mBucketStartNs + mBucketSizeNs;
- info.mDuration = mBucketSizeNs;
- // Full duration buckets are attributed to the current stateKey.
- (*output)[mEventKey].push_back(info);
- // Safe to send these buckets to anomaly tracker since they must be full buckets.
- // If it's a partial bucket, numBucketsForward would be 0.
- addPastBucketToAnomalyTrackers(mEventKey, info.mDuration, mCurrentBucketNum + i);
- VLOG(" add filling bucket with duration %lld", (long long)info.mDuration);
- }
- } else {
- if (numBucketsForward >= 2) {
- addPastBucketToAnomalyTrackers(mEventKey, 0, mCurrentBucketNum + numBucketsForward - 1);
- }
- }
-
- if (numBucketsForward > 0) {
- mCurrentBucketStartTimeNs = fullBucketEnd + (numBucketsForward - 1) * mBucketSizeNs;
- mCurrentBucketNum += numBucketsForward;
- } else { // We must be forming a partial bucket.
- mCurrentBucketStartTimeNs = eventTimeNs;
- }
- mLastStartTime = mCurrentBucketStartTimeNs;
-
- // if all stopped, then tell owner it's safe to remove this tracker.
- return mStarted.empty() && mPaused.empty();
-}
-
-bool OringDurationTracker::flushIfNeeded(
- int64_t eventTimeNs, unordered_map<MetricDimensionKey, vector<DurationBucket>>* output) {
- if (eventTimeNs < getCurrentBucketEndTimeNs()) {
- return false;
- }
- return flushCurrentBucket(eventTimeNs, output);
-}
-
-void OringDurationTracker::onSlicedConditionMayChange(bool overallCondition,
- const int64_t timestamp) {
- vector<pair<HashableDimensionKey, int>> startedToPaused;
- vector<pair<HashableDimensionKey, int>> pausedToStarted;
- if (!mStarted.empty()) {
- for (auto it = mStarted.begin(); it != mStarted.end();) {
- const auto& key = it->first;
- const auto& condIt = mConditionKeyMap.find(key);
- if (condIt == mConditionKeyMap.end()) {
- VLOG("Key %s dont have condition key", key.toString().c_str());
- ++it;
- continue;
- }
- ConditionState conditionState =
- mWizard->query(mConditionTrackerIndex, condIt->second,
- !mHasLinksToAllConditionDimensionsInTracker);
- if (conditionState != ConditionState::kTrue) {
- startedToPaused.push_back(*it);
- it = mStarted.erase(it);
- VLOG("Key %s started -> paused", key.toString().c_str());
- } else {
- ++it;
- }
- }
-
- if (mStarted.empty()) {
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
- (timestamp - mLastStartTime);
- VLOG("record duration %lld, total duration %lld for state key %s",
- (long long)(timestamp - mLastStartTime), (long long)getCurrentStateKeyDuration(),
- mEventKey.getStateValuesKey().toString().c_str());
- detectAndDeclareAnomaly(
- timestamp, mCurrentBucketNum,
- getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
- }
- }
-
- if (!mPaused.empty()) {
- for (auto it = mPaused.begin(); it != mPaused.end();) {
- const auto& key = it->first;
- if (mConditionKeyMap.find(key) == mConditionKeyMap.end()) {
- VLOG("Key %s dont have condition key", key.toString().c_str());
- ++it;
- continue;
- }
- ConditionState conditionState =
- mWizard->query(mConditionTrackerIndex, mConditionKeyMap[key],
- !mHasLinksToAllConditionDimensionsInTracker);
- if (conditionState == ConditionState::kTrue) {
- pausedToStarted.push_back(*it);
- it = mPaused.erase(it);
- VLOG("Key %s paused -> started", key.toString().c_str());
- } else {
- ++it;
- }
- }
-
- if (mStarted.empty() && pausedToStarted.size() > 0) {
- mLastStartTime = timestamp;
- }
- }
-
- if (mStarted.empty() && !pausedToStarted.empty()) {
- startAnomalyAlarm(timestamp);
- }
- mStarted.insert(pausedToStarted.begin(), pausedToStarted.end());
- mPaused.insert(startedToPaused.begin(), startedToPaused.end());
-
- if (mStarted.empty()) {
- stopAnomalyAlarm(timestamp);
- }
-}
-
-void OringDurationTracker::onConditionChanged(bool condition, const int64_t timestamp) {
- if (condition) {
- if (!mPaused.empty()) {
- VLOG("Condition true, all started");
- if (mStarted.empty()) {
- mLastStartTime = timestamp;
- }
- if (mStarted.empty() && !mPaused.empty()) {
- startAnomalyAlarm(timestamp);
- }
- mStarted.insert(mPaused.begin(), mPaused.end());
- mPaused.clear();
- }
- } else {
- if (!mStarted.empty()) {
- VLOG("Condition false, all paused");
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
- (timestamp - mLastStartTime);
- mPaused.insert(mStarted.begin(), mStarted.end());
- mStarted.clear();
- detectAndDeclareAnomaly(
- timestamp, mCurrentBucketNum,
- getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
- }
- }
- if (mStarted.empty()) {
- stopAnomalyAlarm(timestamp);
- }
-}
-
-void OringDurationTracker::onStateChanged(const int64_t timestamp, const int32_t atomId,
- const FieldValue& newState) {
- // Nothing needs to be done on a state change if we have not seen a start
- // event, the metric is currently not active, or condition is false.
- // For these cases, no keys are being tracked in mStarted, so update
- // the current state key and return.
- if (mStarted.empty()) {
- updateCurrentStateKey(atomId, newState);
- return;
- }
- // Add the current duration length to the previous state key and then update
- // the last start time and current state key.
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration += (timestamp - mLastStartTime);
- mLastStartTime = timestamp;
- updateCurrentStateKey(atomId, newState);
-}
-
-int64_t OringDurationTracker::predictAnomalyTimestampNs(
- const DurationAnomalyTracker& anomalyTracker, const int64_t eventTimestampNs) const {
-
- // The anomaly threshold.
- const int64_t thresholdNs = anomalyTracker.getAnomalyThreshold();
-
- // The timestamp of the current bucket end.
- const int64_t currentBucketEndNs = getCurrentBucketEndTimeNs();
-
- // The past duration ns for the current bucket of the current stateKey.
- int64_t currentStateBucketPastNs =
- getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration();
-
- // As we move into the future, old buckets get overwritten (so their old data is erased).
- // Sum of past durations. Will change as we overwrite old buckets.
- int64_t pastNs = currentStateBucketPastNs + anomalyTracker.getSumOverPastBuckets(mEventKey);
-
- // The refractory period end timestamp for dimension mEventKey.
- const int64_t refractoryPeriodEndNs =
- anomalyTracker.getRefractoryPeriodEndsSec(mEventKey) * NS_PER_SEC;
-
- // The anomaly should happen when accumulated wakelock duration is above the threshold and
- // not within the refractory period.
- int64_t anomalyTimestampNs =
- std::max(eventTimestampNs + thresholdNs - pastNs, refractoryPeriodEndNs);
- // If the predicted the anomaly timestamp is within the current bucket, return it directly.
- if (anomalyTimestampNs <= currentBucketEndNs) {
- return std::max(eventTimestampNs, anomalyTimestampNs);
- }
-
- // Remove the old bucket.
- if (anomalyTracker.getNumOfPastBuckets() > 0) {
- pastNs -= anomalyTracker.getPastBucketValue(
- mEventKey,
- mCurrentBucketNum - anomalyTracker.getNumOfPastBuckets());
- // Add the remaining of the current bucket to the accumulated wakelock duration.
- pastNs += (currentBucketEndNs - eventTimestampNs);
- } else {
- // The anomaly depends on only one bucket.
- pastNs = 0;
- }
-
- // The anomaly will not happen in the current bucket. We need to iterate over the future buckets
- // to predict the accumulated wakelock duration and determine the anomaly timestamp accordingly.
- for (int futureBucketIdx = 1; futureBucketIdx <= anomalyTracker.getNumOfPastBuckets() + 1;
- futureBucketIdx++) {
- // The alarm candidate timestamp should meet two requirements:
- // 1. the accumulated wakelock duration is above the threshold.
- // 2. it is not within the refractory period.
- // 3. the alarm timestamp falls in this bucket. Otherwise we need to flush the past buckets,
- // find the new alarm candidate timestamp and check these requirements again.
- const int64_t bucketEndNs = currentBucketEndNs + futureBucketIdx * mBucketSizeNs;
- int64_t anomalyTimestampNs =
- std::max(bucketEndNs - mBucketSizeNs + thresholdNs - pastNs, refractoryPeriodEndNs);
- if (anomalyTimestampNs <= bucketEndNs) {
- return anomalyTimestampNs;
- }
- if (anomalyTracker.getNumOfPastBuckets() <= 0) {
- continue;
- }
-
- // No valid alarm timestamp is found in this bucket. The clock moves to the end of the
- // bucket. Update the pastNs.
- pastNs += mBucketSizeNs;
- // 1. If the oldest past bucket is still in the past bucket window, we could fetch the past
- // bucket and erase it from pastNs.
- // 2. If the oldest past bucket is the current bucket, we should compute the
- // wakelock duration in the current bucket and erase it from pastNs.
- // 3. Otherwise all othe past buckets are ancient.
- if (futureBucketIdx < anomalyTracker.getNumOfPastBuckets()) {
- pastNs -= anomalyTracker.getPastBucketValue(
- mEventKey,
- mCurrentBucketNum - anomalyTracker.getNumOfPastBuckets() + futureBucketIdx);
- } else if (futureBucketIdx == anomalyTracker.getNumOfPastBuckets()) {
- pastNs -= (currentStateBucketPastNs + (currentBucketEndNs - eventTimestampNs));
- }
- }
-
- return std::max(eventTimestampNs + thresholdNs, refractoryPeriodEndNs);
-}
-
-void OringDurationTracker::dumpStates(FILE* out, bool verbose) const {
- fprintf(out, "\t\t started count %lu\n", (unsigned long)mStarted.size());
- fprintf(out, "\t\t paused count %lu\n", (unsigned long)mPaused.size());
- fprintf(out, "\t\t current duration %lld\n", (long long)getCurrentStateKeyDuration());
-}
-
-int64_t OringDurationTracker::getCurrentStateKeyDuration() const {
- auto it = mStateKeyDurationMap.find(mEventKey.getStateValuesKey());
- if (it == mStateKeyDurationMap.end()) {
- return 0;
- } else {
- return it->second.mDuration;
- }
-}
-
-int64_t OringDurationTracker::getCurrentStateKeyFullBucketDuration() const {
- auto it = mStateKeyDurationMap.find(mEventKey.getStateValuesKey());
- if (it == mStateKeyDurationMap.end()) {
- return 0;
- } else {
- return it->second.mDurationFullBucket;
- }
-}
-
-void OringDurationTracker::updateCurrentStateKey(const int32_t atomId, const FieldValue& newState) {
- HashableDimensionKey* stateValuesKey = mEventKey.getMutableStateValuesKey();
- for (size_t i = 0; i < stateValuesKey->getValues().size(); i++) {
- if (stateValuesKey->getValues()[i].mField.getTag() == atomId) {
- stateValuesKey->mutableValue(i)->mValue = newState.mValue;
- }
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
deleted file mode 100644
index bd8017a..0000000
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ORING_DURATION_TRACKER_H
-#define ORING_DURATION_TRACKER_H
-
-#include "DurationTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Tracks the "Or'd" duration -- if 2 durations are overlapping, they won't be double counted.
-class OringDurationTracker : public DurationTracker {
-public:
- OringDurationTracker(const ConfigKey& key, const int64_t& id,
- const MetricDimensionKey& eventKey, sp<ConditionWizard> wizard,
- int conditionIndex, bool nesting, int64_t currentBucketStartNs,
- int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs,
- bool conditionSliced, bool fullLink,
- const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
-
- OringDurationTracker(const OringDurationTracker& tracker) = default;
-
- void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
- const ConditionKey& conditionKey) override;
- void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
- const bool stopAll) override;
- void noteStopAll(const int64_t eventTime) override;
-
- void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) override;
- void onConditionChanged(bool condition, const int64_t timestamp) override;
-
- void onStateChanged(const int64_t timestamp, const int32_t atomId,
- const FieldValue& newState) override;
-
- bool flushCurrentBucket(
- const int64_t& eventTimeNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
- bool flushIfNeeded(
- int64_t timestampNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
-
- int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
- const int64_t currentTimestamp) const override;
- void dumpStates(FILE* out, bool verbose) const override;
-
- int64_t getCurrentStateKeyDuration() const override;
-
- int64_t getCurrentStateKeyFullBucketDuration() const override;
-
- void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState);
-
-private:
- // We don't need to keep track of individual durations. The information that's needed is:
- // 1) which keys are started. We record the first start time.
- // 2) which keys are paused (started but condition was false)
- // 3) whenever a key stops, we remove it from the started set. And if the set becomes empty,
- // it means everything has stopped, we then record the end time.
- std::unordered_map<HashableDimensionKey, int> mStarted;
- std::unordered_map<HashableDimensionKey, int> mPaused;
- int64_t mLastStartTime;
- std::unordered_map<HashableDimensionKey, ConditionKey> mConditionKeyMap;
-
- // return true if we should not allow newKey to be tracked because we are above the threshold
- bool hitGuardRail(const HashableDimensionKey& newKey);
-
- FRIEND_TEST(OringDurationTrackerTest, TestDurationOverlap);
- FRIEND_TEST(OringDurationTrackerTest, TestCrossBucketBoundary);
- FRIEND_TEST(OringDurationTrackerTest, TestDurationConditionChange);
- FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // ORING_DURATION_TRACKER_H
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
deleted file mode 100644
index 8917c36..0000000
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "metrics_manager_util.h"
-
-#include <inttypes.h>
-
-#include "FieldValue.h"
-#include "MetricProducer.h"
-#include "condition/CombinationConditionTracker.h"
-#include "condition/SimpleConditionTracker.h"
-#include "external/StatsPullerManager.h"
-#include "matchers/CombinationLogMatchingTracker.h"
-#include "matchers/EventMatcherWizard.h"
-#include "matchers/SimpleLogMatchingTracker.h"
-#include "metrics/CountMetricProducer.h"
-#include "metrics/DurationMetricProducer.h"
-#include "metrics/EventMetricProducer.h"
-#include "metrics/GaugeMetricProducer.h"
-#include "metrics/ValueMetricProducer.h"
-#include "state/StateManager.h"
-#include "stats_util.h"
-
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-bool hasLeafNode(const FieldMatcher& matcher) {
- if (!matcher.has_field()) {
- return false;
- }
- for (int i = 0; i < matcher.child_size(); ++i) {
- if (hasLeafNode(matcher.child(i))) {
- return true;
- }
- }
- return true;
-}
-
-} // namespace
-
-bool handleMetricWithLogTrackers(const int64_t what, const int metricIndex,
- const bool usedForDimension,
- const vector<sp<LogMatchingTracker>>& allAtomMatchers,
- const unordered_map<int64_t, int>& logTrackerMap,
- unordered_map<int, std::vector<int>>& trackerToMetricMap,
- int& logTrackerIndex) {
- auto logTrackerIt = logTrackerMap.find(what);
- if (logTrackerIt == logTrackerMap.end()) {
- ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)what);
- return false;
- }
- if (usedForDimension && allAtomMatchers[logTrackerIt->second]->getAtomIds().size() > 1) {
- ALOGE("AtomMatcher \"%lld\" has more than one tag ids. When a metric has dimension, "
- "the \"what\" can only about one atom type.",
- (long long)what);
- return false;
- }
- logTrackerIndex = logTrackerIt->second;
- auto& metric_list = trackerToMetricMap[logTrackerIndex];
- metric_list.push_back(metricIndex);
- return true;
-}
-
-bool handlePullMetricTriggerWithLogTrackers(
- const int64_t trigger, const int metricIndex,
- const vector<sp<LogMatchingTracker>>& allAtomMatchers,
- const unordered_map<int64_t, int>& logTrackerMap,
- unordered_map<int, std::vector<int>>& trackerToMetricMap, int& logTrackerIndex) {
- auto logTrackerIt = logTrackerMap.find(trigger);
- if (logTrackerIt == logTrackerMap.end()) {
- ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)trigger);
- return false;
- }
- if (allAtomMatchers[logTrackerIt->second]->getAtomIds().size() > 1) {
- ALOGE("AtomMatcher \"%lld\" has more than one tag ids."
- "Trigger can only be one atom type.",
- (long long)trigger);
- return false;
- }
- logTrackerIndex = logTrackerIt->second;
- auto& metric_list = trackerToMetricMap[logTrackerIndex];
- metric_list.push_back(metricIndex);
- return true;
-}
-
-bool handleMetricWithConditions(
- const int64_t condition, const int metricIndex,
- const unordered_map<int64_t, int>& conditionTrackerMap,
- const ::google::protobuf::RepeatedPtrField<::android::os::statsd::MetricConditionLink>&
- links,
- vector<sp<ConditionTracker>>& allConditionTrackers, int& conditionIndex,
- unordered_map<int, std::vector<int>>& conditionToMetricMap) {
- auto condition_it = conditionTrackerMap.find(condition);
- if (condition_it == conditionTrackerMap.end()) {
- ALOGW("cannot find Predicate \"%lld\" in the config", (long long)condition);
- return false;
- }
-
- for (const auto& link : links) {
- auto it = conditionTrackerMap.find(link.condition());
- if (it == conditionTrackerMap.end()) {
- ALOGW("cannot find Predicate \"%lld\" in the config", (long long)link.condition());
- return false;
- }
- allConditionTrackers[condition_it->second]->setSliced(true);
- allConditionTrackers[it->second]->setSliced(true);
- }
- conditionIndex = condition_it->second;
-
- // will create new vector if not exist before.
- auto& metricList = conditionToMetricMap[condition_it->second];
- metricList.push_back(metricIndex);
- return true;
-}
-
-// Initializes state data structures for a metric.
-// input:
-// [config]: the input config
-// [stateIds]: the slice_by_state ids for this metric
-// [stateAtomIdMap]: this map contains the mapping from all state ids to atom ids
-// [allStateGroupMaps]: this map contains the mapping from state ids and state
-// values to state group ids for all states
-// output:
-// [slicedStateAtoms]: a vector of atom ids of all the slice_by_states
-// [stateGroupMap]: this map should contain the mapping from states ids and state
-// values to state group ids for all states that this metric
-// is interested in
-bool handleMetricWithStates(
- const StatsdConfig& config, const ::google::protobuf::RepeatedField<int64_t>& stateIds,
- const unordered_map<int64_t, int>& stateAtomIdMap,
- const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
- vector<int>& slicedStateAtoms,
- unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap) {
- for (const auto& stateId : stateIds) {
- auto it = stateAtomIdMap.find(stateId);
- if (it == stateAtomIdMap.end()) {
- ALOGW("cannot find State %" PRId64 " in the config", stateId);
- return false;
- }
- int atomId = it->second;
- slicedStateAtoms.push_back(atomId);
-
- auto stateIt = allStateGroupMaps.find(stateId);
- if (stateIt != allStateGroupMaps.end()) {
- stateGroupMap[atomId] = stateIt->second;
- }
- }
- return true;
-}
-
-bool handleMetricWithStateLink(const FieldMatcher& stateMatcher,
- const vector<Matcher>& dimensionsInWhat) {
- vector<Matcher> stateMatchers;
- translateFieldMatcher(stateMatcher, &stateMatchers);
-
- return subsetDimensions(stateMatchers, dimensionsInWhat);
-}
-
-// Validates a metricActivation and populates state.
-// EventActivationMap and EventDeactivationMap are supplied to a MetricProducer
-// to provide the producer with state about its activators and deactivators.
-// Returns false if there are errors.
-bool handleMetricActivation(
- const StatsdConfig& config,
- const int64_t metricId,
- const int metricIndex,
- const unordered_map<int64_t, int>& metricToActivationMap,
- const unordered_map<int64_t, int>& logTrackerMap,
- unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
- unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
- vector<int>& metricsWithActivation,
- unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap) {
- // Check if metric has an associated activation
- auto itr = metricToActivationMap.find(metricId);
- if (itr == metricToActivationMap.end()) return true;
-
- int activationIndex = itr->second;
- const MetricActivation& metricActivation = config.metric_activation(activationIndex);
-
- for (int i = 0; i < metricActivation.event_activation_size(); i++) {
- const EventActivation& activation = metricActivation.event_activation(i);
-
- auto itr = logTrackerMap.find(activation.atom_matcher_id());
- if (itr == logTrackerMap.end()) {
- ALOGE("Atom matcher not found for event activation.");
- return false;
- }
-
- ActivationType activationType = (activation.has_activation_type()) ?
- activation.activation_type() : metricActivation.activation_type();
- std::shared_ptr<Activation> activationWrapper = std::make_shared<Activation>(
- activationType, activation.ttl_seconds() * NS_PER_SEC);
-
- int atomMatcherIndex = itr->second;
- activationAtomTrackerToMetricMap[atomMatcherIndex].push_back(metricIndex);
- eventActivationMap.emplace(atomMatcherIndex, activationWrapper);
-
- if (activation.has_deactivation_atom_matcher_id()) {
- itr = logTrackerMap.find(activation.deactivation_atom_matcher_id());
- if (itr == logTrackerMap.end()) {
- ALOGE("Atom matcher not found for event deactivation.");
- return false;
- }
- int deactivationAtomMatcherIndex = itr->second;
- deactivationAtomTrackerToMetricMap[deactivationAtomMatcherIndex].push_back(metricIndex);
- eventDeactivationMap[deactivationAtomMatcherIndex].push_back(activationWrapper);
- }
- }
-
- metricsWithActivation.push_back(metricIndex);
- return true;
-}
-
-bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap,
- unordered_map<int64_t, int>& logTrackerMap,
- vector<sp<LogMatchingTracker>>& allAtomMatchers, set<int>& allTagIds) {
- vector<AtomMatcher> matcherConfigs;
- const int atomMatcherCount = config.atom_matcher_size();
- matcherConfigs.reserve(atomMatcherCount);
- allAtomMatchers.reserve(atomMatcherCount);
-
- for (int i = 0; i < atomMatcherCount; i++) {
- const AtomMatcher& logMatcher = config.atom_matcher(i);
-
- int index = allAtomMatchers.size();
- switch (logMatcher.contents_case()) {
- case AtomMatcher::ContentsCase::kSimpleAtomMatcher:
- allAtomMatchers.push_back(new SimpleLogMatchingTracker(
- logMatcher.id(), index, logMatcher.simple_atom_matcher(), uidMap));
- break;
- case AtomMatcher::ContentsCase::kCombination:
- allAtomMatchers.push_back(
- new CombinationLogMatchingTracker(logMatcher.id(), index));
- break;
- default:
- ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id());
- return false;
- // continue;
- }
- if (logTrackerMap.find(logMatcher.id()) != logTrackerMap.end()) {
- ALOGE("Duplicate AtomMatcher found!");
- return false;
- }
- logTrackerMap[logMatcher.id()] = index;
- matcherConfigs.push_back(logMatcher);
- }
-
- vector<bool> stackTracker2(allAtomMatchers.size(), false);
- for (auto& matcher : allAtomMatchers) {
- if (!matcher->init(matcherConfigs, allAtomMatchers, logTrackerMap, stackTracker2)) {
- return false;
- }
- // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
- const set<int>& tagIds = matcher->getAtomIds();
- allTagIds.insert(tagIds.begin(), tagIds.end());
- }
- return true;
-}
-
-bool initConditions(const ConfigKey& key, const StatsdConfig& config,
- const unordered_map<int64_t, int>& logTrackerMap,
- unordered_map<int64_t, int>& conditionTrackerMap,
- vector<sp<ConditionTracker>>& allConditionTrackers,
- unordered_map<int, std::vector<int>>& trackerToConditionMap,
- vector<ConditionState>& initialConditionCache) {
- vector<Predicate> conditionConfigs;
- const int conditionTrackerCount = config.predicate_size();
- conditionConfigs.reserve(conditionTrackerCount);
- allConditionTrackers.reserve(conditionTrackerCount);
- initialConditionCache.reserve(conditionTrackerCount);
- std::fill(initialConditionCache.begin(), initialConditionCache.end(), ConditionState::kUnknown);
-
- for (int i = 0; i < conditionTrackerCount; i++) {
- const Predicate& condition = config.predicate(i);
- int index = allConditionTrackers.size();
- switch (condition.contents_case()) {
- case Predicate::ContentsCase::kSimplePredicate: {
- allConditionTrackers.push_back(new SimpleConditionTracker(
- key, condition.id(), index, condition.simple_predicate(), logTrackerMap));
- break;
- }
- case Predicate::ContentsCase::kCombination: {
- allConditionTrackers.push_back(
- new CombinationConditionTracker(condition.id(), index));
- break;
- }
- default:
- ALOGE("Predicate \"%lld\" malformed", (long long)condition.id());
- return false;
- }
- if (conditionTrackerMap.find(condition.id()) != conditionTrackerMap.end()) {
- ALOGE("Duplicate Predicate found!");
- return false;
- }
- conditionTrackerMap[condition.id()] = index;
- conditionConfigs.push_back(condition);
- }
-
- vector<bool> stackTracker(allConditionTrackers.size(), false);
- for (size_t i = 0; i < allConditionTrackers.size(); i++) {
- auto& conditionTracker = allConditionTrackers[i];
- if (!conditionTracker->init(conditionConfigs, allConditionTrackers, conditionTrackerMap,
- stackTracker, initialConditionCache)) {
- return false;
- }
- for (const int trackerIndex : conditionTracker->getLogTrackerIndex()) {
- auto& conditionList = trackerToConditionMap[trackerIndex];
- conditionList.push_back(i);
- }
- }
- return true;
-}
-
-bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap,
- unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps) {
- for (int i = 0; i < config.state_size(); i++) {
- const State& state = config.state(i);
- const int64_t stateId = state.id();
- stateAtomIdMap[stateId] = state.atom_id();
-
- const StateMap& stateMap = state.map();
- for (auto group : stateMap.group()) {
- for (auto value : group.value()) {
- allStateGroupMaps[stateId][value] = group.group_id();
- }
- }
- }
-
- return true;
-}
-
-bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
- const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
- const unordered_map<int64_t, int>& logTrackerMap,
- const unordered_map<int64_t, int>& conditionTrackerMap,
- const vector<sp<LogMatchingTracker>>& allAtomMatchers,
- const unordered_map<int64_t, int>& stateAtomIdMap,
- const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
- vector<sp<ConditionTracker>>& allConditionTrackers,
- const vector<ConditionState>& initialConditionCache,
- vector<sp<MetricProducer>>& allMetricProducers,
- unordered_map<int, vector<int>>& conditionToMetricMap,
- unordered_map<int, vector<int>>& trackerToMetricMap,
- unordered_map<int64_t, int>& metricMap, std::set<int64_t>& noReportMetricIds,
- unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
- unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
- vector<int>& metricsWithActivation) {
- sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
- sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchers);
- const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
- config.event_metric_size() + config.gauge_metric_size() +
- config.value_metric_size();
- allMetricProducers.reserve(allMetricsCount);
-
- // Construct map from metric id to metric activation index. The map will be used to determine
- // the metric activation corresponding to a metric.
- unordered_map<int64_t, int> metricToActivationMap;
- for (int i = 0; i < config.metric_activation_size(); i++) {
- const MetricActivation& metricActivation = config.metric_activation(i);
- int64_t metricId = metricActivation.metric_id();
- if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) {
- ALOGE("Metric %lld has multiple MetricActivations", (long long) metricId);
- return false;
- }
- metricToActivationMap.insert({metricId, i});
- }
-
- // Build MetricProducers for each metric defined in config.
- // build CountMetricProducer
- for (int i = 0; i < config.count_metric_size(); i++) {
- const CountMetric& metric = config.count_metric(i);
- if (!metric.has_what()) {
- ALOGW("cannot find \"what\" in CountMetric \"%lld\"", (long long)metric.id());
- return false;
- }
-
- int metricIndex = allMetricProducers.size();
- metricMap.insert({metric.id(), metricIndex});
- int trackerIndex;
- if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
- metric.has_dimensions_in_what(),
- allAtomMatchers, logTrackerMap, trackerToMetricMap,
- trackerIndex)) {
- return false;
- }
-
- int conditionIndex = -1;
- if (metric.has_condition()) {
- if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
- metric.links(), allConditionTrackers, conditionIndex,
- conditionToMetricMap)) {
- return false;
- }
- } else {
- if (metric.links_size() > 0) {
- ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
- return false;
- }
- }
-
- std::vector<int> slicedStateAtoms;
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
- if (metric.slice_by_state_size() > 0) {
- if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
- allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
- return false;
- }
- } else {
- if (metric.state_link_size() > 0) {
- ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
- return false;
- }
- }
-
- unordered_map<int, shared_ptr<Activation>> eventActivationMap;
- unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
- if (!success) return false;
-
- sp<MetricProducer> countProducer =
- new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
- timeBaseTimeNs, currentTimeNs, eventActivationMap,
- eventDeactivationMap, slicedStateAtoms, stateGroupMap);
- allMetricProducers.push_back(countProducer);
- }
-
- // build DurationMetricProducer
- for (int i = 0; i < config.duration_metric_size(); i++) {
- int metricIndex = allMetricProducers.size();
- const DurationMetric& metric = config.duration_metric(i);
- metricMap.insert({metric.id(), metricIndex});
-
- auto what_it = conditionTrackerMap.find(metric.what());
- if (what_it == conditionTrackerMap.end()) {
- ALOGE("DurationMetric's \"what\" is invalid");
- return false;
- }
-
- const Predicate& durationWhat = config.predicate(what_it->second);
-
- if (durationWhat.contents_case() != Predicate::ContentsCase::kSimplePredicate) {
- ALOGE("DurationMetric's \"what\" must be a simple condition");
- return false;
- }
-
- const auto& simplePredicate = durationWhat.simple_predicate();
-
- bool nesting = simplePredicate.count_nesting();
-
- int trackerIndices[3] = {-1, -1, -1};
- if (!simplePredicate.has_start() ||
- !handleMetricWithLogTrackers(simplePredicate.start(), metricIndex,
- metric.has_dimensions_in_what(), allAtomMatchers,
- logTrackerMap, trackerToMetricMap, trackerIndices[0])) {
- ALOGE("Duration metrics must specify a valid the start event matcher");
- return false;
- }
-
- if (simplePredicate.has_stop() &&
- !handleMetricWithLogTrackers(simplePredicate.stop(), metricIndex,
- metric.has_dimensions_in_what(), allAtomMatchers,
- logTrackerMap, trackerToMetricMap, trackerIndices[1])) {
- return false;
- }
-
- if (simplePredicate.has_stop_all() &&
- !handleMetricWithLogTrackers(simplePredicate.stop_all(), metricIndex,
- metric.has_dimensions_in_what(), allAtomMatchers,
- logTrackerMap, trackerToMetricMap, trackerIndices[2])) {
- return false;
- }
-
- FieldMatcher internalDimensions = simplePredicate.dimensions();
-
- int conditionIndex = -1;
-
- if (metric.has_condition()) {
- bool good = handleMetricWithConditions(
- metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
- allConditionTrackers, conditionIndex, conditionToMetricMap);
- if (!good) {
- return false;
- }
- } else {
- if (metric.links_size() > 0) {
- ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
- return false;
- }
- }
-
- std::vector<int> slicedStateAtoms;
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
- if (metric.slice_by_state_size() > 0) {
- if (metric.aggregation_type() == DurationMetric::MAX_SPARSE) {
- ALOGE("DurationMetric with aggregation type MAX_SPARSE cannot be sliced by state");
- return false;
- }
- if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
- allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
- return false;
- }
- } else {
- if (metric.state_link_size() > 0) {
- ALOGW("DurationMetric has a MetricStateLink but doesn't have a sliced state");
- return false;
- }
- }
-
- // Check that all metric state links are a subset of dimensions_in_what fields.
- std::vector<Matcher> dimensionsInWhat;
- translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
- for (const auto& stateLink : metric.state_link()) {
- if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
- return false;
- }
- }
-
- unordered_map<int, shared_ptr<Activation>> eventActivationMap;
- unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
- if (!success) return false;
-
- sp<MetricProducer> durationMetric = new DurationMetricProducer(
- key, metric, conditionIndex, initialConditionCache, trackerIndices[0],
- trackerIndices[1], trackerIndices[2], nesting, wizard, internalDimensions,
- timeBaseTimeNs, currentTimeNs, eventActivationMap, eventDeactivationMap,
- slicedStateAtoms, stateGroupMap);
-
- allMetricProducers.push_back(durationMetric);
- }
-
- // build EventMetricProducer
- for (int i = 0; i < config.event_metric_size(); i++) {
- int metricIndex = allMetricProducers.size();
- const EventMetric& metric = config.event_metric(i);
- metricMap.insert({metric.id(), metricIndex});
- if (!metric.has_id() || !metric.has_what()) {
- ALOGW("cannot find the metric name or what in config");
- return false;
- }
- int trackerIndex;
- if (!handleMetricWithLogTrackers(metric.what(), metricIndex, false, allAtomMatchers,
- logTrackerMap, trackerToMetricMap, trackerIndex)) {
- return false;
- }
-
- int conditionIndex = -1;
- if (metric.has_condition()) {
- bool good = handleMetricWithConditions(
- metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
- allConditionTrackers, conditionIndex, conditionToMetricMap);
- if (!good) {
- return false;
- }
- } else {
- if (metric.links_size() > 0) {
- ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
- return false;
- }
- }
-
- unordered_map<int, shared_ptr<Activation>> eventActivationMap;
- unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
- if (!success) return false;
-
- sp<MetricProducer> eventMetric =
- new EventMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
- timeBaseTimeNs, eventActivationMap, eventDeactivationMap);
-
- allMetricProducers.push_back(eventMetric);
- }
-
- // build ValueMetricProducer
- for (int i = 0; i < config.value_metric_size(); i++) {
- const ValueMetric& metric = config.value_metric(i);
- if (!metric.has_what()) {
- ALOGW("cannot find \"what\" in ValueMetric \"%lld\"", (long long)metric.id());
- return false;
- }
- if (!metric.has_value_field()) {
- ALOGW("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
- return false;
- }
- std::vector<Matcher> fieldMatchers;
- translateFieldMatcher(metric.value_field(), &fieldMatchers);
- if (fieldMatchers.size() < 1) {
- ALOGW("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
- return false;
- }
-
- int metricIndex = allMetricProducers.size();
- metricMap.insert({metric.id(), metricIndex});
- int trackerIndex;
- if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
- metric.has_dimensions_in_what(),
- allAtomMatchers, logTrackerMap, trackerToMetricMap,
- trackerIndex)) {
- return false;
- }
-
- sp<LogMatchingTracker> atomMatcher = allAtomMatchers.at(trackerIndex);
- // If it is pulled atom, it should be simple matcher with one tagId.
- if (atomMatcher->getAtomIds().size() != 1) {
- return false;
- }
- int atomTagId = *(atomMatcher->getAtomIds().begin());
- int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
-
- int conditionIndex = -1;
- if (metric.has_condition()) {
- bool good = handleMetricWithConditions(
- metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
- allConditionTrackers, conditionIndex, conditionToMetricMap);
- if (!good) {
- return false;
- }
- } else {
- if (metric.links_size() > 0) {
- ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
- return false;
- }
- }
-
- std::vector<int> slicedStateAtoms;
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
- if (metric.slice_by_state_size() > 0) {
- if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
- allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
- return false;
- }
- } else {
- if (metric.state_link_size() > 0) {
- ALOGW("ValueMetric has a MetricStateLink but doesn't have a sliced state");
- return false;
- }
- }
-
- // Check that all metric state links are a subset of dimensions_in_what fields.
- std::vector<Matcher> dimensionsInWhat;
- translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
- for (const auto& stateLink : metric.state_link()) {
- if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
- return false;
- }
- }
-
- unordered_map<int, shared_ptr<Activation>> eventActivationMap;
- unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(
- config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- metricsWithActivation, eventActivationMap, eventDeactivationMap);
- if (!success) return false;
-
- sp<MetricProducer> valueProducer = new ValueMetricProducer(
- key, metric, conditionIndex, initialConditionCache, wizard, trackerIndex,
- matcherWizard, pullTagId, timeBaseTimeNs, currentTimeNs, pullerManager,
- eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap);
- allMetricProducers.push_back(valueProducer);
- }
-
- // Gauge metrics.
- for (int i = 0; i < config.gauge_metric_size(); i++) {
- const GaugeMetric& metric = config.gauge_metric(i);
- if (!metric.has_what()) {
- ALOGW("cannot find \"what\" in GaugeMetric \"%lld\"", (long long)metric.id());
- return false;
- }
-
- if ((!metric.gauge_fields_filter().has_include_all() ||
- (metric.gauge_fields_filter().include_all() == false)) &&
- !hasLeafNode(metric.gauge_fields_filter().fields())) {
- ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
- return false;
- }
- if ((metric.gauge_fields_filter().has_include_all() &&
- metric.gauge_fields_filter().include_all() == true) &&
- hasLeafNode(metric.gauge_fields_filter().fields())) {
- ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
- return false;
- }
-
- int metricIndex = allMetricProducers.size();
- metricMap.insert({metric.id(), metricIndex});
- int trackerIndex;
- if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
- metric.has_dimensions_in_what(),
- allAtomMatchers, logTrackerMap, trackerToMetricMap,
- trackerIndex)) {
- return false;
- }
-
- sp<LogMatchingTracker> atomMatcher = allAtomMatchers.at(trackerIndex);
- // For GaugeMetric atom, it should be simple matcher with one tagId.
- if (atomMatcher->getAtomIds().size() != 1) {
- return false;
- }
- int atomTagId = *(atomMatcher->getAtomIds().begin());
- int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
-
- int triggerTrackerIndex;
- int triggerAtomId = -1;
- if (metric.has_trigger_event()) {
- if (pullTagId == -1) {
- ALOGW("Pull atom not specified for trigger");
- return false;
- }
- // event_trigger should be used with FIRST_N_SAMPLES
- if (metric.sampling_type() != GaugeMetric::FIRST_N_SAMPLES) {
- return false;
- }
- if (!handlePullMetricTriggerWithLogTrackers(metric.trigger_event(), metricIndex,
- allAtomMatchers, logTrackerMap,
- trackerToMetricMap, triggerTrackerIndex)) {
- return false;
- }
- sp<LogMatchingTracker> triggerAtomMatcher = allAtomMatchers.at(triggerTrackerIndex);
- triggerAtomId = *(triggerAtomMatcher->getAtomIds().begin());
- }
-
- if (!metric.has_trigger_event() && pullTagId != -1 &&
- metric.sampling_type() == GaugeMetric::FIRST_N_SAMPLES) {
- ALOGW("FIRST_N_SAMPLES is only for pushed event or pull_on_trigger");
- return false;
- }
-
- int conditionIndex = -1;
- if (metric.has_condition()) {
- bool good = handleMetricWithConditions(
- metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
- allConditionTrackers, conditionIndex, conditionToMetricMap);
- if (!good) {
- return false;
- }
- } else {
- if (metric.links_size() > 0) {
- ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
- return false;
- }
- }
-
- unordered_map<int, shared_ptr<Activation>> eventActivationMap;
- unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
- if (!success) return false;
-
- sp<MetricProducer> gaugeProducer = new GaugeMetricProducer(
- key, metric, conditionIndex, initialConditionCache, wizard, trackerIndex,
- matcherWizard, pullTagId, triggerAtomId, atomTagId, timeBaseTimeNs, currentTimeNs,
- pullerManager, eventActivationMap, eventDeactivationMap);
- allMetricProducers.push_back(gaugeProducer);
- }
- for (int i = 0; i < config.no_report_metric_size(); ++i) {
- const auto no_report_metric = config.no_report_metric(i);
- if (metricMap.find(no_report_metric) == metricMap.end()) {
- ALOGW("no_report_metric %" PRId64 " not exist", no_report_metric);
- return false;
- }
- noReportMetricIds.insert(no_report_metric);
- }
-
- const set<int> whitelistedAtomIds(config.whitelisted_atom_ids().begin(),
- config.whitelisted_atom_ids().end());
- for (const auto& it : allMetricProducers) {
- // Register metrics to StateTrackers
- for (int atomId : it->getSlicedStateAtoms()) {
- // Register listener for non-whitelisted atoms only. Using whitelisted atom as a sliced
- // state atom is not allowed.
- if (whitelistedAtomIds.find(atomId) == whitelistedAtomIds.end()) {
- StateManager::getInstance().registerListener(atomId, it);
- } else {
- return false;
- }
- }
- }
- return true;
-}
-
-bool initAlerts(const StatsdConfig& config,
- const unordered_map<int64_t, int>& metricProducerMap,
- unordered_map<int64_t, int>& alertTrackerMap,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- vector<sp<MetricProducer>>& allMetricProducers,
- vector<sp<AnomalyTracker>>& allAnomalyTrackers) {
- for (int i = 0; i < config.alert_size(); i++) {
- const Alert& alert = config.alert(i);
- const auto& itr = metricProducerMap.find(alert.metric_id());
- if (itr == metricProducerMap.end()) {
- ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
- (long long)alert.metric_id());
- return false;
- }
- if (!alert.has_trigger_if_sum_gt()) {
- ALOGW("invalid alert: missing threshold");
- return false;
- }
- if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) {
- ALOGW("invalid alert: threshold=%f num_buckets= %d",
- alert.trigger_if_sum_gt(), alert.num_buckets());
- return false;
- }
- const int metricIndex = itr->second;
- sp<MetricProducer> metric = allMetricProducers[metricIndex];
- sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert, anomalyAlarmMonitor);
- if (anomalyTracker == nullptr) {
- // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
- return false;
- }
- alertTrackerMap.insert(std::make_pair(alert.id(), allAnomalyTrackers.size()));
- allAnomalyTrackers.push_back(anomalyTracker);
- }
- for (int i = 0; i < config.subscription_size(); ++i) {
- const Subscription& subscription = config.subscription(i);
- if (subscription.rule_type() != Subscription::ALERT) {
- continue;
- }
- if (subscription.subscriber_information_case() ==
- Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
- ALOGW("subscription \"%lld\" has no subscriber info.\"",
- (long long)subscription.id());
- return false;
- }
- const auto& itr = alertTrackerMap.find(subscription.rule_id());
- if (itr == alertTrackerMap.end()) {
- ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
- (long long)subscription.id(), (long long)subscription.rule_id());
- return false;
- }
- const int anomalyTrackerIndex = itr->second;
- allAnomalyTrackers[anomalyTrackerIndex]->addSubscription(subscription);
- }
- return true;
-}
-
-bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
- const sp<AlarmMonitor>& periodicAlarmMonitor,
- const int64_t timeBaseNs, const int64_t currentTimeNs,
- vector<sp<AlarmTracker>>& allAlarmTrackers) {
- unordered_map<int64_t, int> alarmTrackerMap;
- int64_t startMillis = timeBaseNs / 1000 / 1000;
- int64_t currentTimeMillis = currentTimeNs / 1000 /1000;
- for (int i = 0; i < config.alarm_size(); i++) {
- const Alarm& alarm = config.alarm(i);
- if (alarm.offset_millis() <= 0) {
- ALOGW("Alarm offset_millis should be larger than 0.");
- return false;
- }
- if (alarm.period_millis() <= 0) {
- ALOGW("Alarm period_millis should be larger than 0.");
- return false;
- }
- alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
- allAlarmTrackers.push_back(
- new AlarmTracker(startMillis, currentTimeMillis,
- alarm, key, periodicAlarmMonitor));
- }
- for (int i = 0; i < config.subscription_size(); ++i) {
- const Subscription& subscription = config.subscription(i);
- if (subscription.rule_type() != Subscription::ALARM) {
- continue;
- }
- if (subscription.subscriber_information_case() ==
- Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
- ALOGW("subscription \"%lld\" has no subscriber info.\"",
- (long long)subscription.id());
- return false;
- }
- const auto& itr = alarmTrackerMap.find(subscription.rule_id());
- if (itr == alarmTrackerMap.end()) {
- ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
- (long long)subscription.id(), (long long)subscription.rule_id());
- return false;
- }
- const int trackerIndex = itr->second;
- allAlarmTrackers[trackerIndex]->addSubscription(subscription);
- }
- return true;
-}
-
-bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap,
- const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
- const int64_t currentTimeNs, set<int>& allTagIds,
- vector<sp<LogMatchingTracker>>& allAtomMatchers,
- vector<sp<ConditionTracker>>& allConditionTrackers,
- vector<sp<MetricProducer>>& allMetricProducers,
- vector<sp<AnomalyTracker>>& allAnomalyTrackers,
- vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
- unordered_map<int, std::vector<int>>& conditionToMetricMap,
- unordered_map<int, std::vector<int>>& trackerToMetricMap,
- unordered_map<int, std::vector<int>>& trackerToConditionMap,
- unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
- unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
- unordered_map<int64_t, int>& alertTrackerMap,
- vector<int>& metricsWithActivation,
- std::set<int64_t>& noReportMetricIds) {
- unordered_map<int64_t, int> logTrackerMap;
- unordered_map<int64_t, int> conditionTrackerMap;
- vector<ConditionState> initialConditionCache;
- unordered_map<int64_t, int> metricProducerMap;
- unordered_map<int64_t, int> stateAtomIdMap;
- unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
-
- if (!initLogTrackers(config, uidMap, logTrackerMap, allAtomMatchers, allTagIds)) {
- ALOGE("initLogMatchingTrackers failed");
- return false;
- }
- VLOG("initLogMatchingTrackers succeed...");
-
- if (!initConditions(key, config, logTrackerMap, conditionTrackerMap, allConditionTrackers,
- trackerToConditionMap, initialConditionCache)) {
- ALOGE("initConditionTrackers failed");
- return false;
- }
-
- if (!initStates(config, stateAtomIdMap, allStateGroupMaps)) {
- ALOGE("initStates failed");
- return false;
- }
- if (!initMetrics(key, config, timeBaseNs, currentTimeNs, pullerManager, logTrackerMap,
- conditionTrackerMap, allAtomMatchers, stateAtomIdMap, allStateGroupMaps,
- allConditionTrackers, initialConditionCache, allMetricProducers,
- conditionToMetricMap, trackerToMetricMap, metricProducerMap, noReportMetricIds,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- metricsWithActivation)) {
- ALOGE("initMetricProducers failed");
- return false;
- }
- if (!initAlerts(config, metricProducerMap, alertTrackerMap, anomalyAlarmMonitor,
- allMetricProducers, allAnomalyTrackers)) {
- ALOGE("initAlerts failed");
- return false;
- }
- if (!initAlarms(config, key, periodicAlarmMonitor,
- timeBaseNs, currentTimeNs, allPeriodicAlarmTrackers)) {
- ALOGE("initAlarms failed");
- return false;
- }
-
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
deleted file mode 100644
index 96b5c26..0000000
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "../anomaly/AlarmTracker.h"
-#include "../condition/ConditionTracker.h"
-#include "../external/StatsPullerManager.h"
-#include "../matchers/LogMatchingTracker.h"
-#include "../metrics/MetricProducer.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Helper functions for MetricsManager to initialize from StatsdConfig.
-// *Note*: only initStatsdConfig() should be called from outside.
-// All other functions are intermediate
-// steps, created to make unit tests easier. And most of the parameters in these
-// functions are temporary objects in the initialization phase.
-
-// Initialize the LogMatchingTrackers.
-// input:
-// [key]: the config key that this config belongs to
-// [config]: the input StatsdConfig
-// output:
-// [logTrackerMap]: this map should contain matcher name to index mapping
-// [allAtomMatchers]: should store the sp to all the LogMatchingTracker
-// [allTagIds]: contains the set of all interesting tag ids to this config.
-bool initLogTrackers(const StatsdConfig& config,
- const UidMap& uidMap,
- std::unordered_map<int64_t, int>& logTrackerMap,
- std::vector<sp<LogMatchingTracker>>& allAtomMatchers,
- std::set<int>& allTagIds);
-
-// Initialize ConditionTrackers
-// input:
-// [key]: the config key that this config belongs to
-// [config]: the input config
-// [logTrackerMap]: LogMatchingTracker name to index mapping from previous step.
-// output:
-// [conditionTrackerMap]: this map should contain condition name to index mapping
-// [allConditionTrackers]: stores the sp to all the ConditionTrackers
-// [trackerToConditionMap]: contain the mapping from index of
-// log tracker to condition trackers that use the log tracker
-// [initialConditionCache]: stores the initial conditions for each ConditionTracker
-bool initConditions(const ConfigKey& key, const StatsdConfig& config,
- const std::unordered_map<int64_t, int>& logTrackerMap,
- std::unordered_map<int64_t, int>& conditionTrackerMap,
- std::vector<sp<ConditionTracker>>& allConditionTrackers,
- std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
- std::unordered_map<int, std::vector<MetricConditionLink>>& eventConditionLinks,
- std::vector<ConditionState>& initialConditionCache);
-
-// Initialize State maps using State protos in the config. These maps will
-// eventually be passed to MetricProducers to initialize their state info.
-// input:
-// [config]: the input config
-// output:
-// [stateAtomIdMap]: this map should contain the mapping from state ids to atom ids
-// [allStateGroupMaps]: this map should contain the mapping from states ids and state
-// values to state group ids for all states
-bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap,
- unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps);
-
-// Initialize MetricProducers.
-// input:
-// [key]: the config key that this config belongs to
-// [config]: the input config
-// [timeBaseSec]: start time base for all metrics
-// [logTrackerMap]: LogMatchingTracker name to index mapping from previous step.
-// [conditionTrackerMap]: condition name to index mapping
-// [stateAtomIdMap]: contains the mapping from state ids to atom ids
-// [allStateGroupMaps]: contains the mapping from atom ids and state values to
-// state group ids for all states
-// output:
-// [allMetricProducers]: contains the list of sp to the MetricProducers created.
-// [conditionToMetricMap]: contains the mapping from condition tracker index to
-// the list of MetricProducer index
-// [trackerToMetricMap]: contains the mapping from log tracker to MetricProducer index.
-bool initMetrics(
- const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
- const int64_t currentTimeNs, UidMap& uidMap, const sp<StatsPullerManager>& pullerManager,
- const std::unordered_map<int64_t, int>& logTrackerMap,
- const std::unordered_map<int64_t, int>& conditionTrackerMap,
- const std::unordered_map<int, std::vector<MetricConditionLink>>& eventConditionLinks,
- const vector<sp<LogMatchingTracker>>& allAtomMatchers,
- const unordered_map<int64_t, int>& stateAtomIdMap,
- const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
- vector<sp<ConditionTracker>>& allConditionTrackers,
- const std::vector<ConditionState>& initialConditionCache,
- std::vector<sp<MetricProducer>>& allMetricProducers,
- std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
- std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
- std::set<int64_t>& noReportMetricIds,
- std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
- std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
- std::vector<int>& metricsWithActivation);
-
-// Initialize MetricsManager from StatsdConfig.
-// Parameters are the members of MetricsManager. See MetricsManager for declaration.
-bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap,
- const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
- const int64_t currentTimeNs, std::set<int>& allTagIds,
- std::vector<sp<LogMatchingTracker>>& allAtomMatchers,
- std::vector<sp<ConditionTracker>>& allConditionTrackers,
- std::vector<sp<MetricProducer>>& allMetricProducers,
- vector<sp<AnomalyTracker>>& allAnomalyTrackers,
- vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
- std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
- std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
- std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
- unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
- unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
- std::unordered_map<int64_t, int>& alertTrackerMap,
- vector<int>& metricsWithActivation,
- std::set<int64_t>& noReportMetricIds);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/packages/PackageInfoListener.h b/cmds/statsd/src/packages/PackageInfoListener.h
deleted file mode 100644
index 6c50a8c..0000000
--- a/cmds/statsd/src/packages/PackageInfoListener.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STATSD_PACKAGE_INFO_LISTENER_H
-#define STATSD_PACKAGE_INFO_LISTENER_H
-
-#include <string>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PackageInfoListener : public virtual android::RefBase {
-public:
- // Uid map will notify this listener that the app with apk name and uid has been upgraded to
- // the specified version.
- virtual void notifyAppUpgrade(const int64_t& eventTimeNs, const std::string& apk,
- const int uid, const int64_t version) = 0;
-
- // Notify interested listeners that the given apk and uid combination no longer exits.
- virtual void notifyAppRemoved(const int64_t& eventTimeNs, const std::string& apk,
- const int uid) = 0;
-
- // Notify the listener that the UidMap snapshot is available.
- virtual void onUidMapReceived(const int64_t& eventTimeNs) = 0;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // STATSD_PACKAGE_INFO_LISTENER_H
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
deleted file mode 100644
index acf40c8..0000000
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, versionCode 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "hash.h"
-#include "stats_log_util.h"
-#include "guardrail/StatsdStats.h"
-#include "packages/UidMap.h"
-
-#include <inttypes.h>
-
-using namespace android;
-
-using android::base::StringPrintf;
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_UINT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const int FIELD_ID_SNAPSHOT_PACKAGE_NAME = 1;
-const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION = 2;
-const int FIELD_ID_SNAPSHOT_PACKAGE_UID = 3;
-const int FIELD_ID_SNAPSHOT_PACKAGE_DELETED = 4;
-const int FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH = 5;
-const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING = 6;
-const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING_HASH = 7;
-const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER = 8;
-const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_HASH = 9;
-const int FIELD_ID_SNAPSHOT_TIMESTAMP = 1;
-const int FIELD_ID_SNAPSHOT_PACKAGE_INFO = 2;
-const int FIELD_ID_SNAPSHOTS = 1;
-const int FIELD_ID_CHANGES = 2;
-const int FIELD_ID_CHANGE_DELETION = 1;
-const int FIELD_ID_CHANGE_TIMESTAMP = 2;
-const int FIELD_ID_CHANGE_PACKAGE = 3;
-const int FIELD_ID_CHANGE_UID = 4;
-const int FIELD_ID_CHANGE_NEW_VERSION = 5;
-const int FIELD_ID_CHANGE_PREV_VERSION = 6;
-const int FIELD_ID_CHANGE_PACKAGE_HASH = 7;
-const int FIELD_ID_CHANGE_NEW_VERSION_STRING = 8;
-const int FIELD_ID_CHANGE_PREV_VERSION_STRING = 9;
-const int FIELD_ID_CHANGE_NEW_VERSION_STRING_HASH = 10;
-const int FIELD_ID_CHANGE_PREV_VERSION_STRING_HASH = 11;
-
-UidMap::UidMap() : mBytesUsed(0) {}
-
-UidMap::~UidMap() {}
-
-sp<UidMap> UidMap::getInstance() {
- static sp<UidMap> sInstance = new UidMap();
- return sInstance;
-}
-
-bool UidMap::hasApp(int uid, const string& packageName) const {
- lock_guard<mutex> lock(mMutex);
-
- auto it = mMap.find(std::make_pair(uid, packageName));
- return it != mMap.end() && !it->second.deleted;
-}
-
-string UidMap::normalizeAppName(const string& appName) const {
- string normalizedName = appName;
- std::transform(normalizedName.begin(), normalizedName.end(), normalizedName.begin(), ::tolower);
- return normalizedName;
-}
-
-std::set<string> UidMap::getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const {
- lock_guard<mutex> lock(mMutex);
- return getAppNamesFromUidLocked(uid,returnNormalized);
-}
-
-std::set<string> UidMap::getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const {
- std::set<string> names;
- for (const auto& kv : mMap) {
- if (kv.first.first == uid && !kv.second.deleted) {
- names.insert(returnNormalized ? normalizeAppName(kv.first.second) : kv.first.second);
- }
- }
- return names;
-}
-
-int64_t UidMap::getAppVersion(int uid, const string& packageName) const {
- lock_guard<mutex> lock(mMutex);
-
- auto it = mMap.find(std::make_pair(uid, packageName));
- if (it == mMap.end() || it->second.deleted) {
- return 0;
- }
- return it->second.versionCode;
-}
-
-void UidMap::updateMap(const int64_t& timestamp, const vector<int32_t>& uid,
- const vector<int64_t>& versionCode, const vector<String16>& versionString,
- const vector<String16>& packageName, const vector<String16>& installer) {
- wp<PackageInfoListener> broadcast = NULL;
- {
- lock_guard<mutex> lock(mMutex); // Exclusively lock for updates.
-
- std::unordered_map<std::pair<int, string>, AppData, PairHash> deletedApps;
-
- // Copy all the deleted apps.
- for (const auto& kv : mMap) {
- if (kv.second.deleted) {
- deletedApps[kv.first] = kv.second;
- }
- }
-
- mMap.clear();
- for (size_t j = 0; j < uid.size(); j++) {
- string package = string(String8(packageName[j]).string());
- mMap[std::make_pair(uid[j], package)] =
- AppData(versionCode[j], string(String8(versionString[j]).string()),
- string(String8(installer[j]).string()));
- }
-
- for (const auto& kv : deletedApps) {
- auto mMapIt = mMap.find(kv.first);
- if (mMapIt != mMap.end()) {
- // Insert this deleted app back into the current map.
- mMap[kv.first] = kv.second;
- }
- }
-
- ensureBytesUsedBelowLimit();
- StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
- broadcast = mSubscriber;
- }
- // To avoid invoking callback while holding the internal lock. we get a copy of the listener
- // and invoke the callback. It's still possible that after we copy the listener, it removes
- // itself before we call it. It's then the listener's job to handle it (expect the callback to
- // be called after listener is removed, and the listener should properly ignore it).
- auto strongPtr = broadcast.promote();
- if (strongPtr != NULL) {
- strongPtr->onUidMapReceived(timestamp);
- }
-}
-
-void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid,
- const int64_t& versionCode, const String16& versionString,
- const String16& installer) {
- wp<PackageInfoListener> broadcast = NULL;
- string appName = string(String8(app_16).string());
- {
- lock_guard<mutex> lock(mMutex);
- int32_t prevVersion = 0;
- string prevVersionString = "";
- string newVersionString = string(String8(versionString).string());
- bool found = false;
- auto it = mMap.find(std::make_pair(uid, appName));
- if (it != mMap.end()) {
- found = true;
- prevVersion = it->second.versionCode;
- prevVersionString = it->second.versionString;
- it->second.versionCode = versionCode;
- it->second.versionString = newVersionString;
- it->second.installer = string(String8(installer).string());
- it->second.deleted = false;
- }
- if (!found) {
- // Otherwise, we need to add an app at this uid.
- mMap[std::make_pair(uid, appName)] =
- AppData(versionCode, newVersionString, string(String8(installer).string()));
- } else {
- // Only notify the listeners if this is an app upgrade. If this app is being installed
- // for the first time, then we don't notify the listeners.
- // It's also OK to split again if we're forming a partial bucket after re-installing an
- // app after deletion.
- broadcast = mSubscriber;
- }
- mChanges.emplace_back(false, timestamp, appName, uid, versionCode, newVersionString,
- prevVersion, prevVersionString);
- mBytesUsed += kBytesChangeRecord;
- ensureBytesUsedBelowLimit();
- StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
- StatsdStats::getInstance().setUidMapChanges(mChanges.size());
- }
-
- auto strongPtr = broadcast.promote();
- if (strongPtr != NULL) {
- strongPtr->notifyAppUpgrade(timestamp, appName, uid, versionCode);
- }
-}
-
-void UidMap::ensureBytesUsedBelowLimit() {
- size_t limit;
- if (maxBytesOverride <= 0) {
- limit = StatsdStats::kMaxBytesUsedUidMap;
- } else {
- limit = maxBytesOverride;
- }
- while (mBytesUsed > limit) {
- ALOGI("Bytes used %zu is above limit %zu, need to delete something", mBytesUsed, limit);
- if (mChanges.size() > 0) {
- mBytesUsed -= kBytesChangeRecord;
- mChanges.pop_front();
- StatsdStats::getInstance().noteUidMapDropped(1);
- }
- }
-}
-
-void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid) {
- wp<PackageInfoListener> broadcast = NULL;
- string app = string(String8(app_16).string());
- {
- lock_guard<mutex> lock(mMutex);
-
- int64_t prevVersion = 0;
- string prevVersionString = "";
- auto key = std::make_pair(uid, app);
- auto it = mMap.find(key);
- if (it != mMap.end() && !it->second.deleted) {
- prevVersion = it->second.versionCode;
- prevVersionString = it->second.versionString;
- it->second.deleted = true;
- mDeletedApps.push_back(key);
- }
- if (mDeletedApps.size() > StatsdStats::kMaxDeletedAppsInUidMap) {
- // Delete the oldest one.
- auto oldest = mDeletedApps.front();
- mDeletedApps.pop_front();
- mMap.erase(oldest);
- StatsdStats::getInstance().noteUidMapAppDeletionDropped();
- }
- mChanges.emplace_back(true, timestamp, app, uid, 0, "", prevVersion, prevVersionString);
- mBytesUsed += kBytesChangeRecord;
- ensureBytesUsedBelowLimit();
- StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
- StatsdStats::getInstance().setUidMapChanges(mChanges.size());
- broadcast = mSubscriber;
- }
-
- auto strongPtr = broadcast.promote();
- if (strongPtr != NULL) {
- strongPtr->notifyAppRemoved(timestamp, app, uid);
- }
-}
-
-void UidMap::setListener(wp<PackageInfoListener> listener) {
- lock_guard<mutex> lock(mMutex); // Lock for updates
- mSubscriber = listener;
-}
-
-void UidMap::assignIsolatedUid(int isolatedUid, int parentUid) {
- lock_guard<mutex> lock(mIsolatedMutex);
-
- mIsolatedUidMap[isolatedUid] = parentUid;
-}
-
-void UidMap::removeIsolatedUid(int isolatedUid) {
- lock_guard<mutex> lock(mIsolatedMutex);
-
- auto it = mIsolatedUidMap.find(isolatedUid);
- if (it != mIsolatedUidMap.end()) {
- mIsolatedUidMap.erase(it);
- }
-}
-
-int UidMap::getHostUidOrSelf(int uid) const {
- lock_guard<mutex> lock(mIsolatedMutex);
-
- auto it = mIsolatedUidMap.find(uid);
- if (it != mIsolatedUidMap.end()) {
- return it->second;
- }
- return uid;
-}
-
-void UidMap::clearOutput() {
- mChanges.clear();
- // Also update the guardrail trackers.
- StatsdStats::getInstance().setUidMapChanges(0);
- mBytesUsed = 0;
- StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
-}
-
-int64_t UidMap::getMinimumTimestampNs() {
- int64_t m = 0;
- for (const auto& kv : mLastUpdatePerConfigKey) {
- if (m == 0) {
- m = kv.second;
- } else if (kv.second < m) {
- m = kv.second;
- }
- }
- return m;
-}
-
-size_t UidMap::getBytesUsed() const {
- return mBytesUsed;
-}
-
-void UidMap::writeUidMapSnapshot(int64_t timestamp, bool includeVersionStrings,
- bool includeInstaller, const std::set<int32_t>& interestingUids,
- std::set<string>* str_set, ProtoOutputStream* proto) {
- lock_guard<mutex> lock(mMutex);
-
- writeUidMapSnapshotLocked(timestamp, includeVersionStrings, includeInstaller, interestingUids,
- str_set, proto);
-}
-
-void UidMap::writeUidMapSnapshotLocked(int64_t timestamp, bool includeVersionStrings,
- bool includeInstaller,
- const std::set<int32_t>& interestingUids,
- std::set<string>* str_set, ProtoOutputStream* proto) {
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_TIMESTAMP, (long long)timestamp);
- for (const auto& kv : mMap) {
- if (!interestingUids.empty() &&
- interestingUids.find(kv.first.first) == interestingUids.end()) {
- continue;
- }
- uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SNAPSHOT_PACKAGE_INFO);
- if (str_set != nullptr) {
- str_set->insert(kv.first.second);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH,
- (long long)Hash64(kv.first.second));
- if (includeVersionStrings) {
- str_set->insert(kv.second.versionString);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING_HASH,
- (long long)Hash64(kv.second.versionString));
- }
- if (includeInstaller) {
- str_set->insert(kv.second.installer);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_HASH,
- (long long)Hash64(kv.second.installer));
- }
- } else {
- proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_NAME, kv.first.second);
- if (includeVersionStrings) {
- proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING,
- kv.second.versionString);
- }
- if (includeInstaller) {
- proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER,
- kv.second.installer);
- }
- }
-
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION,
- (long long)kv.second.versionCode);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_UID, kv.first.first);
- proto->write(FIELD_TYPE_BOOL | FIELD_ID_SNAPSHOT_PACKAGE_DELETED, kv.second.deleted);
- proto->end(token);
- }
-}
-
-void UidMap::appendUidMap(const int64_t& timestamp, const ConfigKey& key, std::set<string>* str_set,
- bool includeVersionStrings, bool includeInstaller,
- ProtoOutputStream* proto) {
- lock_guard<mutex> lock(mMutex); // Lock for updates
-
- for (const ChangeRecord& record : mChanges) {
- if (record.timestampNs > mLastUpdatePerConfigKey[key]) {
- uint64_t changesToken =
- proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CHANGES);
- proto->write(FIELD_TYPE_BOOL | FIELD_ID_CHANGE_DELETION, (bool)record.deletion);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_TIMESTAMP,
- (long long)record.timestampNs);
- if (str_set != nullptr) {
- str_set->insert(record.package);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PACKAGE_HASH,
- (long long)Hash64(record.package));
- if (includeVersionStrings) {
- str_set->insert(record.versionString);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_NEW_VERSION_STRING_HASH,
- (long long)Hash64(record.versionString));
- str_set->insert(record.prevVersionString);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PREV_VERSION_STRING_HASH,
- (long long)Hash64(record.prevVersionString));
- }
- } else {
- proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PACKAGE, record.package);
- if (includeVersionStrings) {
- proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_NEW_VERSION_STRING,
- record.versionString);
- proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PREV_VERSION_STRING,
- record.prevVersionString);
- }
- }
-
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CHANGE_UID, (int)record.uid);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_NEW_VERSION, (long long)record.version);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_PREV_VERSION,
- (long long)record.prevVersion);
- proto->end(changesToken);
- }
- }
-
- // Write snapshot from current uid map state.
- uint64_t snapshotsToken =
- proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SNAPSHOTS);
- writeUidMapSnapshotLocked(timestamp, includeVersionStrings, includeInstaller,
- std::set<int32_t>() /*empty uid set means including every uid*/,
- str_set, proto);
- proto->end(snapshotsToken);
-
- int64_t prevMin = getMinimumTimestampNs();
- mLastUpdatePerConfigKey[key] = timestamp;
- int64_t newMin = getMinimumTimestampNs();
-
- if (newMin > prevMin) { // Delete anything possible now that the minimum has
- // moved forward.
- int64_t cutoff_nanos = newMin;
- for (auto it_changes = mChanges.begin(); it_changes != mChanges.end();) {
- if (it_changes->timestampNs < cutoff_nanos) {
- mBytesUsed -= kBytesChangeRecord;
- it_changes = mChanges.erase(it_changes);
- } else {
- ++it_changes;
- }
- }
- }
- StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
- StatsdStats::getInstance().setUidMapChanges(mChanges.size());
-}
-
-void UidMap::printUidMap(int out) const {
- lock_guard<mutex> lock(mMutex);
-
- for (const auto& kv : mMap) {
- if (!kv.second.deleted) {
- dprintf(out, "%s, v%" PRId64 ", %s, %s (%i)\n", kv.first.second.c_str(),
- kv.second.versionCode, kv.second.versionString.c_str(),
- kv.second.installer.c_str(), kv.first.first);
- }
- }
-}
-
-void UidMap::OnConfigUpdated(const ConfigKey& key) {
- mLastUpdatePerConfigKey[key] = -1;
-}
-
-void UidMap::OnConfigRemoved(const ConfigKey& key) {
- mLastUpdatePerConfigKey.erase(key);
-}
-
-set<int32_t> UidMap::getAppUid(const string& package) const {
- lock_guard<mutex> lock(mMutex);
-
- set<int32_t> results;
- for (const auto& kv : mMap) {
- if (kv.first.second == package && !kv.second.deleted) {
- results.insert(kv.first.first);
- }
- }
- return results;
-}
-
-// Note not all the following AIDs are used as uids. Some are used only for gids.
-// It's ok to leave them in the map, but we won't ever see them in the log's uid field.
-// App's uid starts from 10000, and will not overlap with the following AIDs.
-const std::map<string, uint32_t> UidMap::sAidToUidMapping = {{"AID_ROOT", 0},
- {"AID_SYSTEM", 1000},
- {"AID_RADIO", 1001},
- {"AID_BLUETOOTH", 1002},
- {"AID_GRAPHICS", 1003},
- {"AID_INPUT", 1004},
- {"AID_AUDIO", 1005},
- {"AID_CAMERA", 1006},
- {"AID_LOG", 1007},
- {"AID_COMPASS", 1008},
- {"AID_MOUNT", 1009},
- {"AID_WIFI", 1010},
- {"AID_ADB", 1011},
- {"AID_INSTALL", 1012},
- {"AID_MEDIA", 1013},
- {"AID_DHCP", 1014},
- {"AID_SDCARD_RW", 1015},
- {"AID_VPN", 1016},
- {"AID_KEYSTORE", 1017},
- {"AID_USB", 1018},
- {"AID_DRM", 1019},
- {"AID_MDNSR", 1020},
- {"AID_GPS", 1021},
- // {"AID_UNUSED1", 1022},
- {"AID_MEDIA_RW", 1023},
- {"AID_MTP", 1024},
- // {"AID_UNUSED2", 1025},
- {"AID_DRMRPC", 1026},
- {"AID_NFC", 1027},
- {"AID_SDCARD_R", 1028},
- {"AID_CLAT", 1029},
- {"AID_LOOP_RADIO", 1030},
- {"AID_MEDIA_DRM", 1031},
- {"AID_PACKAGE_INFO", 1032},
- {"AID_SDCARD_PICS", 1033},
- {"AID_SDCARD_AV", 1034},
- {"AID_SDCARD_ALL", 1035},
- {"AID_LOGD", 1036},
- {"AID_SHARED_RELRO", 1037},
- {"AID_DBUS", 1038},
- {"AID_TLSDATE", 1039},
- {"AID_MEDIA_EX", 1040},
- {"AID_AUDIOSERVER", 1041},
- {"AID_METRICS_COLL", 1042},
- {"AID_METRICSD", 1043},
- {"AID_WEBSERV", 1044},
- {"AID_DEBUGGERD", 1045},
- {"AID_MEDIA_CODEC", 1046},
- {"AID_CAMERASERVER", 1047},
- {"AID_FIREWALL", 1048},
- {"AID_TRUNKS", 1049},
- {"AID_NVRAM", 1050},
- {"AID_DNS", 1051},
- {"AID_DNS_TETHER", 1052},
- {"AID_WEBVIEW_ZYGOTE", 1053},
- {"AID_VEHICLE_NETWORK", 1054},
- {"AID_MEDIA_AUDIO", 1055},
- {"AID_MEDIA_VIDEO", 1056},
- {"AID_MEDIA_IMAGE", 1057},
- {"AID_TOMBSTONED", 1058},
- {"AID_MEDIA_OBB", 1059},
- {"AID_ESE", 1060},
- {"AID_OTA_UPDATE", 1061},
- {"AID_AUTOMOTIVE_EVS", 1062},
- {"AID_LOWPAN", 1063},
- {"AID_HSM", 1064},
- {"AID_RESERVED_DISK", 1065},
- {"AID_STATSD", 1066},
- {"AID_INCIDENTD", 1067},
- {"AID_SECURE_ELEMENT", 1068},
- {"AID_LMKD", 1069},
- {"AID_LLKD", 1070},
- {"AID_IORAPD", 1071},
- {"AID_GPU_SERVICE", 1072},
- {"AID_NETWORK_STACK", 1073},
- {"AID_GSID", 1074},
- {"AID_FSVERITY_CERT", 1075},
- {"AID_CREDSTORE", 1076},
- {"AID_EXTERNAL_STORAGE", 1077},
- {"AID_EXT_DATA_RW", 1078},
- {"AID_EXT_OBB_RW", 1079},
- {"AID_CONTEXT_HUB", 1080},
- {"AID_SHELL", 2000},
- {"AID_CACHE", 2001},
- {"AID_DIAG", 2002}};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
deleted file mode 100644
index 22250ae..0000000
--- a/cmds/statsd/src/packages/UidMap.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-#include "config/ConfigListener.h"
-#include "packages/PackageInfoListener.h"
-#include "stats_util.h"
-
-#include <gtest/gtest_prod.h>
-#include <stdio.h>
-#include <utils/RefBase.h>
-#include <utils/String16.h>
-
-#include <list>
-#include <mutex>
-#include <set>
-#include <string>
-#include <unordered_map>
-
-using namespace android;
-using namespace std;
-
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct AppData {
- int64_t versionCode;
- string versionString;
- string installer;
- bool deleted;
-
- // Empty constructor needed for unordered map.
- AppData() {
- }
-
- AppData(const int64_t v, const string& versionString, const string& installer)
- : versionCode(v), versionString(versionString), installer(installer), deleted(false){};
-};
-
-// When calling appendUidMap, we retrieve all the ChangeRecords since the last
-// timestamp we called appendUidMap for this configuration key.
-struct ChangeRecord {
- const bool deletion;
- const int64_t timestampNs;
- const string package;
- const int32_t uid;
- const int64_t version;
- const int64_t prevVersion;
- const string versionString;
- const string prevVersionString;
-
- ChangeRecord(const bool isDeletion, const int64_t timestampNs, const string& package,
- const int32_t uid, const int64_t version, const string versionString,
- const int64_t prevVersion, const string prevVersionString)
- : deletion(isDeletion),
- timestampNs(timestampNs),
- package(package),
- uid(uid),
- version(version),
- prevVersion(prevVersion),
- versionString(versionString),
- prevVersionString(prevVersionString) {
- }
-};
-
-const unsigned int kBytesChangeRecord = sizeof(struct ChangeRecord);
-
-// UidMap keeps track of what the corresponding app name (APK name) and version code for every uid
-// at any given moment. This map must be updated by StatsCompanionService.
-class UidMap : public virtual android::RefBase {
-public:
- UidMap();
- ~UidMap();
- static const std::map<std::string, uint32_t> sAidToUidMapping;
-
- static sp<UidMap> getInstance();
- /*
- * All three inputs must be the same size, and the jth element in each array refers to the same
- * tuple, ie. uid[j] corresponds to packageName[j] with versionCode[j].
- */
- void updateMap(const int64_t& timestamp, const vector<int32_t>& uid,
- const vector<int64_t>& versionCode, const vector<String16>& versionString,
- const vector<String16>& packageName, const vector<String16>& installer);
-
- void updateApp(const int64_t& timestamp, const String16& packageName, const int32_t& uid,
- const int64_t& versionCode, const String16& versionString,
- const String16& installer);
- void removeApp(const int64_t& timestamp, const String16& packageName, const int32_t& uid);
-
- // Returns true if the given uid contains the specified app (eg. com.google.android.gms).
- bool hasApp(int uid, const string& packageName) const;
-
- // Returns the app names from uid.
- std::set<string> getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const;
-
- int64_t getAppVersion(int uid, const string& packageName) const;
-
- // Helper for debugging contents of this uid map. Can be triggered with:
- // adb shell cmd stats print-uid-map
- void printUidMap(int outFd) const;
-
- // Command for indicating to the map that StatsLogProcessor should be notified if an app is
- // updated. This allows metric producers and managers to distinguish when the same uid or app
- // represents a different version of an app.
- void setListener(wp<PackageInfoListener> listener);
-
- // Informs uid map that a config is added/updated. Used for keeping mConfigKeys up to date.
- void OnConfigUpdated(const ConfigKey& key);
-
- // Informs uid map that a config is removed. Used for keeping mConfigKeys up to date.
- void OnConfigRemoved(const ConfigKey& key);
-
- void assignIsolatedUid(int isolatedUid, int parentUid);
- void removeIsolatedUid(int isolatedUid);
-
- // Returns the host uid if it exists. Otherwise, returns the same uid that was passed-in.
- virtual int getHostUidOrSelf(int uid) const;
-
- // Gets all snapshots and changes that have occurred since the last output.
- // If every config key has received a change or snapshot record, then this
- // record is deleted.
- void appendUidMap(const int64_t& timestamp, const ConfigKey& key, std::set<string>* str_set,
- bool includeVersionStrings, bool includeInstaller,
- ProtoOutputStream* proto);
-
- // Forces the output to be cleared. We still generate a snapshot based on the current state.
- // This results in extra data uploaded but helps us reconstruct the uid mapping on the server
- // in case we lose a previous upload.
- void clearOutput();
-
- // Get currently cached value of memory used by UID map.
- size_t getBytesUsed() const;
-
- virtual std::set<int32_t> getAppUid(const string& package) const;
-
- // Write current PackageInfoSnapshot to ProtoOutputStream.
- // interestingUids: If not empty, only write the package info for these uids. If empty, write
- // package info for all uids.
- // str_set: if not null, add new string to the set and write str_hash to proto
- // if null, write string to proto.
- void writeUidMapSnapshot(int64_t timestamp, bool includeVersionStrings, bool includeInstaller,
- const std::set<int32_t>& interestingUids, std::set<string>* str_set,
- ProtoOutputStream* proto);
-
-private:
- std::set<string> getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const;
- string normalizeAppName(const string& appName) const;
-
- void writeUidMapSnapshotLocked(int64_t timestamp, bool includeVersionStrings,
- bool includeInstaller, const std::set<int32_t>& interestingUids,
- std::set<string>* str_set, ProtoOutputStream* proto);
-
- mutable mutex mMutex;
- mutable mutex mIsolatedMutex;
-
- struct PairHash {
- size_t operator()(std::pair<int, string> p) const noexcept {
- std::hash<std::string> hash_fn;
- return hash_fn(std::to_string(p.first) + p.second);
- }
- };
- // Maps uid and package name to application data.
- std::unordered_map<std::pair<int, string>, AppData, PairHash> mMap;
-
- // Maps isolated uid to the parent uid. Any metrics for an isolated uid will instead contribute
- // to the parent uid.
- std::unordered_map<int, int> mIsolatedUidMap;
-
- // Record the changes that can be provided with the uploads.
- std::list<ChangeRecord> mChanges;
-
- // Store which uid and apps represent deleted ones.
- std::list<std::pair<int, string>> mDeletedApps;
-
- // Notify StatsLogProcessor if there's an upgrade/removal in any app.
- wp<PackageInfoListener> mSubscriber;
-
- // Mapping of config keys we're aware of to the epoch time they last received an update. This
- // lets us know it's safe to delete events older than the oldest update. The value is nanosec.
- // Value of -1 denotes this config key has never received an upload.
- std::unordered_map<ConfigKey, int64_t> mLastUpdatePerConfigKey;
-
- // Returns the minimum value from mConfigKeys.
- int64_t getMinimumTimestampNs();
-
- // If our current used bytes is above the limit, then we clear out the earliest snapshot. If
- // there are no more snapshots, then we clear out the earliest delta. We repeat the deletions
- // until the memory consumed by mOutput is below the specified limit.
- void ensureBytesUsedBelowLimit();
-
- // Override used for testing the max memory allowed by uid map. 0 means we use the value
- // specified in StatsdStats.h with the rest of the guardrails.
- size_t maxBytesOverride = 0;
-
- // Cache the size of mOutput;
- size_t mBytesUsed;
-
- // Allows unit-test to access private methods.
- FRIEND_TEST(UidMapTest, TestClearingOutput);
- FRIEND_TEST(UidMapTest, TestRemovedAppRetained);
- FRIEND_TEST(UidMapTest, TestRemovedAppOverGuardrail);
- FRIEND_TEST(UidMapTest, TestOutputIncludesAtLeastOneSnapshot);
- FRIEND_TEST(UidMapTest, TestMemoryComputed);
- FRIEND_TEST(UidMapTest, TestMemoryGuardrail);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp
deleted file mode 100644
index fd883c2..0000000
--- a/cmds/statsd/src/shell/ShellSubscriber.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "ShellSubscriber.h"
-
-#include <android-base/file.h>
-
-#include "matchers/matcher_util.h"
-#include "stats_log_util.h"
-
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const static int FIELD_ID_ATOM = 1;
-
-void ShellSubscriber::startNewSubscription(int in, int out, int timeoutSec) {
- int myToken = claimToken();
- VLOG("ShellSubscriber: new subscription %d has come in", myToken);
- mSubscriptionShouldEnd.notify_one();
-
- shared_ptr<SubscriptionInfo> mySubscriptionInfo = make_shared<SubscriptionInfo>(in, out);
- if (!readConfig(mySubscriptionInfo)) return;
-
- {
- std::unique_lock<std::mutex> lock(mMutex);
- mSubscriptionInfo = mySubscriptionInfo;
- spawnHelperThread(myToken);
- waitForSubscriptionToEndLocked(mySubscriptionInfo, myToken, lock, timeoutSec);
-
- if (mSubscriptionInfo == mySubscriptionInfo) {
- mSubscriptionInfo = nullptr;
- }
-
- }
-}
-
-void ShellSubscriber::spawnHelperThread(int myToken) {
- std::thread t([this, myToken] { pullAndSendHeartbeats(myToken); });
- t.detach();
-}
-
-void ShellSubscriber::waitForSubscriptionToEndLocked(shared_ptr<SubscriptionInfo> myInfo,
- int myToken,
- std::unique_lock<std::mutex>& lock,
- int timeoutSec) {
- if (timeoutSec > 0) {
- mSubscriptionShouldEnd.wait_for(lock, timeoutSec * 1s, [this, myToken, &myInfo] {
- return mToken != myToken || !myInfo->mClientAlive;
- });
- } else {
- mSubscriptionShouldEnd.wait(lock, [this, myToken, &myInfo] {
- return mToken != myToken || !myInfo->mClientAlive;
- });
- }
-}
-
-// Atomically claim the next token. Token numbers denote subscriber ordering.
-int ShellSubscriber::claimToken() {
- std::unique_lock<std::mutex> lock(mMutex);
- int myToken = ++mToken;
- return myToken;
-}
-
-// Read and parse single config. There should only one config per input.
-bool ShellSubscriber::readConfig(shared_ptr<SubscriptionInfo> subscriptionInfo) {
- // Read the size of the config.
- size_t bufferSize;
- if (!android::base::ReadFully(subscriptionInfo->mInputFd, &bufferSize, sizeof(bufferSize))) {
- return false;
- }
-
- // Read the config.
- vector<uint8_t> buffer(bufferSize);
- if (!android::base::ReadFully(subscriptionInfo->mInputFd, buffer.data(), bufferSize)) {
- return false;
- }
-
- // Parse the config.
- ShellSubscription config;
- if (!config.ParseFromArray(buffer.data(), bufferSize)) {
- return false;
- }
-
- // Update SubscriptionInfo with state from config
- for (const auto& pushed : config.pushed()) {
- subscriptionInfo->mPushedMatchers.push_back(pushed);
- }
-
- for (const auto& pulled : config.pulled()) {
- vector<string> packages;
- vector<int32_t> uids;
- for (const string& pkg : pulled.packages()) {
- auto it = UidMap::sAidToUidMapping.find(pkg);
- if (it != UidMap::sAidToUidMapping.end()) {
- uids.push_back(it->second);
- } else {
- packages.push_back(pkg);
- }
- }
-
- subscriptionInfo->mPulledInfo.emplace_back(pulled.matcher(), pulled.freq_millis(), packages,
- uids);
- VLOG("adding matcher for pulled atom %d", pulled.matcher().atom_id());
- }
-
- return true;
-}
-
-void ShellSubscriber::pullAndSendHeartbeats(int myToken) {
- VLOG("ShellSubscriber: helper thread %d starting", myToken);
- while (true) {
- int64_t sleepTimeMs = INT_MAX;
- {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mSubscriptionInfo || mToken != myToken) {
- VLOG("ShellSubscriber: helper thread %d done!", myToken);
- return;
- }
-
- int64_t nowMillis = getElapsedRealtimeMillis();
- int64_t nowNanos = getElapsedRealtimeNs();
- for (PullInfo& pullInfo : mSubscriptionInfo->mPulledInfo) {
- if (pullInfo.mPrevPullElapsedRealtimeMs + pullInfo.mInterval >= nowMillis) {
- continue;
- }
-
- vector<int32_t> uids;
- getUidsForPullAtom(&uids, pullInfo);
-
- vector<std::shared_ptr<LogEvent>> data;
- mPullerMgr->Pull(pullInfo.mPullerMatcher.atom_id(), uids, nowNanos, &data);
- VLOG("Pulled %zu atoms with id %d", data.size(), pullInfo.mPullerMatcher.atom_id());
- writePulledAtomsLocked(data, pullInfo.mPullerMatcher);
-
- pullInfo.mPrevPullElapsedRealtimeMs = nowMillis;
- }
-
- // Send a heartbeat, consisting of a data size of 0, if perfd hasn't recently received
- // data from statsd. When it receives the data size of 0, perfd will not expect any
- // atoms and recheck whether the subscription should end.
- if (nowMillis - mLastWriteMs > kMsBetweenHeartbeats) {
- attemptWriteToPipeLocked(/*dataSize=*/0);
- }
-
- // Determine how long to sleep before doing more work.
- for (PullInfo& pullInfo : mSubscriptionInfo->mPulledInfo) {
- int64_t nextPullTime = pullInfo.mPrevPullElapsedRealtimeMs + pullInfo.mInterval;
- int64_t timeBeforePull = nextPullTime - nowMillis; // guaranteed to be non-negative
- if (timeBeforePull < sleepTimeMs) sleepTimeMs = timeBeforePull;
- }
- int64_t timeBeforeHeartbeat = (mLastWriteMs + kMsBetweenHeartbeats) - nowMillis;
- if (timeBeforeHeartbeat < sleepTimeMs) sleepTimeMs = timeBeforeHeartbeat;
- }
-
- VLOG("ShellSubscriber: helper thread %d sleeping for %lld ms", myToken,
- (long long)sleepTimeMs);
- std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
- }
-}
-
-void ShellSubscriber::getUidsForPullAtom(vector<int32_t>* uids, const PullInfo& pullInfo) {
- uids->insert(uids->end(), pullInfo.mPullUids.begin(), pullInfo.mPullUids.end());
- // This is slow. Consider storing the uids per app and listening to uidmap updates.
- for (const string& pkg : pullInfo.mPullPackages) {
- set<int32_t> uidsForPkg = mUidMap->getAppUid(pkg);
- uids->insert(uids->end(), uidsForPkg.begin(), uidsForPkg.end());
- }
- uids->push_back(DEFAULT_PULL_UID);
-}
-
-void ShellSubscriber::writePulledAtomsLocked(const vector<std::shared_ptr<LogEvent>>& data,
- const SimpleAtomMatcher& matcher) {
- mProto.clear();
- int count = 0;
- for (const auto& event : data) {
- if (matchesSimple(*mUidMap, matcher, *event)) {
- count++;
- uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
- util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
- event->ToProto(mProto);
- mProto.end(atomToken);
- }
- }
-
- if (count > 0) attemptWriteToPipeLocked(mProto.size());
-}
-
-void ShellSubscriber::onLogEvent(const LogEvent& event) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mSubscriptionInfo) return;
-
- mProto.clear();
- for (const auto& matcher : mSubscriptionInfo->mPushedMatchers) {
- if (matchesSimple(*mUidMap, matcher, event)) {
- uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
- util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
- event.ToProto(mProto);
- mProto.end(atomToken);
- attemptWriteToPipeLocked(mProto.size());
- }
- }
-}
-
-// Tries to write the atom encoded in mProto to the pipe. If the write fails
-// because the read end of the pipe has closed, signals to other threads that
-// the subscription should end.
-void ShellSubscriber::attemptWriteToPipeLocked(size_t dataSize) {
- // First, write the payload size.
- if (!android::base::WriteFully(mSubscriptionInfo->mOutputFd, &dataSize, sizeof(dataSize))) {
- mSubscriptionInfo->mClientAlive = false;
- mSubscriptionShouldEnd.notify_one();
- return;
- }
-
- // Then, write the payload if this is not just a heartbeat.
- if (dataSize > 0 && !mProto.flush(mSubscriptionInfo->mOutputFd)) {
- mSubscriptionInfo->mClientAlive = false;
- mSubscriptionShouldEnd.notify_one();
- return;
- }
-
- mLastWriteMs = getElapsedRealtimeMillis();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/shell/ShellSubscriber.h b/cmds/statsd/src/shell/ShellSubscriber.h
deleted file mode 100644
index 4c05fa7..0000000
--- a/cmds/statsd/src/shell/ShellSubscriber.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/util/ProtoOutputStream.h>
-#include <private/android_filesystem_config.h>
-
-#include <condition_variable>
-#include <mutex>
-#include <thread>
-
-#include "external/StatsPullerManager.h"
-#include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Handles atoms subscription via shell cmd.
- *
- * A shell subscription lasts *until shell exits*. Unlike config based clients, a shell client
- * communicates with statsd via file descriptors. They can subscribe pushed and pulled atoms.
- * The atoms are sent back to the client in real time, as opposed to keeping the data in memory.
- * Shell clients do not subscribe aggregated metrics, as they are responsible for doing the
- * aggregation after receiving the atom events.
- *
- * Shell clients pass ShellSubscription in the proto binary format. Clients can update the
- * subscription by sending a new subscription. The new subscription would replace the old one.
- * Input data stream format is:
- *
- * |size_t|subscription proto|size_t|subscription proto|....
- *
- * statsd sends the events back in Atom proto binary format. Each Atom message is preceded
- * with sizeof(size_t) bytes indicating the size of the proto message payload.
- *
- * The stream would be in the following format:
- * |size_t|shellData proto|size_t|shellData proto|....
- *
- * Only one shell subscriber is allowed at a time because each shell subscriber blocks one thread
- * until it exits.
- */
-class ShellSubscriber : public virtual RefBase {
-public:
- ShellSubscriber(sp<UidMap> uidMap, sp<StatsPullerManager> pullerMgr)
- : mUidMap(uidMap), mPullerMgr(pullerMgr){};
-
- void startNewSubscription(int inFd, int outFd, int timeoutSec);
-
- void onLogEvent(const LogEvent& event);
-
-private:
- struct PullInfo {
- PullInfo(const SimpleAtomMatcher& matcher, int64_t interval,
- const std::vector<std::string>& packages, const std::vector<int32_t>& uids)
- : mPullerMatcher(matcher),
- mInterval(interval),
- mPrevPullElapsedRealtimeMs(0),
- mPullPackages(packages),
- mPullUids(uids) {
- }
- SimpleAtomMatcher mPullerMatcher;
- int64_t mInterval;
- int64_t mPrevPullElapsedRealtimeMs;
- std::vector<std::string> mPullPackages;
- std::vector<int32_t> mPullUids;
- };
-
- struct SubscriptionInfo {
- SubscriptionInfo(const int& inputFd, const int& outputFd)
- : mInputFd(inputFd), mOutputFd(outputFd), mClientAlive(true) {
- }
-
- int mInputFd;
- int mOutputFd;
- std::vector<SimpleAtomMatcher> mPushedMatchers;
- std::vector<PullInfo> mPulledInfo;
- bool mClientAlive;
- };
-
- int claimToken();
-
- bool readConfig(std::shared_ptr<SubscriptionInfo> subscriptionInfo);
-
- void spawnHelperThread(int myToken);
-
- void waitForSubscriptionToEndLocked(std::shared_ptr<SubscriptionInfo> myInfo,
- int myToken,
- std::unique_lock<std::mutex>& lock,
- int timeoutSec);
-
- // Helper thread that pulls atoms at a regular frequency and sends
- // heartbeats to perfd if statsd hasn't recently sent any data. Statsd must
- // send heartbeats for perfd to escape a blocking read call and recheck if
- // the user has terminated the subscription.
- void pullAndSendHeartbeats(int myToken);
-
- void writePulledAtomsLocked(const vector<std::shared_ptr<LogEvent>>& data,
- const SimpleAtomMatcher& matcher);
-
- void getUidsForPullAtom(vector<int32_t>* uids, const PullInfo& pullInfo);
-
- void attemptWriteToPipeLocked(size_t dataSize);
-
- sp<UidMap> mUidMap;
-
- sp<StatsPullerManager> mPullerMgr;
-
- android::util::ProtoOutputStream mProto;
-
- mutable std::mutex mMutex;
-
- std::condition_variable mSubscriptionShouldEnd;
-
- std::shared_ptr<SubscriptionInfo> mSubscriptionInfo = nullptr;
-
- int mToken = 0;
-
- const int32_t DEFAULT_PULL_UID = AID_SYSTEM;
-
- // Tracks when we last send data to perfd. We need that time to determine
- // when next to send a heartbeat.
- int64_t mLastWriteMs = 0;
- const int64_t kMsBetweenHeartbeats = 1000;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/shell/shell_config.proto b/cmds/statsd/src/shell/shell_config.proto
deleted file mode 100644
index 07d0310..0000000
--- a/cmds/statsd/src/shell/shell_config.proto
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.os";
-option java_outer_classname = "ShellConfig";
-
-import "frameworks/base/cmds/statsd/src/statsd_config.proto";
-
-message PulledAtomSubscription {
- optional SimpleAtomMatcher matcher = 1;
-
- /* gap between two pulls in milliseconds */
- optional int32 freq_millis = 2;
-
- /* Packages that the pull is requested from */
- repeated string packages = 3;
-}
-
-message ShellSubscription {
- repeated SimpleAtomMatcher pushed = 1;
- repeated PulledAtomSubscription pulled = 2;
-}
\ No newline at end of file
diff --git a/cmds/statsd/src/shell/shell_data.proto b/cmds/statsd/src/shell/shell_data.proto
deleted file mode 100644
index 236bdbd..0000000
--- a/cmds/statsd/src/shell/shell_data.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.os.statsd";
-option java_outer_classname = "ShellDataProto";
-
-import "frameworks/base/cmds/statsd/src/atoms.proto";
-
-// The output of shell subscription, including both pulled and pushed subscriptions.
-message ShellData {
- repeated Atom atom = 1;
-}
diff --git a/cmds/statsd/src/socket/StatsSocketListener.cpp b/cmds/statsd/src/socket/StatsSocketListener.cpp
deleted file mode 100755
index b877cc9..0000000
--- a/cmds/statsd/src/socket/StatsSocketListener.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include <ctype.h>
-#include <limits.h>
-#include <stdio.h>
-#include <sys/cdefs.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <cutils/sockets.h>
-
-#include "StatsSocketListener.h"
-#include "guardrail/StatsdStats.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsSocketListener::StatsSocketListener(std::shared_ptr<LogEventQueue> queue)
- : SocketListener(getLogSocket(), false /*start listen*/), mQueue(queue) {
-}
-
-StatsSocketListener::~StatsSocketListener() {
-}
-
-bool StatsSocketListener::onDataAvailable(SocketClient* cli) {
- static bool name_set;
- if (!name_set) {
- prctl(PR_SET_NAME, "statsd.writer");
- name_set = true;
- }
-
- // + 1 to ensure null terminator if MAX_PAYLOAD buffer is received
- char buffer[sizeof(android_log_header_t) + LOGGER_ENTRY_MAX_PAYLOAD + 1];
- struct iovec iov = {buffer, sizeof(buffer) - 1};
-
- alignas(4) char control[CMSG_SPACE(sizeof(struct ucred))];
- struct msghdr hdr = {
- NULL, 0, &iov, 1, control, sizeof(control), 0,
- };
-
- int socket = cli->getSocket();
-
- // To clear the entire buffer is secure/safe, but this contributes to 1.68%
- // overhead under logging load. We are safe because we check counts, but
- // still need to clear null terminator
- // memset(buffer, 0, sizeof(buffer));
- ssize_t n = recvmsg(socket, &hdr, 0);
- if (n <= (ssize_t)(sizeof(android_log_header_t))) {
- return false;
- }
-
- buffer[n] = 0;
-
- struct ucred* cred = NULL;
-
- struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
- while (cmsg != NULL) {
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
- cred = (struct ucred*)CMSG_DATA(cmsg);
- break;
- }
- cmsg = CMSG_NXTHDR(&hdr, cmsg);
- }
-
- struct ucred fake_cred;
- if (cred == NULL) {
- cred = &fake_cred;
- cred->pid = 0;
- cred->uid = DEFAULT_OVERFLOWUID;
- }
-
- uint8_t* ptr = ((uint8_t*)buffer) + sizeof(android_log_header_t);
- n -= sizeof(android_log_header_t);
-
- // When a log failed to write to statsd socket (e.g., due ot EBUSY), a special message would
- // be sent to statsd when the socket communication becomes available again.
- // The format is android_log_event_int_t with a single integer in the payload indicating the
- // number of logs that failed. (*FORMAT MUST BE IN SYNC WITH system/core/libstats*)
- // Note that all normal stats logs are in the format of event_list, so there won't be confusion.
- //
- // TODO(b/80538532): In addition to log it in StatsdStats, we should properly reset the config.
- if (n == sizeof(android_log_event_long_t)) {
- android_log_event_long_t* long_event = reinterpret_cast<android_log_event_long_t*>(ptr);
- if (long_event->payload.type == EVENT_TYPE_LONG) {
- int64_t composed_long = long_event->payload.data;
-
- // format:
- // |last_tag|dropped_count|
- int32_t dropped_count = (int32_t)(0xffffffff & composed_long);
- int32_t last_atom_tag = (int32_t)((0xffffffff00000000 & (uint64_t)composed_long) >> 32);
-
- ALOGE("Found dropped events: %d error %d last atom tag %d from uid %d", dropped_count,
- long_event->header.tag, last_atom_tag, cred->uid);
- StatsdStats::getInstance().noteLogLost((int32_t)getWallClockSec(), dropped_count,
- long_event->header.tag, last_atom_tag, cred->uid,
- cred->pid);
- return true;
- }
- }
-
- // move past the 4-byte StatsEventTag
- uint8_t* msg = ptr + sizeof(uint32_t);
- uint32_t len = n - sizeof(uint32_t);
- uint32_t uid = cred->uid;
- uint32_t pid = cred->pid;
-
- int64_t oldestTimestamp;
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(uid, pid);
- logEvent->parseBuffer(msg, len);
-
- if (!mQueue->push(std::move(logEvent), &oldestTimestamp)) {
- StatsdStats::getInstance().noteEventQueueOverflow(oldestTimestamp);
- }
-
- return true;
-}
-
-int StatsSocketListener::getLogSocket() {
- static const char socketName[] = "statsdw";
- int sock = android_get_control_socket(socketName);
-
- if (sock < 0) { // statsd started up in init.sh
- sock = socket_local_server(socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM);
-
- int on = 1;
- if (setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
- return -1;
- }
- }
- return sock;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/socket/StatsSocketListener.h b/cmds/statsd/src/socket/StatsSocketListener.h
deleted file mode 100644
index 2167a56..0000000
--- a/cmds/statsd/src/socket/StatsSocketListener.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <sysutils/SocketListener.h>
-#include <utils/RefBase.h>
-#include "logd/LogEventQueue.h"
-
-// DEFAULT_OVERFLOWUID is defined in linux/highuid.h, which is not part of
-// the uapi headers for userspace to use. This value is filled in on the
-// out-of-band socket credentials if the OS fails to find one available.
-// One of the causes of this is if SO_PASSCRED is set, all the packets before
-// that point will have this value. We also use it in a fake credential if
-// no socket credentials are supplied.
-#ifndef DEFAULT_OVERFLOWUID
-#define DEFAULT_OVERFLOWUID 65534
-#endif
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsSocketListener : public SocketListener, public virtual android::RefBase {
-public:
- explicit StatsSocketListener(std::shared_ptr<LogEventQueue> queue);
-
- virtual ~StatsSocketListener();
-
-protected:
- virtual bool onDataAvailable(SocketClient* cli);
-
-private:
- static int getLogSocket();
- /**
- * Who is going to get the events when they're read.
- */
- std::shared_ptr<LogEventQueue> mQueue;
-};
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/state/StateListener.h b/cmds/statsd/src/state/StateListener.h
deleted file mode 100644
index 6388001..0000000
--- a/cmds/statsd/src/state/StateListener.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-
-#include "HashableDimensionKey.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StateListener : public virtual RefBase {
-public:
- StateListener(){};
-
- virtual ~StateListener(){};
-
- /**
- * Interface for handling a state change.
- *
- * The old and new state values map to the original state values.
- * StateTrackers only track the original state values and are unaware
- * of higher-level state groups. MetricProducers hold information on
- * state groups and are responsible for mapping original state values to
- * the correct state group.
- *
- * [eventTimeNs]: Time of the state change log event.
- * [atomId]: The id of the state atom
- * [primaryKey]: The primary field values of the state atom
- * [oldState]: Previous state value before state change
- * [newState]: Current state value after state change
- */
- virtual void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey, const FieldValue& oldState,
- const FieldValue& newState) = 0;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/state/StateManager.cpp b/cmds/statsd/src/state/StateManager.cpp
deleted file mode 100644
index c29afeb..0000000
--- a/cmds/statsd/src/state/StateManager.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StateManager.h"
-
-#include <private/android_filesystem_config.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StateManager::StateManager()
- : mAllowedPkg({
- "com.android.systemui",
- }) {
-}
-
-StateManager& StateManager::getInstance() {
- static StateManager sStateManager;
- return sStateManager;
-}
-
-void StateManager::clear() {
- mStateTrackers.clear();
-}
-
-void StateManager::onLogEvent(const LogEvent& event) {
- // Only process state events from uids in AID_* and packages that are whitelisted in
- // mAllowedPkg.
- // Whitelisted AIDs are AID_ROOT and all AIDs in [1000, 2000)
- if (event.GetUid() == AID_ROOT || (event.GetUid() >= 1000 && event.GetUid() < 2000) ||
- mAllowedLogSources.find(event.GetUid()) != mAllowedLogSources.end()) {
- if (mStateTrackers.find(event.GetTagId()) != mStateTrackers.end()) {
- mStateTrackers[event.GetTagId()]->onLogEvent(event);
- }
- }
-}
-
-void StateManager::registerListener(const int32_t atomId, wp<StateListener> listener) {
- // Check if state tracker already exists.
- if (mStateTrackers.find(atomId) == mStateTrackers.end()) {
- mStateTrackers[atomId] = new StateTracker(atomId);
- }
- mStateTrackers[atomId]->registerListener(listener);
-}
-
-void StateManager::unregisterListener(const int32_t atomId, wp<StateListener> listener) {
- std::unique_lock<std::mutex> lock(mMutex);
-
- // Hold the sp<> until the lock is released so that ~StateTracker() is
- // not called while the lock is held.
- sp<StateTracker> toRemove;
-
- // Unregister listener from correct StateTracker
- auto it = mStateTrackers.find(atomId);
- if (it != mStateTrackers.end()) {
- it->second->unregisterListener(listener);
-
- // Remove the StateTracker if it has no listeners
- if (it->second->getListenersCount() == 0) {
- toRemove = it->second;
- mStateTrackers.erase(it);
- }
- } else {
- ALOGE("StateManager cannot unregister listener, StateTracker for atom %d does not exist",
- atomId);
- }
- lock.unlock();
-}
-
-bool StateManager::getStateValue(const int32_t atomId, const HashableDimensionKey& key,
- FieldValue* output) const {
- auto it = mStateTrackers.find(atomId);
- if (it != mStateTrackers.end()) {
- return it->second->getStateValue(key, output);
- }
- return false;
-}
-
-void StateManager::updateLogSources(const sp<UidMap>& uidMap) {
- mAllowedLogSources.clear();
- for (const auto& pkg : mAllowedPkg) {
- auto uids = uidMap->getAppUid(pkg);
- mAllowedLogSources.insert(uids.begin(), uids.end());
- }
-}
-
-void StateManager::notifyAppChanged(const string& apk, const sp<UidMap>& uidMap) {
- if (mAllowedPkg.find(apk) != mAllowedPkg.end()) {
- updateLogSources(uidMap);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/state/StateManager.h b/cmds/statsd/src/state/StateManager.h
deleted file mode 100644
index 18c404c..0000000
--- a/cmds/statsd/src/state/StateManager.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <inttypes.h>
-#include <utils/RefBase.h>
-
-#include <set>
-#include <string>
-#include <unordered_map>
-
-#include "HashableDimensionKey.h"
-#include "packages/UidMap.h"
-#include "state/StateListener.h"
-#include "state/StateTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * This class is NOT thread safe.
- * It should only be used while StatsLogProcessor's lock is held.
- */
-class StateManager : public virtual RefBase {
-public:
- StateManager();
-
- ~StateManager(){};
-
- // Returns a pointer to the single, shared StateManager object.
- static StateManager& getInstance();
-
- // Unregisters all listeners and removes all trackers from StateManager.
- void clear();
-
- // Notifies the correct StateTracker of an event.
- void onLogEvent(const LogEvent& event);
-
- // Notifies the StateTracker for the given atomId to register listener.
- // If the correct StateTracker does not exist, a new StateTracker is created.
- // Note: StateTrackers can be created for non-state atoms. They are essentially empty and
- // do not perform any actions.
- void registerListener(const int32_t atomId, wp<StateListener> listener);
-
- // Notifies the correct StateTracker to unregister a listener
- // and removes the tracker if it no longer has any listeners.
- void unregisterListener(const int32_t atomId, wp<StateListener> listener);
-
- // Returns true if the StateTracker exists and queries for the
- // original state value mapped to the given query key. The state value is
- // stored and output in a FieldValue class.
- // Returns false if the StateTracker doesn't exist.
- bool getStateValue(const int32_t atomId, const HashableDimensionKey& queryKey,
- FieldValue* output) const;
-
- // Updates mAllowedLogSources with the latest uids for the packages that are allowed to log.
- void updateLogSources(const sp<UidMap>& uidMap);
-
- void notifyAppChanged(const string& apk, const sp<UidMap>& uidMap);
-
- inline int getStateTrackersCount() const {
- return mStateTrackers.size();
- }
-
- inline int getListenersCount(const int32_t atomId) const {
- auto it = mStateTrackers.find(atomId);
- if (it != mStateTrackers.end()) {
- return it->second->getListenersCount();
- }
- return -1;
- }
-
-private:
- mutable std::mutex mMutex;
-
- // Maps state atom ids to StateTrackers
- std::unordered_map<int32_t, sp<StateTracker>> mStateTrackers;
-
- // The package names that can log state events.
- const std::set<std::string> mAllowedPkg;
-
- // The combined uid sources (after translating pkg name to uid).
- // State events from uids that are not in the list will be ignored to avoid state pollution.
- std::set<int32_t> mAllowedLogSources;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/state/StateTracker.cpp b/cmds/statsd/src/state/StateTracker.cpp
deleted file mode 100644
index 41e525c..0000000
--- a/cmds/statsd/src/state/StateTracker.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG true // STOPSHIP if true
-#include "Log.h"
-
-#include "stats_util.h"
-
-#include "StateTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StateTracker::StateTracker(const int32_t atomId) : mField(atomId, 0) {
-}
-
-void StateTracker::onLogEvent(const LogEvent& event) {
- const int64_t eventTimeNs = event.GetElapsedTimestampNs();
-
- // Parse event for primary field values i.e. primary key.
- HashableDimensionKey primaryKey;
- filterPrimaryKey(event.getValues(), &primaryKey);
-
- FieldValue newState;
- if (!getStateFieldValueFromLogEvent(event, &newState)) {
- ALOGE("StateTracker error extracting state from log event. Missing exclusive state field.");
- clearStateForPrimaryKey(eventTimeNs, primaryKey);
- return;
- }
-
- mField.setField(newState.mField.getField());
-
- if (newState.mValue.getType() != INT) {
- ALOGE("StateTracker error extracting state from log event. Type: %d",
- newState.mValue.getType());
- clearStateForPrimaryKey(eventTimeNs, primaryKey);
- return;
- }
-
- if (int resetState = event.getResetState(); resetState != -1) {
- VLOG("StateTracker new reset state: %d", resetState);
- const FieldValue resetStateFieldValue(mField, Value(resetState));
- handleReset(eventTimeNs, resetStateFieldValue);
- return;
- }
-
- const bool nested = newState.mAnnotations.isNested();
- StateValueInfo* stateValueInfo = &mStateMap[primaryKey];
- updateStateForPrimaryKey(eventTimeNs, primaryKey, newState, nested, stateValueInfo);
-}
-
-void StateTracker::registerListener(wp<StateListener> listener) {
- mListeners.insert(listener);
-}
-
-void StateTracker::unregisterListener(wp<StateListener> listener) {
- mListeners.erase(listener);
-}
-
-bool StateTracker::getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const {
- output->mField = mField;
-
- if (const auto it = mStateMap.find(queryKey); it != mStateMap.end()) {
- output->mValue = it->second.state;
- return true;
- }
-
- // Set the state value to kStateUnknown if query key is not found in state map.
- output->mValue = kStateUnknown;
- return false;
-}
-
-void StateTracker::handleReset(const int64_t eventTimeNs, const FieldValue& newState) {
- VLOG("StateTracker handle reset");
- for (auto& [primaryKey, stateValueInfo] : mStateMap) {
- updateStateForPrimaryKey(eventTimeNs, primaryKey, newState,
- false /* nested; treat this state change as not nested */,
- &stateValueInfo);
- }
-}
-
-void StateTracker::clearStateForPrimaryKey(const int64_t eventTimeNs,
- const HashableDimensionKey& primaryKey) {
- VLOG("StateTracker clear state for primary key");
- const std::unordered_map<HashableDimensionKey, StateValueInfo>::iterator it =
- mStateMap.find(primaryKey);
-
- // If there is no entry for the primaryKey in mStateMap, then the state is already
- // kStateUnknown.
- const FieldValue state(mField, Value(kStateUnknown));
- if (it != mStateMap.end()) {
- updateStateForPrimaryKey(eventTimeNs, primaryKey, state,
- false /* nested; treat this state change as not nested */,
- &it->second);
- }
-}
-
-void StateTracker::updateStateForPrimaryKey(const int64_t eventTimeNs,
- const HashableDimensionKey& primaryKey,
- const FieldValue& newState, const bool nested,
- StateValueInfo* stateValueInfo) {
- FieldValue oldState;
- oldState.mField = mField;
- oldState.mValue.setInt(stateValueInfo->state);
- const int32_t oldStateValue = stateValueInfo->state;
- const int32_t newStateValue = newState.mValue.int_value;
-
- if (kStateUnknown == newStateValue) {
- mStateMap.erase(primaryKey);
- }
-
- // Update state map for non-nested counting case.
- // Every state event triggers a state overwrite.
- if (!nested) {
- stateValueInfo->state = newStateValue;
- stateValueInfo->count = 1;
-
- // Notify listeners if state has changed.
- if (oldStateValue != newStateValue) {
- notifyListeners(eventTimeNs, primaryKey, oldState, newState);
- }
- return;
- }
-
- // Update state map for nested counting case.
- //
- // Nested counting is only allowed for binary state events such as ON/OFF or
- // ACQUIRE/RELEASE. For example, WakelockStateChanged might have the state
- // events: ON, ON, OFF. The state will still be ON until we see the same
- // number of OFF events as ON events.
- //
- // In atoms.proto, a state atom with nested counting enabled
- // must only have 2 states. There is no enforcemnt here of this requirement.
- // The atom must be logged correctly.
- if (kStateUnknown == newStateValue) {
- if (kStateUnknown != oldStateValue) {
- notifyListeners(eventTimeNs, primaryKey, oldState, newState);
- }
- } else if (oldStateValue == kStateUnknown) {
- stateValueInfo->state = newStateValue;
- stateValueInfo->count = 1;
- notifyListeners(eventTimeNs, primaryKey, oldState, newState);
- } else if (oldStateValue == newStateValue) {
- stateValueInfo->count++;
- } else if (--stateValueInfo->count == 0) {
- stateValueInfo->state = newStateValue;
- stateValueInfo->count = 1;
- notifyListeners(eventTimeNs, primaryKey, oldState, newState);
- }
-}
-
-void StateTracker::notifyListeners(const int64_t eventTimeNs,
- const HashableDimensionKey& primaryKey,
- const FieldValue& oldState, const FieldValue& newState) {
- for (auto l : mListeners) {
- auto sl = l.promote();
- if (sl != nullptr) {
- sl->onStateChanged(eventTimeNs, mField.getTag(), primaryKey, oldState, newState);
- }
- }
-}
-
-bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output) {
- const int exclusiveStateFieldIndex = event.getExclusiveStateFieldIndex();
- if (-1 == exclusiveStateFieldIndex) {
- ALOGE("error extracting state from log event. Missing exclusive state field.");
- return false;
- }
-
- *output = event.getValues()[exclusiveStateFieldIndex];
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/state/StateTracker.h b/cmds/statsd/src/state/StateTracker.h
deleted file mode 100644
index abd579e..0000000
--- a/cmds/statsd/src/state/StateTracker.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-#include "HashableDimensionKey.h"
-#include "logd/LogEvent.h"
-
-#include "state/StateListener.h"
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StateTracker : public virtual RefBase {
-public:
- StateTracker(const int32_t atomId);
-
- virtual ~StateTracker(){};
-
- // Updates state map and notifies all listeners if a state change occurs.
- // Checks if a state change has occurred by getting the state value from
- // the log event and comparing the old and new states.
- void onLogEvent(const LogEvent& event);
-
- // Adds new listeners to set of StateListeners. If a listener is already
- // registered, it is ignored.
- void registerListener(wp<StateListener> listener);
-
- void unregisterListener(wp<StateListener> listener);
-
- // The output is a FieldValue object that has mStateField as the field and
- // the original state value (found using the given query key) as the value.
- //
- // If the key isn't mapped to a state or the key size doesn't match the
- // number of primary fields, the output value is set to kStateUnknown.
- bool getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const;
-
- inline int getListenersCount() const {
- return mListeners.size();
- }
-
- const static int kStateUnknown = -1;
-
-private:
- struct StateValueInfo {
- int32_t state = kStateUnknown; // state value
- int count = 0; // nested count (only used for binary states)
- };
-
- Field mField;
-
- // Maps primary key to state value info
- std::unordered_map<HashableDimensionKey, StateValueInfo> mStateMap;
-
- // Set of all StateListeners (objects listening for state changes)
- std::set<wp<StateListener>> mListeners;
-
- // Reset all state values in map to the given state.
- void handleReset(const int64_t eventTimeNs, const FieldValue& newState);
-
- // Clears the state value mapped to the given primary key by setting it to kStateUnknown.
- void clearStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey);
-
- // Update the StateMap based on the received state value.
- void updateStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey,
- const FieldValue& newState, const bool nested,
- StateValueInfo* stateValueInfo);
-
- // Notify registered state listeners of state change.
- void notifyListeners(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey,
- const FieldValue& oldState, const FieldValue& newState);
-};
-
-bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
deleted file mode 100644
index ddd2725..0000000
--- a/cmds/statsd/src/stats_log.proto
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.os";
-option java_outer_classname = "StatsLog";
-
-import "frameworks/base/cmds/statsd/src/atoms.proto";
-
-message DimensionsValue {
- optional int32 field = 1;
-
- oneof value {
- string value_str = 2;
- int32 value_int = 3;
- int64 value_long = 4;
- bool value_bool = 5;
- float value_float = 6;
- DimensionsValueTuple value_tuple = 7;
- uint64 value_str_hash = 8;
- }
-}
-
-message DimensionsValueTuple {
- repeated DimensionsValue dimensions_value = 1;
-}
-
-message StateValue {
- optional int32 atom_id = 1;
-
- oneof contents {
- int64 group_id = 2;
- int32 value = 3;
- }
-}
-
-message EventMetricData {
- optional int64 elapsed_timestamp_nanos = 1;
-
- optional Atom atom = 2;
-
- optional int64 wall_clock_timestamp_nanos = 3 [deprecated = true];
-}
-
-message CountBucketInfo {
- optional int64 start_bucket_elapsed_nanos = 1;
-
- optional int64 end_bucket_elapsed_nanos = 2;
-
- optional int64 count = 3;
-
- optional int64 bucket_num = 4;
-
- optional int64 start_bucket_elapsed_millis = 5;
-
- optional int64 end_bucket_elapsed_millis = 6;
-}
-
-message CountMetricData {
- optional DimensionsValue dimensions_in_what = 1;
-
- repeated StateValue slice_by_state = 6;
-
- repeated CountBucketInfo bucket_info = 3;
-
- repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
- optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
- repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message DurationBucketInfo {
- optional int64 start_bucket_elapsed_nanos = 1;
-
- optional int64 end_bucket_elapsed_nanos = 2;
-
- optional int64 duration_nanos = 3;
-
- optional int64 bucket_num = 4;
-
- optional int64 start_bucket_elapsed_millis = 5;
-
- optional int64 end_bucket_elapsed_millis = 6;
-}
-
-message DurationMetricData {
- optional DimensionsValue dimensions_in_what = 1;
-
- repeated StateValue slice_by_state = 6;
-
- repeated DurationBucketInfo bucket_info = 3;
-
- repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
- optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
- repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message ValueBucketInfo {
- optional int64 start_bucket_elapsed_nanos = 1;
-
- optional int64 end_bucket_elapsed_nanos = 2;
-
- optional int64 value = 3 [deprecated = true];
-
- oneof single_value {
- int64 value_long = 7 [deprecated = true];
-
- double value_double = 8 [deprecated = true];
- }
-
- message Value {
- optional int32 index = 1;
- oneof value {
- int64 value_long = 2;
- double value_double = 3;
- }
- }
-
- repeated Value values = 9;
-
- optional int64 bucket_num = 4;
-
- optional int64 start_bucket_elapsed_millis = 5;
-
- optional int64 end_bucket_elapsed_millis = 6;
-
- optional int64 condition_true_nanos = 10;
-}
-
-message ValueMetricData {
- optional DimensionsValue dimensions_in_what = 1;
-
- repeated StateValue slice_by_state = 6;
-
- repeated ValueBucketInfo bucket_info = 3;
-
- repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
- optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
- repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message GaugeBucketInfo {
- optional int64 start_bucket_elapsed_nanos = 1;
-
- optional int64 end_bucket_elapsed_nanos = 2;
-
- repeated Atom atom = 3;
-
- repeated int64 elapsed_timestamp_nanos = 4;
-
- repeated int64 wall_clock_timestamp_nanos = 5 [deprecated = true];
-
- optional int64 bucket_num = 6;
-
- optional int64 start_bucket_elapsed_millis = 7;
-
- optional int64 end_bucket_elapsed_millis = 8;
-}
-
-message GaugeMetricData {
- optional DimensionsValue dimensions_in_what = 1;
-
- // Currently unsupported
- repeated StateValue slice_by_state = 6;
-
- repeated GaugeBucketInfo bucket_info = 3;
-
- repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
- optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
- repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message StatsLogReport {
- optional int64 metric_id = 1;
-
- // Fields 2 and 3 are reserved.
-
- // Keep this in sync with BucketDropReason enum in MetricProducer.h.
- enum BucketDropReason {
- // For ValueMetric, a bucket is dropped during a dump report request iff
- // current bucket should be included, a pull is needed (pulled metric and
- // condition is true), and we are under fast time constraints.
- DUMP_REPORT_REQUESTED = 1;
- EVENT_IN_WRONG_BUCKET = 2;
- CONDITION_UNKNOWN = 3;
- PULL_FAILED = 4;
- PULL_DELAYED = 5;
- DIMENSION_GUARDRAIL_REACHED = 6;
- MULTIPLE_BUCKETS_SKIPPED = 7;
- // Not an invalid bucket case, but the bucket is dropped.
- BUCKET_TOO_SMALL = 8;
- // Not an invalid bucket case, but the bucket is skipped.
- NO_DATA = 9;
- };
-
- message DropEvent {
- optional BucketDropReason drop_reason = 1;
-
- optional int64 drop_time_millis = 2;
- }
-
- message SkippedBuckets {
- optional int64 start_bucket_elapsed_nanos = 1;
-
- optional int64 end_bucket_elapsed_nanos = 2;
-
- optional int64 start_bucket_elapsed_millis = 3;
-
- optional int64 end_bucket_elapsed_millis = 4;
-
- // The number of drop events is capped by StatsdStats::kMaxLoggedBucketDropEvents.
- // The current maximum is 10 drop events.
- repeated DropEvent drop_event = 5;
- }
-
- message EventMetricDataWrapper {
- repeated EventMetricData data = 1;
- }
- message CountMetricDataWrapper {
- repeated CountMetricData data = 1;
- }
- message DurationMetricDataWrapper {
- repeated DurationMetricData data = 1;
- }
- message ValueMetricDataWrapper {
- repeated ValueMetricData data = 1;
- repeated SkippedBuckets skipped = 2;
- }
-
- message GaugeMetricDataWrapper {
- repeated GaugeMetricData data = 1;
- repeated SkippedBuckets skipped = 2;
- }
-
- oneof data {
- EventMetricDataWrapper event_metrics = 4;
- CountMetricDataWrapper count_metrics = 5;
- DurationMetricDataWrapper duration_metrics = 6;
- ValueMetricDataWrapper value_metrics = 7;
- GaugeMetricDataWrapper gauge_metrics = 8;
- }
-
- optional int64 time_base_elapsed_nano_seconds = 9;
-
- optional int64 bucket_size_nano_seconds = 10;
-
- optional DimensionsValue dimensions_path_in_what = 11;
-
- optional DimensionsValue dimensions_path_in_condition = 12 [deprecated = true];
-
- // DO NOT USE field 13.
-
- optional bool is_active = 14;
-}
-
-message UidMapping {
- message PackageInfoSnapshot {
- message PackageInfo {
- optional string name = 1;
-
- optional int64 version = 2;
-
- optional int32 uid = 3;
-
- optional bool deleted = 4;
-
- optional uint64 name_hash = 5;
-
- optional string version_string = 6;
-
- optional uint64 version_string_hash = 7;
-
- optional string installer = 8;
-
- optional uint64 installer_hash = 9;
- }
- optional int64 elapsed_timestamp_nanos = 1;
-
- repeated PackageInfo package_info = 2;
- }
- repeated PackageInfoSnapshot snapshots = 1;
-
- message Change {
- optional bool deletion = 1;
-
- optional int64 elapsed_timestamp_nanos = 2;
- optional string app = 3;
- optional int32 uid = 4;
-
- optional int64 new_version = 5;
- optional int64 prev_version = 6;
- optional uint64 app_hash = 7;
- optional string new_version_string = 8;
- optional string prev_version_string = 9;
- optional uint64 new_version_string_hash = 10;
- optional uint64 prev_version_string_hash = 11;
- }
- repeated Change changes = 2;
-}
-
-message ConfigMetricsReport {
- repeated StatsLogReport metrics = 1;
-
- optional UidMapping uid_map = 2;
-
- optional int64 last_report_elapsed_nanos = 3;
-
- optional int64 current_report_elapsed_nanos = 4;
-
- optional int64 last_report_wall_clock_nanos = 5;
-
- optional int64 current_report_wall_clock_nanos = 6;
-
- message Annotation {
- optional int64 field_int64 = 1;
- optional int32 field_int32 = 2;
- }
- repeated Annotation annotation = 7;
-
- enum DumpReportReason {
- DEVICE_SHUTDOWN = 1;
- CONFIG_UPDATED = 2;
- CONFIG_REMOVED = 3;
- GET_DATA_CALLED = 4;
- ADB_DUMP = 5;
- CONFIG_RESET = 6;
- STATSCOMPANION_DIED = 7;
- TERMINATION_SIGNAL_RECEIVED = 8;
- }
- optional DumpReportReason dump_report_reason = 8;
-
- repeated string strings = 9;
-}
-
-message ConfigMetricsReportList {
- message ConfigKey {
- optional int32 uid = 1;
- optional int64 id = 2;
- }
- optional ConfigKey config_key = 1;
-
- repeated ConfigMetricsReport reports = 2;
-
- reserved 10;
-}
-
-message StatsdStatsReport {
- optional int32 stats_begin_time_sec = 1;
-
- optional int32 stats_end_time_sec = 2;
-
- message MatcherStats {
- optional int64 id = 1;
- optional int32 matched_times = 2;
- }
-
- message ConditionStats {
- optional int64 id = 1;
- optional int32 max_tuple_counts = 2;
- }
-
- message MetricStats {
- optional int64 id = 1;
- optional int32 max_tuple_counts = 2;
- }
-
- message AlertStats {
- optional int64 id = 1;
- optional int32 alerted_times = 2;
- }
-
- message ConfigStats {
- optional int32 uid = 1;
- optional int64 id = 2;
- optional int32 creation_time_sec = 3;
- optional int32 deletion_time_sec = 4;
- optional int32 reset_time_sec = 19;
- optional int32 metric_count = 5;
- optional int32 condition_count = 6;
- optional int32 matcher_count = 7;
- optional int32 alert_count = 8;
- optional bool is_valid = 9;
- repeated int32 broadcast_sent_time_sec = 10;
- repeated int32 data_drop_time_sec = 11;
- repeated int64 data_drop_bytes = 21;
- repeated int32 dump_report_time_sec = 12;
- repeated int32 dump_report_data_size = 20;
- repeated MatcherStats matcher_stats = 13;
- repeated ConditionStats condition_stats = 14;
- repeated MetricStats metric_stats = 15;
- repeated AlertStats alert_stats = 16;
- repeated MetricStats metric_dimension_in_condition_stats = 17 [deprecated = true];
- message Annotation {
- optional int64 field_int64 = 1;
- optional int32 field_int32 = 2;
- }
- repeated Annotation annotation = 18;
- repeated int32 activation_time_sec = 22;
- repeated int32 deactivation_time_sec = 23;
- }
-
- repeated ConfigStats config_stats = 3;
-
- message AtomStats {
- optional int32 tag = 1;
- optional int32 count = 2;
- optional int32 error_count = 3;
- }
-
- repeated AtomStats atom_stats = 7;
-
- message UidMapStats {
- optional int32 changes = 1;
- optional int32 bytes_used = 2;
- optional int32 dropped_changes = 3;
- optional int32 deleted_apps = 4;
- }
- optional UidMapStats uidmap_stats = 8;
-
- message AnomalyAlarmStats {
- optional int32 alarms_registered = 1;
- }
- optional AnomalyAlarmStats anomaly_alarm_stats = 9;
-
- message PulledAtomStats {
- optional int32 atom_id = 1;
- optional int64 total_pull = 2;
- optional int64 total_pull_from_cache = 3;
- optional int64 min_pull_interval_sec = 4;
- optional int64 average_pull_time_nanos = 5;
- optional int64 max_pull_time_nanos = 6;
- optional int64 average_pull_delay_nanos = 7;
- optional int64 max_pull_delay_nanos = 8;
- optional int64 data_error = 9;
- optional int64 pull_timeout = 10;
- optional int64 pull_exceed_max_delay = 11;
- optional int64 pull_failed = 12;
- optional int64 stats_companion_pull_failed = 13 [deprecated = true];
- optional int64 stats_companion_pull_binder_transaction_failed = 14 [deprecated = true];
- optional int64 empty_data = 15;
- optional int64 registered_count = 16;
- optional int64 unregistered_count = 17;
- optional int32 atom_error_count = 18;
- optional int64 binder_call_failed = 19;
- optional int64 failed_uid_provider_not_found = 20;
- optional int64 puller_not_found = 21;
- message PullTimeoutMetadata {
- optional int64 pull_timeout_uptime_millis = 1;
- optional int64 pull_timeout_elapsed_millis = 2;
- }
- repeated PullTimeoutMetadata pull_atom_metadata = 22;
- }
- repeated PulledAtomStats pulled_atom_stats = 10;
-
- message AtomMetricStats {
- optional int64 metric_id = 1;
- optional int64 hard_dimension_limit_reached = 2;
- optional int64 late_log_event_skipped = 3;
- optional int64 skipped_forward_buckets = 4;
- optional int64 bad_value_type = 5;
- optional int64 condition_change_in_next_bucket = 6;
- optional int64 invalidated_bucket = 7;
- optional int64 bucket_dropped = 8;
- optional int64 min_bucket_boundary_delay_ns = 9;
- optional int64 max_bucket_boundary_delay_ns = 10;
- optional int64 bucket_unknown_condition = 11;
- optional int64 bucket_count = 12;
- }
- repeated AtomMetricStats atom_metric_stats = 17;
-
- message LoggerErrorStats {
- optional int32 logger_disconnection_sec = 1;
- optional int32 error_code = 2;
- }
- repeated LoggerErrorStats logger_error_stats = 11;
-
- message PeriodicAlarmStats {
- optional int32 alarms_registered = 1;
- }
- optional PeriodicAlarmStats periodic_alarm_stats = 12;
-
- message SkippedLogEventStats {
- optional int32 tag = 1;
- optional int64 elapsed_timestamp_nanos = 2;
- }
- repeated SkippedLogEventStats skipped_log_event_stats = 13;
-
- repeated int64 log_loss_stats = 14;
-
- repeated int32 system_restart_sec = 15;
-
- message LogLossStats {
- optional int32 detected_time_sec = 1;
- optional int32 count = 2;
- optional int32 last_error = 3;
- optional int32 last_tag = 4;
- optional int32 uid = 5;
- optional int32 pid = 6;
- }
- repeated LogLossStats detected_log_loss = 16;
-
- message EventQueueOverflow {
- optional int32 count = 1;
- optional int64 max_queue_history_ns = 2;
- optional int64 min_queue_history_ns = 3;
- }
-
- optional EventQueueOverflow queue_overflow = 18;
-
- message ActivationBroadcastGuardrail {
- optional int32 uid = 1;
- repeated int32 guardrail_met_sec = 2;
- }
-
- repeated ActivationBroadcastGuardrail activation_guardrail_stats = 19;
-}
-
-message AlertTriggerDetails {
- message MetricValue {
- optional int64 metric_id = 1;
- optional DimensionsValue dimension_in_what = 2;
- optional DimensionsValue dimension_in_condition = 3 [deprecated = true];
- optional int64 value = 4;
- }
- oneof value {
- MetricValue trigger_metric = 1;
- EventMetricData trigger_event = 2;
- }
- optional UidMapping.PackageInfoSnapshot package_info = 3;
-}
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
deleted file mode 100644
index 423bae8..0000000
--- a/cmds/statsd/src/stats_log_util.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "hash.h"
-#include "stats_log_util.h"
-
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <private/android_filesystem_config.h>
-#include <set>
-#include <utils/SystemClock.h>
-
-#include "statscompanion_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FIXED64;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::FIELD_TYPE_UINT64;
-using android::util::ProtoOutputStream;
-
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-using std::string;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for DimensionsValue Proto
-const int DIMENSIONS_VALUE_FIELD = 1;
-const int DIMENSIONS_VALUE_VALUE_STR = 2;
-const int DIMENSIONS_VALUE_VALUE_INT = 3;
-const int DIMENSIONS_VALUE_VALUE_LONG = 4;
-// const int DIMENSIONS_VALUE_VALUE_BOOL = 5; // logd doesn't have bool data type.
-const int DIMENSIONS_VALUE_VALUE_FLOAT = 6;
-const int DIMENSIONS_VALUE_VALUE_TUPLE = 7;
-const int DIMENSIONS_VALUE_VALUE_STR_HASH = 8;
-
-const int DIMENSIONS_VALUE_TUPLE_VALUE = 1;
-
-// for StateValue Proto
-const int STATE_VALUE_ATOM_ID = 1;
-const int STATE_VALUE_CONTENTS_GROUP_ID = 2;
-const int STATE_VALUE_CONTENTS_VALUE = 3;
-
-// for PulledAtomStats proto
-const int FIELD_ID_PULLED_ATOM_STATS = 10;
-const int FIELD_ID_PULL_ATOM_ID = 1;
-const int FIELD_ID_TOTAL_PULL = 2;
-const int FIELD_ID_TOTAL_PULL_FROM_CACHE = 3;
-const int FIELD_ID_MIN_PULL_INTERVAL_SEC = 4;
-const int FIELD_ID_AVERAGE_PULL_TIME_NANOS = 5;
-const int FIELD_ID_MAX_PULL_TIME_NANOS = 6;
-const int FIELD_ID_AVERAGE_PULL_DELAY_NANOS = 7;
-const int FIELD_ID_MAX_PULL_DELAY_NANOS = 8;
-const int FIELD_ID_DATA_ERROR = 9;
-const int FIELD_ID_PULL_TIMEOUT = 10;
-const int FIELD_ID_PULL_EXCEED_MAX_DELAY = 11;
-const int FIELD_ID_PULL_FAILED = 12;
-const int FIELD_ID_EMPTY_DATA = 15;
-const int FIELD_ID_PULL_REGISTERED_COUNT = 16;
-const int FIELD_ID_PULL_UNREGISTERED_COUNT = 17;
-const int FIELD_ID_ATOM_ERROR_COUNT = 18;
-const int FIELD_ID_BINDER_CALL_FAIL_COUNT = 19;
-const int FIELD_ID_PULL_UID_PROVIDER_NOT_FOUND = 20;
-const int FIELD_ID_PULLER_NOT_FOUND = 21;
-const int FIELD_ID_PULL_TIMEOUT_METADATA = 22;
-const int FIELD_ID_PULL_TIMEOUT_METADATA_UPTIME_MILLIS = 1;
-const int FIELD_ID_PULL_TIMEOUT_METADATA_ELAPSED_MILLIS = 2;
-
-// for AtomMetricStats proto
-const int FIELD_ID_ATOM_METRIC_STATS = 17;
-const int FIELD_ID_METRIC_ID = 1;
-const int FIELD_ID_HARD_DIMENSION_LIMIT_REACHED = 2;
-const int FIELD_ID_LATE_LOG_EVENT_SKIPPED = 3;
-const int FIELD_ID_SKIPPED_FORWARD_BUCKETS = 4;
-const int FIELD_ID_BAD_VALUE_TYPE = 5;
-const int FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET = 6;
-const int FIELD_ID_INVALIDATED_BUCKET = 7;
-const int FIELD_ID_BUCKET_DROPPED = 8;
-const int FIELD_ID_MIN_BUCKET_BOUNDARY_DELAY_NS = 9;
-const int FIELD_ID_MAX_BUCKET_BOUNDARY_DELAY_NS = 10;
-const int FIELD_ID_BUCKET_UNKNOWN_CONDITION = 11;
-const int FIELD_ID_BUCKET_COUNT = 12;
-
-namespace {
-
-void writeDimensionToProtoHelper(const std::vector<FieldValue>& dims, size_t* index, int depth,
- int prefix, std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- size_t count = dims.size();
- while (*index < count) {
- const auto& dim = dims[*index];
- const int valueDepth = dim.mField.getDepth();
- const int valuePrefix = dim.mField.getPrefix(depth);
- const int fieldNum = dim.mField.getPosAtDepth(depth);
- if (valueDepth > 2) {
- ALOGE("Depth > 2 not supported");
- return;
- }
-
- if (depth == valueDepth && valuePrefix == prefix) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- DIMENSIONS_VALUE_TUPLE_VALUE);
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
- switch (dim.mValue.getType()) {
- case INT:
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_VALUE_INT,
- dim.mValue.int_value);
- break;
- case LONG:
- protoOutput->write(FIELD_TYPE_INT64 | DIMENSIONS_VALUE_VALUE_LONG,
- (long long)dim.mValue.long_value);
- break;
- case FLOAT:
- protoOutput->write(FIELD_TYPE_FLOAT | DIMENSIONS_VALUE_VALUE_FLOAT,
- dim.mValue.float_value);
- break;
- case STRING:
- if (str_set == nullptr) {
- protoOutput->write(FIELD_TYPE_STRING | DIMENSIONS_VALUE_VALUE_STR,
- dim.mValue.str_value);
- } else {
- str_set->insert(dim.mValue.str_value);
- protoOutput->write(
- FIELD_TYPE_UINT64 | DIMENSIONS_VALUE_VALUE_STR_HASH,
- (long long)Hash64(dim.mValue.str_value));
- }
- break;
- default:
- break;
- }
- if (token != 0) {
- protoOutput->end(token);
- }
- (*index)++;
- } else if (valueDepth > depth && valuePrefix == prefix) {
- // Writing the sub tree
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | DIMENSIONS_VALUE_TUPLE_VALUE);
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
- uint64_t tupleToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
- writeDimensionToProtoHelper(dims, index, valueDepth, dim.mField.getPrefix(valueDepth),
- str_set, protoOutput);
- protoOutput->end(tupleToken);
- protoOutput->end(dimensionToken);
- } else {
- // Done with the prev sub tree
- return;
- }
- }
-}
-
-void writeDimensionLeafToProtoHelper(const std::vector<FieldValue>& dims,
- const int dimensionLeafField,
- size_t* index, int depth,
- int prefix, std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- size_t count = dims.size();
- while (*index < count) {
- const auto& dim = dims[*index];
- const int valueDepth = dim.mField.getDepth();
- const int valuePrefix = dim.mField.getPrefix(depth);
- if (valueDepth > 2) {
- ALOGE("Depth > 2 not supported");
- return;
- }
-
- if (depth == valueDepth && valuePrefix == prefix) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- dimensionLeafField);
- switch (dim.mValue.getType()) {
- case INT:
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_VALUE_INT,
- dim.mValue.int_value);
- break;
- case LONG:
- protoOutput->write(FIELD_TYPE_INT64 | DIMENSIONS_VALUE_VALUE_LONG,
- (long long)dim.mValue.long_value);
- break;
- case FLOAT:
- protoOutput->write(FIELD_TYPE_FLOAT | DIMENSIONS_VALUE_VALUE_FLOAT,
- dim.mValue.float_value);
- break;
- case STRING:
- if (str_set == nullptr) {
- protoOutput->write(FIELD_TYPE_STRING | DIMENSIONS_VALUE_VALUE_STR,
- dim.mValue.str_value);
- } else {
- str_set->insert(dim.mValue.str_value);
- protoOutput->write(
- FIELD_TYPE_UINT64 | DIMENSIONS_VALUE_VALUE_STR_HASH,
- (long long)Hash64(dim.mValue.str_value));
- }
- break;
- default:
- break;
- }
- if (token != 0) {
- protoOutput->end(token);
- }
- (*index)++;
- } else if (valueDepth > depth && valuePrefix == prefix) {
- writeDimensionLeafToProtoHelper(dims, dimensionLeafField,
- index, valueDepth, dim.mField.getPrefix(valueDepth),
- str_set, protoOutput);
- } else {
- // Done with the prev sub tree
- return;
- }
- }
-}
-
-void writeDimensionPathToProtoHelper(const std::vector<Matcher>& fieldMatchers,
- size_t* index, int depth, int prefix,
- ProtoOutputStream* protoOutput) {
- size_t count = fieldMatchers.size();
- while (*index < count) {
- const Field& field = fieldMatchers[*index].mMatcher;
- const int valueDepth = field.getDepth();
- const int valuePrefix = field.getPrefix(depth);
- const int fieldNum = field.getPosAtDepth(depth);
- if (valueDepth > 2) {
- ALOGE("Depth > 2 not supported");
- return;
- }
-
- if (depth == valueDepth && valuePrefix == prefix) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- DIMENSIONS_VALUE_TUPLE_VALUE);
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
- if (token != 0) {
- protoOutput->end(token);
- }
- (*index)++;
- } else if (valueDepth > depth && valuePrefix == prefix) {
- // Writing the sub tree
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | DIMENSIONS_VALUE_TUPLE_VALUE);
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
- uint64_t tupleToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
- writeDimensionPathToProtoHelper(fieldMatchers, index, valueDepth,
- field.getPrefix(valueDepth), protoOutput);
- protoOutput->end(tupleToken);
- protoOutput->end(dimensionToken);
- } else {
- // Done with the prev sub tree
- return;
- }
- }
-}
-
-} // namespace
-
-void writeDimensionToProto(const HashableDimensionKey& dimension, std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- if (dimension.getValues().size() == 0) {
- return;
- }
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD,
- dimension.getValues()[0].mField.getTag());
- uint64_t topToken = protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
- size_t index = 0;
- writeDimensionToProtoHelper(dimension.getValues(), &index, 0, 0, str_set, protoOutput);
- protoOutput->end(topToken);
-}
-
-void writeDimensionLeafNodesToProto(const HashableDimensionKey& dimension,
- const int dimensionLeafFieldId,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- if (dimension.getValues().size() == 0) {
- return;
- }
- size_t index = 0;
- writeDimensionLeafToProtoHelper(dimension.getValues(), dimensionLeafFieldId,
- &index, 0, 0, str_set, protoOutput);
-}
-
-void writeDimensionPathToProto(const std::vector<Matcher>& fieldMatchers,
- ProtoOutputStream* protoOutput) {
- if (fieldMatchers.size() == 0) {
- return;
- }
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD,
- fieldMatchers[0].mMatcher.getTag());
- uint64_t topToken = protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
- size_t index = 0;
- writeDimensionPathToProtoHelper(fieldMatchers, &index, 0, 0, protoOutput);
- protoOutput->end(topToken);
-}
-
-// Supported Atoms format
-// XYZ_Atom {
-// repeated SubMsg field_1 = 1;
-// SubMsg2 field_2 = 2;
-// int32/float/string/int63 field_3 = 3;
-// }
-// logd's msg format, doesn't allow us to distinguish between the 2 cases below
-// Case (1):
-// Atom {
-// SubMsg {
-// int i = 1;
-// int j = 2;
-// }
-// repeated SubMsg
-// }
-//
-// and case (2):
-// Atom {
-// SubMsg {
-// repeated int i = 1;
-// repeated int j = 2;
-// }
-// optional SubMsg = 1;
-// }
-//
-//
-void writeFieldValueTreeToStreamHelper(int tagId, const std::vector<FieldValue>& dims,
- size_t* index, int depth, int prefix,
- ProtoOutputStream* protoOutput) {
- size_t count = dims.size();
- while (*index < count) {
- const auto& dim = dims[*index];
- const int valueDepth = dim.mField.getDepth();
- const int valuePrefix = dim.mField.getPrefix(depth);
- const int fieldNum = dim.mField.getPosAtDepth(depth);
- if (valueDepth > 2) {
- ALOGE("Depth > 2 not supported");
- return;
- }
-
- if (depth == valueDepth && valuePrefix == prefix) {
- switch (dim.mValue.getType()) {
- case INT:
- protoOutput->write(FIELD_TYPE_INT32 | fieldNum, dim.mValue.int_value);
- break;
- case LONG:
- protoOutput->write(FIELD_TYPE_INT64 | fieldNum,
- (long long)dim.mValue.long_value);
- break;
- case FLOAT:
- protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value);
- break;
- case STRING: {
- protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
- break;
- }
- case STORAGE:
- protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum,
- (const char*)dim.mValue.storage_value.data(),
- dim.mValue.storage_value.size());
- break;
- default:
- break;
- }
- (*index)++;
- } else if (valueDepth > depth && valuePrefix == prefix) {
- // Writing the sub tree
- uint64_t msg_token = 0ULL;
- if (valueDepth == depth + 2) {
- msg_token =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | fieldNum);
- } else if (valueDepth == depth + 1) {
- msg_token = protoOutput->start(FIELD_TYPE_MESSAGE | fieldNum);
- }
- // Directly jump to the leaf value because the repeated position field is implied
- // by the position of the sub msg in the parent field.
- writeFieldValueTreeToStreamHelper(tagId, dims, index, valueDepth,
- dim.mField.getPrefix(valueDepth), protoOutput);
- if (msg_token != 0) {
- protoOutput->end(msg_token);
- }
- } else {
- // Done with the prev sub tree
- return;
- }
- }
-}
-
-void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& values,
- util::ProtoOutputStream* protoOutput) {
- uint64_t atomToken = protoOutput->start(FIELD_TYPE_MESSAGE | tagId);
-
- size_t index = 0;
- writeFieldValueTreeToStreamHelper(tagId, values, &index, 0, 0, protoOutput);
- protoOutput->end(atomToken);
-}
-
-void writeStateToProto(const FieldValue& state, util::ProtoOutputStream* protoOutput) {
- protoOutput->write(FIELD_TYPE_INT32 | STATE_VALUE_ATOM_ID, state.mField.getTag());
-
- switch (state.mValue.getType()) {
- case INT:
- protoOutput->write(FIELD_TYPE_INT32 | STATE_VALUE_CONTENTS_VALUE,
- state.mValue.int_value);
- break;
- case LONG:
- protoOutput->write(FIELD_TYPE_INT64 | STATE_VALUE_CONTENTS_GROUP_ID,
- state.mValue.long_value);
- break;
- default:
- break;
- }
-}
-
-int64_t TimeUnitToBucketSizeInMillisGuardrailed(int uid, TimeUnit unit) {
- int64_t bucketSizeMillis = TimeUnitToBucketSizeInMillis(unit);
- if (bucketSizeMillis > 1000 && bucketSizeMillis < 5 * 60 * 1000LL && uid != AID_SHELL &&
- uid != AID_ROOT) {
- bucketSizeMillis = 5 * 60 * 1000LL;
- }
- return bucketSizeMillis;
-}
-
-int64_t TimeUnitToBucketSizeInMillis(TimeUnit unit) {
- switch (unit) {
- case ONE_MINUTE:
- return 60 * 1000LL;
- case FIVE_MINUTES:
- return 5 * 60 * 1000LL;
- case TEN_MINUTES:
- return 10 * 60 * 1000LL;
- case THIRTY_MINUTES:
- return 30 * 60 * 1000LL;
- case ONE_HOUR:
- return 60 * 60 * 1000LL;
- case THREE_HOURS:
- return 3 * 60 * 60 * 1000LL;
- case SIX_HOURS:
- return 6 * 60 * 60 * 1000LL;
- case TWELVE_HOURS:
- return 12 * 60 * 60 * 1000LL;
- case ONE_DAY:
- return 24 * 60 * 60 * 1000LL;
- case ONE_WEEK:
- return 7 * 24 * 60 * 60 * 1000LL;
- case CTS:
- return 1000;
- case TIME_UNIT_UNSPECIFIED:
- default:
- return -1;
- }
-}
-
-void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>& pair,
- util::ProtoOutputStream* protoOutput) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_PULLED_ATOM_STATS |
- FIELD_COUNT_REPEATED);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_PULL_ATOM_ID, (int32_t)pair.first);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TOTAL_PULL, (long long)pair.second.totalPull);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TOTAL_PULL_FROM_CACHE,
- (long long)pair.second.totalPullFromCache);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MIN_PULL_INTERVAL_SEC,
- (long long)pair.second.minPullIntervalSec);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_AVERAGE_PULL_TIME_NANOS,
- (long long)pair.second.avgPullTimeNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_PULL_TIME_NANOS,
- (long long)pair.second.maxPullTimeNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_AVERAGE_PULL_DELAY_NANOS,
- (long long)pair.second.avgPullDelayNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_PULL_DELAY_NANOS,
- (long long)pair.second.maxPullDelayNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DATA_ERROR, (long long)pair.second.dataError);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT,
- (long long)pair.second.pullTimeout);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_EXCEED_MAX_DELAY,
- (long long)pair.second.pullExceedMaxDelay);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_FAILED,
- (long long)pair.second.pullFailed);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_EMPTY_DATA,
- (long long)pair.second.emptyData);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_REGISTERED_COUNT,
- (long long) pair.second.registeredCount);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_UNREGISTERED_COUNT,
- (long long) pair.second.unregisteredCount);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_ERROR_COUNT, pair.second.atomErrorCount);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BINDER_CALL_FAIL_COUNT,
- (long long)pair.second.binderCallFailCount);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_UID_PROVIDER_NOT_FOUND,
- (long long)pair.second.pullUidProviderNotFound);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULLER_NOT_FOUND,
- (long long)pair.second.pullerNotFound);
- for (const auto& pullTimeoutMetadata : pair.second.pullTimeoutMetadata) {
- uint64_t timeoutMetadataToken = protoOutput->start(FIELD_TYPE_MESSAGE |
- FIELD_ID_PULL_TIMEOUT_METADATA |
- FIELD_COUNT_REPEATED);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT_METADATA_UPTIME_MILLIS,
- pullTimeoutMetadata.pullTimeoutUptimeMillis);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT_METADATA_ELAPSED_MILLIS,
- pullTimeoutMetadata.pullTimeoutElapsedMillis);
- protoOutput->end(timeoutMetadataToken);
- }
- protoOutput->end(token);
-}
-
-void writeAtomMetricStatsToStream(const std::pair<int64_t, StatsdStats::AtomMetricStats> &pair,
- util::ProtoOutputStream *protoOutput) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_METRIC_STATS |
- FIELD_COUNT_REPEATED);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_ID, (long long)pair.first);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_HARD_DIMENSION_LIMIT_REACHED,
- (long long)pair.second.hardDimensionLimitReached);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_LATE_LOG_EVENT_SKIPPED,
- (long long)pair.second.lateLogEventSkipped);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_FORWARD_BUCKETS,
- (long long)pair.second.skippedForwardBuckets);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BAD_VALUE_TYPE,
- (long long)pair.second.badValueType);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET,
- (long long)pair.second.conditionChangeInNextBucket);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_INVALIDATED_BUCKET,
- (long long)pair.second.invalidatedBucket);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_DROPPED,
- (long long)pair.second.bucketDropped);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MIN_BUCKET_BOUNDARY_DELAY_NS,
- (long long)pair.second.minBucketBoundaryDelayNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_BUCKET_BOUNDARY_DELAY_NS,
- (long long)pair.second.maxBucketBoundaryDelayNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_UNKNOWN_CONDITION,
- (long long)pair.second.bucketUnknownCondition);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_COUNT,
- (long long)pair.second.bucketCount);
- protoOutput->end(token);
-}
-
-int64_t getElapsedRealtimeNs() {
- return ::android::elapsedRealtimeNano();
-}
-
-int64_t getElapsedRealtimeSec() {
- return ::android::elapsedRealtimeNano() / NS_PER_SEC;
-}
-
-int64_t getElapsedRealtimeMillis() {
- return ::android::elapsedRealtime();
-}
-
-int64_t getSystemUptimeMillis() {
- return ::android::uptimeMillis();
-}
-
-int64_t getWallClockNs() {
- return time(nullptr) * NS_PER_SEC;
-}
-
-int64_t getWallClockSec() {
- return time(nullptr);
-}
-
-int64_t getWallClockMillis() {
- return time(nullptr) * MS_PER_SEC;
-}
-
-int64_t truncateTimestampIfNecessary(const LogEvent& event) {
- if (event.shouldTruncateTimestamp() ||
- (event.GetTagId() >= StatsdStats::kTimestampTruncationStartTag &&
- event.GetTagId() <= StatsdStats::kTimestampTruncationEndTag)) {
- return event.GetElapsedTimestampNs() / NS_PER_SEC / (5 * 60) * NS_PER_SEC * (5 * 60);
- } else {
- return event.GetElapsedTimestampNs();
- }
-}
-
-int64_t NanoToMillis(const int64_t nano) {
- return nano / 1000000;
-}
-
-int64_t MillisToNano(const int64_t millis) {
- return millis * 1000000;
-}
-
-bool checkPermissionForIds(const char* permission, pid_t pid, uid_t uid) {
- shared_ptr<IStatsCompanionService> scs = getStatsCompanionService();
- if (scs == nullptr) {
- return false;
- }
-
- bool success;
- ::ndk::ScopedAStatus status = scs->checkPermission(string(permission), pid, uid, &success);
- if (!status.isOk()) {
- return false;
- }
-
- return success;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
deleted file mode 100644
index eb65dc6..0000000
--- a/cmds/statsd/src/stats_log_util.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/util/ProtoOutputStream.h>
-
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& values,
- ProtoOutputStream* protoOutput);
-void writeDimensionToProto(const HashableDimensionKey& dimension, std::set<string> *str_set,
- ProtoOutputStream* protoOutput);
-
-void writeDimensionLeafNodesToProto(const HashableDimensionKey& dimension,
- const int dimensionLeafFieldId,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput);
-
-void writeDimensionPathToProto(const std::vector<Matcher>& fieldMatchers,
- ProtoOutputStream* protoOutput);
-
-void writeStateToProto(const FieldValue& state, ProtoOutputStream* protoOutput);
-
-// Convert the TimeUnit enum to the bucket size in millis with a guardrail on
-// bucket size.
-int64_t TimeUnitToBucketSizeInMillisGuardrailed(int uid, TimeUnit unit);
-
-// Convert the TimeUnit enum to the bucket size in millis.
-int64_t TimeUnitToBucketSizeInMillis(TimeUnit unit);
-
-// Gets the elapsed timestamp in ns.
-int64_t getElapsedRealtimeNs();
-
-// Gets the elapsed timestamp in millis.
-int64_t getElapsedRealtimeMillis();
-
-// Gets the elapsed timestamp in seconds.
-int64_t getElapsedRealtimeSec();
-
-// Gets the system uptime in millis.
-int64_t getSystemUptimeMillis();
-
-// Gets the wall clock timestamp in ns.
-int64_t getWallClockNs();
-
-// Gets the wall clock timestamp in millis.
-int64_t getWallClockMillis();
-
-// Gets the wall clock timestamp in seconds.
-int64_t getWallClockSec();
-
-int64_t NanoToMillis(const int64_t nano);
-
-int64_t MillisToNano(const int64_t millis);
-
-// Helper function to write PulledAtomStats to ProtoOutputStream
-void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>& pair,
- ProtoOutputStream* protoOutput);
-
-// Helper function to write AtomMetricStats to ProtoOutputStream
-void writeAtomMetricStatsToStream(const std::pair<int64_t, StatsdStats::AtomMetricStats> &pair,
- ProtoOutputStream *protoOutput);
-
-template<class T>
-bool parseProtoOutputStream(ProtoOutputStream& protoOutput, T* message) {
- std::string pbBytes;
- sp<android::util::ProtoReader> reader = protoOutput.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- pbBytes.append(reinterpret_cast<const char*>(reader->readBuffer()), toRead);
- reader->move(toRead);
- }
- return message->ParseFromArray(pbBytes.c_str(), pbBytes.size());
-}
-
-// Checks the truncate timestamp annotation as well as the blacklisted range of 300,000 - 304,999.
-// Returns the truncated timestamp to the nearest 5 minutes if needed.
-int64_t truncateTimestampIfNecessary(const LogEvent& event);
-
-// Checks permission for given pid and uid.
-bool checkPermissionForIds(const char* permission, pid_t pid, uid_t uid);
-
-inline bool isVendorPulledAtom(int atomId) {
- return atomId >= StatsdStats::kVendorPulledAtomStartTag && atomId < StatsdStats::kMaxAtomTag;
-}
-
-inline bool isPulledAtom(int atomId) {
- return atomId >= StatsdStats::kPullAtomStartTag && atomId < StatsdStats::kVendorAtomStartTag;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/stats_util.h b/cmds/statsd/src/stats_util.h
deleted file mode 100644
index cfc411f..0000000
--- a/cmds/statsd/src/stats_util.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "HashableDimensionKey.h"
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const HashableDimensionKey DEFAULT_DIMENSION_KEY = HashableDimensionKey();
-const MetricDimensionKey DEFAULT_METRIC_DIMENSION_KEY = MetricDimensionKey();
-
-typedef std::map<int64_t, HashableDimensionKey> ConditionKey;
-
-typedef std::unordered_map<MetricDimensionKey, int64_t> DimToValMap;
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/statscompanion_util.cpp b/cmds/statsd/src/statscompanion_util.cpp
deleted file mode 100644
index ce07ec0..0000000
--- a/cmds/statsd/src/statscompanion_util.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "statscompanion_util.h"
-#include <android/binder_auto_utils.h>
-#include <android/binder_manager.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-shared_ptr<IStatsCompanionService> getStatsCompanionService() {
- ::ndk::SpAIBinder binder(AServiceManager_getService("statscompanion"));
- return IStatsCompanionService::fromBinder(binder);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/statscompanion_util.h b/cmds/statsd/src/statscompanion_util.h
deleted file mode 100644
index e20c40b..0000000
--- a/cmds/statsd/src/statscompanion_util.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/IStatsCompanionService.h>
-
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/** Fetches and returns the StatsCompanionService. */
-shared_ptr<IStatsCompanionService> getStatsCompanionService();
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
deleted file mode 100644
index acdffd3..0000000
--- a/cmds/statsd/src/statsd_config.proto
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.internal.os";
-option java_outer_classname = "StatsdConfigProto";
-
-enum Position {
- POSITION_UNKNOWN = 0;
-
- FIRST = 1;
-
- LAST = 2;
-
- ANY = 3;
-
- ALL = 4;
-}
-
-enum TimeUnit {
- TIME_UNIT_UNSPECIFIED = 0;
- ONE_MINUTE = 1; // WILL BE GUARDRAILED TO 5 MINS UNLESS UID = SHELL OR ROOT
- FIVE_MINUTES = 2;
- TEN_MINUTES = 3;
- THIRTY_MINUTES = 4;
- ONE_HOUR = 5;
- THREE_HOURS = 6;
- SIX_HOURS = 7;
- TWELVE_HOURS = 8;
- ONE_DAY = 9;
- ONE_WEEK = 10;
- CTS = 1000;
-}
-
-message FieldMatcher {
- optional int32 field = 1;
-
- optional Position position = 2;
-
- repeated FieldMatcher child = 3;
-}
-
-message FieldValueMatcher {
- optional int32 field = 1;
-
- optional Position position = 2;
-
- oneof value_matcher {
- bool eq_bool = 3;
- string eq_string = 4;
- int64 eq_int = 5;
-
- int64 lt_int = 6;
- int64 gt_int = 7;
- float lt_float = 8;
- float gt_float = 9;
-
- int64 lte_int = 10;
- int64 gte_int = 11;
-
- MessageMatcher matches_tuple = 12;
-
- StringListMatcher eq_any_string = 13;
- StringListMatcher neq_any_string = 14;
- }
-}
-
-message MessageMatcher {
- repeated FieldValueMatcher field_value_matcher = 1;
-}
-
-message StringListMatcher {
- repeated string str_value = 1;
-}
-
-enum LogicalOperation {
- LOGICAL_OPERATION_UNSPECIFIED = 0;
- AND = 1;
- OR = 2;
- NOT = 3;
- NAND = 4;
- NOR = 5;
-}
-
-message SimpleAtomMatcher {
- optional int32 atom_id = 1;
-
- repeated FieldValueMatcher field_value_matcher = 2;
-}
-
-message AtomMatcher {
- optional int64 id = 1;
-
- message Combination {
- optional LogicalOperation operation = 1;
-
- repeated int64 matcher = 2;
- }
- oneof contents {
- SimpleAtomMatcher simple_atom_matcher = 2;
- Combination combination = 3;
- }
-}
-
-message SimplePredicate {
- optional int64 start = 1;
-
- optional int64 stop = 2;
-
- optional bool count_nesting = 3 [default = true];
-
- optional int64 stop_all = 4;
-
- enum InitialValue {
- UNKNOWN = 0;
- FALSE = 1;
- }
- optional InitialValue initial_value = 5 [default = UNKNOWN];
-
- optional FieldMatcher dimensions = 6;
-}
-
-message Predicate {
- optional int64 id = 1;
-
- message Combination {
- optional LogicalOperation operation = 1;
-
- repeated int64 predicate = 2;
- }
-
- oneof contents {
- SimplePredicate simple_predicate = 2;
- Combination combination = 3;
- }
-}
-
-message StateMap {
- message StateGroup {
- optional int64 group_id = 1;
-
- repeated int32 value = 2;
- }
-
- repeated StateGroup group = 1;
-}
-
-message State {
- optional int64 id = 1;
-
- optional int32 atom_id = 2;
-
- optional StateMap map = 3;
-}
-
-message MetricConditionLink {
- optional int64 condition = 1;
-
- optional FieldMatcher fields_in_what = 2;
-
- optional FieldMatcher fields_in_condition = 3;
-}
-
-message MetricStateLink {
- optional int32 state_atom_id = 1;
-
- optional FieldMatcher fields_in_what = 2;
-
- optional FieldMatcher fields_in_state = 3;
-}
-
-message FieldFilter {
- optional bool include_all = 1 [default = false];
- optional FieldMatcher fields = 2;
-}
-
-message EventMetric {
- optional int64 id = 1;
-
- optional int64 what = 2;
-
- optional int64 condition = 3;
-
- repeated MetricConditionLink links = 4;
-
- reserved 100;
- reserved 101;
-}
-
-message CountMetric {
- optional int64 id = 1;
-
- optional int64 what = 2;
-
- optional int64 condition = 3;
-
- optional FieldMatcher dimensions_in_what = 4;
-
- repeated int64 slice_by_state = 8;
-
- optional TimeUnit bucket = 5;
-
- repeated MetricConditionLink links = 6;
-
- repeated MetricStateLink state_link = 9;
-
- optional FieldMatcher dimensions_in_condition = 7 [deprecated = true];
-
- reserved 100;
- reserved 101;
-}
-
-message DurationMetric {
- optional int64 id = 1;
-
- optional int64 what = 2;
-
- optional int64 condition = 3;
-
- repeated int64 slice_by_state = 9;
-
- repeated MetricConditionLink links = 4;
-
- repeated MetricStateLink state_link = 10;
-
- enum AggregationType {
- SUM = 1;
-
- MAX_SPARSE = 2;
- }
- optional AggregationType aggregation_type = 5 [default = SUM];
-
- optional FieldMatcher dimensions_in_what = 6;
-
- optional TimeUnit bucket = 7;
-
- optional FieldMatcher dimensions_in_condition = 8 [deprecated = true];
-
- reserved 100;
- reserved 101;
-}
-
-message GaugeMetric {
- optional int64 id = 1;
-
- optional int64 what = 2;
-
- optional int64 trigger_event = 12;
-
- optional FieldFilter gauge_fields_filter = 3;
-
- optional int64 condition = 4;
-
- optional FieldMatcher dimensions_in_what = 5;
-
- optional FieldMatcher dimensions_in_condition = 8 [deprecated = true];
-
- optional TimeUnit bucket = 6;
-
- repeated MetricConditionLink links = 7;
-
- enum SamplingType {
- RANDOM_ONE_SAMPLE = 1;
- ALL_CONDITION_CHANGES = 2 [deprecated = true];
- CONDITION_CHANGE_TO_TRUE = 3;
- FIRST_N_SAMPLES = 4;
- }
- optional SamplingType sampling_type = 9 [default = RANDOM_ONE_SAMPLE] ;
-
- optional int64 min_bucket_size_nanos = 10;
-
- optional int64 max_num_gauge_atoms_per_bucket = 11 [default = 10];
-
- optional int32 max_pull_delay_sec = 13 [default = 30];
-
- optional bool split_bucket_for_app_upgrade = 14 [default = true];
-
- reserved 100;
- reserved 101;
-}
-
-message ValueMetric {
- optional int64 id = 1;
-
- optional int64 what = 2;
-
- optional FieldMatcher value_field = 3;
-
- optional int64 condition = 4;
-
- optional FieldMatcher dimensions_in_what = 5;
-
- repeated int64 slice_by_state = 18;
-
- optional TimeUnit bucket = 6;
-
- repeated MetricConditionLink links = 7;
-
- repeated MetricStateLink state_link = 19;
-
- enum AggregationType {
- SUM = 1;
- MIN = 2;
- MAX = 3;
- AVG = 4;
- }
- optional AggregationType aggregation_type = 8 [default = SUM];
-
- optional int64 min_bucket_size_nanos = 10;
-
- optional bool use_absolute_value_on_reset = 11 [default = false];
-
- optional bool use_diff = 12;
-
- optional bool use_zero_default_base = 15 [default = false];
-
- enum ValueDirection {
- UNKNOWN = 0;
- INCREASING = 1;
- DECREASING = 2;
- ANY = 3;
- }
- optional ValueDirection value_direction = 13 [default = INCREASING];
-
- optional bool skip_zero_diff_output = 14 [default = true];
-
- optional int32 max_pull_delay_sec = 16 [default = 30];
-
- optional bool split_bucket_for_app_upgrade = 17 [default = true];
-
- optional FieldMatcher dimensions_in_condition = 9 [deprecated = true];
-
- reserved 100;
- reserved 101;
-}
-
-message Alert {
- optional int64 id = 1;
-
- optional int64 metric_id = 2;
-
- optional int32 num_buckets = 3;
-
- optional int32 refractory_period_secs = 4;
-
- optional double trigger_if_sum_gt = 5;
-}
-
-message Alarm {
- optional int64 id = 1;
-
- optional int64 offset_millis = 2;
-
- optional int64 period_millis = 3;
-}
-
-message IncidentdDetails {
- repeated int32 section = 1;
-
- enum Destination {
- AUTOMATIC = 0;
- EXPLICIT = 1;
- }
- optional Destination dest = 2;
-
- // Package name of the incident report receiver.
- optional string receiver_pkg = 3;
-
- // Class name of the incident report receiver.
- optional string receiver_cls = 4;
-
- optional string alert_description = 5;
-}
-
-message PerfettoDetails {
- // The |trace_config| field is a proto-encoded message of type
- // perfetto.protos.TraceConfig defined in
- // //external/perfetto/protos/perfetto/config/. On device,
- // statsd doesn't need to deserialize the message as it's just
- // passed binary-encoded to the perfetto cmdline client.
- optional bytes trace_config = 1;
-}
-
-message BroadcastSubscriberDetails {
- optional int64 subscriber_id = 1;
- repeated string cookie = 2;
-}
-
-message Subscription {
- optional int64 id = 1;
-
- enum RuleType {
- RULE_TYPE_UNSPECIFIED = 0;
- ALARM = 1;
- ALERT = 2;
- }
- optional RuleType rule_type = 2;
-
- optional int64 rule_id = 3;
-
- oneof subscriber_information {
- IncidentdDetails incidentd_details = 4;
- PerfettoDetails perfetto_details = 5;
- BroadcastSubscriberDetails broadcast_subscriber_details = 6;
- }
-
- optional float probability_of_informing = 7 [default = 1.1];
-
- // This was used for perfprofd historically.
- reserved 8;
-}
-
-enum ActivationType {
- ACTIVATION_TYPE_UNKNOWN = 0;
- ACTIVATE_IMMEDIATELY = 1;
- ACTIVATE_ON_BOOT = 2;
-}
-
-message EventActivation {
- optional int64 atom_matcher_id = 1;
- optional int64 ttl_seconds = 2;
- optional int64 deactivation_atom_matcher_id = 3;
- optional ActivationType activation_type = 4;
-}
-
-message MetricActivation {
- optional int64 metric_id = 1;
-
- optional ActivationType activation_type = 3 [deprecated = true];
-
- repeated EventActivation event_activation = 2;
-}
-
-message PullAtomPackages {
- optional int32 atom_id = 1;
-
- repeated string packages = 2;
-}
-
-message StatsdConfig {
- optional int64 id = 1;
-
- repeated EventMetric event_metric = 2;
-
- repeated CountMetric count_metric = 3;
-
- repeated ValueMetric value_metric = 4;
-
- repeated GaugeMetric gauge_metric = 5;
-
- repeated DurationMetric duration_metric = 6;
-
- repeated AtomMatcher atom_matcher = 7;
-
- repeated Predicate predicate = 8;
-
- repeated Alert alert = 9;
-
- repeated Alarm alarm = 10;
-
- repeated Subscription subscription = 11;
-
- repeated string allowed_log_source = 12;
-
- repeated int64 no_report_metric = 13;
-
- message Annotation {
- optional int64 field_int64 = 1;
- optional int32 field_int32 = 2;
- }
- repeated Annotation annotation = 14;
-
- optional int64 ttl_in_seconds = 15;
-
- optional bool hash_strings_in_metric_report = 16 [default = true];
-
- repeated MetricActivation metric_activation = 17;
-
- optional bool version_strings_in_metric_report = 18;
-
- optional bool installer_in_metric_report = 19;
-
- optional bool persist_locally = 20 [default = false];
-
- repeated State state = 21;
-
- repeated string default_pull_packages = 22;
-
- repeated PullAtomPackages pull_atom_packages = 23;
-
- repeated int32 whitelisted_atom_ids = 24;
-
- // Field number 1000 is reserved for later use.
- reserved 1000;
-}
diff --git a/cmds/statsd/src/statsd_metadata.proto b/cmds/statsd/src/statsd_metadata.proto
deleted file mode 100644
index 200b392..0000000
--- a/cmds/statsd/src/statsd_metadata.proto
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd.metadata;
-
-message ConfigKey {
- optional int64 config_id = 1;
- optional int32 uid = 2;
-}
-
-message Field {
- optional int32 tag = 1;
- optional int32 field = 2;
-}
-
-message FieldValue {
- optional Field field = 1;
- oneof value {
- int32 value_int = 2;
- int64 value_long = 3;
- float value_float = 4;
- double value_double = 5;
- string value_str = 6;
- bytes value_storage = 7;
- }
-}
-
-message MetricDimensionKey {
- repeated FieldValue dimension_key_in_what = 1;
- repeated FieldValue state_values_key = 2;
-}
-
-message AlertDimensionKeyedData {
- // The earliest time the alert can be fired again in wall clock time.
- optional int32 last_refractory_ends_sec = 1;
- optional MetricDimensionKey dimension_key = 2;
-}
-
-message AlertMetadata {
- optional int64 alert_id = 1;
- repeated AlertDimensionKeyedData alert_dim_keyed_data = 2;
-}
-
-// All metadata for a config in statsd
-message StatsMetadata {
- optional ConfigKey config_key = 1;
- repeated AlertMetadata alert_metadata = 2;
-}
-
-message StatsMetadataList {
- repeated StatsMetadata stats_metadata = 1;
-}
\ No newline at end of file
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
deleted file mode 100644
index dcfdfe3..0000000
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ /dev/null
@@ -1,781 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "android-base/stringprintf.h"
-#include "guardrail/StatsdStats.h"
-#include "storage/StorageManager.h"
-#include "stats_log_util.h"
-
-#include <android-base/file.h>
-#include <private/android_filesystem_config.h>
-#include <fstream>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_MESSAGE;
-using std::map;
-
-/**
- * NOTE: these directories are protected by SELinux, any changes here must also update
- * the SELinux policies.
- */
-#define STATS_DATA_DIR "/data/misc/stats-data"
-#define STATS_SERVICE_DIR "/data/misc/stats-service"
-#define TRAIN_INFO_DIR "/data/misc/train-info"
-#define TRAIN_INFO_PATH "/data/misc/train-info/train-info.bin"
-
-// Magic word at the start of the train info file, change this if changing the file format
-const uint32_t TRAIN_INFO_FILE_MAGIC = 0xfb7447bf;
-
-// for ConfigMetricsReportList
-const int FIELD_ID_REPORTS = 2;
-
-std::mutex StorageManager::sTrainInfoMutex;
-
-using android::base::StringPrintf;
-using std::unique_ptr;
-
-struct FileName {
- int64_t mTimestampSec;
- int mUid;
- int64_t mConfigId;
- bool mIsHistory;
- string getFullFileName(const char* path) {
- return StringPrintf("%s/%lld_%d_%lld%s", path, (long long)mTimestampSec, (int)mUid,
- (long long)mConfigId, (mIsHistory ? "_history" : ""));
- };
-};
-
-string StorageManager::getDataFileName(long wallClockSec, int uid, int64_t id) {
- return StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR, wallClockSec, uid,
- (long long)id);
-}
-
-string StorageManager::getDataHistoryFileName(long wallClockSec, int uid, int64_t id) {
- return StringPrintf("%s/%ld_%d_%lld_history", STATS_DATA_DIR, wallClockSec, uid,
- (long long)id);
-}
-
-static string findTrainInfoFileNameLocked(const string& trainName) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(TRAIN_INFO_DIR), closedir);
- if (dir == NULL) {
- VLOG("Path %s does not exist", TRAIN_INFO_DIR);
- return "";
- }
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* fileName = de->d_name;
- if (fileName[0] == '.') continue;
-
- size_t fileNameLength = strlen(fileName);
- if (fileNameLength >= trainName.length()) {
- if (0 == strncmp(fileName + fileNameLength - trainName.length(), trainName.c_str(),
- trainName.length())) {
- return string(fileName);
- }
- }
- }
-
- return "";
-}
-
-// Returns array of int64_t which contains timestamp in seconds, uid,
-// configID and whether the file is a local history file.
-static void parseFileName(char* name, FileName* output) {
- int64_t result[3];
- int index = 0;
- char* substr = strtok(name, "_");
- while (substr != nullptr && index < 3) {
- result[index] = StrToInt64(substr);
- index++;
- substr = strtok(nullptr, "_");
- }
- // When index ends before hitting 3, file name is corrupted. We
- // intentionally put -1 at index 0 to indicate the error to caller.
- // TODO(b/110563137): consider removing files with unexpected name format.
- if (index < 3) {
- result[0] = -1;
- }
-
- output->mTimestampSec = result[0];
- output->mUid = result[1];
- output->mConfigId = result[2];
- // check if the file is a local history.
- output->mIsHistory = (substr != nullptr && strcmp("history", substr) == 0);
-}
-
-void StorageManager::writeFile(const char* file, const void* buffer, int numBytes) {
- int fd = open(file, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
- if (fd == -1) {
- VLOG("Attempt to access %s but failed", file);
- return;
- }
- trimToFit(STATS_SERVICE_DIR);
- trimToFit(STATS_DATA_DIR);
-
- if (android::base::WriteFully(fd, buffer, numBytes)) {
- VLOG("Successfully wrote %s", file);
- } else {
- ALOGE("Failed to write %s", file);
- }
-
- int result = fchown(fd, AID_STATSD, AID_STATSD);
- if (result) {
- VLOG("Failed to chown %s to statsd", file);
- }
-
- close(fd);
-}
-
-bool StorageManager::writeTrainInfo(const InstallTrainInfo& trainInfo) {
- std::lock_guard<std::mutex> lock(sTrainInfoMutex);
-
- if (trainInfo.trainName.empty()) {
- return false;
- }
- deleteSuffixedFiles(TRAIN_INFO_DIR, trainInfo.trainName.c_str());
-
- std::string fileName =
- StringPrintf("%s/%ld_%s", TRAIN_INFO_DIR, (long) getWallClockSec(),
- trainInfo.trainName.c_str());
-
- int fd = open(fileName.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
- if (fd == -1) {
- VLOG("Attempt to access %s but failed", fileName.c_str());
- return false;
- }
-
- size_t result;
- // Write the magic word
- result = write(fd, &TRAIN_INFO_FILE_MAGIC, sizeof(TRAIN_INFO_FILE_MAGIC));
- if (result != sizeof(TRAIN_INFO_FILE_MAGIC)) {
- VLOG("Failed to wrtie train info magic");
- close(fd);
- return false;
- }
-
- // Write the train version
- const size_t trainVersionCodeByteCount = sizeof(trainInfo.trainVersionCode);
- result = write(fd, &trainInfo.trainVersionCode, trainVersionCodeByteCount);
- if (result != trainVersionCodeByteCount) {
- VLOG("Failed to wrtie train version code");
- close(fd);
- return false;
- }
-
- // Write # of bytes in trainName to file
- const size_t trainNameSize = trainInfo.trainName.size();
- const size_t trainNameSizeByteCount = sizeof(trainNameSize);
- result = write(fd, (uint8_t*)&trainNameSize, trainNameSizeByteCount);
- if (result != trainNameSizeByteCount) {
- VLOG("Failed to write train name size");
- close(fd);
- return false;
- }
-
- // Write trainName to file
- result = write(fd, trainInfo.trainName.c_str(), trainNameSize);
- if (result != trainNameSize) {
- VLOG("Failed to write train name");
- close(fd);
- return false;
- }
-
- // Write status to file
- const size_t statusByteCount = sizeof(trainInfo.status);
- result = write(fd, (uint8_t*)&trainInfo.status, statusByteCount);
- if (result != statusByteCount) {
- VLOG("Failed to write status");
- close(fd);
- return false;
- }
-
- // Write experiment id count to file.
- const size_t experimentIdsCount = trainInfo.experimentIds.size();
- const size_t experimentIdsCountByteCount = sizeof(experimentIdsCount);
- result = write(fd, (uint8_t*) &experimentIdsCount, experimentIdsCountByteCount);
- if (result != experimentIdsCountByteCount) {
- VLOG("Failed to write experiment id count");
- close(fd);
- return false;
- }
-
- // Write experimentIds to file
- for (size_t i = 0; i < experimentIdsCount; i++) {
- const int64_t experimentId = trainInfo.experimentIds[i];
- const size_t experimentIdByteCount = sizeof(experimentId);
- result = write(fd, &experimentId, experimentIdByteCount);
- if (result == experimentIdByteCount) {
- VLOG("Successfully wrote experiment IDs");
- } else {
- VLOG("Failed to write experiment ids");
- close(fd);
- return false;
- }
- }
-
- // Write bools to file
- const size_t boolByteCount = sizeof(trainInfo.requiresStaging);
- result = write(fd, (uint8_t*)&trainInfo.requiresStaging, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to write requires staging");
- close(fd);
- return false;
- }
-
- result = write(fd, (uint8_t*)&trainInfo.rollbackEnabled, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to write rollback enabled");
- close(fd);
- return false;
- }
-
- result = write(fd, (uint8_t*)&trainInfo.requiresLowLatencyMonitor, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to write requires log latency monitor");
- close(fd);
- return false;
- }
-
- close(fd);
- return true;
-}
-
-bool StorageManager::readTrainInfo(const std::string& trainName, InstallTrainInfo& trainInfo) {
- std::lock_guard<std::mutex> lock(sTrainInfoMutex);
- return readTrainInfoLocked(trainName, trainInfo);
-}
-
-bool StorageManager::readTrainInfoLocked(const std::string& trainName, InstallTrainInfo& trainInfo) {
- trimToFit(TRAIN_INFO_DIR, /*parseTimestampOnly=*/ true);
- string fileName = findTrainInfoFileNameLocked(trainName);
- if (fileName.empty()) {
- return false;
- }
- int fd = open(StringPrintf("%s/%s", TRAIN_INFO_DIR, fileName.c_str()).c_str(), O_RDONLY | O_CLOEXEC);
- if (fd == -1) {
- VLOG("Failed to open %s", fileName.c_str());
- return false;
- }
-
- // Read the magic word
- uint32_t magic;
- size_t result = read(fd, &magic, sizeof(magic));
- if (result != sizeof(magic)) {
- VLOG("Failed to read train info magic");
- close(fd);
- return false;
- }
-
- if (magic != TRAIN_INFO_FILE_MAGIC) {
- VLOG("Train info magic was 0x%08x, expected 0x%08x", magic, TRAIN_INFO_FILE_MAGIC);
- close(fd);
- return false;
- }
-
- // Read the train version code
- const size_t trainVersionCodeByteCount(sizeof(trainInfo.trainVersionCode));
- result = read(fd, &trainInfo.trainVersionCode, trainVersionCodeByteCount);
- if (result != trainVersionCodeByteCount) {
- VLOG("Failed to read train version code from train info file");
- close(fd);
- return false;
- }
-
- // Read # of bytes taken by trainName in the file.
- size_t trainNameSize;
- result = read(fd, &trainNameSize, sizeof(size_t));
- if (result != sizeof(size_t)) {
- VLOG("Failed to read train name size from train info file");
- close(fd);
- return false;
- }
-
- // Read trainName
- trainInfo.trainName.resize(trainNameSize);
- result = read(fd, trainInfo.trainName.data(), trainNameSize);
- if (result != trainNameSize) {
- VLOG("Failed to read train name from train info file");
- close(fd);
- return false;
- }
-
- // Read status
- const size_t statusByteCount = sizeof(trainInfo.status);
- result = read(fd, &trainInfo.status, statusByteCount);
- if (result != statusByteCount) {
- VLOG("Failed to read train status from train info file");
- close(fd);
- return false;
- }
-
- // Read experiment ids count.
- size_t experimentIdsCount;
- result = read(fd, &experimentIdsCount, sizeof(size_t));
- if (result != sizeof(size_t)) {
- VLOG("Failed to read train experiment id count from train info file");
- close(fd);
- return false;
- }
-
- // Read experimentIds
- for (size_t i = 0; i < experimentIdsCount; i++) {
- int64_t experimentId;
- result = read(fd, &experimentId, sizeof(experimentId));
- if (result != sizeof(experimentId)) {
- VLOG("Failed to read train experiment id from train info file");
- close(fd);
- return false;
- }
- trainInfo.experimentIds.push_back(experimentId);
- }
-
- // Read bools
- const size_t boolByteCount = sizeof(trainInfo.requiresStaging);
- result = read(fd, &trainInfo.requiresStaging, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to read requires requires staging from train info file");
- close(fd);
- return false;
- }
-
- result = read(fd, &trainInfo.rollbackEnabled, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to read requires rollback enabled from train info file");
- close(fd);
- return false;
- }
-
- result = read(fd, &trainInfo.requiresLowLatencyMonitor, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to read requires requires low latency monitor from train info file");
- close(fd);
- return false;
- }
-
- // Expect to be at EOF.
- char c;
- result = read(fd, &c, 1);
- if (result != 0) {
- VLOG("Failed to read train info from file. Did not get expected EOF.");
- close(fd);
- return false;
- }
-
- VLOG("Read train info file successful");
- close(fd);
- return true;
-}
-
-vector<InstallTrainInfo> StorageManager::readAllTrainInfo() {
- std::lock_guard<std::mutex> lock(sTrainInfoMutex);
- vector<InstallTrainInfo> trainInfoList;
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(TRAIN_INFO_DIR), closedir);
- if (dir == NULL) {
- VLOG("Directory does not exist: %s", TRAIN_INFO_DIR);
- return trainInfoList;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') {
- continue;
- }
-
- InstallTrainInfo trainInfo;
- bool readSuccess = StorageManager::readTrainInfoLocked(name, trainInfo);
- if (!readSuccess) {
- continue;
- }
- trainInfoList.push_back(trainInfo);
- }
- return trainInfoList;
-}
-
-void StorageManager::deleteFile(const char* file) {
- if (remove(file) != 0) {
- VLOG("Attempt to delete %s but is not found", file);
- } else {
- VLOG("Successfully deleted %s", file);
- }
-}
-
-void StorageManager::deleteAllFiles(const char* path) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
- if (dir == NULL) {
- VLOG("Directory does not exist: %s", path);
- return;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
- deleteFile(StringPrintf("%s/%s", path, name).c_str());
- }
-}
-
-void StorageManager::deleteSuffixedFiles(const char* path, const char* suffix) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
- if (dir == NULL) {
- VLOG("Directory does not exist: %s", path);
- return;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') {
- continue;
- }
- size_t nameLen = strlen(name);
- size_t suffixLen = strlen(suffix);
- if (suffixLen <= nameLen && strncmp(name + nameLen - suffixLen, suffix, suffixLen) == 0) {
- deleteFile(StringPrintf("%s/%s", path, name).c_str());
- }
- }
-}
-
-void StorageManager::sendBroadcast(const char* path,
- const std::function<void(const ConfigKey&)>& sendBroadcast) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
- if (dir == NULL) {
- VLOG("no stats-data directory on disk");
- return;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
- VLOG("file %s", name);
-
- FileName output;
- parseFileName(name, &output);
- if (output.mTimestampSec == -1 || output.mIsHistory) continue;
- sendBroadcast(ConfigKey((int)output.mUid, output.mConfigId));
- }
-}
-
-bool StorageManager::hasConfigMetricsReport(const ConfigKey& key) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_DATA_DIR), closedir);
- if (dir == NULL) {
- VLOG("Path %s does not exist", STATS_DATA_DIR);
- return false;
- }
-
- string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
-
- size_t nameLen = strlen(name);
- size_t suffixLen = suffix.length();
- if (suffixLen <= nameLen &&
- strncmp(name + nameLen - suffixLen, suffix.c_str(), suffixLen) == 0) {
- // Check again that the file name is parseable.
- FileName output;
- parseFileName(name, &output);
- if (output.mTimestampSec == -1 || output.mIsHistory) continue;
- return true;
- }
- }
- return false;
-}
-
-void StorageManager::appendConfigMetricsReport(const ConfigKey& key, ProtoOutputStream* proto,
- bool erase_data, bool isAdb) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_DATA_DIR), closedir);
- if (dir == NULL) {
- VLOG("Path %s does not exist", STATS_DATA_DIR);
- return;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- string fileName(name);
- if (name[0] == '.') continue;
- FileName output;
- parseFileName(name, &output);
-
- if (output.mTimestampSec == -1 || (output.mIsHistory && !isAdb) ||
- output.mUid != key.GetUid() || output.mConfigId != key.GetId()) {
- continue;
- }
-
- auto fullPathName = StringPrintf("%s/%s", STATS_DATA_DIR, fileName.c_str());
- int fd = open(fullPathName.c_str(), O_RDONLY | O_CLOEXEC);
- if (fd != -1) {
- string content;
- if (android::base::ReadFdToString(fd, &content)) {
- proto->write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS,
- content.c_str(), content.size());
- }
- close(fd);
- } else {
- ALOGE("file cannot be opened");
- }
-
- if (erase_data) {
- remove(fullPathName.c_str());
- } else if (!output.mIsHistory && !isAdb) {
- // This means a real data owner has called to get this data. But the config says it
- // wants to keep a local history. So now this file must be renamed as a history file.
- // So that next time, when owner calls getData() again, this data won't be uploaded
- // again. rename returns 0 on success
- if (rename(fullPathName.c_str(), (fullPathName + "_history").c_str())) {
- ALOGE("Failed to rename file %s", fullPathName.c_str());
- }
- }
- }
-}
-
-bool StorageManager::readFileToString(const char* file, string* content) {
- int fd = open(file, O_RDONLY | O_CLOEXEC);
- bool res = false;
- if (fd != -1) {
- if (android::base::ReadFdToString(fd, content)) {
- res = true;
- } else {
- VLOG("Failed to read file %s\n", file);
- }
- close(fd);
- }
- return res;
-}
-
-void StorageManager::readConfigFromDisk(map<ConfigKey, StatsdConfig>& configsMap) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR), closedir);
- if (dir == NULL) {
- VLOG("no default config on disk");
- return;
- }
- trimToFit(STATS_SERVICE_DIR);
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
-
- FileName output;
- parseFileName(name, &output);
- if (output.mTimestampSec == -1) continue;
- string file_name = output.getFullFileName(STATS_SERVICE_DIR);
- int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
- if (fd != -1) {
- string content;
- if (android::base::ReadFdToString(fd, &content)) {
- StatsdConfig config;
- if (config.ParseFromString(content)) {
- configsMap[ConfigKey(output.mUid, output.mConfigId)] = config;
- VLOG("map key uid=%lld|configID=%lld", (long long)output.mUid,
- (long long)output.mConfigId);
- }
- }
- close(fd);
- }
- }
-}
-
-bool StorageManager::readConfigFromDisk(const ConfigKey& key, StatsdConfig* config) {
- string content;
- return config != nullptr &&
- StorageManager::readConfigFromDisk(key, &content) && config->ParseFromString(content);
-}
-
-bool StorageManager::readConfigFromDisk(const ConfigKey& key, string* content) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR),
- closedir);
- if (dir == NULL) {
- VLOG("Directory does not exist: %s", STATS_SERVICE_DIR);
- return false;
- }
-
- string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') {
- continue;
- }
- size_t nameLen = strlen(name);
- size_t suffixLen = suffix.length();
- // There can be at most one file that matches this suffix (config key).
- if (suffixLen <= nameLen &&
- strncmp(name + nameLen - suffixLen, suffix.c_str(), suffixLen) == 0) {
- int fd = open(StringPrintf("%s/%s", STATS_SERVICE_DIR, name).c_str(),
- O_RDONLY | O_CLOEXEC);
- if (fd != -1) {
- if (android::base::ReadFdToString(fd, content)) {
- return true;
- }
- close(fd);
- }
- }
- }
- return false;
-}
-
-bool StorageManager::hasIdenticalConfig(const ConfigKey& key,
- const vector<uint8_t>& config) {
- string content;
- if (StorageManager::readConfigFromDisk(key, &content)) {
- vector<uint8_t> vec(content.begin(), content.end());
- if (vec == config) {
- return true;
- }
- }
- return false;
-}
-
-void StorageManager::sortFiles(vector<FileInfo>* fileNames) {
- // Reverse sort to effectively remove from the back (oldest entries).
- // This will sort files in reverse-chronological order. Local history files have lower
- // priority than regular data files.
- sort(fileNames->begin(), fileNames->end(), [](FileInfo& lhs, FileInfo& rhs) {
- // first consider if the file is a local history
- if (lhs.mIsHistory && !rhs.mIsHistory) {
- return false;
- } else if (rhs.mIsHistory && !lhs.mIsHistory) {
- return true;
- }
-
- // then consider the age.
- if (lhs.mFileAgeSec < rhs.mFileAgeSec) {
- return true;
- } else if (lhs.mFileAgeSec > rhs.mFileAgeSec) {
- return false;
- }
-
- // then good luck.... use string::compare
- return lhs.mFileName.compare(rhs.mFileName) > 0;
- });
-}
-
-void StorageManager::trimToFit(const char* path, bool parseTimestampOnly) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
- if (dir == NULL) {
- VLOG("Path %s does not exist", path);
- return;
- }
- dirent* de;
- int totalFileSize = 0;
- vector<FileInfo> fileNames;
- auto nowSec = getWallClockSec();
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
-
- FileName output;
- string file_name;
- if (parseTimestampOnly) {
- file_name = StringPrintf("%s/%s", path, name);
- output.mTimestampSec = StrToInt64(strtok(name, "_"));
- output.mIsHistory = false;
- } else {
- parseFileName(name, &output);
- file_name = output.getFullFileName(path);
- }
- if (output.mTimestampSec == -1) continue;
-
- // Check for timestamp and delete if it's too old.
- long fileAge = nowSec - output.mTimestampSec;
- if (fileAge > StatsdStats::kMaxAgeSecond ||
- (output.mIsHistory && fileAge > StatsdStats::kMaxLocalHistoryAgeSecond)) {
- deleteFile(file_name.c_str());
- continue;
- }
-
- ifstream file(file_name.c_str(), ifstream::in | ifstream::binary);
- int fileSize = 0;
- if (file.is_open()) {
- file.seekg(0, ios::end);
- fileSize = file.tellg();
- file.close();
- totalFileSize += fileSize;
- }
- fileNames.emplace_back(file_name, output.mIsHistory, fileSize, fileAge);
- }
-
- if (fileNames.size() > StatsdStats::kMaxFileNumber ||
- totalFileSize > StatsdStats::kMaxFileSize) {
- sortFiles(&fileNames);
- }
-
- // Start removing files from oldest to be under the limit.
- while (fileNames.size() > 0 && (fileNames.size() > StatsdStats::kMaxFileNumber ||
- totalFileSize > StatsdStats::kMaxFileSize)) {
- totalFileSize -= fileNames.at(fileNames.size() - 1).mFileSizeBytes;
- deleteFile(fileNames.at(fileNames.size() - 1).mFileName.c_str());
- fileNames.pop_back();
- }
-}
-
-void StorageManager::printStats(int outFd) {
- printDirStats(outFd, STATS_SERVICE_DIR);
- printDirStats(outFd, STATS_DATA_DIR);
-}
-
-void StorageManager::printDirStats(int outFd, const char* path) {
- dprintf(outFd, "Printing stats of %s\n", path);
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
- if (dir == NULL) {
- VLOG("Path %s does not exist", path);
- return;
- }
- dirent* de;
- int fileCount = 0;
- int totalFileSize = 0;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') {
- continue;
- }
- FileName output;
- parseFileName(name, &output);
- if (output.mTimestampSec == -1) continue;
- dprintf(outFd, "\t #%d, Last updated: %lld, UID: %d, Config ID: %lld, %s", fileCount + 1,
- (long long)output.mTimestampSec, output.mUid, (long long)output.mConfigId,
- (output.mIsHistory ? "local history" : ""));
- string file_name = output.getFullFileName(path);
- ifstream file(file_name.c_str(), ifstream::in | ifstream::binary);
- if (file.is_open()) {
- file.seekg(0, ios::end);
- int fileSize = file.tellg();
- file.close();
- dprintf(outFd, ", File Size: %d bytes", fileSize);
- totalFileSize += fileSize;
- }
- dprintf(outFd, "\n");
- fileCount++;
- }
- dprintf(outFd, "\tTotal number of files: %d, Total size of files: %d bytes.\n", fileCount,
- totalFileSize);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/storage/StorageManager.h b/cmds/statsd/src/storage/StorageManager.h
deleted file mode 100644
index d59046d..0000000
--- a/cmds/statsd/src/storage/StorageManager.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STORAGE_MANAGER_H
-#define STORAGE_MANAGER_H
-
-#include <android/util/ProtoOutputStream.h>
-#include <utils/Log.h>
-#include <utils/RefBase.h>
-
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-
-class StorageManager : public virtual RefBase {
-public:
- struct FileInfo {
- FileInfo(std::string name, bool isHistory, int fileSize, long fileAge)
- : mFileName(name),
- mIsHistory(isHistory),
- mFileSizeBytes(fileSize),
- mFileAgeSec(fileAge) {
- }
- std::string mFileName;
- bool mIsHistory;
- int mFileSizeBytes;
- long mFileAgeSec;
- };
-
- /**
- * Writes a given byte array as a file to the specified file path.
- */
- static void writeFile(const char* file, const void* buffer, int numBytes);
-
- /**
- * Writes train info.
- */
- static bool writeTrainInfo(const InstallTrainInfo& trainInfo);
-
- /**
- * Reads train info.
- */
- static bool readTrainInfo(const std::string& trainName, InstallTrainInfo& trainInfo);
-
- /**
- * Reads train info assuming lock is obtained.
- */
- static bool readTrainInfoLocked(const std::string& trainName, InstallTrainInfo& trainInfo);
-
- /**
- * Reads all train info and returns a vector of train info.
- */
- static vector<InstallTrainInfo> readAllTrainInfo();
-
- /**
- * Reads the file content to the buffer.
- */
- static bool readFileToString(const char* file, string* content);
-
- /**
- * Deletes a single file given a file name.
- */
- static void deleteFile(const char* file);
-
- /**
- * Deletes all files in a given directory.
- */
- static void deleteAllFiles(const char* path);
-
- /**
- * Deletes all files whose name matches with a provided suffix.
- */
- static void deleteSuffixedFiles(const char* path, const char* suffix);
-
- /**
- * Send broadcasts to relevant receiver for each data stored on disk.
- */
- static void sendBroadcast(const char* path,
- const std::function<void(const ConfigKey&)>& sendBroadcast);
-
- /**
- * Returns true if there's at least one report on disk.
- */
- static bool hasConfigMetricsReport(const ConfigKey& key);
-
- /**
- * Appends the ConfigMetricsReport found on disk to the specifid proto
- * and, if erase_data, deletes it from disk.
- *
- * [isAdb]: if the caller is adb dump. This includes local adb dump or dumpsys by
- * bugreport or incidentd. When true, we will append any local history data too.
- *
- * When
- * erase_data=true, isAdb=true: append history data to output, remove all data after read
- * erase_data=false, isAdb=true: append history data to output, keep data after read
- * erase_data=true, isAdb=false: do not append history data, and remove data after read
- * erase_data=false, isAdb=false: do not append history data and *rename* all data files to
- * history files.
- */
- static void appendConfigMetricsReport(const ConfigKey& key, ProtoOutputStream* proto,
- bool erase_data, bool isAdb);
-
- /**
- * Call to load the saved configs from disk.
- */
- static void readConfigFromDisk(std::map<ConfigKey, StatsdConfig>& configsMap);
-
- /**
- * Call to load the specified config from disk. Returns false if the config file does not
- * exist or error occurs when reading the file.
- */
- static bool readConfigFromDisk(const ConfigKey& key, StatsdConfig* config);
- static bool readConfigFromDisk(const ConfigKey& key, string* config);
-
- /**
- * Trims files in the provided directory to limit the total size, number of
- * files, accumulation of outdated files.
- */
- static void trimToFit(const char* dir, bool parseTimestampOnly = false);
-
- /**
- * Returns true if there already exists identical configuration on device.
- */
- static bool hasIdenticalConfig(const ConfigKey& key,
- const vector<uint8_t>& config);
-
- /**
- * Prints disk usage statistics related to statsd.
- */
- static void printStats(int out);
-
- static string getDataFileName(long wallClockSec, int uid, int64_t id);
-
- static string getDataHistoryFileName(long wallClockSec, int uid, int64_t id);
-
- static void sortFiles(vector<FileInfo>* fileNames);
-
-private:
- /**
- * Prints disk usage statistics about a directory related to statsd.
- */
- static void printDirStats(int out, const char* path);
-
- static std::mutex sTrainInfoMutex;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // STORAGE_MANAGER_H
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
deleted file mode 100644
index 1d77513..0000000
--- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false
-#include "Log.h"
-
-#include "FieldValue.h"
-#include "IncidentdReporter.h"
-#include "packages/UidMap.h"
-#include "stats_log_util.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include <incident/incident_report.h>
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-using std::vector;
-
-using util::FIELD_TYPE_INT32;
-using util::FIELD_TYPE_INT64;
-using util::FIELD_TYPE_MESSAGE;
-using util::FIELD_TYPE_STRING;
-
-// field ids in IncidentHeaderProto
-const int FIELD_ID_ALERT_ID = 1;
-const int FIELD_ID_REASON = 2;
-const int FIELD_ID_CONFIG_KEY = 3;
-const int FIELD_ID_CONFIG_KEY_UID = 1;
-const int FIELD_ID_CONFIG_KEY_ID = 2;
-
-const int FIELD_ID_TRIGGER_DETAILS = 4;
-const int FIELD_ID_TRIGGER_DETAILS_TRIGGER_METRIC = 1;
-const int FIELD_ID_METRIC_VALUE_METRIC_ID = 1;
-const int FIELD_ID_METRIC_VALUE_DIMENSION_IN_WHAT = 2;
-const int FIELD_ID_METRIC_VALUE_VALUE = 4;
-
-const int FIELD_ID_PACKAGE_INFO = 3;
-
-namespace {
-void getProtoData(const int64_t& rule_id, int64_t metricId, const MetricDimensionKey& dimensionKey,
- int64_t metricValue, const ConfigKey& configKey, const string& reason,
- vector<uint8_t>* protoData) {
- ProtoOutputStream headerProto;
- headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_ID, (long long)rule_id);
- headerProto.write(FIELD_TYPE_STRING | FIELD_ID_REASON, reason);
- uint64_t token =
- headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
- headerProto.write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_KEY_UID, configKey.GetUid());
- headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_KEY_ID, (long long)configKey.GetId());
- headerProto.end(token);
-
- token = headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_TRIGGER_DETAILS);
-
- // MetricValue trigger_metric = 1;
- uint64_t metricToken =
- headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_TRIGGER_DETAILS_TRIGGER_METRIC);
- // message MetricValue {
- // optional int64 metric_id = 1;
- headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_VALUE_METRIC_ID, (long long)metricId);
- // optional DimensionsValue dimension_in_what = 2;
- uint64_t dimToken =
- headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_METRIC_VALUE_DIMENSION_IN_WHAT);
- writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), nullptr, &headerProto);
- headerProto.end(dimToken);
-
- // deprecated field
- // optional DimensionsValue dimension_in_condition = 3;
-
- // optional int64 value = 4;
- headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_VALUE_VALUE, (long long)metricValue);
-
- // }
- headerProto.end(metricToken);
-
- // write relevant uid package info
- std::set<int32_t> uids;
-
- for (const auto& dim : dimensionKey.getDimensionKeyInWhat().getValues()) {
- int uid = getUidIfExists(dim);
- // any uid <= 2000 are predefined AID_*
- if (uid > 2000) {
- uids.insert(uid);
- }
- }
-
- if (!uids.empty()) {
- uint64_t token = headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_PACKAGE_INFO);
- UidMap::getInstance()->writeUidMapSnapshot(getElapsedRealtimeNs(), true, true, uids,
- nullptr /*string set*/, &headerProto);
- headerProto.end(token);
- }
-
- headerProto.end(token);
-
- protoData->resize(headerProto.size());
- size_t pos = 0;
- sp<android::util::ProtoReader> reader = headerProto.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((*protoData)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-}
-} // namespace
-
-bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int64_t metricId,
- const MetricDimensionKey& dimensionKey, int64_t metricValue,
- const ConfigKey& configKey) {
- if (config.section_size() == 0) {
- VLOG("The alert %lld contains zero section in config(%d,%lld)", (unsigned long long)rule_id,
- configKey.GetUid(), (long long)configKey.GetId());
- return false;
- }
-
- AIncidentReportArgs* args = AIncidentReportArgs_init();
-
- vector<uint8_t> protoData;
- getProtoData(rule_id, metricId, dimensionKey, metricValue, configKey,
- config.alert_description(), &protoData);
- AIncidentReportArgs_addHeader(args, protoData.data(), protoData.size());
-
- for (int i = 0; i < config.section_size(); i++) {
- AIncidentReportArgs_addSection(args, config.section(i));
- }
-
- uint8_t dest;
- switch (config.dest()) {
- case IncidentdDetails_Destination_AUTOMATIC:
- dest = INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC;
- break;
- case IncidentdDetails_Destination_EXPLICIT:
- dest = INCIDENT_REPORT_PRIVACY_POLICY_EXPLICIT;
- break;
- default:
- dest = INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC;
- }
- AIncidentReportArgs_setPrivacyPolicy(args, dest);
-
- AIncidentReportArgs_setReceiverPackage(args, config.receiver_pkg().c_str());
-
- AIncidentReportArgs_setReceiverClass(args, config.receiver_cls().c_str());
-
- int err = AIncidentReportArgs_takeReport(args);
- AIncidentReportArgs_delete(args);
-
- return err == NO_ERROR;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.h b/cmds/statsd/src/subscriber/IncidentdReporter.h
deleted file mode 100644
index e78a4d9..0000000
--- a/cmds/statsd/src/subscriber/IncidentdReporter.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "HashableDimensionKey.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alert, IncidentdDetails
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Calls incidentd to trigger an incident report and put in dropbox for uploading.
- */
-bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int64_t metricId,
- const MetricDimensionKey& dimensionKey, int64_t metricValue,
- const ConfigKey& configKey);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.cpp b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
deleted file mode 100644
index c915ef3..0000000
--- a/cmds/statsd/src/subscriber/SubscriberReporter.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "SubscriberReporter.h"
-
-using std::lock_guard;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-struct BroadcastSubscriberDeathCookie {
- BroadcastSubscriberDeathCookie(const ConfigKey& configKey, int64_t subscriberId,
- const shared_ptr<IPendingIntentRef>& pir):
- mConfigKey(configKey),
- mSubscriberId(subscriberId),
- mPir(pir) {}
-
- ConfigKey mConfigKey;
- int64_t mSubscriberId;
- shared_ptr<IPendingIntentRef> mPir;
-};
-
-void SubscriberReporter::broadcastSubscriberDied(void* cookie) {
- auto cookie_ = static_cast<BroadcastSubscriberDeathCookie*>(cookie);
- ConfigKey& configKey = cookie_->mConfigKey;
- int64_t subscriberId = cookie_->mSubscriberId;
- shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
-
- SubscriberReporter& thiz = getInstance();
-
- // Erase the mapping from a (config_key, subscriberId) to a pir if the
- // mapping exists.
- lock_guard<mutex> lock(thiz.mLock);
- auto subscriberMapIt = thiz.mIntentMap.find(configKey);
- if (subscriberMapIt != thiz.mIntentMap.end()) {
- auto subscriberMap = subscriberMapIt->second;
- auto pirIt = subscriberMap.find(subscriberId);
- if (pirIt != subscriberMap.end() && pirIt->second == pir) {
- subscriberMap.erase(subscriberId);
- if (subscriberMap.empty()) {
- thiz.mIntentMap.erase(configKey);
- }
- }
- }
-
- // The death recipient corresponding to this specific pir can never be
- // triggered again, so free up resources.
- delete cookie_;
-}
-
-SubscriberReporter::SubscriberReporter() :
- mBroadcastSubscriberDeathRecipient(AIBinder_DeathRecipient_new(broadcastSubscriberDied)) {
-}
-
-void SubscriberReporter::setBroadcastSubscriber(const ConfigKey& configKey,
- int64_t subscriberId,
- const shared_ptr<IPendingIntentRef>& pir) {
- VLOG("SubscriberReporter::setBroadcastSubscriber called.");
- {
- lock_guard<mutex> lock(mLock);
- mIntentMap[configKey][subscriberId] = pir;
- }
- AIBinder_linkToDeath(pir->asBinder().get(), mBroadcastSubscriberDeathRecipient.get(),
- new BroadcastSubscriberDeathCookie(configKey, subscriberId, pir));
-}
-
-void SubscriberReporter::unsetBroadcastSubscriber(const ConfigKey& configKey,
- int64_t subscriberId) {
- VLOG("SubscriberReporter::unsetBroadcastSubscriber called.");
- lock_guard<mutex> lock(mLock);
- auto subscriberMapIt = mIntentMap.find(configKey);
- if (subscriberMapIt != mIntentMap.end()) {
- subscriberMapIt->second.erase(subscriberId);
- if (subscriberMapIt->second.empty()) {
- mIntentMap.erase(configKey);
- }
- }
-}
-
-void SubscriberReporter::alertBroadcastSubscriber(const ConfigKey& configKey,
- const Subscription& subscription,
- const MetricDimensionKey& dimKey) const {
- // Reminder about ids:
- // subscription id - name of the Subscription (that ties the Alert to the broadcast)
- // subscription rule_id - the name of the Alert (that triggers the broadcast)
- // subscriber_id - name of the PendingIntent to use to send the broadcast
- // config uid - the uid that uploaded the config (and therefore gave the PendingIntent,
- // although the intent may be to broadcast to a different uid)
- // config id - the name of this config (for this particular uid)
-
- VLOG("SubscriberReporter::alertBroadcastSubscriber called.");
- lock_guard<mutex> lock(mLock);
-
- if (!subscription.has_broadcast_subscriber_details()
- || !subscription.broadcast_subscriber_details().has_subscriber_id()) {
- ALOGE("Broadcast subscriber does not have an id.");
- return;
- }
- int64_t subscriberId = subscription.broadcast_subscriber_details().subscriber_id();
-
- vector<string> cookies;
- cookies.reserve(subscription.broadcast_subscriber_details().cookie_size());
- for (auto& cookie : subscription.broadcast_subscriber_details().cookie()) {
- cookies.push_back(cookie);
- }
-
- auto it1 = mIntentMap.find(configKey);
- if (it1 == mIntentMap.end()) {
- ALOGW("Cannot inform subscriber for missing config key %s ", configKey.ToString().c_str());
- return;
- }
- auto it2 = it1->second.find(subscriberId);
- if (it2 == it1->second.end()) {
- ALOGW("Cannot inform subscriber of config %s for missing subscriberId %lld ",
- configKey.ToString().c_str(), (long long)subscriberId);
- return;
- }
- sendBroadcastLocked(it2->second, configKey, subscription, cookies, dimKey);
-}
-
-void SubscriberReporter::sendBroadcastLocked(const shared_ptr<IPendingIntentRef>& pir,
- const ConfigKey& configKey,
- const Subscription& subscription,
- const vector<string>& cookies,
- const MetricDimensionKey& dimKey) const {
- VLOG("SubscriberReporter::sendBroadcastLocked called.");
- pir->sendSubscriberBroadcast(
- configKey.GetUid(),
- configKey.GetId(),
- subscription.id(),
- subscription.rule_id(),
- cookies,
- dimKey.getDimensionKeyInWhat().toStatsDimensionsValueParcel());
-}
-
-shared_ptr<IPendingIntentRef> SubscriberReporter::getBroadcastSubscriber(const ConfigKey& configKey,
- int64_t subscriberId) {
- lock_guard<mutex> lock(mLock);
- auto subscriberMapIt = mIntentMap.find(configKey);
- if (subscriberMapIt == mIntentMap.end()) {
- return nullptr;
- }
- auto pirMapIt = subscriberMapIt->second.find(subscriberId);
- if (pirMapIt == subscriberMapIt->second.end()) {
- return nullptr;
- }
- return pirMapIt->second;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.h b/cmds/statsd/src/subscriber/SubscriberReporter.h
deleted file mode 100644
index 4fe4281..0000000
--- a/cmds/statsd/src/subscriber/SubscriberReporter.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/IPendingIntentRef.h>
-#include <utils/RefBase.h>
-#include <utils/String16.h>
-
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // subscription
-#include "HashableDimensionKey.h"
-
-#include <mutex>
-#include <unordered_map>
-#include <vector>
-
-using aidl::android::os::IPendingIntentRef;
-using std::mutex;
-using std::shared_ptr;
-using std::string;
-using std::unordered_map;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Reports information to subscribers.
-// Single instance shared across the process. All methods are thread safe.
-class SubscriberReporter {
-public:
- /** Get (singleton) instance of SubscriberReporter. */
- static SubscriberReporter& getInstance() {
- static SubscriberReporter subscriberReporter;
- return subscriberReporter;
- }
-
- ~SubscriberReporter(){};
- SubscriberReporter(SubscriberReporter const&) = delete;
- void operator=(SubscriberReporter const&) = delete;
-
- /**
- * Stores the given intentSender, associating it with the given (configKey, subscriberId) pair.
- */
- void setBroadcastSubscriber(const ConfigKey& configKey,
- int64_t subscriberId,
- const shared_ptr<IPendingIntentRef>& pir);
-
- /**
- * Erases any intentSender information from the given (configKey, subscriberId) pair.
- */
- void unsetBroadcastSubscriber(const ConfigKey& configKey, int64_t subscriberId);
-
- /**
- * Sends a broadcast via the intentSender previously stored for the
- * given (configKey, subscriberId) pair by setBroadcastSubscriber.
- * Information about the subscriber, as well as information extracted from the dimKey, is sent.
- */
- void alertBroadcastSubscriber(const ConfigKey& configKey,
- const Subscription& subscription,
- const MetricDimensionKey& dimKey) const;
-
- shared_ptr<IPendingIntentRef> getBroadcastSubscriber(const ConfigKey& configKey,
- int64_t subscriberId);
-
-private:
- SubscriberReporter();
-
- mutable mutex mLock;
-
- /** Maps <ConfigKey, SubscriberId> -> IPendingIntentRef (which represents a PendingIntent). */
- unordered_map<ConfigKey, unordered_map<int64_t, shared_ptr<IPendingIntentRef>>> mIntentMap;
-
- /**
- * Sends a broadcast via the given intentSender (using mStatsCompanionService), along
- * with the information in the other parameters.
- */
- void sendBroadcastLocked(const shared_ptr<IPendingIntentRef>& pir,
- const ConfigKey& configKey,
- const Subscription& subscription,
- const vector<string>& cookies,
- const MetricDimensionKey& dimKey) const;
-
- ::ndk::ScopedAIBinder_DeathRecipient mBroadcastSubscriberDeathRecipient;
-
- /**
- * Death recipient callback that is called when a broadcast subscriber dies.
- * The cookie is a pointer to a BroadcastSubscriberDeathCookie.
- */
- static void broadcastSubscriberDied(void* cookie);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/uid_data.proto b/cmds/statsd/src/uid_data.proto
deleted file mode 100644
index a6fa26cd..0000000
--- a/cmds/statsd/src/uid_data.proto
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.internal.os";
-option java_outer_classname = "UidDataProto";
-
-message ApplicationInfo {
- optional int32 uid = 1;
- optional int64 version = 2;
- optional string version_string = 3;
- optional string package_name = 4;
- optional string installer = 5;
-}
-
-// StatsServiceCompanion uses the proto to supply statsd with uid-package
-// mapping updates.
-message UidData {
- repeated ApplicationInfo app_info = 1;
-}
diff --git a/cmds/statsd/src/utils/MultiConditionTrigger.cpp b/cmds/statsd/src/utils/MultiConditionTrigger.cpp
deleted file mode 100644
index 43a6933..0000000
--- a/cmds/statsd/src/utils/MultiConditionTrigger.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-
-#include "MultiConditionTrigger.h"
-
-#include <thread>
-
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-MultiConditionTrigger::MultiConditionTrigger(const set<string>& conditionNames,
- function<void()> trigger)
- : mRemainingConditionNames(conditionNames),
- mTrigger(trigger),
- mCompleted(mRemainingConditionNames.empty()) {
- if (mCompleted) {
- thread executorThread([this] { mTrigger(); });
- executorThread.detach();
- }
-}
-
-void MultiConditionTrigger::markComplete(const string& conditionName) {
- bool doTrigger = false;
- {
- lock_guard<mutex> lg(mMutex);
- if (mCompleted) {
- return;
- }
- mRemainingConditionNames.erase(conditionName);
- mCompleted = mRemainingConditionNames.empty();
- doTrigger = mCompleted;
- }
- if (doTrigger) {
- std::thread executorThread([this] { mTrigger(); });
- executorThread.detach();
- }
-}
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/utils/MultiConditionTrigger.h b/cmds/statsd/src/utils/MultiConditionTrigger.h
deleted file mode 100644
index 51f6029..0000000
--- a/cmds/statsd/src/utils/MultiConditionTrigger.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <gtest/gtest_prod.h>
-
-#include <mutex>
-#include <set>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * This class provides a utility to wait for a set of named conditions to occur.
- *
- * It will execute the trigger runnable in a detached thread once all conditions have been marked
- * true.
- */
-class MultiConditionTrigger {
-public:
- explicit MultiConditionTrigger(const std::set<std::string>& conditionNames,
- std::function<void()> trigger);
-
- MultiConditionTrigger(const MultiConditionTrigger&) = delete;
- MultiConditionTrigger& operator=(const MultiConditionTrigger&) = delete;
-
- // Mark a specific condition as true. If this condition has called markComplete already or if
- // the event was not specified in the constructor, the function is a no-op.
- void markComplete(const std::string& eventName);
-
-private:
- mutable std::mutex mMutex;
- std::set<std::string> mRemainingConditionNames;
- std::function<void()> mTrigger;
- bool mCompleted;
-
- FRIEND_TEST(MultiConditionTriggerTest, TestCountDownCalledBySameEventName);
-};
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/statsd_test.xml b/cmds/statsd/statsd_test.xml
deleted file mode 100644
index 8f9bb1c..0000000
--- a/cmds/statsd/statsd_test.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Runs statsd_test.">
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="apct-native" />
- <option name="test-suite-tag" value="mts" />
-
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
- <option name="cleanup" value="true" />
- <option name="push" value="statsd_test->/data/local/tmp/statsd_test" />
- <option name="append-bitness" value="true" />
- </target_preparer>
-
- <test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="statsd_test" />
- </test>
-
- <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
- <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
- </object>
-</configuration>
diff --git a/cmds/statsd/tests/AlarmMonitor_test.cpp b/cmds/statsd/tests/AlarmMonitor_test.cpp
deleted file mode 100644
index 1dc9795..0000000
--- a/cmds/statsd/tests/AlarmMonitor_test.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "anomaly/AlarmMonitor.h"
-
-#include <gtest/gtest.h>
-
-using namespace android::os::statsd;
-using std::shared_ptr;
-
-#ifdef __ANDROID__
-TEST(AlarmMonitor, popSoonerThan) {
- std::string emptyMetricId;
- std::string emptyDimensionId;
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> set;
- AlarmMonitor am(2,
- [](const shared_ptr<IStatsCompanionService>&, int64_t){},
- [](const shared_ptr<IStatsCompanionService>&){});
-
- set = am.popSoonerThan(5);
- EXPECT_TRUE(set.empty());
-
- sp<const InternalAlarm> a = new InternalAlarm{10};
- sp<const InternalAlarm> b = new InternalAlarm{20};
- sp<const InternalAlarm> c = new InternalAlarm{20};
- sp<const InternalAlarm> d = new InternalAlarm{30};
- sp<const InternalAlarm> e = new InternalAlarm{40};
- sp<const InternalAlarm> f = new InternalAlarm{50};
-
- am.add(a);
- am.add(b);
- am.add(c);
- am.add(d);
- am.add(e);
- am.add(f);
-
- set = am.popSoonerThan(5);
- EXPECT_TRUE(set.empty());
-
- set = am.popSoonerThan(30);
- ASSERT_EQ(4u, set.size());
- EXPECT_EQ(1u, set.count(a));
- EXPECT_EQ(1u, set.count(b));
- EXPECT_EQ(1u, set.count(c));
- EXPECT_EQ(1u, set.count(d));
-
- set = am.popSoonerThan(60);
- ASSERT_EQ(2u, set.size());
- EXPECT_EQ(1u, set.count(e));
- EXPECT_EQ(1u, set.count(f));
-
- set = am.popSoonerThan(80);
- ASSERT_EQ(0u, set.size());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/ConfigManager_test.cpp b/cmds/statsd/tests/ConfigManager_test.cpp
deleted file mode 100644
index 9455304..0000000
--- a/cmds/statsd/tests/ConfigManager_test.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/config/ConfigManager.h"
-#include "src/metrics/MetricsManager.h"
-#include "statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-#include <iostream>
-
-using namespace android;
-using namespace android::os::statsd;
-using namespace testing;
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static ostream& operator<<(ostream& os, const StatsdConfig& config) {
- return os << "StatsdConfig{id=" << config.id() << "}";
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-/**
- * Mock ConfigListener
- */
-class MockListener : public ConfigListener {
-public:
- MOCK_METHOD3(OnConfigUpdated, void(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config));
- MOCK_METHOD1(OnConfigRemoved, void(const ConfigKey& key));
-};
-
-/**
- * Validate that the ConfigKey is the one we wanted.
- */
-MATCHER_P2(ConfigKeyEq, uid, id, "") {
- return arg.GetUid() == uid && (long long)arg.GetId() == (long long)id;
-}
-
-/**
- * Validate that the StatsdConfig is the one we wanted.
- */
-MATCHER_P(StatsdConfigEq, id, 0) {
- return (long long)arg.id() == (long long)id;
-}
-
-const int64_t testConfigId = 12345;
-
-/**
- * Test the addOrUpdate and remove methods
- */
-TEST(ConfigManagerTest, TestAddUpdateRemove) {
- sp<MockListener> listener = new StrictMock<MockListener>();
-
- sp<ConfigManager> manager = new ConfigManager();
- manager->AddListener(listener);
-
- StatsdConfig config91;
- config91.set_id(91);
- StatsdConfig config92;
- config92.set_id(92);
- StatsdConfig config93;
- config93.set_id(93);
- StatsdConfig config94;
- config94.set_id(94);
-
- {
- InSequence s;
-
- manager->StartupForTest();
-
- // Add another one
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")),
- StatsdConfigEq(91)))
- .RetiresOnSaturation();
- manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config91);
-
- // Update It
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")),
- StatsdConfigEq(92)))
- .RetiresOnSaturation();
- manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config92);
-
- // Add one with the same uid but a different name
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("yyy")),
- StatsdConfigEq(93)))
- .RetiresOnSaturation();
- manager->UpdateConfig(ConfigKey(1, StringToId("yyy")), config93);
-
- // Add one with the same name but a different uid
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(2, StringToId("zzz")),
- StatsdConfigEq(94)))
- .RetiresOnSaturation();
- manager->UpdateConfig(ConfigKey(2, StringToId("zzz")), config94);
-
- // Remove (1,yyy)
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(1, StringToId("yyy"))))
- .RetiresOnSaturation();
- manager->RemoveConfig(ConfigKey(1, StringToId("yyy")));
-
- // Remove (2,zzz)
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("zzz"))))
- .RetiresOnSaturation();
- manager->RemoveConfig(ConfigKey(2, StringToId("zzz")));
-
- // Remove (1,zzz)
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(1, StringToId("zzz"))))
- .RetiresOnSaturation();
- manager->RemoveConfig(ConfigKey(1, StringToId("zzz")));
-
- // Remove (2,zzz) again and we shouldn't get the callback
- manager->RemoveConfig(ConfigKey(2, StringToId("zzz")));
- }
-}
-
-/**
- * Test removing all of the configs for a uid.
- */
-TEST(ConfigManagerTest, TestRemoveUid) {
- sp<MockListener> listener = new StrictMock<MockListener>();
-
- sp<ConfigManager> manager = new ConfigManager();
- manager->AddListener(listener);
-
- StatsdConfig config;
-
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, _, _)).Times(5);
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("xxx"))));
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("yyy"))));
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("zzz"))));
-
- manager->StartupForTest();
- manager->UpdateConfig(ConfigKey(1, StringToId("aaa")), config);
- manager->UpdateConfig(ConfigKey(2, StringToId("xxx")), config);
- manager->UpdateConfig(ConfigKey(2, StringToId("yyy")), config);
- manager->UpdateConfig(ConfigKey(2, StringToId("zzz")), config);
- manager->UpdateConfig(ConfigKey(3, StringToId("bbb")), config);
-
- manager->RemoveConfigs(2);
-}
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
deleted file mode 100644
index a21eb9b9..0000000
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/matcher_util.h"
-#include "src/logd/LogEvent.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "subscriber/SubscriberReporter.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-using android::util::ProtoReader;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// These constants must be kept in sync with those in StatsDimensionsValue.java.
-const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2;
-const static int STATS_DIMENSIONS_VALUE_INT_TYPE = 3;
-const static int STATS_DIMENSIONS_VALUE_FLOAT_TYPE = 6;
-const static int STATS_DIMENSIONS_VALUE_TUPLE_TYPE = 7;
-
-namespace {
-void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const vector<int>& attributionUids, const vector<string>& attributionTags,
- const string& name) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, name.c_str());
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const vector<int>& attributionUids, const vector<string>& attributionTags,
- const int32_t value) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeInt32(statsEvent, value);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-} // anonymous namespace
-
-TEST(AtomMatcherTest, TestFieldTranslation) {
- FieldMatcher matcher1;
- matcher1.set_field(10);
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
- child->set_position(Position::ANY);
-
- child = child->add_child();
- child->set_field(1);
-
- vector<Matcher> output;
- translateFieldMatcher(matcher1, &output);
-
- ASSERT_EQ((size_t)1, output.size());
-
- const auto& matcher12 = output[0];
- EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
- EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
- EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask);
-}
-
-TEST(AtomMatcherTest, TestFieldTranslation_ALL) {
- FieldMatcher matcher1;
- matcher1.set_field(10);
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
- child->set_position(Position::ALL);
-
- child = child->add_child();
- child->set_field(1);
-
- vector<Matcher> output;
- translateFieldMatcher(matcher1, &output);
-
- ASSERT_EQ((size_t)1, output.size());
-
- const auto& matcher12 = output[0];
- EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
- EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
- EXPECT_EQ((int32_t)0xff7f7f7f, matcher12.mMask);
-}
-
-TEST(AtomMatcherTest, TestFilter_ALL) {
- FieldMatcher matcher1;
- matcher1.set_field(10);
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
- child->set_position(Position::ALL);
-
- child->add_child()->set_field(1);
- child->add_child()->set_field(2);
-
- child = matcher1.add_child();
- child->set_field(2);
-
- vector<Matcher> matchers;
- translateFieldMatcher(matcher1, &matchers);
-
- std::vector<int> attributionUids = {1111, 2222, 3333};
- std::vector<string> attributionTags = {"location1", "location2", "location3"};
-
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event, 10 /*atomId*/, 1012345, attributionUids, attributionTags, "some value");
- HashableDimensionKey output;
-
- filterValues(matchers, event.getValues(), &output);
-
- ASSERT_EQ((size_t)7, output.getValues().size());
- EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
- EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
- EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
- EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
-
- EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
- EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
- EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
- EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
-
- EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
- EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
- EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
- EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
-
- EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
- EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
-}
-
-TEST(AtomMatcherTest, TestSubDimension) {
- HashableDimensionKey dim;
-
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 1, 3};
- int pos4[] = {2, 0, 0};
- Field field1(10, pos1, 2);
- Field field2(10, pos2, 2);
-
- Field field3(10, pos3, 2);
- Field field4(10, pos4, 0);
-
- Value value1((int32_t)10025);
- Value value2("tag");
-
- Value value11((int32_t)10026);
- Value value22("tag2");
-
- dim.addValue(FieldValue(field1, value1));
- dim.addValue(FieldValue(field2, value2));
-
- HashableDimensionKey subDim1;
- subDim1.addValue(FieldValue(field1, value1));
-
- HashableDimensionKey subDim2;
- subDim1.addValue(FieldValue(field2, value2));
-
- EXPECT_TRUE(dim.contains(dim));
- EXPECT_TRUE(dim.contains(subDim1));
- EXPECT_TRUE(dim.contains(subDim2));
-
- HashableDimensionKey subDim3;
- subDim3.addValue(FieldValue(field1, value11));
- EXPECT_FALSE(dim.contains(subDim3));
-
- HashableDimensionKey subDim4;
- // Empty dimension is always a sub dimension of other dimensions
- EXPECT_TRUE(dim.contains(subDim4));
-}
-
-TEST(AtomMatcherTest, TestMetric2ConditionLink) {
- std::vector<int> attributionUids = {1111, 2222, 3333};
- std::vector<string> attributionTags = {"location1", "location2", "location3"};
-
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event, 10 /*atomId*/, 12345, attributionUids, attributionTags, "some value");
-
- FieldMatcher whatMatcher;
- whatMatcher.set_field(10);
- FieldMatcher* child11 = whatMatcher.add_child();
- child11->set_field(1);
- child11->set_position(Position::ANY);
- child11 = child11->add_child();
- child11->set_field(1);
-
- FieldMatcher conditionMatcher;
- conditionMatcher.set_field(27);
- FieldMatcher* child2 = conditionMatcher.add_child();
- child2->set_field(2);
- child2->set_position(Position::LAST);
-
- child2 = child2->add_child();
- child2->set_field(2);
-
- Metric2Condition link;
-
- translateFieldMatcher(whatMatcher, &link.metricFields);
- translateFieldMatcher(conditionMatcher, &link.conditionFields);
-
- ASSERT_EQ((size_t)1, link.metricFields.size());
- EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
- EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
- EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
-
- ASSERT_EQ((size_t)1, link.conditionFields.size());
- EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
- EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
- EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
-}
-
-TEST(AtomMatcherTest, TestWriteDimensionPath) {
- for (auto position : {Position::ANY, Position::ALL, Position::FIRST, Position::LAST}) {
- FieldMatcher matcher1;
- matcher1.set_field(10);
- FieldMatcher* child = matcher1.add_child();
- child->set_field(2);
- child->set_position(position);
- child->add_child()->set_field(1);
- child->add_child()->set_field(3);
-
- child = matcher1.add_child();
- child->set_field(4);
-
- child = matcher1.add_child();
- child->set_field(6);
- child->add_child()->set_field(2);
-
- vector<Matcher> matchers;
- translateFieldMatcher(matcher1, &matchers);
-
- android::util::ProtoOutputStream protoOut;
- writeDimensionPathToProto(matchers, &protoOut);
-
- vector<uint8_t> outData;
- outData.resize(protoOut.size());
- size_t pos = 0;
- sp<ProtoReader> reader = protoOut.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- DimensionsValue result;
- ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
-
- EXPECT_EQ(10, result.field());
- EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
- ASSERT_EQ(3, result.value_tuple().dimensions_value_size());
-
- const auto& dim1 = result.value_tuple().dimensions_value(0);
- EXPECT_EQ(2, dim1.field());
- ASSERT_EQ(2, dim1.value_tuple().dimensions_value_size());
-
- const auto& dim11 = dim1.value_tuple().dimensions_value(0);
- EXPECT_EQ(1, dim11.field());
-
- const auto& dim12 = dim1.value_tuple().dimensions_value(1);
- EXPECT_EQ(3, dim12.field());
-
- const auto& dim2 = result.value_tuple().dimensions_value(1);
- EXPECT_EQ(4, dim2.field());
-
- const auto& dim3 = result.value_tuple().dimensions_value(2);
- EXPECT_EQ(6, dim3.field());
- ASSERT_EQ(1, dim3.value_tuple().dimensions_value_size());
- const auto& dim31 = dim3.value_tuple().dimensions_value(0);
- EXPECT_EQ(2, dim31.field());
- }
-}
-
-void checkAttributionNodeInDimensionsValueParcel(StatsDimensionsValueParcel& attributionNodeParcel,
- int32_t nodeDepthInAttributionChain,
- int32_t uid, string tag) {
- EXPECT_EQ(attributionNodeParcel.field, nodeDepthInAttributionChain /*position at depth 1*/);
- ASSERT_EQ(attributionNodeParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
- ASSERT_EQ(attributionNodeParcel.tupleValue.size(), 2);
-
- StatsDimensionsValueParcel uidParcel = attributionNodeParcel.tupleValue[0];
- EXPECT_EQ(uidParcel.field, 1 /*position at depth 2*/);
- EXPECT_EQ(uidParcel.valueType, STATS_DIMENSIONS_VALUE_INT_TYPE);
- EXPECT_EQ(uidParcel.intValue, uid);
-
- StatsDimensionsValueParcel tagParcel = attributionNodeParcel.tupleValue[1];
- EXPECT_EQ(tagParcel.field, 2 /*position at depth 2*/);
- EXPECT_EQ(tagParcel.valueType, STATS_DIMENSIONS_VALUE_STRING_TYPE);
- EXPECT_EQ(tagParcel.stringValue, tag);
-}
-
-// Test conversion of a HashableDimensionKey into a StatsDimensionValueParcel
-TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
- int atomId = 10;
- // First four fields form an attribution chain
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 2, 1};
- int pos4[] = {1, 2, 2};
- int pos5[] = {2, 1, 1};
-
- Field field1(atomId, pos1, /*depth=*/2);
- Field field2(atomId, pos2, /*depth=*/2);
- Field field3(atomId, pos3, /*depth=*/2);
- Field field4(atomId, pos4, /*depth=*/2);
- Field field5(atomId, pos5, /*depth=*/0);
-
- Value value1((int32_t)1);
- Value value2("string2");
- Value value3((int32_t)3);
- Value value4("string4");
- Value value5((float)5.0);
-
- HashableDimensionKey dimensionKey;
- dimensionKey.addValue(FieldValue(field1, value1));
- dimensionKey.addValue(FieldValue(field2, value2));
- dimensionKey.addValue(FieldValue(field3, value3));
- dimensionKey.addValue(FieldValue(field4, value4));
- dimensionKey.addValue(FieldValue(field5, value5));
-
- StatsDimensionsValueParcel rootParcel = dimensionKey.toStatsDimensionsValueParcel();
- EXPECT_EQ(rootParcel.field, atomId);
- ASSERT_EQ(rootParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
- ASSERT_EQ(rootParcel.tupleValue.size(), 2);
-
- // Check that attribution chain is populated correctly
- StatsDimensionsValueParcel attributionChainParcel = rootParcel.tupleValue[0];
- EXPECT_EQ(attributionChainParcel.field, 1 /*position at depth 0*/);
- ASSERT_EQ(attributionChainParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
- ASSERT_EQ(attributionChainParcel.tupleValue.size(), 2);
- checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[0],
- /*nodeDepthInAttributionChain=*/1,
- value1.int_value, value2.str_value);
- checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[1],
- /*nodeDepthInAttributionChain=*/2,
- value3.int_value, value4.str_value);
-
- // Check that the float is populated correctly
- StatsDimensionsValueParcel floatParcel = rootParcel.tupleValue[1];
- EXPECT_EQ(floatParcel.field, 2 /*position at depth 0*/);
- EXPECT_EQ(floatParcel.valueType, STATS_DIMENSIONS_VALUE_FLOAT_TYPE);
- EXPECT_EQ(floatParcel.floatValue, value5.float_value);
-}
-
-TEST(AtomMatcherTest, TestWriteDimensionToProto) {
- HashableDimensionKey dim;
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 1, 3};
- int pos4[] = {2, 0, 0};
- Field field1(10, pos1, 2);
- Field field2(10, pos2, 2);
- Field field3(10, pos3, 2);
- Field field4(10, pos4, 0);
-
- Value value1((int32_t)10025);
- Value value2("tag");
- Value value3((int32_t)987654);
- Value value4((int32_t)99999);
-
- dim.addValue(FieldValue(field1, value1));
- dim.addValue(FieldValue(field2, value2));
- dim.addValue(FieldValue(field3, value3));
- dim.addValue(FieldValue(field4, value4));
-
- android::util::ProtoOutputStream protoOut;
- writeDimensionToProto(dim, nullptr /* include strings */, &protoOut);
-
- vector<uint8_t> outData;
- outData.resize(protoOut.size());
- size_t pos = 0;
- sp<ProtoReader> reader = protoOut.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- DimensionsValue result;
- ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
- EXPECT_EQ(10, result.field());
- EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
- ASSERT_EQ(2, result.value_tuple().dimensions_value_size());
-
- const auto& dim1 = result.value_tuple().dimensions_value(0);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
- ASSERT_EQ(3, dim1.value_tuple().dimensions_value_size());
-
- const auto& dim11 = dim1.value_tuple().dimensions_value(0);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
- EXPECT_EQ(10025, dim11.value_int());
-
- const auto& dim12 = dim1.value_tuple().dimensions_value(1);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case());
- EXPECT_EQ("tag", dim12.value_str());
-
- const auto& dim13 = dim1.value_tuple().dimensions_value(2);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case());
- EXPECT_EQ(987654, dim13.value_int());
-
- const auto& dim2 = result.value_tuple().dimensions_value(1);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case());
- EXPECT_EQ(99999, dim2.value_int());
-}
-
-TEST(AtomMatcherTest, TestWriteDimensionLeafNodesToProto) {
- HashableDimensionKey dim;
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 1, 3};
- int pos4[] = {2, 0, 0};
- Field field1(10, pos1, 2);
- Field field2(10, pos2, 2);
- Field field3(10, pos3, 2);
- Field field4(10, pos4, 0);
-
- Value value1((int32_t)10025);
- Value value2("tag");
- Value value3((int32_t)987654);
- Value value4((int64_t)99999);
-
- dim.addValue(FieldValue(field1, value1));
- dim.addValue(FieldValue(field2, value2));
- dim.addValue(FieldValue(field3, value3));
- dim.addValue(FieldValue(field4, value4));
-
- android::util::ProtoOutputStream protoOut;
- writeDimensionLeafNodesToProto(dim, 1, nullptr /* include strings */, &protoOut);
-
- vector<uint8_t> outData;
- outData.resize(protoOut.size());
- size_t pos = 0;
- sp<ProtoReader> reader = protoOut.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- DimensionsValueTuple result;
- ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
- ASSERT_EQ(4, result.dimensions_value_size());
-
- const auto& dim1 = result.dimensions_value(0);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim1.value_case());
- EXPECT_EQ(10025, dim1.value_int());
-
- const auto& dim2 = result.dimensions_value(1);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim2.value_case());
- EXPECT_EQ("tag", dim2.value_str());
-
- const auto& dim3 = result.dimensions_value(2);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim3.value_case());
- EXPECT_EQ(987654, dim3.value_int());
-
- const auto& dim4 = result.dimensions_value(3);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueLong, dim4.value_case());
- EXPECT_EQ(99999, dim4.value_long());
-}
-
-TEST(AtomMatcherTest, TestWriteAtomToProto) {
- std::vector<int> attributionUids = {1111, 2222};
- std::vector<string> attributionTags = {"location1", "location2"};
-
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event, 4 /*atomId*/, 12345, attributionUids, attributionTags, 999);
-
- android::util::ProtoOutputStream protoOutput;
- writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
-
- vector<uint8_t> outData;
- outData.resize(protoOutput.size());
- size_t pos = 0;
- sp<ProtoReader> reader = protoOutput.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- Atom result;
- ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
- EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
- const auto& atom = result.ble_scan_result_received();
- ASSERT_EQ(2, atom.attribution_node_size());
- EXPECT_EQ(1111, atom.attribution_node(0).uid());
- EXPECT_EQ("location1", atom.attribution_node(0).tag());
- EXPECT_EQ(2222, atom.attribution_node(1).uid());
- EXPECT_EQ("location2", atom.attribution_node(1).tag());
- EXPECT_EQ(999, atom.num_results());
-}
-
-/*
- * Test two Matchers is not a subset of one Matcher.
- * Test one Matcher is subset of two Matchers.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions1) {
- // Initialize first set of matchers
- FieldMatcher matcher1;
- matcher1.set_field(10);
-
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
- child->set_position(Position::ALL);
- child->add_child()->set_field(1);
- child->add_child()->set_field(2);
-
- vector<Matcher> matchers1;
- translateFieldMatcher(matcher1, &matchers1);
- ASSERT_EQ(2, matchers1.size());
-
- // Initialize second set of matchers
- FieldMatcher matcher2;
- matcher2.set_field(10);
-
- child = matcher2.add_child();
- child->set_field(1);
- child->set_position(Position::ALL);
- child->add_child()->set_field(1);
-
- vector<Matcher> matchers2;
- translateFieldMatcher(matcher2, &matchers2);
- ASSERT_EQ(1, matchers2.size());
-
- EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
- EXPECT_TRUE(subsetDimensions(matchers2, matchers1));
-}
-/*
- * Test not a subset with one matching Matcher, one non-matching Matcher.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions2) {
- // Initialize first set of matchers
- FieldMatcher matcher1;
- matcher1.set_field(10);
-
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
-
- child = matcher1.add_child();
- child->set_field(2);
-
- vector<Matcher> matchers1;
- translateFieldMatcher(matcher1, &matchers1);
-
- // Initialize second set of matchers
- FieldMatcher matcher2;
- matcher2.set_field(10);
-
- child = matcher2.add_child();
- child->set_field(1);
-
- child = matcher2.add_child();
- child->set_field(3);
-
- vector<Matcher> matchers2;
- translateFieldMatcher(matcher2, &matchers2);
-
- EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
-}
-
-/*
- * Test not a subset if parent field is not equal.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions3) {
- // Initialize first set of matchers
- FieldMatcher matcher1;
- matcher1.set_field(10);
-
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
-
- vector<Matcher> matchers1;
- translateFieldMatcher(matcher1, &matchers1);
-
- // Initialize second set of matchers
- FieldMatcher matcher2;
- matcher2.set_field(5);
-
- child = matcher2.add_child();
- child->set_field(1);
-
- vector<Matcher> matchers2;
- translateFieldMatcher(matcher2, &matchers2);
-
- EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
-}
-
-/*
- * Test is subset with two matching Matchers.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions4) {
- // Initialize first set of matchers
- FieldMatcher matcher1;
- matcher1.set_field(10);
-
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
-
- child = matcher1.add_child();
- child->set_field(2);
-
- vector<Matcher> matchers1;
- translateFieldMatcher(matcher1, &matchers1);
-
- // Initialize second set of matchers
- FieldMatcher matcher2;
- matcher2.set_field(10);
-
- child = matcher2.add_child();
- child->set_field(1);
-
- child = matcher2.add_child();
- child->set_field(2);
-
- child = matcher2.add_child();
- child->set_field(3);
-
- vector<Matcher> matchers2;
- translateFieldMatcher(matcher2, &matchers2);
-
- EXPECT_TRUE(subsetDimensions(matchers1, matchers2));
- EXPECT_FALSE(subsetDimensions(matchers2, matchers1));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/HashableDimensionKey_test.cpp b/cmds/statsd/tests/HashableDimensionKey_test.cpp
deleted file mode 100644
index 29adcd0..0000000
--- a/cmds/statsd/tests/HashableDimensionKey_test.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "src/HashableDimensionKey.h"
-
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-using android::util::ProtoReader;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Test that #containsLinkedStateValues returns false when the whatKey is
- * smaller than the primaryKey.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_WhatKeyTooSmall) {
- std::vector<Metric2State> mMetric2StateLinks;
-
- int32_t uid1 = 1000;
- HashableDimensionKey whatKey = DEFAULT_DIMENSION_KEY;
- HashableDimensionKey primaryKey;
- getUidProcessKey(uid1, &primaryKey);
-
- EXPECT_FALSE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks,
- UID_PROCESS_STATE_ATOM_ID));
-}
-
-/**
- * Test that #containsLinkedStateValues returns false when the linked values
- * are not equal.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_UnequalLinkedValues) {
- int stateAtomId = UID_PROCESS_STATE_ATOM_ID;
-
- FieldMatcher whatMatcher;
- whatMatcher.set_field(util::OVERLAY_STATE_CHANGED);
- FieldMatcher* child11 = whatMatcher.add_child();
- child11->set_field(1);
-
- FieldMatcher stateMatcher;
- stateMatcher.set_field(stateAtomId);
- FieldMatcher* child21 = stateMatcher.add_child();
- child21->set_field(1);
-
- std::vector<Metric2State> mMetric2StateLinks;
- Metric2State ms;
- ms.stateAtomId = stateAtomId;
- translateFieldMatcher(whatMatcher, &ms.metricFields);
- translateFieldMatcher(stateMatcher, &ms.stateFields);
- mMetric2StateLinks.push_back(ms);
-
- int32_t uid1 = 1000;
- int32_t uid2 = 1001;
- HashableDimensionKey whatKey;
- getOverlayKey(uid2, "package", &whatKey);
- HashableDimensionKey primaryKey;
- getUidProcessKey(uid1, &primaryKey);
-
- EXPECT_FALSE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks, stateAtomId));
-}
-
-/**
- * Test that #containsLinkedStateValues returns false when there is no link
- * between the key values.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_MissingMetric2StateLinks) {
- int stateAtomId = UID_PROCESS_STATE_ATOM_ID;
-
- std::vector<Metric2State> mMetric2StateLinks;
-
- int32_t uid1 = 1000;
- HashableDimensionKey whatKey;
- getOverlayKey(uid1, "package", &whatKey);
- HashableDimensionKey primaryKey;
- getUidProcessKey(uid1, &primaryKey);
-
- EXPECT_FALSE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks, stateAtomId));
-}
-
-/**
- * Test that #containsLinkedStateValues returns true when the key values are
- * linked and equal.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_AllConditionsMet) {
- int stateAtomId = UID_PROCESS_STATE_ATOM_ID;
-
- FieldMatcher whatMatcher;
- whatMatcher.set_field(util::OVERLAY_STATE_CHANGED);
- FieldMatcher* child11 = whatMatcher.add_child();
- child11->set_field(1);
-
- FieldMatcher stateMatcher;
- stateMatcher.set_field(stateAtomId);
- FieldMatcher* child21 = stateMatcher.add_child();
- child21->set_field(1);
-
- std::vector<Metric2State> mMetric2StateLinks;
- Metric2State ms;
- ms.stateAtomId = stateAtomId;
- translateFieldMatcher(whatMatcher, &ms.metricFields);
- translateFieldMatcher(stateMatcher, &ms.stateFields);
- mMetric2StateLinks.push_back(ms);
-
- int32_t uid1 = 1000;
- HashableDimensionKey whatKey;
- getOverlayKey(uid1, "package", &whatKey);
- HashableDimensionKey primaryKey;
- getUidProcessKey(uid1, &primaryKey);
-
- EXPECT_TRUE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks, stateAtomId));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
deleted file mode 100644
index 26423d4..0000000
--- a/cmds/statsd/tests/LogEntryMatcher_test.cpp
+++ /dev/null
@@ -1,812 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-#include <log/log_event_list.h>
-#include <log/log_read.h>
-#include <log/logprint.h>
-#include <stdio.h>
-
-#include "annotations.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/matcher_util.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "statsd_test_util.h"
-
-using namespace android::os::statsd;
-using std::unordered_map;
-using std::vector;
-
-const int32_t TAG_ID = 123;
-const int32_t TAG_ID_2 = 28; // hardcoded tag of atom with uid field
-const int FIELD_ID_1 = 1;
-const int FIELD_ID_2 = 2;
-const int FIELD_ID_3 = 2;
-
-const int ATTRIBUTION_UID_FIELD_ID = 1;
-const int ATTRIBUTION_TAG_FIELD_ID = 2;
-
-
-#ifdef __ANDROID__
-
-namespace {
-
-void makeIntLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const int32_t value) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
- AStatsEvent_writeInt32(statsEvent, value);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeFloatLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const float floatValue) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
- AStatsEvent_writeFloat(statsEvent, floatValue);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const string& name) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
- AStatsEvent_writeString(statsEvent, name.c_str());
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeIntWithBoolAnnotationLogEvent(LogEvent* logEvent, const int32_t atomId,
- const int32_t field, const uint8_t annotationId,
- const bool annotationValue) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_writeInt32(statsEvent, field);
- AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeAttributionLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags, const string& name) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, name.c_str());
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeBoolLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const bool bool1, const bool bool2) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
- AStatsEvent_writeBool(statsEvent, bool1);
- AStatsEvent_writeBool(statsEvent, bool2);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-} // anonymous namespace
-
-TEST(AtomMatcherTest, TestSimpleMatcher) {
- UidMap uidMap;
-
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
-
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeIntLogEvent(&event, TAG_ID, 0, 11);
-
- // Test
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // Wrong tag id.
- simpleMatcher->set_atom_id(TAG_ID + 1);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestAttributionMatcher) {
- UidMap uidMap;
- std::vector<int> attributionUids = {1111, 2222, 3333};
- std::vector<string> attributionTags = {"location1", "location2", "location3"};
-
- // Set up the log event.
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
-
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
-
- // Match first node.
- auto attributionMatcher = simpleMatcher->add_field_value_matcher();
- attributionMatcher->set_field(FIELD_ID_1);
- attributionMatcher->set_position(Position::FIRST);
- attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
- ATTRIBUTION_TAG_FIELD_ID);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "tag");
-
- auto fieldMatcher = simpleMatcher->add_field_value_matcher();
- fieldMatcher->set_field(FIELD_ID_2);
- fieldMatcher->set_eq_string("some value");
-
- // Tag not matched.
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location3");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // Match last node.
- attributionMatcher->set_position(Position::LAST);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // Match any node.
- attributionMatcher->set_position(Position::ANY);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location2");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location4");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // Attribution match but primitive field not match.
- attributionMatcher->set_position(Position::ANY);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location2");
- fieldMatcher->set_eq_string("wrong value");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- fieldMatcher->set_eq_string("some value");
-
- // Uid match.
- attributionMatcher->set_position(Position::ANY);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_field(
- ATTRIBUTION_UID_FIELD_ID);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- uidMap.updateMap(
- 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
- {android::String16("v1"), android::String16("v1"), android::String16("v2"),
- android::String16("v1"), android::String16("v2")},
- {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
- android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
- {android::String16(""), android::String16(""), android::String16(""),
- android::String16(""), android::String16("")});
-
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::FIRST);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::LAST);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // Uid + tag.
- attributionMatcher->set_position(Position::ANY);
- attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
- ATTRIBUTION_TAG_FIELD_ID);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location2");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::FIRST);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location2");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::LAST);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location2");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestUidFieldMatcher) {
- UidMap uidMap;
- uidMap.updateMap(
- 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
- {android::String16("v1"), android::String16("v1"), android::String16("v2"),
- android::String16("v1"), android::String16("v2")},
- {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
- android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
- {android::String16(""), android::String16(""), android::String16(""),
- android::String16(""), android::String16("")});
-
- // Set up matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
- simpleMatcher->add_field_value_matcher()->set_field(1);
- simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("pkg0");
-
- // Make event without is_uid annotation.
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeIntLogEvent(&event1, TAG_ID, 0, 1111);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
-
- // Make event with is_uid annotation.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeIntWithBoolAnnotationLogEvent(&event2, TAG_ID_2, 1111, ANNOTATION_ID_IS_UID, true);
-
- // Event has is_uid annotation, so mapping from uid to package name occurs.
- simpleMatcher->set_atom_id(TAG_ID_2);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
-
- // Event has is_uid annotation, but uid maps to different package name.
- simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("Pkg2");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2));
-}
-
-TEST(AtomMatcherTest, TestNeqAnyStringMatcher) {
- UidMap uidMap;
- uidMap.updateMap(
- 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
- {android::String16("v1"), android::String16("v1"), android::String16("v2"),
- android::String16("v1"), android::String16("v2")},
- {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
- android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
- {android::String16(""), android::String16(""), android::String16(""),
- android::String16(""), android::String16("")});
-
- std::vector<int> attributionUids = {1111, 2222, 3333, 1066};
- std::vector<string> attributionTags = {"location1", "location2", "location3", "location3"};
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
-
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
-
- // Match first node.
- auto attributionMatcher = simpleMatcher->add_field_value_matcher();
- attributionMatcher->set_field(FIELD_ID_1);
- attributionMatcher->set_position(Position::FIRST);
- attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
- ATTRIBUTION_UID_FIELD_ID);
- auto neqStringList = attributionMatcher->mutable_matches_tuple()
- ->mutable_field_value_matcher(0)
- ->mutable_neq_any_string();
- neqStringList->add_str_value("pkg2");
- neqStringList->add_str_value("pkg3");
-
- auto fieldMatcher = simpleMatcher->add_field_value_matcher();
- fieldMatcher->set_field(FIELD_ID_2);
- fieldMatcher->set_eq_string("some value");
-
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- neqStringList->Clear();
- neqStringList->add_str_value("pkg1");
- neqStringList->add_str_value("pkg3");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::ANY);
- neqStringList->Clear();
- neqStringList->add_str_value("maps.com");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- neqStringList->Clear();
- neqStringList->add_str_value("PkG3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::LAST);
- neqStringList->Clear();
- neqStringList->add_str_value("AID_STATSD");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestEqAnyStringMatcher) {
- UidMap uidMap;
- uidMap.updateMap(
- 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
- {android::String16("v1"), android::String16("v1"), android::String16("v2"),
- android::String16("v1"), android::String16("v2")},
- {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
- android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
- {android::String16(""), android::String16(""), android::String16(""),
- android::String16(""), android::String16("")});
-
- std::vector<int> attributionUids = {1067, 2222, 3333, 1066};
- std::vector<string> attributionTags = {"location1", "location2", "location3", "location3"};
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
-
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
-
- // Match first node.
- auto attributionMatcher = simpleMatcher->add_field_value_matcher();
- attributionMatcher->set_field(FIELD_ID_1);
- attributionMatcher->set_position(Position::FIRST);
- attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
- ATTRIBUTION_UID_FIELD_ID);
- auto eqStringList = attributionMatcher->mutable_matches_tuple()
- ->mutable_field_value_matcher(0)
- ->mutable_eq_any_string();
- eqStringList->add_str_value("AID_ROOT");
- eqStringList->add_str_value("AID_INCIDENTD");
-
- auto fieldMatcher = simpleMatcher->add_field_value_matcher();
- fieldMatcher->set_field(FIELD_ID_2);
- fieldMatcher->set_eq_string("some value");
-
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::ANY);
- eqStringList->Clear();
- eqStringList->add_str_value("AID_STATSD");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- eqStringList->Clear();
- eqStringList->add_str_value("pkg1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- auto normalStringField = fieldMatcher->mutable_eq_any_string();
- normalStringField->add_str_value("some value123");
- normalStringField->add_str_value("some value");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- normalStringField->Clear();
- normalStringField->add_str_value("AID_STATSD");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- eqStringList->Clear();
- eqStringList->add_str_value("maps.com");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestBoolMatcher) {
- UidMap uidMap;
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
- auto keyValue1 = simpleMatcher->add_field_value_matcher();
- keyValue1->set_field(FIELD_ID_1);
- auto keyValue2 = simpleMatcher->add_field_value_matcher();
- keyValue2->set_field(FIELD_ID_2);
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeBoolLogEvent(&event, TAG_ID, 0, true, false);
-
- // Test
- keyValue1->set_eq_bool(true);
- keyValue2->set_eq_bool(false);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- keyValue1->set_eq_bool(false);
- keyValue2->set_eq_bool(false);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- keyValue1->set_eq_bool(false);
- keyValue2->set_eq_bool(true);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- keyValue1->set_eq_bool(true);
- keyValue2->set_eq_bool(true);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestStringMatcher) {
- UidMap uidMap;
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
- auto keyValue = simpleMatcher->add_field_value_matcher();
- keyValue->set_field(FIELD_ID_1);
- keyValue->set_eq_string("some value");
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeStringLogEvent(&event, TAG_ID, 0, "some value");
-
- // Test
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestMultiFieldsMatcher) {
- UidMap uidMap;
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
- auto keyValue1 = simpleMatcher->add_field_value_matcher();
- keyValue1->set_field(FIELD_ID_1);
- auto keyValue2 = simpleMatcher->add_field_value_matcher();
- keyValue2->set_field(FIELD_ID_2);
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(&event, TAG_ID, 0, 2, 3);
-
- // Test
- keyValue1->set_eq_int(2);
- keyValue2->set_eq_int(3);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- keyValue1->set_eq_int(2);
- keyValue2->set_eq_int(4);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- keyValue1->set_eq_int(4);
- keyValue2->set_eq_int(3);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestIntComparisonMatcher) {
- UidMap uidMap;
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-
- simpleMatcher->set_atom_id(TAG_ID);
- auto keyValue = simpleMatcher->add_field_value_matcher();
- keyValue->set_field(FIELD_ID_1);
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeIntLogEvent(&event, TAG_ID, 0, 11);
-
- // Test
-
- // eq_int
- keyValue->set_eq_int(10);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_eq_int(11);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_eq_int(12);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // lt_int
- keyValue->set_lt_int(10);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_lt_int(11);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_lt_int(12);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // lte_int
- keyValue->set_lte_int(10);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_lte_int(11);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_lte_int(12);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // gt_int
- keyValue->set_gt_int(10);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_gt_int(11);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_gt_int(12);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // gte_int
- keyValue->set_gte_int(10);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_gte_int(11);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_gte_int(12);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestFloatComparisonMatcher) {
- UidMap uidMap;
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
-
- auto keyValue = simpleMatcher->add_field_value_matcher();
- keyValue->set_field(FIELD_ID_1);
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeFloatLogEvent(&event1, TAG_ID, 0, 10.1f);
- keyValue->set_lt_float(10.0);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeFloatLogEvent(&event2, TAG_ID, 0, 9.9f);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
-
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeFloatLogEvent(&event3, TAG_ID, 0, 10.1f);
- keyValue->set_gt_float(10.0);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event3));
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeFloatLogEvent(&event4, TAG_ID, 0, 9.9f);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event4));
-}
-
-// Helper for the composite matchers.
-void addSimpleMatcher(SimpleAtomMatcher* simpleMatcher, int tag, int key, int val) {
- simpleMatcher->set_atom_id(tag);
- auto keyValue = simpleMatcher->add_field_value_matcher();
- keyValue->set_field(key);
- keyValue->set_eq_int(val);
-}
-
-TEST(AtomMatcherTest, TestAndMatcher) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::AND;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
- children.push_back(2);
-
- vector<MatchingState> matcherResults;
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kMatched);
-
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kMatched);
-
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestOrMatcher) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::OR;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
- children.push_back(2);
-
- vector<MatchingState> matcherResults;
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kMatched);
-
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
-
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestNotMatcher) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NOT;
-
- vector<int> children;
- children.push_back(0);
-
- vector<MatchingState> matcherResults;
- matcherResults.push_back(MatchingState::kMatched);
-
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kNotMatched);
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestNandMatcher) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NAND;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
-
- vector<MatchingState> matcherResults;
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
-
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kMatched);
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestNorMatcher) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NOR;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
-
- vector<MatchingState> matcherResults;
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
-
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kMatched);
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-}
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
deleted file mode 100644
index 5c170c0..0000000
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/logd/LogEvent.h"
-
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
-#include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h"
-#include "log/log_event_list.h"
-#include "stats_event.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::string;
-using std::vector;
-using util::ProtoOutputStream;
-using util::ProtoReader;
-
-namespace {
-
-Field getField(int32_t tag, const vector<int32_t>& pos, int32_t depth, const vector<bool>& last) {
- Field f(tag, (int32_t*)pos.data(), depth);
-
- // For loop starts at 1 because the last field at depth 0 is not decorated.
- for (int i = 1; i < depth; i++) {
- if (last[i]) f.decorateLastPos(i);
- }
-
- return f;
-}
-
-void createIntWithBoolAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId,
- bool annotationValue) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
- AStatsEvent_writeInt32(statsEvent, 10);
- AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue);
- AStatsEvent_build(statsEvent);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
- EXPECT_TRUE(logEvent->parseBuffer(buf, size));
-
- AStatsEvent_release(statsEvent);
-}
-
-void createIntWithIntAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId,
- int annotationValue) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
- AStatsEvent_writeInt32(statsEvent, 10);
- AStatsEvent_addInt32Annotation(statsEvent, annotationId, annotationValue);
- AStatsEvent_build(statsEvent);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
- EXPECT_TRUE(logEvent->parseBuffer(buf, size));
-
- AStatsEvent_release(statsEvent);
-}
-
-} // anonymous namespace
-
-TEST(LogEventTest, TestPrimitiveParsing) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
- AStatsEvent_writeInt32(event, 10);
- AStatsEvent_writeInt64(event, 0x123456789);
- AStatsEvent_writeFloat(event, 2.0);
- AStatsEvent_writeBool(event, true);
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
- LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
- EXPECT_EQ(100, logEvent.GetTagId());
- EXPECT_EQ(1000, logEvent.GetUid());
- EXPECT_EQ(1001, logEvent.GetPid());
- EXPECT_FALSE(logEvent.hasAttributionChain());
-
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(4, values.size());
-
- const FieldValue& int32Item = values[0];
- Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
- EXPECT_EQ(expectedField, int32Item.mField);
- EXPECT_EQ(Type::INT, int32Item.mValue.getType());
- EXPECT_EQ(10, int32Item.mValue.int_value);
-
- const FieldValue& int64Item = values[1];
- expectedField = getField(100, {2, 1, 1}, 0, {false, false, false});
- EXPECT_EQ(expectedField, int64Item.mField);
- EXPECT_EQ(Type::LONG, int64Item.mValue.getType());
- EXPECT_EQ(0x123456789, int64Item.mValue.long_value);
-
- const FieldValue& floatItem = values[2];
- expectedField = getField(100, {3, 1, 1}, 0, {false, false, false});
- EXPECT_EQ(expectedField, floatItem.mField);
- EXPECT_EQ(Type::FLOAT, floatItem.mValue.getType());
- EXPECT_EQ(2.0, floatItem.mValue.float_value);
-
- const FieldValue& boolItem = values[3];
- expectedField = getField(100, {4, 1, 1}, 0, {true, false, false});
- EXPECT_EQ(expectedField, boolItem.mField);
- EXPECT_EQ(Type::INT, boolItem.mValue.getType()); // FieldValue does not support boolean type
- EXPECT_EQ(1, boolItem.mValue.int_value);
-
- AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestStringAndByteArrayParsing) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
- string str = "test";
- AStatsEvent_writeString(event, str.c_str());
- AStatsEvent_writeByteArray(event, (uint8_t*)str.c_str(), str.length());
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
- LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
- EXPECT_EQ(100, logEvent.GetTagId());
- EXPECT_EQ(1000, logEvent.GetUid());
- EXPECT_EQ(1001, logEvent.GetPid());
- EXPECT_FALSE(logEvent.hasAttributionChain());
-
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(2, values.size());
-
- const FieldValue& stringItem = values[0];
- Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
- EXPECT_EQ(expectedField, stringItem.mField);
- EXPECT_EQ(Type::STRING, stringItem.mValue.getType());
- EXPECT_EQ(str, stringItem.mValue.str_value);
-
- const FieldValue& storageItem = values[1];
- expectedField = getField(100, {2, 1, 1}, 0, {true, false, false});
- EXPECT_EQ(expectedField, storageItem.mField);
- EXPECT_EQ(Type::STORAGE, storageItem.mValue.getType());
- vector<uint8_t> expectedValue = {'t', 'e', 's', 't'};
- EXPECT_EQ(expectedValue, storageItem.mValue.storage_value);
-
- AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestEmptyString) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
- string empty = "";
- AStatsEvent_writeString(event, empty.c_str());
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
- LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
- EXPECT_EQ(100, logEvent.GetTagId());
- EXPECT_EQ(1000, logEvent.GetUid());
- EXPECT_EQ(1001, logEvent.GetPid());
- EXPECT_FALSE(logEvent.hasAttributionChain());
-
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(1, values.size());
-
- const FieldValue& item = values[0];
- Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
- EXPECT_EQ(expectedField, item.mField);
- EXPECT_EQ(Type::STRING, item.mValue.getType());
- EXPECT_EQ(empty, item.mValue.str_value);
-
- AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestByteArrayWithNullCharacter) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
- uint8_t message[] = {'\t', 'e', '\0', 's', 't'};
- AStatsEvent_writeByteArray(event, message, 5);
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
- LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
- EXPECT_EQ(100, logEvent.GetTagId());
- EXPECT_EQ(1000, logEvent.GetUid());
- EXPECT_EQ(1001, logEvent.GetPid());
-
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(1, values.size());
-
- const FieldValue& item = values[0];
- Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
- EXPECT_EQ(expectedField, item.mField);
- EXPECT_EQ(Type::STORAGE, item.mValue.getType());
- vector<uint8_t> expectedValue(message, message + 5);
- EXPECT_EQ(expectedValue, item.mValue.storage_value);
-
- AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestAttributionChain) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
-
- string tag1 = "tag1";
- string tag2 = "tag2";
-
- uint32_t uids[] = {1001, 1002};
- const char* tags[] = {tag1.c_str(), tag2.c_str()};
-
- AStatsEvent_writeAttributionChain(event, uids, tags, 2);
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
- LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
- EXPECT_EQ(100, logEvent.GetTagId());
- EXPECT_EQ(1000, logEvent.GetUid());
- EXPECT_EQ(1001, logEvent.GetPid());
-
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(4, values.size()); // 2 per attribution node
-
- std::pair<int, int> attrIndexRange;
- EXPECT_TRUE(logEvent.hasAttributionChain(&attrIndexRange));
- EXPECT_EQ(0, attrIndexRange.first);
- EXPECT_EQ(3, attrIndexRange.second);
-
- // Check first attribution node
- const FieldValue& uid1Item = values[0];
- Field expectedField = getField(100, {1, 1, 1}, 2, {true, false, false});
- EXPECT_EQ(expectedField, uid1Item.mField);
- EXPECT_EQ(Type::INT, uid1Item.mValue.getType());
- EXPECT_EQ(1001, uid1Item.mValue.int_value);
-
- const FieldValue& tag1Item = values[1];
- expectedField = getField(100, {1, 1, 2}, 2, {true, false, true});
- EXPECT_EQ(expectedField, tag1Item.mField);
- EXPECT_EQ(Type::STRING, tag1Item.mValue.getType());
- EXPECT_EQ(tag1, tag1Item.mValue.str_value);
-
- // Check second attribution nodes
- const FieldValue& uid2Item = values[2];
- expectedField = getField(100, {1, 2, 1}, 2, {true, true, false});
- EXPECT_EQ(expectedField, uid2Item.mField);
- EXPECT_EQ(Type::INT, uid2Item.mValue.getType());
- EXPECT_EQ(1002, uid2Item.mValue.int_value);
-
- const FieldValue& tag2Item = values[3];
- expectedField = getField(100, {1, 2, 2}, 2, {true, true, true});
- EXPECT_EQ(expectedField, tag2Item.mField);
- EXPECT_EQ(Type::STRING, tag2Item.mValue.getType());
- EXPECT_EQ(tag2, tag2Item.mValue.str_value);
-
- AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestAnnotationIdIsUid) {
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_IS_UID, true);
-
- const vector<FieldValue>& values = event.getValues();
- ASSERT_EQ(values.size(), 1);
- EXPECT_EQ(event.getUidFieldIndex(), 0);
-}
-
-TEST(LogEventTest, TestAnnotationIdStateNested) {
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_STATE_NESTED, true);
-
- const vector<FieldValue>& values = event.getValues();
- ASSERT_EQ(values.size(), 1);
- EXPECT_TRUE(values[0].mAnnotations.isNested());
-}
-
-TEST(LogEventTest, TestPrimaryFieldAnnotation) {
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_PRIMARY_FIELD, true);
-
- const vector<FieldValue>& values = event.getValues();
- ASSERT_EQ(values.size(), 1);
- EXPECT_TRUE(values[0].mAnnotations.isPrimaryField());
-}
-
-TEST(LogEventTest, TestExclusiveStateAnnotation) {
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_EXCLUSIVE_STATE, true);
-
- const vector<FieldValue>& values = event.getValues();
- ASSERT_EQ(values.size(), 1);
- EXPECT_TRUE(values[0].mAnnotations.isExclusiveState());
-}
-
-TEST(LogEventTest, TestPrimaryFieldFirstUidAnnotation) {
- // Event has 10 ints and then an attribution chain
- int numInts = 10;
- int firstUidInChainIndex = numInts;
- string tag1 = "tag1";
- string tag2 = "tag2";
- uint32_t uids[] = {1001, 1002};
- const char* tags[] = {tag1.c_str(), tag2.c_str()};
-
- // Construct AStatsEvent
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, 100);
- for (int i = 0; i < numInts; i++) {
- AStatsEvent_writeInt32(statsEvent, 10);
- }
- AStatsEvent_writeAttributionChain(statsEvent, uids, tags, 2);
- AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
- AStatsEvent_build(statsEvent);
-
- // Construct LogEvent
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
- LogEvent logEvent(/*uid=*/0, /*pid=*/0);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
- AStatsEvent_release(statsEvent);
-
- // Check annotation
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(values.size(), numInts + 4);
- EXPECT_TRUE(values[firstUidInChainIndex].mAnnotations.isPrimaryField());
-}
-
-TEST(LogEventTest, TestResetStateAnnotation) {
- int32_t resetState = 10;
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createIntWithIntAnnotationLogEvent(&event, ANNOTATION_ID_TRIGGER_STATE_RESET, resetState);
-
- const vector<FieldValue>& values = event.getValues();
- ASSERT_EQ(values.size(), 1);
- EXPECT_EQ(event.getResetState(), resetState);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/LogReader_test.cpp b/cmds/statsd/tests/LogReader_test.cpp
deleted file mode 100644
index 7ce1d6a..0000000
--- a/cmds/statsd/tests/LogReader_test.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-
-TEST(LogReaderTest, TestNothingAtAll) {
- printf("yay!");
-}
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
deleted file mode 100644
index 6259757..0000000
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ /dev/null
@@ -1,799 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-#include <private/android_filesystem_config.h>
-#include <stdio.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "metrics/metrics_test_helper.h"
-#include "src/condition/ConditionTracker.h"
-#include "src/matchers/LogMatchingTracker.h"
-#include "src/metrics/CountMetricProducer.h"
-#include "src/metrics/GaugeMetricProducer.h"
-#include "src/metrics/MetricProducer.h"
-#include "src/metrics/ValueMetricProducer.h"
-#include "src/metrics/metrics_manager_util.h"
-#include "src/state/StateManager.h"
-#include "statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using android::os::statsd::Predicate;
-using std::map;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-const ConfigKey kConfigKey(0, 12345);
-const long kAlertId = 3;
-
-const long timeBaseSec = 1000;
-
-StatsdConfig buildGoodConfig() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
-
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("SCREEN_IS_ON"));
- combination->add_matcher(StringToId("SCREEN_IS_OFF"));
-
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("SCREEN_IS_ON"));
- metric->set_bucket(ONE_MINUTE);
- metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
- metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
- config.add_no_report_metric(3);
-
- auto alert = config.add_alert();
- alert->set_id(kAlertId);
- alert->set_metric_id(3);
- alert->set_num_buckets(10);
- alert->set_refractory_period_secs(100);
- alert->set_trigger_if_sum_gt(100);
- return config;
-}
-
-StatsdConfig buildCircleMatchers() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("SCREEN_IS_ON"));
- // Circle dependency
- combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
-
- return config;
-}
-
-StatsdConfig buildAlertWithUnknownMetric() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("SCREEN_IS_ON"));
- metric->set_bucket(ONE_MINUTE);
- metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
- metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
- auto alert = config.add_alert();
- alert->set_id(3);
- alert->set_metric_id(2);
- alert->set_num_buckets(10);
- alert->set_refractory_period_secs(100);
- alert->set_trigger_if_sum_gt(100);
- return config;
-}
-
-StatsdConfig buildMissingMatchers() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("SCREEN_IS_ON"));
- // undefined matcher
- combination->add_matcher(StringToId("ABC"));
-
- return config;
-}
-
-StatsdConfig buildMissingPredicate() {
- StatsdConfig config;
- config.set_id(12345);
-
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("SCREEN_EVENT"));
- metric->set_bucket(ONE_MINUTE);
- metric->set_condition(StringToId("SOME_CONDITION"));
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_EVENT"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2);
-
- return config;
-}
-
-StatsdConfig buildDimensionMetricsWithMultiTags() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(3);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("BATTERY_LOW"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
- combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
-
- // Count process state changes, slice by uid, while SCREEN_IS_OFF
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("BATTERY_LOW"));
- metric->set_bucket(ONE_MINUTE);
- // This case is interesting. We want to dimension across two atoms.
- metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
- auto alert = config.add_alert();
- alert->set_id(kAlertId);
- alert->set_metric_id(3);
- alert->set_num_buckets(10);
- alert->set_refractory_period_secs(100);
- alert->set_trigger_if_sum_gt(100);
- return config;
-}
-
-StatsdConfig buildCirclePredicates() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
-
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
-
- auto condition = config.add_predicate();
- condition->set_id(StringToId("SCREEN_IS_ON"));
- SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
- simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
- simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
-
- condition = config.add_predicate();
- condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
-
- Predicate_Combination* combination = condition->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_predicate(StringToId("SCREEN_IS_ON"));
- combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
-
- return config;
-}
-
-StatsdConfig buildConfigWithDifferentPredicates() {
- StatsdConfig config;
- config.set_id(12345);
-
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = screenOnAtomMatcher;
- auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = screenOffAtomMatcher;
- auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
- *config.add_atom_matcher() = batteryNoneAtomMatcher;
- auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
- *config.add_atom_matcher() = batteryUsbAtomMatcher;
-
- // Simple condition with InitialValue set to default (unknown).
- auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = screenOnUnknownPredicate;
-
- // Simple condition with InitialValue set to false.
- auto screenOnFalsePredicate = config.add_predicate();
- screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
- SimplePredicate* simpleScreenOnFalsePredicate =
- screenOnFalsePredicate->mutable_simple_predicate();
- simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
- simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
- simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
-
- // Simple condition with InitialValue set to false.
- auto onBatteryFalsePredicate = config.add_predicate();
- onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
- SimplePredicate* simpleOnBatteryFalsePredicate =
- onBatteryFalsePredicate->mutable_simple_predicate();
- simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
- simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
- simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
-
- // Combination condition with both simple condition InitialValues set to false.
- auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
- screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
- screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
- LogicalOperation::AND);
- addPredicateToPredicateCombination(*screenOnFalsePredicate,
- screenOnFalseOnBatteryFalsePredicate);
- addPredicateToPredicateCombination(*onBatteryFalsePredicate,
- screenOnFalseOnBatteryFalsePredicate);
-
- // Combination condition with one simple condition InitialValue set to unknown and one set to
- // false.
- auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
- screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
- screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
- LogicalOperation::AND);
- addPredicateToPredicateCombination(screenOnUnknownPredicate,
- screenOnUnknownOnBatteryFalsePredicate);
- addPredicateToPredicateCombination(*onBatteryFalsePredicate,
- screenOnUnknownOnBatteryFalsePredicate);
-
- // Simple condition metric with initial value false.
- ValueMetric* metric1 = config.add_value_metric();
- metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
- metric1->set_what(pulledAtomMatcher.id());
- *metric1->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric1->set_bucket(FIVE_MINUTES);
- metric1->set_condition(screenOnFalsePredicate->id());
-
- // Simple condition metric with initial value unknown.
- ValueMetric* metric2 = config.add_value_metric();
- metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
- metric2->set_what(pulledAtomMatcher.id());
- *metric2->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric2->set_bucket(FIVE_MINUTES);
- metric2->set_condition(screenOnUnknownPredicate.id());
-
- // Combination condition metric with initial values false and false.
- ValueMetric* metric3 = config.add_value_metric();
- metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
- metric3->set_what(pulledAtomMatcher.id());
- *metric3->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric3->set_bucket(FIVE_MINUTES);
- metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
-
- // Combination condition metric with initial values unknown and false.
- ValueMetric* metric4 = config.add_value_metric();
- metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
- metric4->set_what(pulledAtomMatcher.id());
- *metric4->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric4->set_bucket(FIVE_MINUTES);
- metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
-
- return config;
-}
-
-bool isSubset(const set<int32_t>& set1, const set<int32_t>& set2) {
- return std::includes(set2.begin(), set2.end(), set1.begin(), set1.end());
-}
-} // anonymous namespace
-
-TEST(MetricsManagerTest, TestInitialConditions) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildConfigWithDifferentPredicates();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_TRUE(initStatsdConfig(
- kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, allConditionTrackers,
- allMetricProducers, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
- ASSERT_EQ(4u, allMetricProducers.size());
- ASSERT_EQ(5u, allConditionTrackers.size());
-
- ConditionKey queryKey;
- vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
-
- allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
- allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
- EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
- EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
-
- EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
- EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
-}
-
-TEST(MetricsManagerTest, TestGoodConfig) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildGoodConfig();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
- ASSERT_EQ(1u, allMetricProducers.size());
- ASSERT_EQ(1u, allAnomalyTrackers.size());
- ASSERT_EQ(1u, noReportMetricIds.size());
- ASSERT_EQ(1u, alertTrackerMap.size());
- EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
- EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
-}
-
-TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildDimensionMetricsWithMultiTags();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildCircleMatchers();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestMissingMatchers) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildMissingMatchers();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestMissingPredicate) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildMissingPredicate();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation, noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestCirclePredicateDependency) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildCirclePredicates();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildAlertWithUnknownMetric();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestLogSources) {
- string app1 = "app1";
- set<int32_t> app1Uids = {1111, 11111};
- string app2 = "app2";
- set<int32_t> app2Uids = {2222};
- string app3 = "app3";
- set<int32_t> app3Uids = {3333, 1111};
-
- map<string, set<int32_t>> pkgToUids;
- pkgToUids[app1] = app1Uids;
- pkgToUids[app2] = app2Uids;
- pkgToUids[app3] = app3Uids;
-
- int32_t atom1 = 10;
- int32_t atom2 = 20;
- int32_t atom3 = 30;
- sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
- EXPECT_CALL(*uidMap, getAppUid(_))
- .Times(4)
- .WillRepeatedly(Invoke([&pkgToUids](const string& pkg) {
- const auto& it = pkgToUids.find(pkg);
- if (it != pkgToUids.end()) {
- return it->second;
- }
- return set<int32_t>();
- }));
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterPullUidProvider(kConfigKey, _)).Times(1);
- EXPECT_CALL(*pullerManager, UnregisterPullUidProvider(kConfigKey, _)).Times(1);
-
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
-
- StatsdConfig config = buildGoodConfig();
- config.add_allowed_log_source("AID_SYSTEM");
- config.add_allowed_log_source(app1);
- config.add_default_pull_packages("AID_SYSTEM");
- config.add_default_pull_packages("AID_ROOT");
-
- const set<int32_t> defaultPullUids = {AID_SYSTEM, AID_ROOT};
-
- PullAtomPackages* pullAtomPackages = config.add_pull_atom_packages();
- pullAtomPackages->set_atom_id(atom1);
- pullAtomPackages->add_packages(app1);
- pullAtomPackages->add_packages(app3);
-
- pullAtomPackages = config.add_pull_atom_packages();
- pullAtomPackages->set_atom_id(atom2);
- pullAtomPackages->add_packages(app2);
- pullAtomPackages->add_packages("AID_STATSD");
-
- MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
- pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
- EXPECT_TRUE(metricsManager.isConfigValid());
-
- ASSERT_EQ(metricsManager.mAllowedUid.size(), 1);
- EXPECT_EQ(metricsManager.mAllowedUid[0], AID_SYSTEM);
-
- ASSERT_EQ(metricsManager.mAllowedPkg.size(), 1);
- EXPECT_EQ(metricsManager.mAllowedPkg[0], app1);
-
- ASSERT_EQ(metricsManager.mAllowedLogSources.size(), 3);
- EXPECT_TRUE(isSubset({AID_SYSTEM}, metricsManager.mAllowedLogSources));
- EXPECT_TRUE(isSubset(app1Uids, metricsManager.mAllowedLogSources));
-
- ASSERT_EQ(metricsManager.mDefaultPullUids.size(), 2);
- EXPECT_TRUE(isSubset(defaultPullUids, metricsManager.mDefaultPullUids));
- ;
-
- vector<int32_t> atom1Uids = metricsManager.getPullAtomUids(atom1);
- ASSERT_EQ(atom1Uids.size(), 5);
- set<int32_t> expectedAtom1Uids;
- expectedAtom1Uids.insert(defaultPullUids.begin(), defaultPullUids.end());
- expectedAtom1Uids.insert(app1Uids.begin(), app1Uids.end());
- expectedAtom1Uids.insert(app3Uids.begin(), app3Uids.end());
- EXPECT_TRUE(isSubset(expectedAtom1Uids, set<int32_t>(atom1Uids.begin(), atom1Uids.end())));
-
- vector<int32_t> atom2Uids = metricsManager.getPullAtomUids(atom2);
- ASSERT_EQ(atom2Uids.size(), 4);
- set<int32_t> expectedAtom2Uids;
- expectedAtom1Uids.insert(defaultPullUids.begin(), defaultPullUids.end());
- expectedAtom1Uids.insert(app2Uids.begin(), app2Uids.end());
- expectedAtom1Uids.insert(AID_STATSD);
- EXPECT_TRUE(isSubset(expectedAtom2Uids, set<int32_t>(atom2Uids.begin(), atom2Uids.end())));
-
- vector<int32_t> atom3Uids = metricsManager.getPullAtomUids(atom3);
- ASSERT_EQ(atom3Uids.size(), 2);
- EXPECT_TRUE(isSubset(defaultPullUids, set<int32_t>(atom3Uids.begin(), atom3Uids.end())));
-}
-
-TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom) {
- sp<UidMap> uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
-
- StatsdConfig config = buildGoodConfig();
- config.add_whitelisted_atom_ids(3);
- config.add_whitelisted_atom_ids(4);
-
- MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
- pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
- LogEvent event(0 /* uid */, 0 /* pid */);
- CreateNoValuesLogEvent(&event, 10 /* atom id */, 0 /* timestamp */);
- EXPECT_FALSE(metricsManager.checkLogCredentials(event));
-
- CreateNoValuesLogEvent(&event, 3 /* atom id */, 0 /* timestamp */);
- EXPECT_TRUE(metricsManager.checkLogCredentials(event));
-
- CreateNoValuesLogEvent(&event, 4 /* atom id */, 0 /* timestamp */);
- EXPECT_TRUE(metricsManager.checkLogCredentials(event));
-}
-
-TEST(MetricsManagerTest, TestWhitelistedAtomStateTracker) {
- sp<UidMap> uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
-
- StatsdConfig config = buildGoodConfig();
- config.add_allowed_log_source("AID_SYSTEM");
- config.add_whitelisted_atom_ids(3);
- config.add_whitelisted_atom_ids(4);
-
- State state;
- state.set_id(1);
- state.set_atom_id(3);
-
- *config.add_state() = state;
-
- config.mutable_count_metric(0)->add_slice_by_state(state.id());
-
- StateManager::getInstance().clear();
-
- MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
- pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
- EXPECT_EQ(0, StateManager::getInstance().getStateTrackersCount());
- EXPECT_FALSE(metricsManager.isConfigValid());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
deleted file mode 100644
index 1e6680c..0000000
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ /dev/null
@@ -1,1886 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "StatsLogProcessor.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include "StatsService.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-#include "statslog_statsdtest.h"
-#include "storage/StorageManager.h"
-#include "tests/statsd_test_util.h"
-
-using namespace android;
-using namespace testing;
-using ::ndk::SharedRefBase;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-
-#ifdef __ANDROID__
-
-/**
- * Mock MetricsManager (ByteSize() is called).
- */
-class MockMetricsManager : public MetricsManager {
-public:
- MockMetricsManager()
- : MetricsManager(ConfigKey(1, 12345), StatsdConfig(), 1000, 1000, new UidMap(),
- new StatsPullerManager(),
- new AlarmMonitor(10,
- [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
- [](const shared_ptr<IStatsCompanionService>&) {}),
- new AlarmMonitor(10,
- [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
- [](const shared_ptr<IStatsCompanionService>&) {})) {
- }
-
- MOCK_METHOD0(byteSize, size_t());
-
- MOCK_METHOD1(dropData, void(const int64_t dropTimeNs));
-};
-
-TEST(StatsLogProcessorTest, TestRateLimitByteSize) {
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- // Construct the processor with a dummy sendBroadcast function that does nothing.
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, 0,
- [](const ConfigKey& key) { return true; },
- [](const int&, const vector<int64_t>&) {return true;});
-
- MockMetricsManager mockMetricsManager;
-
- ConfigKey key(100, 12345);
- // Expect only the first flush to trigger a check for byte size since the last two are
- // rate-limited.
- EXPECT_CALL(mockMetricsManager, byteSize()).Times(1);
- p.flushIfNecessaryLocked(key, mockMetricsManager);
- p.flushIfNecessaryLocked(key, mockMetricsManager);
- p.flushIfNecessaryLocked(key, mockMetricsManager);
-}
-
-TEST(StatsLogProcessorTest, TestRateLimitBroadcast) {
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- },
- [](const int&, const vector<int64_t>&) {return true;});
-
- MockMetricsManager mockMetricsManager;
-
- ConfigKey key(100, 12345);
- EXPECT_CALL(mockMetricsManager, byteSize())
- .Times(1)
- .WillRepeatedly(::testing::Return(int(
- StatsdStats::kMaxMetricsBytesPerConfig * .95)));
-
- // Expect only one broadcast despite always returning a size that should trigger broadcast.
- p.flushIfNecessaryLocked(key, mockMetricsManager);
- EXPECT_EQ(1, broadcastCount);
-
- // b/73089712
- // This next call to flush should not trigger a broadcast.
- // p.mLastByteSizeTimes.clear(); // Force another check for byte size.
- // p.flushIfNecessaryLocked(2, key, mockMetricsManager);
- // EXPECT_EQ(1, broadcastCount);
-}
-
-TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) {
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- },
- [](const int&, const vector<int64_t>&) {return true;});
-
- MockMetricsManager mockMetricsManager;
-
- ConfigKey key(100, 12345);
- EXPECT_CALL(mockMetricsManager, byteSize())
- .Times(1)
- .WillRepeatedly(::testing::Return(int(StatsdStats::kMaxMetricsBytesPerConfig * 1.2)));
-
- EXPECT_CALL(mockMetricsManager, dropData(_)).Times(1);
-
- // Expect to call the onDumpReport and skip the broadcast.
- p.flushIfNecessaryLocked(key, mockMetricsManager);
- EXPECT_EQ(0, broadcastCount);
-}
-
-StatsdConfig MakeConfig(bool includeMetric) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- if (includeMetric) {
- auto appCrashMatcher = CreateProcessCrashAtomMatcher();
- *config.add_atom_matcher() = appCrashMatcher;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(StringToId("AppCrashes"));
- countMetric->set_what(appCrashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- }
- return config;
-}
-
-TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) {
- // Setup simple config key corresponding to empty config.
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")},
- {String16("p1"), String16("p2")}, {String16(""), String16("")});
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- },
- [](const int&, const vector<int64_t>&) {return true;});
- ConfigKey key(3, 4);
- StatsdConfig config = MakeConfig(true);
- p.OnConfigUpdated(0, key, config);
-
- // Expect to get no metrics, but snapshot specified above in uidmap.
- vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, true, ADB_DUMP, FAST, &bytes);
-
- ConfigMetricsReportList output;
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_TRUE(output.reports_size() > 0);
- auto uidmap = output.reports(0).uid_map();
- EXPECT_TRUE(uidmap.snapshots_size() > 0);
- ASSERT_EQ(2, uidmap.snapshots(0).package_info_size());
-}
-
-TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) {
- // Setup simple config key corresponding to empty config.
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")},
- {String16("p1"), String16("p2")}, {String16(""), String16("")});
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- },
- [](const int&, const vector<int64_t>&) {return true;});
- ConfigKey key(3, 4);
- StatsdConfig config = MakeConfig(false);
- p.OnConfigUpdated(0, key, config);
-
- // Expect to get no metrics, but snapshot specified above in uidmap.
- vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, true, ADB_DUMP, FAST, &bytes);
-
- ConfigMetricsReportList output;
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_TRUE(output.reports_size() > 0);
- EXPECT_FALSE(output.reports(0).has_uid_map());
-}
-
-TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) {
- // Setup simple config key corresponding to empty config.
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- },
- [](const int&, const vector<int64_t>&) {return true;});
- ConfigKey key(3, 4);
- StatsdConfig config;
- auto annotation = config.add_annotation();
- annotation->set_field_int64(1);
- annotation->set_field_int32(2);
- config.add_allowed_log_source("AID_ROOT");
- p.OnConfigUpdated(1, key, config);
-
- // Expect to get no metrics, but snapshot specified above in uidmap.
- vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, true, ADB_DUMP, FAST, &bytes);
-
- ConfigMetricsReportList output;
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_TRUE(output.reports_size() > 0);
- auto report = output.reports(0);
- ASSERT_EQ(1, report.annotation_size());
- EXPECT_EQ(1, report.annotation(0).field_int64());
- EXPECT_EQ(2, report.annotation(0).field_int32());
-}
-
-TEST(StatsLogProcessorTest, TestOnDumpReportEraseData) {
- // Setup a simple config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = wakelockAcquireMatcher;
-
- auto countMetric = config.add_count_metric();
- countMetric->set_id(123456);
- countMetric->set_what(wakelockAcquireMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
-
- ConfigKey cfgKey;
- sp<StatsLogProcessor> processor = CreateStatsLogProcessor(1, 1, config, cfgKey);
-
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event =
- CreateAcquireWakelockEvent(2 /*timestamp*/, attributionUids, attributionTags, "wl1");
- processor->OnLogEvent(event.get());
-
- vector<uint8_t> bytes;
- ConfigMetricsReportList output;
-
- // Dump report WITHOUT erasing data.
- processor->onDumpReport(cfgKey, 3, true, false /* Do NOT erase data. */, ADB_DUMP, FAST,
- &bytes);
- output.ParseFromArray(bytes.data(), bytes.size());
- ASSERT_EQ(output.reports_size(), 1);
- ASSERT_EQ(output.reports(0).metrics_size(), 1);
- ASSERT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1);
-
- // Dump report WITH erasing data. There should be data since we didn't previously erase it.
- processor->onDumpReport(cfgKey, 4, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes);
- output.ParseFromArray(bytes.data(), bytes.size());
- ASSERT_EQ(output.reports_size(), 1);
- ASSERT_EQ(output.reports(0).metrics_size(), 1);
- ASSERT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1);
-
- // Dump report again. There should be no data since we erased it.
- processor->onDumpReport(cfgKey, 5, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes);
- output.ParseFromArray(bytes.data(), bytes.size());
- // We don't care whether statsd has a report, as long as it has no count metrics in it.
- bool noData = output.reports_size() == 0 || output.reports(0).metrics_size() == 0 ||
- output.reports(0).metrics(0).count_metrics().data_size() == 0;
- EXPECT_TRUE(noData);
-}
-
-TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate) {
- // Setup simple config key corresponding to empty config.
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- StatsLogProcessor p(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [](const ConfigKey& key) { return true; },
- [](const int&, const vector<int64_t>&) { return true; });
- ConfigKey key(3, 4);
- StatsdConfig config = MakeConfig(false);
- p.OnConfigUpdated(0, key, config);
- EXPECT_NE(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
-
- config.add_default_pull_packages("AID_STATSD");
- p.OnConfigUpdated(5, key, config);
- EXPECT_NE(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
-
- p.OnConfigRemoved(key);
- EXPECT_EQ(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
-}
-
-TEST(StatsLogProcessorTest, InvalidConfigRemoved) {
- // Setup simple config key corresponding to empty config.
- StatsdStats::getInstance().reset();
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")},
- {String16("p1"), String16("p2")}, {String16(""), String16("")});
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [](const ConfigKey& key) { return true; },
- [](const int&, const vector<int64_t>&) {return true;});
- ConfigKey key(3, 4);
- StatsdConfig config = MakeConfig(true);
- p.OnConfigUpdated(0, key, config);
- EXPECT_EQ(1, p.mMetricsManagers.size());
- EXPECT_NE(p.mMetricsManagers.find(key), p.mMetricsManagers.end());
- // Cannot assert the size of mConfigStats since it is static and does not get cleared on reset.
- EXPECT_NE(StatsdStats::getInstance().mConfigStats.end(),
- StatsdStats::getInstance().mConfigStats.find(key));
- EXPECT_EQ(0, StatsdStats::getInstance().mIceBox.size());
-
- StatsdConfig invalidConfig = MakeConfig(true);
- invalidConfig.clear_allowed_log_source();
- p.OnConfigUpdated(0, key, invalidConfig);
- EXPECT_EQ(0, p.mMetricsManagers.size());
- // The current configs should not contain the invalid config.
- EXPECT_EQ(StatsdStats::getInstance().mConfigStats.end(),
- StatsdStats::getInstance().mConfigStats.find(key));
- // Both "config" and "invalidConfig" should be in the icebox.
- EXPECT_EQ(2, StatsdStats::getInstance().mIceBox.size());
-
-}
-
-
-TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) {
- int uid = 1111;
-
- // Setup a simple config, no activation
- StatsdConfig config1;
- int64_t cfgId1 = 12341;
- config1.set_id(cfgId1);
- config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- *config1.add_atom_matcher() = wakelockAcquireMatcher;
-
- long metricId1 = 1234561;
- long metricId2 = 1234562;
- auto countMetric1 = config1.add_count_metric();
- countMetric1->set_id(metricId1);
- countMetric1->set_what(wakelockAcquireMatcher.id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- auto countMetric2 = config1.add_count_metric();
- countMetric2->set_id(metricId2);
- countMetric2->set_what(wakelockAcquireMatcher.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- ConfigKey cfgKey1(uid, cfgId1);
-
- // Add another config, with two metrics, one with activation
- StatsdConfig config2;
- int64_t cfgId2 = 12342;
- config2.set_id(cfgId2);
- config2.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config2.add_atom_matcher() = wakelockAcquireMatcher;
-
- long metricId3 = 1234561;
- long metricId4 = 1234562;
-
- auto countMetric3 = config2.add_count_metric();
- countMetric3->set_id(metricId3);
- countMetric3->set_what(wakelockAcquireMatcher.id());
- countMetric3->set_bucket(FIVE_MINUTES);
-
- auto countMetric4 = config2.add_count_metric();
- countMetric4->set_id(metricId4);
- countMetric4->set_what(wakelockAcquireMatcher.id());
- countMetric4->set_bucket(FIVE_MINUTES);
-
- auto metric3Activation = config2.add_metric_activation();
- metric3Activation->set_metric_id(metricId3);
- metric3Activation->set_activation_type(ACTIVATE_IMMEDIATELY);
- auto metric3ActivationTrigger = metric3Activation->add_event_activation();
- metric3ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric3ActivationTrigger->set_ttl_seconds(100);
-
- ConfigKey cfgKey2(uid, cfgId2);
-
- // Add another config, with two metrics, both with activations
- StatsdConfig config3;
- int64_t cfgId3 = 12343;
- config3.set_id(cfgId3);
- config3.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config3.add_atom_matcher() = wakelockAcquireMatcher;
-
- long metricId5 = 1234565;
- long metricId6 = 1234566;
- auto countMetric5 = config3.add_count_metric();
- countMetric5->set_id(metricId5);
- countMetric5->set_what(wakelockAcquireMatcher.id());
- countMetric5->set_bucket(FIVE_MINUTES);
-
- auto countMetric6 = config3.add_count_metric();
- countMetric6->set_id(metricId6);
- countMetric6->set_what(wakelockAcquireMatcher.id());
- countMetric6->set_bucket(FIVE_MINUTES);
-
- auto metric5Activation = config3.add_metric_activation();
- metric5Activation->set_metric_id(metricId5);
- metric5Activation->set_activation_type(ACTIVATE_IMMEDIATELY);
- auto metric5ActivationTrigger = metric5Activation->add_event_activation();
- metric5ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric5ActivationTrigger->set_ttl_seconds(100);
-
- auto metric6Activation = config3.add_metric_activation();
- metric6Activation->set_metric_id(metricId6);
- metric6Activation->set_activation_type(ACTIVATE_IMMEDIATELY);
- auto metric6ActivationTrigger = metric6Activation->add_event_activation();
- metric6ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric6ActivationTrigger->set_ttl_seconds(200);
-
- ConfigKey cfgKey3(uid, cfgId3);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, timeBase1,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(1, cfgKey1, config1);
- processor.OnConfigUpdated(2, cfgKey2, config2);
- processor.OnConfigUpdated(3, cfgKey3, config3);
-
- ASSERT_EQ(3, processor.mMetricsManagers.size());
-
- // Expect the first config and both metrics in it to be active.
- auto it = processor.mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor.mMetricsManagers.end());
- auto& metricsManager1 = it->second;
- EXPECT_TRUE(metricsManager1->isActive());
-
- auto metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer1 = *metricIt;
- EXPECT_TRUE(metricProducer1->isActive());
-
- metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer2 = *metricIt;
- EXPECT_TRUE(metricProducer2->isActive());
-
- // Expect config 2 to be active. Metric 3 shouldn't be active, metric 4 should be active.
- it = processor.mMetricsManagers.find(cfgKey2);
- EXPECT_TRUE(it != processor.mMetricsManagers.end());
- auto& metricsManager2 = it->second;
- EXPECT_TRUE(metricsManager2->isActive());
-
- metricIt = metricsManager2->mAllMetricProducers.begin();
- for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId3) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end());
- auto& metricProducer3 = *metricIt;
- EXPECT_FALSE(metricProducer3->isActive());
-
- metricIt = metricsManager2->mAllMetricProducers.begin();
- for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId4) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end());
- auto& metricProducer4 = *metricIt;
- EXPECT_TRUE(metricProducer4->isActive());
-
- // Expect the third config and both metrics in it to be inactive.
- it = processor.mMetricsManagers.find(cfgKey3);
- EXPECT_TRUE(it != processor.mMetricsManagers.end());
- auto& metricsManager3 = it->second;
- EXPECT_FALSE(metricsManager3->isActive());
-
- metricIt = metricsManager3->mAllMetricProducers.begin();
- for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId5) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end());
- auto& metricProducer5 = *metricIt;
- EXPECT_FALSE(metricProducer5->isActive());
-
- metricIt = metricsManager3->mAllMetricProducers.begin();
- for (; metricIt != metricsManager3->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId6) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end());
- auto& metricProducer6 = *metricIt;
- EXPECT_FALSE(metricProducer6->isActive());
-
- // No broadcast for active configs should have happened yet.
- EXPECT_EQ(broadcastCount, 0);
-
- // Activate all 3 metrics that were not active.
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event =
- CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
- processor.OnLogEvent(event.get());
-
- // Assert that all 3 configs are active.
- EXPECT_TRUE(metricsManager1->isActive());
- EXPECT_TRUE(metricsManager2->isActive());
- EXPECT_TRUE(metricsManager3->isActive());
-
- // A broadcast should have happened, and all 3 configs should be active in the broadcast.
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 3);
- EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId1) !=
- activeConfigsBroadcast.end());
- EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId2) !=
- activeConfigsBroadcast.end());
- EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId3) !=
- activeConfigsBroadcast.end());
-
- // When we shut down, metrics 3 & 5 have 100ns remaining, metric 6 has 100s + 100ns.
- int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
- processor.SaveActiveConfigsToDisk(shutDownTime);
- const int64_t ttl3 = event->GetElapsedTimestampNs() +
- metric3ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime;
- const int64_t ttl5 = event->GetElapsedTimestampNs() +
- metric5ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime;
- const int64_t ttl6 = event->GetElapsedTimestampNs() +
- metric6ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime;
-
- // Create a second StatsLogProcessor and push the same 3 configs.
- long timeBase2 = 1000;
- sp<StatsLogProcessor> processor2 =
- CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
- processor2->OnConfigUpdated(timeBase2, cfgKey2, config2);
- processor2->OnConfigUpdated(timeBase2, cfgKey3, config3);
-
- ASSERT_EQ(3, processor2->mMetricsManagers.size());
-
- // First config and both metrics are active.
- it = processor2->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1001 = it->second;
- EXPECT_TRUE(metricsManager1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1001 = *metricIt;
- EXPECT_TRUE(metricProducer1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1002 = *metricIt;
- EXPECT_TRUE(metricProducer1002->isActive());
-
- // Second config is active. Metric 3 is inactive, metric 4 is active.
- it = processor2->mMetricsManagers.find(cfgKey2);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1002 = it->second;
- EXPECT_TRUE(metricsManager1002->isActive());
-
- metricIt = metricsManager1002->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId3) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end());
- auto& metricProducer1003 = *metricIt;
- EXPECT_FALSE(metricProducer1003->isActive());
-
- metricIt = metricsManager1002->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId4) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end());
- auto& metricProducer1004 = *metricIt;
- EXPECT_TRUE(metricProducer1004->isActive());
-
- // Config 3 is inactive. both metrics are inactive.
- it = processor2->mMetricsManagers.find(cfgKey3);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1003 = it->second;
- EXPECT_FALSE(metricsManager1003->isActive());
- ASSERT_EQ(2, metricsManager1003->mAllMetricProducers.size());
-
- metricIt = metricsManager1003->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId5) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end());
- auto& metricProducer1005 = *metricIt;
- EXPECT_FALSE(metricProducer1005->isActive());
-
- metricIt = metricsManager1003->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1003->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId6) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end());
- auto& metricProducer1006 = *metricIt;
- EXPECT_FALSE(metricProducer1006->isActive());
-
- // Assert that all 3 metrics with activation are inactive and that the ttls were properly set.
- EXPECT_FALSE(metricProducer1003->isActive());
- const auto& activation1003 = metricProducer1003->mEventActivationMap.begin()->second;
- EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns);
- EXPECT_EQ(0, activation1003->start_ns);
- EXPECT_FALSE(metricProducer1005->isActive());
- const auto& activation1005 = metricProducer1005->mEventActivationMap.begin()->second;
- EXPECT_EQ(100 * NS_PER_SEC, activation1005->ttl_ns);
- EXPECT_EQ(0, activation1005->start_ns);
- EXPECT_FALSE(metricProducer1006->isActive());
- const auto& activation1006 = metricProducer1006->mEventActivationMap.begin()->second;
- EXPECT_EQ(200 * NS_PER_SEC, activation1006->ttl_ns);
- EXPECT_EQ(0, activation1006->start_ns);
-
- processor2->LoadActiveConfigsFromDisk();
-
- // After loading activations from disk, assert that all 3 metrics are active.
- EXPECT_TRUE(metricProducer1003->isActive());
- EXPECT_EQ(timeBase2 + ttl3 - activation1003->ttl_ns, activation1003->start_ns);
- EXPECT_TRUE(metricProducer1005->isActive());
- EXPECT_EQ(timeBase2 + ttl5 - activation1005->ttl_ns, activation1005->start_ns);
- EXPECT_TRUE(metricProducer1006->isActive());
- EXPECT_EQ(timeBase2 + ttl6 - activation1006->ttl_ns, activation1003->start_ns);
-
- // Make sure no more broadcasts have happened.
- EXPECT_EQ(broadcastCount, 1);
-}
-
-TEST(StatsLogProcessorTest, TestActivationOnBoot) {
- int uid = 1111;
-
- StatsdConfig config1;
- config1.set_id(12341);
- config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- *config1.add_atom_matcher() = wakelockAcquireMatcher;
-
- long metricId1 = 1234561;
- long metricId2 = 1234562;
- auto countMetric1 = config1.add_count_metric();
- countMetric1->set_id(metricId1);
- countMetric1->set_what(wakelockAcquireMatcher.id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- auto countMetric2 = config1.add_count_metric();
- countMetric2->set_id(metricId2);
- countMetric2->set_what(wakelockAcquireMatcher.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- auto metric1Activation = config1.add_metric_activation();
- metric1Activation->set_metric_id(metricId1);
- metric1Activation->set_activation_type(ACTIVATE_ON_BOOT);
- auto metric1ActivationTrigger = metric1Activation->add_event_activation();
- metric1ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric1ActivationTrigger->set_ttl_seconds(100);
-
- ConfigKey cfgKey1(uid, 12341);
- long timeBase1 = 1;
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
-
- ASSERT_EQ(1, processor->mMetricsManagers.size());
- auto it = processor->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor->mMetricsManagers.end());
- auto& metricsManager1 = it->second;
- EXPECT_TRUE(metricsManager1->isActive());
-
- auto metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer1 = *metricIt;
- EXPECT_FALSE(metricProducer1->isActive());
-
- metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer2 = *metricIt;
- EXPECT_TRUE(metricProducer2->isActive());
-
- const auto& activation1 = metricProducer1->mEventActivationMap.begin()->second;
- EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kNotActive, activation1->state);
-
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event =
- CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
- processor->OnLogEvent(event.get());
-
- EXPECT_FALSE(metricProducer1->isActive());
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1->state);
-
- int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
- processor->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_FALSE(metricProducer1->isActive());
- const int64_t ttl1 = metric1ActivationTrigger->ttl_seconds() * NS_PER_SEC;
-
- long timeBase2 = 1000;
- sp<StatsLogProcessor> processor2 =
- CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
-
- ASSERT_EQ(1, processor2->mMetricsManagers.size());
- it = processor2->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1001 = it->second;
- EXPECT_TRUE(metricsManager1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1001 = *metricIt;
- EXPECT_FALSE(metricProducer1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1002 = *metricIt;
- EXPECT_TRUE(metricProducer1002->isActive());
-
- const auto& activation1001 = metricProducer1001->mEventActivationMap.begin()->second;
- EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns);
- EXPECT_EQ(0, activation1001->start_ns);
- EXPECT_EQ(kNotActive, activation1001->state);
-
- processor2->LoadActiveConfigsFromDisk();
-
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation1001->ttl_ns, activation1001->start_ns);
- EXPECT_EQ(kActive, activation1001->state);
-}
-
-TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations) {
- int uid = 1111;
-
- // Create config with 2 metrics:
- // Metric 1: Activate on boot with 2 activations
- // Metric 2: Always active
- StatsdConfig config1;
- config1.set_id(12341);
- config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- *config1.add_atom_matcher() = wakelockAcquireMatcher;
- *config1.add_atom_matcher() = screenOnMatcher;
-
- long metricId1 = 1234561;
- long metricId2 = 1234562;
-
- auto countMetric1 = config1.add_count_metric();
- countMetric1->set_id(metricId1);
- countMetric1->set_what(wakelockAcquireMatcher.id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- auto countMetric2 = config1.add_count_metric();
- countMetric2->set_id(metricId2);
- countMetric2->set_what(wakelockAcquireMatcher.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- auto metric1Activation = config1.add_metric_activation();
- metric1Activation->set_metric_id(metricId1);
- metric1Activation->set_activation_type(ACTIVATE_ON_BOOT);
- auto metric1ActivationTrigger1 = metric1Activation->add_event_activation();
- metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric1ActivationTrigger1->set_ttl_seconds(100);
- auto metric1ActivationTrigger2 = metric1Activation->add_event_activation();
- metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id());
- metric1ActivationTrigger2->set_ttl_seconds(200);
-
- ConfigKey cfgKey1(uid, 12341);
- long timeBase1 = 1;
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor->mMetricsManagers.size());
- auto it = processor->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor->mMetricsManagers.end());
- auto& metricsManager1 = it->second;
- EXPECT_TRUE(metricsManager1->isActive());
-
- auto metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer1 = *metricIt;
- EXPECT_FALSE(metricProducer1->isActive());
-
- metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer2 = *metricIt;
- EXPECT_TRUE(metricProducer2->isActive());
-
- int i = 0;
- for (; i < metricsManager1->mAllAtomMatchers.size(); i++) {
- if (metricsManager1->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation1 = metricProducer1->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kNotActive, activation1->state);
-
- i = 0;
- for (; i < metricsManager1->mAllAtomMatchers.size(); i++) {
- if (metricsManager1->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation2 = metricProducer1->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
- // }}}------------------------------------------------------------------------------
-
- // Trigger Activation 1 for Metric 1
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event =
- CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
- processor->OnLogEvent(event.get());
-
- // Metric 1 is not active; Activation 1 set to kActiveOnBoot
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_FALSE(metricProducer1->isActive());
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1->state);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
-
- EXPECT_TRUE(metricProducer2->isActive());
- // }}}-----------------------------------------------------------------------------
-
- // Simulate shutdown by saving state to disk
- int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
- processor->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_FALSE(metricProducer1->isActive());
- int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC;
-
- // Simulate device restarted state by creating new instance of StatsLogProcessor with the
- // same config.
- long timeBase2 = 1000;
- sp<StatsLogProcessor> processor2 =
- CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor2->mMetricsManagers.size());
- it = processor2->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1001 = it->second;
- EXPECT_TRUE(metricsManager1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1001 = *metricIt;
- EXPECT_FALSE(metricProducer1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1002 = *metricIt;
- EXPECT_TRUE(metricProducer1002->isActive());
-
- i = 0;
- for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) {
- if (metricsManager1001->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation1001_1 = metricProducer1001->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activation1001_1->ttl_ns);
- EXPECT_EQ(0, activation1001_1->start_ns);
- EXPECT_EQ(kNotActive, activation1001_1->state);
-
- i = 0;
- for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) {
- if (metricsManager1001->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
-
- const auto& activation1001_2 = metricProducer1001->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activation1001_2->ttl_ns);
- EXPECT_EQ(0, activation1001_2->start_ns);
- EXPECT_EQ(kNotActive, activation1001_2->state);
- // }}}-----------------------------------------------------------------------------------
-
- // Load saved state from disk.
- processor2->LoadActiveConfigsFromDisk();
-
- // Metric 1 active; Activation 1 is active, Activation 2 is not active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns);
- EXPECT_EQ(kActive, activation1001_1->state);
- EXPECT_EQ(0, activation1001_2->start_ns);
- EXPECT_EQ(kNotActive, activation1001_2->state);
-
- EXPECT_TRUE(metricProducer1002->isActive());
- // }}}--------------------------------------------------------------------------------
-
- // Trigger Activation 2 for Metric 1.
- auto screenOnEvent =
- CreateScreenStateChangedEvent(timeBase2 + 200, android::view::DISPLAY_STATE_ON);
- processor2->OnLogEvent(screenOnEvent.get());
-
- // Metric 1 active; Activation 1 is active, Activation 2 is set to kActiveOnBoot
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns);
- EXPECT_EQ(kActive, activation1001_1->state);
- EXPECT_EQ(0, activation1001_2->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1001_2->state);
-
- EXPECT_TRUE(metricProducer1002->isActive());
- // }}}---------------------------------------------------------------------------
-
- // Simulate shutdown by saving state to disk
- shutDownTime = timeBase2 + 50 * NS_PER_SEC;
- processor2->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_TRUE(metricProducer1002->isActive());
- ttl1 = timeBase2 + metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC - shutDownTime;
- int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC;
-
- // Simulate device restarted state by creating new instance of StatsLogProcessor with the
- // same config.
- long timeBase3 = timeBase2 + 120 * NS_PER_SEC;
- sp<StatsLogProcessor> processor3 =
- CreateStatsLogProcessor(timeBase3, timeBase3, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor3->mMetricsManagers.size());
- it = processor3->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor3->mMetricsManagers.end());
- auto& metricsManagerTimeBase3 = it->second;
- EXPECT_TRUE(metricsManagerTimeBase3->isActive());
-
- metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end());
- auto& metricProducerTimeBase3_1 = *metricIt;
- EXPECT_FALSE(metricProducerTimeBase3_1->isActive());
-
- metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end());
- auto& metricProducerTimeBase3_2 = *metricIt;
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
-
- i = 0;
- for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activationTimeBase3_1 = metricProducerTimeBase3_1->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase3_1->ttl_ns);
- EXPECT_EQ(0, activationTimeBase3_1->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase3_1->state);
-
- i = 0;
- for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
-
- const auto& activationTimeBase3_2 = metricProducerTimeBase3_1->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase3_2->ttl_ns);
- EXPECT_EQ(0, activationTimeBase3_2->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase3_2->state);
-
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
- // }}}----------------------------------------------------------------------------------
-
- // Load saved state from disk.
- processor3->LoadActiveConfigsFromDisk();
-
- // Metric 1 active: Activation 1 is active, Activation 2 is active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducerTimeBase3_1->isActive());
- EXPECT_EQ(timeBase3 + ttl1 - activationTimeBase3_1->ttl_ns, activationTimeBase3_1->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_1->state);
- EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_2->state);
-
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
- // }}}-------------------------------------------------------------------------------
-
- // Trigger Activation 2 for Metric 1 again.
- screenOnEvent = CreateScreenStateChangedEvent(timeBase3 + 100 * NS_PER_SEC,
- android::view::DISPLAY_STATE_ON);
- processor3->OnLogEvent(screenOnEvent.get());
-
- // Metric 1 active; Activation 1 is not active, Activation 2 is set to active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducerTimeBase3_1->isActive());
- EXPECT_EQ(kNotActive, activationTimeBase3_1->state);
- EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_2->state);
-
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
- // }}}---------------------------------------------------------------------------
-
- // Simulate shutdown by saving state to disk.
- shutDownTime = timeBase3 + 500 * NS_PER_SEC;
- processor3->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_TRUE(metricProducer1002->isActive());
- ttl1 = timeBase3 + ttl1 - shutDownTime;
- ttl2 = timeBase3 + metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC - shutDownTime;
-
- // Simulate device restarted state by creating new instance of StatsLogProcessor with the
- // same config.
- long timeBase4 = timeBase3 + 600 * NS_PER_SEC;
- sp<StatsLogProcessor> processor4 =
- CreateStatsLogProcessor(timeBase4, timeBase4, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor4->mMetricsManagers.size());
- it = processor4->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor4->mMetricsManagers.end());
- auto& metricsManagerTimeBase4 = it->second;
- EXPECT_TRUE(metricsManagerTimeBase4->isActive());
-
- metricIt = metricsManagerTimeBase4->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase4->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase4->mAllMetricProducers.end());
- auto& metricProducerTimeBase4_1 = *metricIt;
- EXPECT_FALSE(metricProducerTimeBase4_1->isActive());
-
- metricIt = metricsManagerTimeBase4->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase4->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase4->mAllMetricProducers.end());
- auto& metricProducerTimeBase4_2 = *metricIt;
- EXPECT_TRUE(metricProducerTimeBase4_2->isActive());
-
- i = 0;
- for (; i < metricsManagerTimeBase4->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase4->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activationTimeBase4_1 = metricProducerTimeBase4_1->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase4_1->ttl_ns);
- EXPECT_EQ(0, activationTimeBase4_1->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase4_1->state);
-
- i = 0;
- for (; i < metricsManagerTimeBase4->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase4->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
-
- const auto& activationTimeBase4_2 = metricProducerTimeBase4_1->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase4_2->ttl_ns);
- EXPECT_EQ(0, activationTimeBase4_2->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase4_2->state);
-
- EXPECT_TRUE(metricProducerTimeBase4_2->isActive());
- // }}}----------------------------------------------------------------------------------
-
- // Load saved state from disk.
- processor4->LoadActiveConfigsFromDisk();
-
- // Metric 1 active: Activation 1 is not active, Activation 2 is not active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_FALSE(metricProducerTimeBase4_1->isActive());
- EXPECT_EQ(kNotActive, activationTimeBase4_1->state);
- EXPECT_EQ(kNotActive, activationTimeBase4_2->state);
-
- EXPECT_TRUE(metricProducerTimeBase4_2->isActive());
- // }}}-------------------------------------------------------------------------------
-}
-
-TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActivationTypes) {
- int uid = 1111;
-
- // Create config with 2 metrics:
- // Metric 1: Activate on boot with 2 activations
- // Metric 2: Always active
- StatsdConfig config1;
- config1.set_id(12341);
- config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- *config1.add_atom_matcher() = wakelockAcquireMatcher;
- *config1.add_atom_matcher() = screenOnMatcher;
-
- long metricId1 = 1234561;
- long metricId2 = 1234562;
-
- auto countMetric1 = config1.add_count_metric();
- countMetric1->set_id(metricId1);
- countMetric1->set_what(wakelockAcquireMatcher.id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- auto countMetric2 = config1.add_count_metric();
- countMetric2->set_id(metricId2);
- countMetric2->set_what(wakelockAcquireMatcher.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- auto metric1Activation = config1.add_metric_activation();
- metric1Activation->set_metric_id(metricId1);
- metric1Activation->set_activation_type(ACTIVATE_ON_BOOT);
- auto metric1ActivationTrigger1 = metric1Activation->add_event_activation();
- metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric1ActivationTrigger1->set_ttl_seconds(100);
- auto metric1ActivationTrigger2 = metric1Activation->add_event_activation();
- metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id());
- metric1ActivationTrigger2->set_ttl_seconds(200);
- metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
-
- ConfigKey cfgKey1(uid, 12341);
- long timeBase1 = 1;
- sp<StatsLogProcessor> processor1 =
- CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor1->mMetricsManagers.size());
- auto it = processor1->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor1->mMetricsManagers.end());
- auto& metricsManager1 = it->second;
- EXPECT_TRUE(metricsManager1->isActive());
-
- ASSERT_EQ(metricsManager1->mAllMetricProducers.size(), 2);
- // We assume that the index of a MetricProducer within the mAllMetricProducers
- // array follows the order in which metrics are added to the config.
- auto& metricProducer1_1 = metricsManager1->mAllMetricProducers[0];
- EXPECT_EQ(metricProducer1_1->getMetricId(), metricId1);
- EXPECT_FALSE(metricProducer1_1->isActive()); // inactive due to associated MetricActivation
-
- auto& metricProducer1_2 = metricsManager1->mAllMetricProducers[1];
- EXPECT_EQ(metricProducer1_2->getMetricId(), metricId2);
- EXPECT_TRUE(metricProducer1_2->isActive());
-
- ASSERT_EQ(metricProducer1_1->mEventActivationMap.size(), 2);
- // The key in mEventActivationMap is the index of the associated atom matcher. We assume
- // that matchers are indexed in the order that they are added to the config.
- const auto& activation1_1_1 = metricProducer1_1->mEventActivationMap.at(0);
- EXPECT_EQ(100 * NS_PER_SEC, activation1_1_1->ttl_ns);
- EXPECT_EQ(0, activation1_1_1->start_ns);
- EXPECT_EQ(kNotActive, activation1_1_1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1_1_1->activationType);
-
- const auto& activation1_1_2 = metricProducer1_1->mEventActivationMap.at(1);
- EXPECT_EQ(200 * NS_PER_SEC, activation1_1_2->ttl_ns);
- EXPECT_EQ(0, activation1_1_2->start_ns);
- EXPECT_EQ(kNotActive, activation1_1_2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1_1_2->activationType);
- // }}}------------------------------------------------------------------------------
-
- // Trigger Activation 1 for Metric 1
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event =
- CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
- processor1->OnLogEvent(event.get());
-
- // Metric 1 is not active; Activation 1 set to kActiveOnBoot
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_FALSE(metricProducer1_1->isActive());
- EXPECT_EQ(0, activation1_1_1->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1_1_1->state);
- EXPECT_EQ(0, activation1_1_2->start_ns);
- EXPECT_EQ(kNotActive, activation1_1_2->state);
-
- EXPECT_TRUE(metricProducer1_2->isActive());
- // }}}-----------------------------------------------------------------------------
-
- // Simulate shutdown by saving state to disk
- int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
- processor1->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_FALSE(metricProducer1_1->isActive());
-
- // Simulate device restarted state by creating new instance of StatsLogProcessor with the
- // same config.
- long timeBase2 = 1000;
- sp<StatsLogProcessor> processor2 =
- CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor2->mMetricsManagers.size());
- it = processor2->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager2 = it->second;
- EXPECT_TRUE(metricsManager2->isActive());
-
- ASSERT_EQ(metricsManager2->mAllMetricProducers.size(), 2);
- // We assume that the index of a MetricProducer within the mAllMetricProducers
- // array follows the order in which metrics are added to the config.
- auto& metricProducer2_1 = metricsManager2->mAllMetricProducers[0];
- EXPECT_EQ(metricProducer2_1->getMetricId(), metricId1);
- EXPECT_FALSE(metricProducer2_1->isActive());
-
- auto& metricProducer2_2 = metricsManager2->mAllMetricProducers[1];
- EXPECT_EQ(metricProducer2_2->getMetricId(), metricId2);
- EXPECT_TRUE(metricProducer2_2->isActive());
-
- ASSERT_EQ(metricProducer2_1->mEventActivationMap.size(), 2);
- // The key in mEventActivationMap is the index of the associated atom matcher. We assume
- // that matchers are indexed in the order that they are added to the config.
- const auto& activation2_1_1 = metricProducer2_1->mEventActivationMap.at(0);
- EXPECT_EQ(100 * NS_PER_SEC, activation2_1_1->ttl_ns);
- EXPECT_EQ(0, activation2_1_1->start_ns);
- EXPECT_EQ(kNotActive, activation2_1_1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation2_1_1->activationType);
-
- const auto& activation2_1_2 = metricProducer2_1->mEventActivationMap.at(1);
- EXPECT_EQ(200 * NS_PER_SEC, activation2_1_2->ttl_ns);
- EXPECT_EQ(0, activation2_1_2->start_ns);
- EXPECT_EQ(kNotActive, activation2_1_2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2_1_2->activationType);
- // }}}-----------------------------------------------------------------------------------
-
- // Load saved state from disk.
- processor2->LoadActiveConfigsFromDisk();
-
- // Metric 1 active; Activation 1 is active, Activation 2 is not active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer2_1->isActive());
- int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC;
- EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns);
- EXPECT_EQ(kActive, activation2_1_1->state);
- EXPECT_EQ(0, activation2_1_2->start_ns);
- EXPECT_EQ(kNotActive, activation2_1_2->state);
-
- EXPECT_TRUE(metricProducer2_2->isActive());
- // }}}--------------------------------------------------------------------------------
-
- // Trigger Activation 2 for Metric 1.
- auto screenOnEvent =
- CreateScreenStateChangedEvent(timeBase2 + 200, android::view::DISPLAY_STATE_ON);
- processor2->OnLogEvent(screenOnEvent.get());
-
- // Metric 1 active; Activation 1 is active, Activation 2 is active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer2_1->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns);
- EXPECT_EQ(kActive, activation2_1_1->state);
- EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation2_1_2->start_ns);
- EXPECT_EQ(kActive, activation2_1_2->state);
-
- EXPECT_TRUE(metricProducer2_2->isActive());
- // }}}---------------------------------------------------------------------------
-
- // Simulate shutdown by saving state to disk
- shutDownTime = timeBase2 + 50 * NS_PER_SEC;
- processor2->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_TRUE(metricProducer2_1->isActive());
- EXPECT_TRUE(metricProducer2_2->isActive());
- ttl1 -= shutDownTime - timeBase2;
- int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC -
- (shutDownTime - screenOnEvent->GetElapsedTimestampNs());
-
- // Simulate device restarted state by creating new instance of StatsLogProcessor with the
- // same config.
- long timeBase3 = timeBase2 + 120 * NS_PER_SEC;
- sp<StatsLogProcessor> processor3 =
- CreateStatsLogProcessor(timeBase3, timeBase3, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor3->mMetricsManagers.size());
- it = processor3->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor3->mMetricsManagers.end());
- auto& metricsManager3 = it->second;
- EXPECT_TRUE(metricsManager3->isActive());
-
- ASSERT_EQ(metricsManager3->mAllMetricProducers.size(), 2);
- // We assume that the index of a MetricProducer within the mAllMetricProducers
- // array follows the order in which metrics are added to the config.
- auto& metricProducer3_1 = metricsManager3->mAllMetricProducers[0];
- EXPECT_EQ(metricProducer3_1->getMetricId(), metricId1);
- EXPECT_FALSE(metricProducer3_1->isActive());
-
- auto& metricProducer3_2 = metricsManager3->mAllMetricProducers[1];
- EXPECT_EQ(metricProducer3_2->getMetricId(), metricId2);
- EXPECT_TRUE(metricProducer3_2->isActive());
-
- ASSERT_EQ(metricProducer3_1->mEventActivationMap.size(), 2);
- // The key in mEventActivationMap is the index of the associated atom matcher. We assume
- // that matchers are indexed in the order that they are added to the config.
- const auto& activation3_1_1 = metricProducer3_1->mEventActivationMap.at(0);
- EXPECT_EQ(100 * NS_PER_SEC, activation3_1_1->ttl_ns);
- EXPECT_EQ(0, activation3_1_1->start_ns);
- EXPECT_EQ(kNotActive, activation3_1_1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation3_1_1->activationType);
-
- const auto& activation3_1_2 = metricProducer3_1->mEventActivationMap.at(1);
- EXPECT_EQ(200 * NS_PER_SEC, activation3_1_2->ttl_ns);
- EXPECT_EQ(0, activation3_1_2->start_ns);
- EXPECT_EQ(kNotActive, activation3_1_2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation3_1_2->activationType);
- // }}}----------------------------------------------------------------------------------
-
- // Load saved state from disk.
- processor3->LoadActiveConfigsFromDisk();
-
- // Metric 1 active: Activation 1 is active, Activation 2 is active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer3_1->isActive());
- EXPECT_EQ(timeBase3 + ttl1 - activation3_1_1->ttl_ns, activation3_1_1->start_ns);
- EXPECT_EQ(kActive, activation3_1_1->state);
- EXPECT_EQ(timeBase3 + ttl2 - activation3_1_2->ttl_ns, activation3_1_2->start_ns);
- EXPECT_EQ(kActive, activation3_1_2->state);
-
- EXPECT_TRUE(metricProducer3_2->isActive());
- // }}}-------------------------------------------------------------------------------
-
- // Trigger Activation 2 for Metric 1 again.
- screenOnEvent = CreateScreenStateChangedEvent(timeBase3 + 100 * NS_PER_SEC,
- android::view::DISPLAY_STATE_ON);
- processor3->OnLogEvent(screenOnEvent.get());
-
- // Metric 1 active; Activation 1 is inactive (above screenOnEvent causes ttl1 to expire),
- // Activation 2 is set to active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer3_1->isActive());
- EXPECT_EQ(kNotActive, activation3_1_1->state);
- EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation3_1_2->start_ns);
- EXPECT_EQ(kActive, activation3_1_2->state);
-
- EXPECT_TRUE(metricProducer3_2->isActive());
- // }}}---------------------------------------------------------------------------
-}
-
-TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart) {
- int uid = 9876;
- long configId = 12341;
-
- // Create config with 3 metrics:
- // Metric 1: Activate on 2 activations, 1 on boot, 1 immediate.
- // Metric 2: Activate on 2 activations, 1 on boot, 1 immediate.
- // Metric 3: Always active
- StatsdConfig config1;
- config1.set_id(configId);
- config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto jobStartMatcher = CreateStartScheduledJobAtomMatcher();
- auto jobFinishMatcher = CreateFinishScheduledJobAtomMatcher();
- *config1.add_atom_matcher() = wakelockAcquireMatcher;
- *config1.add_atom_matcher() = screenOnMatcher;
- *config1.add_atom_matcher() = jobStartMatcher;
- *config1.add_atom_matcher() = jobFinishMatcher;
-
- long metricId1 = 1234561;
- long metricId2 = 1234562;
- long metricId3 = 1234563;
-
- auto countMetric1 = config1.add_count_metric();
- countMetric1->set_id(metricId1);
- countMetric1->set_what(wakelockAcquireMatcher.id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- auto countMetric2 = config1.add_count_metric();
- countMetric2->set_id(metricId2);
- countMetric2->set_what(wakelockAcquireMatcher.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- auto countMetric3 = config1.add_count_metric();
- countMetric3->set_id(metricId3);
- countMetric3->set_what(wakelockAcquireMatcher.id());
- countMetric3->set_bucket(FIVE_MINUTES);
-
- // Metric 1 activates on boot for wakelock acquire, immediately for screen on.
- auto metric1Activation = config1.add_metric_activation();
- metric1Activation->set_metric_id(metricId1);
- auto metric1ActivationTrigger1 = metric1Activation->add_event_activation();
- metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric1ActivationTrigger1->set_ttl_seconds(100);
- metric1ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT);
- auto metric1ActivationTrigger2 = metric1Activation->add_event_activation();
- metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id());
- metric1ActivationTrigger2->set_ttl_seconds(200);
- metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
-
- // Metric 2 activates on boot for scheduled job start, immediately for scheduled job finish.
- auto metric2Activation = config1.add_metric_activation();
- metric2Activation->set_metric_id(metricId2);
- auto metric2ActivationTrigger1 = metric2Activation->add_event_activation();
- metric2ActivationTrigger1->set_atom_matcher_id(jobStartMatcher.id());
- metric2ActivationTrigger1->set_ttl_seconds(100);
- metric2ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT);
- auto metric2ActivationTrigger2 = metric2Activation->add_event_activation();
- metric2ActivationTrigger2->set_atom_matcher_id(jobFinishMatcher.id());
- metric2ActivationTrigger2->set_ttl_seconds(200);
- metric2ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
-
- // Send the config.
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- string serialized = config1.SerializeAsString();
- service->addConfigurationChecked(uid, configId, {serialized.begin(), serialized.end()});
-
- // Make sure the config is stored on disk. Otherwise, we will not reset on system server death.
- StatsdConfig tmpConfig;
- ConfigKey cfgKey1(uid, configId);
- EXPECT_TRUE(StorageManager::readConfigFromDisk(cfgKey1, &tmpConfig));
-
- // Metric 1 is not active.
- // Metric 2 is not active.
- // Metric 3 is active.
- // {{{---------------------------------------------------------------------------
- sp<StatsLogProcessor> processor = service->mProcessor;
- ASSERT_EQ(1, processor->mMetricsManagers.size());
- auto it = processor->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor->mMetricsManagers.end());
- auto& metricsManager1 = it->second;
- EXPECT_TRUE(metricsManager1->isActive());
- ASSERT_EQ(3, metricsManager1->mAllMetricProducers.size());
-
- auto& metricProducer1 = metricsManager1->mAllMetricProducers[0];
- EXPECT_EQ(metricId1, metricProducer1->getMetricId());
- EXPECT_FALSE(metricProducer1->isActive());
-
- auto& metricProducer2 = metricsManager1->mAllMetricProducers[1];
- EXPECT_EQ(metricId2, metricProducer2->getMetricId());
- EXPECT_FALSE(metricProducer2->isActive());
-
- auto& metricProducer3 = metricsManager1->mAllMetricProducers[2];
- EXPECT_EQ(metricId3, metricProducer3->getMetricId());
- EXPECT_TRUE(metricProducer3->isActive());
-
- // Check event activations.
- ASSERT_EQ(metricsManager1->mAllAtomMatchers.size(), 4);
- EXPECT_EQ(metricsManager1->mAllAtomMatchers[0]->getId(),
- metric1ActivationTrigger1->atom_matcher_id());
- const auto& activation1 = metricProducer1->mEventActivationMap.at(0);
- EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kNotActive, activation1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1->activationType);
-
- EXPECT_EQ(metricsManager1->mAllAtomMatchers[1]->getId(),
- metric1ActivationTrigger2->atom_matcher_id());
- const auto& activation2 = metricProducer1->mEventActivationMap.at(1);
- EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2->activationType);
-
- EXPECT_EQ(metricsManager1->mAllAtomMatchers[2]->getId(),
- metric2ActivationTrigger1->atom_matcher_id());
- const auto& activation3 = metricProducer2->mEventActivationMap.at(2);
- EXPECT_EQ(100 * NS_PER_SEC, activation3->ttl_ns);
- EXPECT_EQ(0, activation3->start_ns);
- EXPECT_EQ(kNotActive, activation3->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation3->activationType);
-
- EXPECT_EQ(metricsManager1->mAllAtomMatchers[3]->getId(),
- metric2ActivationTrigger2->atom_matcher_id());
- const auto& activation4 = metricProducer2->mEventActivationMap.at(3);
- EXPECT_EQ(200 * NS_PER_SEC, activation4->ttl_ns);
- EXPECT_EQ(0, activation4->start_ns);
- EXPECT_EQ(kNotActive, activation4->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation4->activationType);
- // }}}------------------------------------------------------------------------------
-
- // Trigger Activation 1 for Metric 1. Should activate on boot.
- // Trigger Activation 4 for Metric 2. Should activate immediately.
- int64_t configAddedTimeNs = metricsManager1->mLastReportTimeNs;
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent(
- 1 + configAddedTimeNs, attributionUids, attributionTags, "wl1");
- processor->OnLogEvent(event1.get());
-
- std::unique_ptr<LogEvent> event2 = CreateFinishScheduledJobEvent(
- 2 + configAddedTimeNs, attributionUids, attributionTags, "finish1");
- processor->OnLogEvent(event2.get());
-
- // Metric 1 is not active; Activation 1 set to kActiveOnBoot
- // Metric 2 is active. Activation 4 set to kActive
- // Metric 3 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_FALSE(metricProducer1->isActive());
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1->state);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
-
- EXPECT_TRUE(metricProducer2->isActive());
- EXPECT_EQ(0, activation3->start_ns);
- EXPECT_EQ(kNotActive, activation3->state);
- EXPECT_EQ(2 + configAddedTimeNs, activation4->start_ns);
- EXPECT_EQ(kActive, activation4->state);
-
- EXPECT_TRUE(metricProducer3->isActive());
- // }}}-----------------------------------------------------------------------------
-
- // Can't fake time with StatsService.
- // Lets get a time close to the system server death time and make sure it's sane.
- int64_t approximateSystemServerDeath = getElapsedRealtimeNs();
- EXPECT_TRUE(approximateSystemServerDeath > 2 + configAddedTimeNs);
- EXPECT_TRUE(approximateSystemServerDeath < NS_PER_SEC + configAddedTimeNs);
-
- // System server dies.
- service->statsCompanionServiceDiedImpl();
-
- // We should have a new metrics manager. Lets get it and ensure activation status is restored.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor->mMetricsManagers.size());
- it = processor->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor->mMetricsManagers.end());
- auto& metricsManager2 = it->second;
- EXPECT_TRUE(metricsManager2->isActive());
- ASSERT_EQ(3, metricsManager2->mAllMetricProducers.size());
-
- auto& metricProducer1001 = metricsManager2->mAllMetricProducers[0];
- EXPECT_EQ(metricId1, metricProducer1001->getMetricId());
- EXPECT_FALSE(metricProducer1001->isActive());
-
- auto& metricProducer1002 = metricsManager2->mAllMetricProducers[1];
- EXPECT_EQ(metricId2, metricProducer1002->getMetricId());
- EXPECT_TRUE(metricProducer1002->isActive());
-
- auto& metricProducer1003 = metricsManager2->mAllMetricProducers[2];
- EXPECT_EQ(metricId3, metricProducer1003->getMetricId());
- EXPECT_TRUE(metricProducer1003->isActive());
-
- // Check event activations.
- // Activation 1 is kActiveOnBoot.
- // Activation 2 and 3 are not active.
- // Activation 4 is active.
- ASSERT_EQ(metricsManager2->mAllAtomMatchers.size(), 4);
- EXPECT_EQ(metricsManager2->mAllAtomMatchers[0]->getId(),
- metric1ActivationTrigger1->atom_matcher_id());
- const auto& activation1001 = metricProducer1001->mEventActivationMap.at(0);
- EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns);
- EXPECT_EQ(0, activation1001->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1001->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1001->activationType);
-
- EXPECT_EQ(metricsManager2->mAllAtomMatchers[1]->getId(),
- metric1ActivationTrigger2->atom_matcher_id());
- const auto& activation1002 = metricProducer1001->mEventActivationMap.at(1);
- EXPECT_EQ(200 * NS_PER_SEC, activation1002->ttl_ns);
- EXPECT_EQ(0, activation1002->start_ns);
- EXPECT_EQ(kNotActive, activation1002->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1002->activationType);
-
- EXPECT_EQ(metricsManager2->mAllAtomMatchers[2]->getId(),
- metric2ActivationTrigger1->atom_matcher_id());
- const auto& activation1003 = metricProducer1002->mEventActivationMap.at(2);
- EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns);
- EXPECT_EQ(0, activation1003->start_ns);
- EXPECT_EQ(kNotActive, activation1003->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1003->activationType);
-
- EXPECT_EQ(metricsManager2->mAllAtomMatchers[3]->getId(),
- metric2ActivationTrigger2->atom_matcher_id());
- const auto& activation1004 = metricProducer1002->mEventActivationMap.at(3);
- EXPECT_EQ(200 * NS_PER_SEC, activation1004->ttl_ns);
- EXPECT_EQ(2 + configAddedTimeNs, activation1004->start_ns);
- EXPECT_EQ(kActive, activation1004->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1004->activationType);
- // }}}------------------------------------------------------------------------------
-
- // Clear the data stored on disk as a result of the system server death.
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey1, configAddedTimeNs + NS_PER_SEC, false, true, ADB_DUMP, FAST,
- &buffer);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogHostUid) {
- int hostUid = 20;
- int isolatedUid = 30;
- uint64_t eventTimeNs = 12355;
- int atomId = 89;
- int field1 = 90;
- int field2 = 28;
- sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
- ConfigKey cfgKey;
- StatsdConfig config = MakeConfig(false);
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
- shared_ptr<LogEvent> logEvent = makeUidLogEvent(atomId, eventTimeNs, hostUid, field1, field2);
-
- processor->OnLogEvent(logEvent.get());
-
- const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(field1, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(field2, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogIsolatedUid) {
- int hostUid = 20;
- int isolatedUid = 30;
- uint64_t eventTimeNs = 12355;
- int atomId = 89;
- int field1 = 90;
- int field2 = 28;
- sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
- ConfigKey cfgKey;
- StatsdConfig config = MakeConfig(false);
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
- shared_ptr<LogEvent> logEvent =
- makeUidLogEvent(atomId, eventTimeNs, isolatedUid, field1, field2);
-
- processor->OnLogEvent(logEvent.get());
-
- const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(field1, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(field2, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogHostUidAttributionChain) {
- int hostUid = 20;
- int isolatedUid = 30;
- uint64_t eventTimeNs = 12355;
- int atomId = 89;
- int field1 = 90;
- int field2 = 28;
- sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
- ConfigKey cfgKey;
- StatsdConfig config = MakeConfig(false);
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
- shared_ptr<LogEvent> logEvent = makeAttributionLogEvent(atomId, eventTimeNs, {hostUid, 200},
- {"tag1", "tag2"}, field1, field2);
-
- processor->OnLogEvent(logEvent.get());
-
- const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(200, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(field1, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(field2, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogIsolatedUidAttributionChain) {
- int hostUid = 20;
- int isolatedUid = 30;
- uint64_t eventTimeNs = 12355;
- int atomId = 89;
- int field1 = 90;
- int field2 = 28;
- sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
- ConfigKey cfgKey;
- StatsdConfig config = MakeConfig(false);
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
- shared_ptr<LogEvent> logEvent = makeAttributionLogEvent(atomId, eventTimeNs, {isolatedUid, 200},
- {"tag1", "tag2"}, field1, field2);
-
- processor->OnLogEvent(logEvent.get());
-
- const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(200, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(field1, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(field2, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest, TestDumpReportWithoutErasingDataDoesNotUpdateTimestamp) {
- int hostUid = 20;
- int isolatedUid = 30;
- sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
- ConfigKey key(3, 4);
-
- // TODO: All tests should not persist state on disk. This removes any reports that were present.
- ProtoOutputStream proto;
- StorageManager::appendConfigMetricsReport(key, &proto, /*erase data=*/true, /*isAdb=*/false);
-
- StatsdConfig config = MakeConfig(false);
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(1, 1, config, key, nullptr, 0, mockUidMap);
- vector<uint8_t> bytes;
-
- int64_t dumpTime1Ns = 1 * NS_PER_SEC;
- processor->onDumpReport(key, dumpTime1Ns, false /* include_current_bucket */,
- true /* erase_data */, ADB_DUMP, FAST, &bytes);
-
- ConfigMetricsReportList output;
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_EQ(output.reports_size(), 1);
- EXPECT_EQ(output.reports(0).current_report_elapsed_nanos(), dumpTime1Ns);
-
- int64_t dumpTime2Ns = 5 * NS_PER_SEC;
- processor->onDumpReport(key, dumpTime2Ns, false /* include_current_bucket */,
- false /* erase_data */, ADB_DUMP, FAST, &bytes);
-
- // Check that the dump report without clearing data is successful.
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_EQ(output.reports_size(), 1);
- EXPECT_EQ(output.reports(0).current_report_elapsed_nanos(), dumpTime2Ns);
- EXPECT_EQ(output.reports(0).last_report_elapsed_nanos(), dumpTime1Ns);
-
- int64_t dumpTime3Ns = 10 * NS_PER_SEC;
- processor->onDumpReport(key, dumpTime3Ns, false /* include_current_bucket */,
- true /* erase_data */, ADB_DUMP, FAST, &bytes);
-
- // Check that the previous dump report that didn't clear data did not overwrite the first dump's
- // timestamps.
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_EQ(output.reports_size(), 1);
- EXPECT_EQ(output.reports(0).current_report_elapsed_nanos(), dumpTime3Ns);
- EXPECT_EQ(output.reports(0).last_report_elapsed_nanos(), dumpTime1Ns);
-
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/StatsService_test.cpp b/cmds/statsd/tests/StatsService_test.cpp
deleted file mode 100644
index cc38c4a..0000000
--- a/cmds/statsd/tests/StatsService_test.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "StatsService.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-#include <android/binder_interface_utils.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-
-using namespace android;
-using namespace testing;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-using ::ndk::SharedRefBase;
-
-#ifdef __ANDROID__
-
-TEST(StatsServiceTest, TestAddConfig_simple) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- StatsdConfig config;
- config.set_id(12345);
- string serialized = config.SerializeAsString();
-
- EXPECT_TRUE(
- service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
-}
-
-TEST(StatsServiceTest, TestAddConfig_empty) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- string serialized = "";
-
- EXPECT_TRUE(
- service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
-}
-
-TEST(StatsServiceTest, TestAddConfig_invalid) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- string serialized = "Invalid config!";
-
- EXPECT_FALSE(
- service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
-}
-
-TEST(StatsServiceTest, TestGetUidFromArgs) {
- Vector<String8> args;
- args.push(String8("-1"));
- args.push(String8("0"));
- args.push(String8("1"));
- args.push(String8("a1"));
- args.push(String8(""));
-
- int32_t uid;
-
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- service->mEngBuild = true;
-
- // "-1"
- EXPECT_FALSE(service->getUidFromArgs(args, 0, uid));
-
- // "0"
- EXPECT_TRUE(service->getUidFromArgs(args, 1, uid));
- EXPECT_EQ(0, uid);
-
- // "1"
- EXPECT_TRUE(service->getUidFromArgs(args, 2, uid));
- EXPECT_EQ(1, uid);
-
- // "a1"
- EXPECT_FALSE(service->getUidFromArgs(args, 3, uid));
-
- // ""
- EXPECT_FALSE(service->getUidFromArgs(args, 4, uid));
-
- // For a non-userdebug, uid "1" cannot be impersonated.
- service->mEngBuild = false;
- EXPECT_FALSE(service->getUidFromArgs(args, 2, uid));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp
deleted file mode 100644
index 293e8ed..0000000
--- a/cmds/statsd/tests/UidMap_test.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "packages/UidMap.h"
-#include "StatsLogProcessor.h"
-#include "config/ConfigKey.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "hash.h"
-#include "statslog_statsdtest.h"
-#include "statsd_test_util.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-
-using namespace android;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-using android::util::ProtoReader;
-
-#ifdef __ANDROID__
-const string kApp1 = "app1.sharing.1";
-const string kApp2 = "app2.sharing.1";
-
-TEST(UidMapTest, TestIsolatedUID) {
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- // Construct the processor with a dummy sendBroadcast function that does nothing.
- StatsLogProcessor p(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [](const ConfigKey& key) { return true; },
- [](const int&, const vector<int64_t>&) { return true; });
-
- std::unique_ptr<LogEvent> addEvent = CreateIsolatedUidChangedEvent(
- 1 /*timestamp*/, 100 /*hostUid*/, 101 /*isolatedUid*/, 1 /*is_create*/);
- EXPECT_EQ(101, m->getHostUidOrSelf(101));
- p.OnLogEvent(addEvent.get());
- EXPECT_EQ(100, m->getHostUidOrSelf(101));
-
- std::unique_ptr<LogEvent> removeEvent = CreateIsolatedUidChangedEvent(
- 1 /*timestamp*/, 100 /*hostUid*/, 101 /*isolatedUid*/, 0 /*is_create*/);
- p.OnLogEvent(removeEvent.get());
- EXPECT_EQ(101, m->getHostUidOrSelf(101));
-}
-
-TEST(UidMapTest, TestMatching) {
- UidMap m;
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> apps;
- vector<String16> versionStrings;
- vector<String16> installers;
-
- uids.push_back(1000);
- uids.push_back(1000);
- versionStrings.push_back(String16("v1"));
- versionStrings.push_back(String16("v1"));
- installers.push_back(String16(""));
- installers.push_back(String16(""));
- apps.push_back(String16(kApp1.c_str()));
- apps.push_back(String16(kApp2.c_str()));
- versions.push_back(4);
- versions.push_back(5);
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
- EXPECT_TRUE(m.hasApp(1000, kApp1));
- EXPECT_TRUE(m.hasApp(1000, kApp2));
- EXPECT_FALSE(m.hasApp(1000, "not.app"));
-
- std::set<string> name_set = m.getAppNamesFromUid(1000u, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 2u);
- EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
- name_set = m.getAppNamesFromUid(12345, true /* returnNormalized */);
- EXPECT_TRUE(name_set.empty());
-}
-
-TEST(UidMapTest, TestAddAndRemove) {
- UidMap m;
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> apps;
- vector<String16> versionStrings;
- vector<String16> installers;
-
- uids.push_back(1000);
- uids.push_back(1000);
- versionStrings.push_back(String16("v1"));
- versionStrings.push_back(String16("v1"));
- installers.push_back(String16(""));
- installers.push_back(String16(""));
- apps.push_back(String16(kApp1.c_str()));
- apps.push_back(String16(kApp2.c_str()));
- versions.push_back(4);
- versions.push_back(5);
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 2u);
- EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
- // Update the app1 version.
- m.updateApp(2, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""));
- EXPECT_EQ(40, m.getAppVersion(1000, kApp1));
-
- name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 2u);
- EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
- m.removeApp(3, String16(kApp1.c_str()), 1000);
- EXPECT_FALSE(m.hasApp(1000, kApp1));
- EXPECT_TRUE(m.hasApp(1000, kApp2));
- name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 1u);
- EXPECT_TRUE(name_set.find(kApp1) == name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
- // Remove app2.
- m.removeApp(4, String16(kApp2.c_str()), 1000);
- EXPECT_FALSE(m.hasApp(1000, kApp1));
- EXPECT_FALSE(m.hasApp(1000, kApp2));
- name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- EXPECT_TRUE(name_set.empty());
-}
-
-TEST(UidMapTest, TestUpdateApp) {
- UidMap m;
- m.updateMap(1, {1000, 1000}, {4, 5}, {String16("v4"), String16("v5")},
- {String16(kApp1.c_str()), String16(kApp2.c_str())}, {String16(""), String16("")});
- std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 2u);
- EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
- // Adds a new name for uid 1000.
- m.updateApp(2, String16("NeW_aPP1_NAmE"), 1000, 40, String16("v40"), String16(""));
- name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 3u);
- EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
- EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
- EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
-
- // This name is also reused by another uid 2000.
- m.updateApp(3, String16("NeW_aPP1_NAmE"), 2000, 1, String16("v1"), String16(""));
- name_set = m.getAppNamesFromUid(2000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 1u);
- EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
- EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
-}
-
-static void protoOutputStreamToUidMapping(ProtoOutputStream* proto, UidMapping* results) {
- vector<uint8_t> bytes;
- bytes.resize(proto->size());
- size_t pos = 0;
- sp<ProtoReader> reader = proto->data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
- results->ParseFromArray(bytes.data(), bytes.size());
-}
-
-// Test that uid map returns at least one snapshot even if we already obtained
-// this snapshot from a previous call to getData.
-TEST(UidMapTest, TestOutputIncludesAtLeastOneSnapshot) {
- UidMap m;
- // Initialize single config key.
- ConfigKey config1(1, StringToId("config1"));
- m.OnConfigUpdated(config1);
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> apps;
- vector<String16> versionStrings;
- vector<String16> installers;
- uids.push_back(1000);
- apps.push_back(String16(kApp2.c_str()));
- versionStrings.push_back(String16("v1"));
- installers.push_back(String16(""));
- versions.push_back(5);
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- // Set the last timestamp for this config key to be newer.
- m.mLastUpdatePerConfigKey[config1] = 2;
-
- ProtoOutputStream proto;
- m.appendUidMap(3, config1, nullptr, true, true, &proto);
-
- // Check there's still a uidmap attached this one.
- UidMapping results;
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
- EXPECT_EQ("v1", results.snapshots(0).package_info(0).version_string());
-}
-
-TEST(UidMapTest, TestRemovedAppRetained) {
- UidMap m;
- // Initialize single config key.
- ConfigKey config1(1, StringToId("config1"));
- m.OnConfigUpdated(config1);
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> versionStrings;
- vector<String16> installers;
- vector<String16> apps;
- uids.push_back(1000);
- apps.push_back(String16(kApp2.c_str()));
- versions.push_back(5);
- versionStrings.push_back(String16("v5"));
- installers.push_back(String16(""));
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
- m.removeApp(2, String16(kApp2.c_str()), 1000);
-
- ProtoOutputStream proto;
- m.appendUidMap(3, config1, nullptr, true, true, &proto);
-
- // Snapshot should still contain this item as deleted.
- UidMapping results;
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots(0).package_info_size());
- EXPECT_EQ(true, results.snapshots(0).package_info(0).deleted());
-}
-
-TEST(UidMapTest, TestRemovedAppOverGuardrail) {
- UidMap m;
- // Initialize single config key.
- ConfigKey config1(1, StringToId("config1"));
- m.OnConfigUpdated(config1);
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> versionStrings;
- vector<String16> installers;
- vector<String16> apps;
- const int maxDeletedApps = StatsdStats::kMaxDeletedAppsInUidMap;
- for (int j = 0; j < maxDeletedApps + 10; j++) {
- uids.push_back(j);
- apps.push_back(String16(kApp1.c_str()));
- versions.push_back(j);
- versionStrings.push_back(String16("v"));
- installers.push_back(String16(""));
- }
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- // First, verify that we have the expected number of items.
- UidMapping results;
- ProtoOutputStream proto;
- m.appendUidMap(3, config1, nullptr, true, true, &proto);
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(maxDeletedApps + 10, results.snapshots(0).package_info_size());
-
- // Now remove all the apps.
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
- for (int j = 0; j < maxDeletedApps + 10; j++) {
- m.removeApp(4, String16(kApp1.c_str()), j);
- }
-
- proto.clear();
- m.appendUidMap(5, config1, nullptr, true, true, &proto);
- // Snapshot drops the first nine items.
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(maxDeletedApps, results.snapshots(0).package_info_size());
-}
-
-TEST(UidMapTest, TestClearingOutput) {
- UidMap m;
-
- ConfigKey config1(1, StringToId("config1"));
- ConfigKey config2(1, StringToId("config2"));
-
- m.OnConfigUpdated(config1);
-
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> versionStrings;
- vector<String16> installers;
- vector<String16> apps;
- uids.push_back(1000);
- uids.push_back(1000);
- apps.push_back(String16(kApp1.c_str()));
- apps.push_back(String16(kApp2.c_str()));
- versions.push_back(4);
- versions.push_back(5);
- versionStrings.push_back(String16("v4"));
- versionStrings.push_back(String16("v5"));
- installers.push_back(String16(""));
- installers.push_back(String16(""));
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- ProtoOutputStream proto;
- m.appendUidMap(2, config1, nullptr, true, true, &proto);
- UidMapping results;
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
-
- // We have to keep at least one snapshot in memory at all times.
- proto.clear();
- m.appendUidMap(2, config1, nullptr, true, true, &proto);
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
-
- // Now add another configuration.
- m.OnConfigUpdated(config2);
- m.updateApp(5, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""));
- ASSERT_EQ(1U, m.mChanges.size());
- proto.clear();
- m.appendUidMap(6, config1, nullptr, true, true, &proto);
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
- ASSERT_EQ(1, results.changes_size());
- ASSERT_EQ(1U, m.mChanges.size());
-
- // Add another delta update.
- m.updateApp(7, String16(kApp2.c_str()), 1001, 41, String16("v41"), String16(""));
- ASSERT_EQ(2U, m.mChanges.size());
-
- // We still can't remove anything.
- proto.clear();
- m.appendUidMap(8, config1, nullptr, true, true, &proto);
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
- ASSERT_EQ(1, results.changes_size());
- ASSERT_EQ(2U, m.mChanges.size());
-
- proto.clear();
- m.appendUidMap(9, config2, nullptr, true, true, &proto);
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
- ASSERT_EQ(2, results.changes_size());
- // At this point both should be cleared.
- ASSERT_EQ(0U, m.mChanges.size());
-}
-
-TEST(UidMapTest, TestMemoryComputed) {
- UidMap m;
-
- ConfigKey config1(1, StringToId("config1"));
- m.OnConfigUpdated(config1);
-
- size_t startBytes = m.mBytesUsed;
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> apps;
- vector<String16> versionStrings;
- vector<String16> installers;
- uids.push_back(1000);
- apps.push_back(String16(kApp1.c_str()));
- versions.push_back(1);
- versionStrings.push_back(String16("v1"));
- installers.push_back(String16(""));
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- m.updateApp(3, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""));
-
- ProtoOutputStream proto;
- vector<uint8_t> bytes;
- m.appendUidMap(2, config1, nullptr, true, true, &proto);
- size_t prevBytes = m.mBytesUsed;
-
- m.appendUidMap(4, config1, nullptr, true, true, &proto);
- EXPECT_TRUE(m.mBytesUsed < prevBytes);
-}
-
-TEST(UidMapTest, TestMemoryGuardrail) {
- UidMap m;
- string buf;
-
- ConfigKey config1(1, StringToId("config1"));
- m.OnConfigUpdated(config1);
-
- size_t startBytes = m.mBytesUsed;
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> versionStrings;
- vector<String16> installers;
- vector<String16> apps;
- for (int i = 0; i < 100; i++) {
- uids.push_back(1);
- buf = "EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY." + to_string(i);
- apps.push_back(String16(buf.c_str()));
- versions.push_back(1);
- versionStrings.push_back(String16("v1"));
- installers.push_back(String16(""));
- }
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- m.updateApp(3, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 2,
- String16("v2"), String16(""));
- ASSERT_EQ(1U, m.mChanges.size());
-
- // Now force deletion by limiting the memory to hold one delta change.
- m.maxBytesOverride = 120; // Since the app string alone requires >45 characters.
- m.updateApp(5, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 4,
- String16("v4"), String16(""));
- ASSERT_EQ(1U, m.mChanges.size());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
deleted file mode 100644
index 64ea219..0000000
--- a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/anomaly/AlarmTracker.h"
-
-#include <gtest/gtest.h>
-#include <log/log_time.h>
-#include <stdio.h>
-#include <vector>
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::shared_ptr;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-TEST(AlarmTrackerTest, TestTriggerTimestamp) {
- sp<AlarmMonitor> subscriberAlarmMonitor =
- new AlarmMonitor(100,
- [](const shared_ptr<IStatsCompanionService>&, int64_t){},
- [](const shared_ptr<IStatsCompanionService>&){});
- Alarm alarm;
- alarm.set_offset_millis(15 * MS_PER_SEC);
- alarm.set_period_millis(60 * 60 * MS_PER_SEC); // 1hr
- int64_t startMillis = 100000000 * MS_PER_SEC;
- int64_t nextAlarmTime = startMillis / MS_PER_SEC + 15;
- AlarmTracker tracker(startMillis, startMillis, alarm, kConfigKey, subscriberAlarmMonitor);
-
- EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
-
- uint64_t currentTimeSec = startMillis / MS_PER_SEC + 10;
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarmSet =
- subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- EXPECT_TRUE(firedAlarmSet.empty());
- tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
- EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
- EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-
- currentTimeSec = startMillis / MS_PER_SEC + 7000;
- nextAlarmTime = startMillis / MS_PER_SEC + 15 + 2 * 60 * 60;
- firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- ASSERT_EQ(firedAlarmSet.size(), 1u);
- tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
- EXPECT_TRUE(firedAlarmSet.empty());
- EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
- EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-
- // Alarm fires exactly on time.
- currentTimeSec = startMillis / MS_PER_SEC + 15 + 2 * 60 * 60;
- nextAlarmTime = startMillis / MS_PER_SEC + 15 + 3 * 60 * 60;
- firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- ASSERT_EQ(firedAlarmSet.size(), 1u);
- tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
- EXPECT_TRUE(firedAlarmSet.empty());
- EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
- EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-
- // Alarm fires exactly 1 period late.
- currentTimeSec = startMillis / MS_PER_SEC + 15 + 4 * 60 * 60;
- nextAlarmTime = startMillis / MS_PER_SEC + 15 + 5 * 60 * 60;
- firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- ASSERT_EQ(firedAlarmSet.size(), 1u);
- tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
- EXPECT_TRUE(firedAlarmSet.empty());
- EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
- EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
deleted file mode 100644
index 0cc8af1..0000000
--- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/anomaly/AnomalyTracker.h"
-
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-MetricDimensionKey getMockMetricDimensionKey(int key, string value) {
- int pos[] = {key, 0, 0};
- HashableDimensionKey dim;
- dim.addValue(FieldValue(Field(1, pos, 0), Value(value)));
- return MetricDimensionKey(dim, DEFAULT_DIMENSION_KEY);
-}
-
-void AddValueToBucket(const std::vector<std::pair<MetricDimensionKey, long>>& key_value_pair_list,
- std::shared_ptr<DimToValMap> bucket) {
- for (auto itr = key_value_pair_list.begin(); itr != key_value_pair_list.end(); itr++) {
- (*bucket)[itr->first] += itr->second;
- }
-}
-
-std::shared_ptr<DimToValMap> MockBucket(
- const std::vector<std::pair<MetricDimensionKey, long>>& key_value_pair_list) {
- std::shared_ptr<DimToValMap> bucket = std::make_shared<DimToValMap>();
- AddValueToBucket(key_value_pair_list, bucket);
- return bucket;
-}
-
-// Returns the value, for the given key, in that bucket, or 0 if not present.
-int64_t getBucketValue(const std::shared_ptr<DimToValMap>& bucket,
- const MetricDimensionKey& key) {
- const auto& itr = bucket->find(key);
- if (itr != bucket->end()) {
- return itr->second;
- }
- return 0;
-}
-
-// Returns true if keys in trueList are detected as anomalies and keys in falseList are not.
-bool detectAnomaliesPass(AnomalyTracker& tracker,
- const int64_t& bucketNum,
- const std::shared_ptr<DimToValMap>& currentBucket,
- const std::set<const MetricDimensionKey>& trueList,
- const std::set<const MetricDimensionKey>& falseList) {
- for (const MetricDimensionKey& key : trueList) {
- if (!tracker.detectAnomaly(bucketNum, key, getBucketValue(currentBucket, key))) {
- return false;
- }
- }
- for (const MetricDimensionKey& key : falseList) {
- if (tracker.detectAnomaly(bucketNum, key, getBucketValue(currentBucket, key))) {
- return false;
- }
- }
- return true;
-}
-
-// Calls tracker.detectAndDeclareAnomaly on each key in the bucket.
-void detectAndDeclareAnomalies(AnomalyTracker& tracker,
- const int64_t& bucketNum,
- const std::shared_ptr<DimToValMap>& bucket,
- const int64_t& eventTimestamp) {
- for (const auto& kv : *bucket) {
- tracker.detectAndDeclareAnomaly(eventTimestamp, bucketNum, 0 /*metric_id*/, kv.first,
- kv.second);
- }
-}
-
-// Asserts that the refractory time for each key in timestamps is the corresponding
-// timestamp (in ns) + refractoryPeriodSec.
-// If a timestamp value is negative, instead asserts that the refractory period is inapplicable
-// (either non-existant or already past).
-void checkRefractoryTimes(AnomalyTracker& tracker,
- const int64_t& currTimestampNs,
- const int32_t& refractoryPeriodSec,
- const std::unordered_map<MetricDimensionKey, int64_t>& timestamps) {
- for (const auto& kv : timestamps) {
- if (kv.second < 0) {
- // Make sure that, if there is a refractory period, it is already past.
- EXPECT_LT(tracker.getRefractoryPeriodEndsSec(kv.first) * NS_PER_SEC,
- (uint64_t)currTimestampNs)
- << "Failure was at currTimestampNs " << currTimestampNs;
- } else {
- EXPECT_EQ(tracker.getRefractoryPeriodEndsSec(kv.first),
- std::ceil(1.0 * kv.second / NS_PER_SEC) + refractoryPeriodSec)
- << "Failure was at currTimestampNs " << currTimestampNs;
- }
- }
-}
-
-TEST(AnomalyTrackerTest, TestConsecutiveBuckets) {
- const int64_t bucketSizeNs = 30 * NS_PER_SEC;
- const int32_t refractoryPeriodSec = 2 * bucketSizeNs / NS_PER_SEC;
- Alert alert;
- alert.set_num_buckets(3);
- alert.set_refractory_period_secs(refractoryPeriodSec);
- alert.set_trigger_if_sum_gt(2);
-
- AnomalyTracker anomalyTracker(alert, kConfigKey);
- MetricDimensionKey keyA = getMockMetricDimensionKey(1, "a");
- MetricDimensionKey keyB = getMockMetricDimensionKey(1, "b");
- MetricDimensionKey keyC = getMockMetricDimensionKey(1, "c");
-
- int64_t eventTimestamp0 = 10 * NS_PER_SEC;
- int64_t eventTimestamp1 = bucketSizeNs + 11 * NS_PER_SEC;
- int64_t eventTimestamp2 = 2 * bucketSizeNs + 12 * NS_PER_SEC;
- int64_t eventTimestamp3 = 3 * bucketSizeNs + 13 * NS_PER_SEC;
- int64_t eventTimestamp4 = 4 * bucketSizeNs + 14 * NS_PER_SEC;
- int64_t eventTimestamp5 = 5 * bucketSizeNs + 5 * NS_PER_SEC;
- int64_t eventTimestamp6 = 6 * bucketSizeNs + 16 * NS_PER_SEC;
-
- std::shared_ptr<DimToValMap> bucket0 = MockBucket({{keyA, 1}, {keyB, 2}, {keyC, 1}});
- std::shared_ptr<DimToValMap> bucket1 = MockBucket({{keyA, 1}});
- std::shared_ptr<DimToValMap> bucket2 = MockBucket({{keyB, 1}});
- std::shared_ptr<DimToValMap> bucket3 = MockBucket({{keyA, 2}});
- std::shared_ptr<DimToValMap> bucket4 = MockBucket({{keyB, 5}});
- std::shared_ptr<DimToValMap> bucket5 = MockBucket({{keyA, 2}});
- std::shared_ptr<DimToValMap> bucket6 = MockBucket({{keyA, 2}});
-
- // Start time with no events.
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0u);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, -1LL);
-
- // Event from bucket #0 occurs.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 0, bucket0, {}, {keyA, keyB, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 0, bucket0, eventTimestamp1);
- checkRefractoryTimes(anomalyTracker, eventTimestamp0, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}});
-
- // Adds past bucket #0
- anomalyTracker.addPastBucket(bucket0, 0);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3u);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 0LL);
-
- // Event from bucket #1 occurs.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 1, bucket1, {}, {keyA, keyB, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 1, bucket1, eventTimestamp1);
- checkRefractoryTimes(anomalyTracker, eventTimestamp1, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}});
-
- // Adds past bucket #0 again. The sum does not change.
- anomalyTracker.addPastBucket(bucket0, 0);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3u);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 0LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 1, bucket1, {}, {keyA, keyB, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 1, bucket1, eventTimestamp1 + 1);
- checkRefractoryTimes(anomalyTracker, eventTimestamp1, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}});
-
- // Adds past bucket #1.
- anomalyTracker.addPastBucket(bucket1, 1);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 1L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-
- // Event from bucket #2 occurs. New anomaly on keyB.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 2, bucket2, {keyB}, {keyA, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 2, bucket2, eventTimestamp2);
- checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}});
-
- // Adds past bucket #1 again. Nothing changes.
- anomalyTracker.addPastBucket(bucket1, 1);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 1L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- // Event from bucket #2 occurs (again).
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 2, bucket2, {keyB}, {keyA, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 2, bucket2, eventTimestamp2 + 1);
- checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}});
-
- // Adds past bucket #2.
- anomalyTracker.addPastBucket(bucket2, 2);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 2L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
-
- // Event from bucket #3 occurs. New anomaly on keyA.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 3, bucket3, {keyA}, {keyB, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 3, bucket3, eventTimestamp3);
- checkRefractoryTimes(anomalyTracker, eventTimestamp3, refractoryPeriodSec,
- {{keyA, eventTimestamp3}, {keyB, eventTimestamp2}, {keyC, -1}});
-
- // Adds bucket #3.
- anomalyTracker.addPastBucket(bucket3, 3L);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 3L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
-
- // Event from bucket #4 occurs. New anomaly on keyB.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 4, bucket4, {keyB}, {keyA, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 4, bucket4, eventTimestamp4);
- checkRefractoryTimes(anomalyTracker, eventTimestamp4, refractoryPeriodSec,
- {{keyA, eventTimestamp3}, {keyB, eventTimestamp4}, {keyC, -1}});
-
- // Adds bucket #4.
- anomalyTracker.addPastBucket(bucket4, 4);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 4L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 5LL);
-
- // Event from bucket #5 occurs. New anomaly on keyA, which is still in refractory.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 5, bucket5, {keyA, keyB}, {keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 5, bucket5, eventTimestamp5);
- checkRefractoryTimes(anomalyTracker, eventTimestamp5, refractoryPeriodSec,
- {{keyA, eventTimestamp3}, {keyB, eventTimestamp4}, {keyC, -1}});
-
- // Adds bucket #5.
- anomalyTracker.addPastBucket(bucket5, 5);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 5L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 5LL);
-
- // Event from bucket #6 occurs. New anomaly on keyA, which is now out of refractory.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 6, bucket6, {keyA, keyB}, {keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 6, bucket6, eventTimestamp6);
- checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
- {{keyA, eventTimestamp6}, {keyB, eventTimestamp4}, {keyC, -1}});
-}
-
-TEST(AnomalyTrackerTest, TestSparseBuckets) {
- const int64_t bucketSizeNs = 30 * NS_PER_SEC;
- const int32_t refractoryPeriodSec = 2 * bucketSizeNs / NS_PER_SEC;
- Alert alert;
- alert.set_num_buckets(3);
- alert.set_refractory_period_secs(refractoryPeriodSec);
- alert.set_trigger_if_sum_gt(2);
-
- AnomalyTracker anomalyTracker(alert, kConfigKey);
- MetricDimensionKey keyA = getMockMetricDimensionKey(1, "a");
- MetricDimensionKey keyB = getMockMetricDimensionKey(1, "b");
- MetricDimensionKey keyC = getMockMetricDimensionKey(1, "c");
- MetricDimensionKey keyD = getMockMetricDimensionKey(1, "d");
- MetricDimensionKey keyE = getMockMetricDimensionKey(1, "e");
-
- std::shared_ptr<DimToValMap> bucket9 = MockBucket({{keyA, 1}, {keyB, 2}, {keyC, 1}});
- std::shared_ptr<DimToValMap> bucket16 = MockBucket({{keyB, 4}});
- std::shared_ptr<DimToValMap> bucket18 = MockBucket({{keyB, 1}, {keyC, 1}});
- std::shared_ptr<DimToValMap> bucket20 = MockBucket({{keyB, 3}, {keyC, 1}});
- std::shared_ptr<DimToValMap> bucket25 = MockBucket({{keyD, 1}});
- std::shared_ptr<DimToValMap> bucket28 = MockBucket({{keyE, 2}});
-
- int64_t eventTimestamp1 = bucketSizeNs * 8 + 1;
- int64_t eventTimestamp2 = bucketSizeNs * 15 + 11;
- int64_t eventTimestamp3 = bucketSizeNs * 17 + 1;
- int64_t eventTimestamp4 = bucketSizeNs * 19 + 2;
- int64_t eventTimestamp5 = bucketSizeNs * 24 + 3;
- int64_t eventTimestamp6 = bucketSizeNs * 27 + 3;
-
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, -1LL);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 9, bucket9, {}, {keyA, keyB, keyC, keyD}));
- detectAndDeclareAnomalies(anomalyTracker, 9, bucket9, eventTimestamp1);
- checkRefractoryTimes(anomalyTracker, eventTimestamp1, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Add past bucket #9
- anomalyTracker.addPastBucket(bucket9, 9);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 9L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 16, bucket16, {keyB}, {keyA, keyC, keyD}));
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L);
- detectAndDeclareAnomalies(anomalyTracker, 16, bucket16, eventTimestamp2);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L);
- checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Add past bucket #16
- anomalyTracker.addPastBucket(bucket16, 16);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 16L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 18, bucket18, {keyB}, {keyA, keyC, keyD}));
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
- // Within refractory period.
- detectAndDeclareAnomalies(anomalyTracker, 18, bucket18, eventTimestamp3);
- checkRefractoryTimes(anomalyTracker, eventTimestamp3, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
-
- // Add past bucket #18
- anomalyTracker.addPastBucket(bucket18, 18);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 18L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 20, bucket20, {keyB}, {keyA, keyC, keyD}));
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 19L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- detectAndDeclareAnomalies(anomalyTracker, 20, bucket20, eventTimestamp4);
- checkRefractoryTimes(anomalyTracker, eventTimestamp4, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Add bucket #18 again. Nothing changes.
- anomalyTracker.addPastBucket(bucket18, 18);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 19L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 20, bucket20, {keyB}, {keyA, keyC, keyD}));
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- detectAndDeclareAnomalies(anomalyTracker, 20, bucket20, eventTimestamp4 + 1);
- // Within refractory period.
- checkRefractoryTimes(anomalyTracker, eventTimestamp4 + 1, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Add past bucket #20
- anomalyTracker.addPastBucket(bucket20, 20);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 20L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 3LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 25, bucket25, {}, {keyA, keyB, keyC, keyD}));
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 24L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- detectAndDeclareAnomalies(anomalyTracker, 25, bucket25, eventTimestamp5);
- checkRefractoryTimes(anomalyTracker, eventTimestamp5, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Add past bucket #25
- anomalyTracker.addPastBucket(bucket25, 25);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 25L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyD), 1LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {},
- {keyA, keyB, keyC, keyD, keyE}));
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Updates current bucket #28.
- (*bucket28)[keyE] = 5;
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {keyE},
- {keyA, keyB, keyC, keyD}));
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6 + 7);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, eventTimestamp6 + 7}});
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp b/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
deleted file mode 100644
index 1d501fd..0000000
--- a/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "condition/condition_util.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-#include <vector>
-
-using namespace android::os::statsd;
-using std::vector;
-
-#ifdef __ANDROID__
-
-TEST(ConditionTrackerTest, TestUnknownCondition) {
- LogicalOperation operation = LogicalOperation::AND;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
- children.push_back(2);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kUnknown);
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kTrue);
-
- EXPECT_EQ(evaluateCombinationCondition(children, operation, conditionResults),
- ConditionState::kUnknown);
-}
-
-TEST(ConditionTrackerTest, TestAndCondition) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::AND;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
- children.push_back(2);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kTrue);
-
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kTrue);
-
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-TEST(ConditionTrackerTest, TestOrCondition) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::OR;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
- children.push_back(2);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kTrue);
-
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kFalse);
-
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-TEST(ConditionTrackerTest, TestNotCondition) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NOT;
-
- vector<int> children;
- children.push_back(0);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kTrue);
-
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kFalse);
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
- children.clear();
- conditionResults.clear();
- EXPECT_EQ(evaluateCombinationCondition(children, operation, conditionResults),
- ConditionState::kUnknown);
-}
-
-TEST(ConditionTrackerTest, TestNandCondition) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NAND;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kFalse);
-
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kFalse);
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kTrue);
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-TEST(ConditionTrackerTest, TestNorCondition) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NOR;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kFalse);
-
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kFalse);
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kTrue);
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/condition/ConditionTimer_test.cpp b/cmds/statsd/tests/condition/ConditionTimer_test.cpp
deleted file mode 100644
index ea02cd3..0000000
--- a/cmds/statsd/tests/condition/ConditionTimer_test.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/condition/ConditionTimer.h"
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static int64_t time_base = 10;
-static int64_t ct_start_time = 200;
-
-TEST(ConditionTimerTest, TestTimer_Inital_False) {
- ConditionTimer timer(false, time_base);
- EXPECT_EQ(false, timer.mCondition);
- EXPECT_EQ(0, timer.mTimerNs);
-
- EXPECT_EQ(0, timer.newBucketStart(ct_start_time));
- EXPECT_EQ(0, timer.mTimerNs);
-
- timer.onConditionChanged(true, ct_start_time + 5);
- EXPECT_EQ(ct_start_time + 5, timer.mLastConditionTrueTimestampNs);
- EXPECT_EQ(true, timer.mCondition);
-
- EXPECT_EQ(95, timer.newBucketStart(ct_start_time + 100));
- EXPECT_EQ(ct_start_time + 100, timer.mLastConditionTrueTimestampNs);
- EXPECT_EQ(true, timer.mCondition);
-}
-
-TEST(ConditionTimerTest, TestTimer_Inital_True) {
- ConditionTimer timer(true, time_base);
- EXPECT_EQ(true, timer.mCondition);
- EXPECT_EQ(0, timer.mTimerNs);
-
- EXPECT_EQ(ct_start_time - time_base, timer.newBucketStart(ct_start_time));
- EXPECT_EQ(true, timer.mCondition);
- EXPECT_EQ(0, timer.mTimerNs);
- EXPECT_EQ(ct_start_time, timer.mLastConditionTrueTimestampNs);
-
- timer.onConditionChanged(false, ct_start_time + 5);
- EXPECT_EQ(5, timer.mTimerNs);
-
- EXPECT_EQ(5, timer.newBucketStart(ct_start_time + 100));
- EXPECT_EQ(0, timer.mTimerNs);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
deleted file mode 100644
index 07b5311b..0000000
--- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
+++ /dev/null
@@ -1,739 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/condition/SimpleConditionTracker.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include <vector>
-#include <numeric>
-
-using std::map;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-
-const int ATTRIBUTION_NODE_FIELD_ID = 1;
-const int ATTRIBUTION_UID_FIELD_ID = 1;
-const int TAG_ID = 1;
-
-SimplePredicate getWakeLockHeldCondition(bool countNesting, bool defaultFalse,
- bool outputSlicedUid, Position position) {
- SimplePredicate simplePredicate;
- simplePredicate.set_start(StringToId("WAKE_LOCK_ACQUIRE"));
- simplePredicate.set_stop(StringToId("WAKE_LOCK_RELEASE"));
- simplePredicate.set_stop_all(StringToId("RELEASE_ALL"));
- if (outputSlicedUid) {
- simplePredicate.mutable_dimensions()->set_field(TAG_ID);
- simplePredicate.mutable_dimensions()->add_child()->set_field(ATTRIBUTION_NODE_FIELD_ID);
- simplePredicate.mutable_dimensions()->mutable_child(0)->set_position(position);
- simplePredicate.mutable_dimensions()->mutable_child(0)->add_child()->set_field(
- ATTRIBUTION_UID_FIELD_ID);
- }
-
- simplePredicate.set_count_nesting(countNesting);
- simplePredicate.set_initial_value(defaultFalse ? SimplePredicate_InitialValue_FALSE
- : SimplePredicate_InitialValue_UNKNOWN);
- return simplePredicate;
-}
-
-void makeWakeLockEvent(LogEvent* logEvent, uint32_t atomId, uint64_t timestamp,
- const vector<int>& uids, const string& wl, int acquire) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
- vector<std::string> tags(uids.size()); // vector of empty strings
- writeAttribution(statsEvent, uids, tags);
-
- AStatsEvent_writeString(statsEvent, wl.c_str());
- AStatsEvent_writeInt32(statsEvent, acquire);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-} // anonymous namespace
-
-
-std::map<int64_t, HashableDimensionKey> getWakeLockQueryKey(
- const Position position,
- const std::vector<int> &uids, const string& conditionName) {
- std::map<int64_t, HashableDimensionKey> outputKeyMap;
- std::vector<int> uid_indexes;
- int pos[] = {1, 1, 1};
- int depth = 2;
- Field field(1, pos, depth);
- switch(position) {
- case Position::FIRST:
- uid_indexes.push_back(0);
- break;
- case Position::LAST:
- uid_indexes.push_back(uids.size() - 1);
- field.setField(0x02018001);
- break;
- case Position::ANY:
- uid_indexes.resize(uids.size());
- std::iota(uid_indexes.begin(), uid_indexes.end(), 0);
- field.setField(0x02010001);
- break;
- default:
- break;
- }
-
- for (const int idx : uid_indexes) {
- Value value((int32_t)uids[idx]);
- HashableDimensionKey dim;
- dim.addValue(FieldValue(field, value));
- outputKeyMap[StringToId(conditionName)] = dim;
- }
- return outputKeyMap;
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedInitialValueFalse) {
- SimplePredicate simplePredicate;
- simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
- simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
- simplePredicate.set_count_nesting(false);
- simplePredicate.set_initial_value(SimplePredicate_InitialValue_FALSE);
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"),
- 0 /*tracker index*/, simplePredicate,
- trackerNameIndexMap);
-
- ConditionKey queryKey;
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-
- // Check that initial condition is false.
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-
- vector<MatchingState> matcherState;
- vector<bool> changedCache(1, false);
-
- // Matched stop event.
- // Check that condition is still false.
- unique_ptr<LogEvent> screenOffEvent =
- CreateScreenStateChangedEvent(/*timestamp=*/50, android::view::DISPLAY_STATE_OFF);
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched); // On matcher not matched
- matcherState.push_back(MatchingState::kMatched); // Off matcher matched
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.evaluateCondition(*screenOffEvent, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-
- // Matched start event.
- // Check that condition has changed to true.
- unique_ptr<LogEvent> screenOnEvent =
- CreateScreenStateChangedEvent(/*timestamp=*/100, android::view::DISPLAY_STATE_ON);
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched); // On matcher matched
- matcherState.push_back(MatchingState::kNotMatched); // Off matcher not matched
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(*screenOnEvent, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedInitialValueUnknown) {
- SimplePredicate simplePredicate;
- simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
- simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
- simplePredicate.set_count_nesting(false);
- simplePredicate.set_initial_value(SimplePredicate_InitialValue_UNKNOWN);
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"),
- 0 /*tracker index*/, simplePredicate,
- trackerNameIndexMap);
-
- ConditionKey queryKey;
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-
- // Check that initial condition is unknown.
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
-
- vector<MatchingState> matcherState;
- vector<bool> changedCache(1, false);
-
- // Matched stop event.
- // Check that condition is changed to false.
- unique_ptr<LogEvent> screenOffEvent =
- CreateScreenStateChangedEvent(/*timestamp=*/50, android::view::DISPLAY_STATE_OFF);
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched); // On matcher not matched
- matcherState.push_back(MatchingState::kMatched); // Off matcher matched
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.evaluateCondition(*screenOffEvent, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-
- // Matched start event.
- // Check that condition has changed to true.
- unique_ptr<LogEvent> screenOnEvent =
- CreateScreenStateChangedEvent(/*timestamp=*/100, android::view::DISPLAY_STATE_ON);
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched); // On matcher matched
- matcherState.push_back(MatchingState::kNotMatched); // Off matcher not matched
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(*screenOnEvent, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedCondition) {
- SimplePredicate simplePredicate;
- simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
- simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
- simplePredicate.set_count_nesting(false);
- simplePredicate.set_initial_value(SimplePredicate_InitialValue_UNKNOWN);
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"), 0 /*tracker index*/,
- simplePredicate, trackerNameIndexMap);
- EXPECT_FALSE(conditionTracker.isSliced());
-
- // This event is not accessed in this test besides dimensions which is why this is okay.
- // This is technically an invalid LogEvent because we do not call parseBuffer.
- LogEvent event(/*uid=*/0, /*pid=*/0);
-
- vector<MatchingState> matcherState;
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
-
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
- vector<bool> changedCache(1, false);
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- // not matched start or stop. condition doesn't change
- EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-
- // prepare a case for match start.
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- // now condition should change to true.
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-
- // match nothing.
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-
- // the case for match stop.
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
-
- // condition changes to false.
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-
- // match stop again.
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- // condition should still be false. not changed.
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedConditionNestCounting) {
- std::vector<sp<ConditionTracker>> allConditions;
- SimplePredicate simplePredicate;
- simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
- simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
- simplePredicate.set_count_nesting(true);
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"),
- 0 /*condition tracker index*/, simplePredicate,
- trackerNameIndexMap);
- EXPECT_FALSE(conditionTracker.isSliced());
-
- // This event is not accessed in this test besides dimensions which is why this is okay.
- // This is technically an invalid LogEvent because we do not call parseBuffer.
- LogEvent event(/*uid=*/0, /*pid=*/0);
-
- // one matched start
- vector<MatchingState> matcherState;
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
- vector<bool> changedCache(1, false);
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
-
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-
- // prepare for another matched start.
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
-
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-
- // ONE MATCHED STOP
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- // result should still be true
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-
- // ANOTHER MATCHED STOP
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
- std::vector<sp<ConditionTracker>> allConditions;
- for (Position position : {Position::FIRST, Position::LAST}) {
- SimplePredicate simplePredicate = getWakeLockHeldCondition(
- true /*nesting*/, true /*default to false*/, true /*output slice by uid*/,
- position);
- string conditionName = "WL_HELD_BY_UID2";
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
- trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
- trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
- 0 /*condition tracker index*/, simplePredicate,
- trackerNameIndexMap);
-
- std::vector<int> uids = {111, 222, 333};
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/1);
-
- // one matched start
- vector<MatchingState> matcherState;
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
- vector<bool> changedCache(1, false);
-
- conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
- changedCache);
-
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
- } else {
- ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
- }
- EXPECT_TRUE(changedCache[0]);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), 1u);
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
- } else {
- EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(),
- uids.size());
- }
-
- // Now test query
- const auto queryKey = getWakeLockQueryKey(position, uids, conditionName);
- conditionCache[0] = ConditionState::kNotEvaluated;
-
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
- // another wake lock acquired by this uid
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids, "wl2", /*acquire=*/1);
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_FALSE(changedCache[0]);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
- } else {
- ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
- }
- EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-
-
- // wake lock 1 release
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/0);
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
- changedCache);
- // nothing changes, because wake lock 2 is still held for this uid
- EXPECT_FALSE(changedCache[0]);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
- } else {
- ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
- }
- EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event4, /*atomId=*/1, /*timestamp=*/0, uids, "wl2", /*acquire=*/0);
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
- changedCache);
- ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
- EXPECT_TRUE(changedCache[0]);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), 1u);
- EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
- } else {
- EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(),
- uids.size());
- }
-
- // query again
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- }
-
-}
-
-TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
- std::vector<sp<ConditionTracker>> allConditions;
-
- SimplePredicate simplePredicate =
- getWakeLockHeldCondition(true /*nesting*/, true /*default to false*/,
- false /*slice output by uid*/, Position::ANY /* position */);
- string conditionName = "WL_HELD";
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
- trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
- trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
- 0 /*condition tracker index*/, simplePredicate,
- trackerNameIndexMap);
-
- EXPECT_FALSE(conditionTracker.isSliced());
-
- std::vector<int> uids1 = {111, 1111, 11111};
- string uid1_wl1 = "wl1_1";
- std::vector<int> uids2 = {222, 2222, 22222};
- string uid2_wl1 = "wl2_1";
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids1, uid1_wl1, /*acquire=*/1);
-
- // one matched start for uid1
- vector<MatchingState> matcherState;
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
- vector<bool> changedCache(1, false);
-
- conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
- changedCache);
-
- ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
- EXPECT_TRUE(changedCache[0]);
-
- // Now test query
- ConditionKey queryKey;
- conditionCache[0] = ConditionState::kNotEvaluated;
-
- conditionTracker.isConditionMet(queryKey, allPredicates, true, conditionCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
- // another wake lock acquired by this uid
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids2, uid2_wl1, /*acquire=*/1);
-
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_FALSE(changedCache[0]);
-
- // uid1 wake lock 1 release
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids1, uid1_wl1,
- /*release=*/0); // now release it.
-
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
- changedCache);
- // nothing changes, because uid2 is still holding wl.
- EXPECT_FALSE(changedCache[0]);
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event4, /*atomId=*/1, /*timestamp=*/0, uids2, uid2_wl1,
- /*acquire=*/0); // now release it.
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
- changedCache);
- ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
- EXPECT_TRUE(changedCache[0]);
-
- // query again
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, true, conditionCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestStopAll) {
- std::vector<sp<ConditionTracker>> allConditions;
- for (Position position : {Position::FIRST, Position::LAST}) {
- SimplePredicate simplePredicate =
- getWakeLockHeldCondition(true /*nesting*/, true /*default to false*/,
- true /*output slice by uid*/, position);
- string conditionName = "WL_HELD_BY_UID3";
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
- trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
- trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
- 0 /*condition tracker index*/, simplePredicate,
- trackerNameIndexMap);
-
- std::vector<int> uids1 = {111, 1111, 11111};
- std::vector<int> uids2 = {222, 2222, 22222};
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids1, "wl1", /*acquire=*/1);
-
- // one matched start
- vector<MatchingState> matcherState;
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
- vector<bool> changedCache(1, false);
-
- conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
- changedCache);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
- } else {
- ASSERT_EQ(uids1.size(), conditionTracker.mSlicedConditionState.size());
- }
- EXPECT_TRUE(changedCache[0]);
- {
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
- } else {
- EXPECT_EQ(uids1.size(),
- conditionTracker.getChangedToTrueDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
- }
- }
-
- // Now test query
- const auto queryKey = getWakeLockQueryKey(position, uids1, conditionName);
- conditionCache[0] = ConditionState::kNotEvaluated;
-
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
- // another wake lock acquired by uid2
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids2, "wl2", /*acquire=*/1);
-
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
- changedCache);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(2UL, conditionTracker.mSlicedConditionState.size());
- } else {
- ASSERT_EQ(uids1.size() + uids2.size(), conditionTracker.mSlicedConditionState.size());
- }
- EXPECT_TRUE(changedCache[0]);
- {
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
- } else {
- EXPECT_EQ(uids2.size(),
- conditionTracker.getChangedToTrueDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
- }
- }
-
- // TEST QUERY
- const auto queryKey2 = getWakeLockQueryKey(position, uids2, conditionName);
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
-
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
- // stop all event
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids2, "wl2", /*acquire=*/1);
-
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
-
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_TRUE(changedCache[0]);
- ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
- {
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(2UL, conditionTracker.getChangedToFalseDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
- } else {
- EXPECT_EQ(uids1.size() + uids2.size(),
- conditionTracker.getChangedToFalseDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
- }
- }
-
- // TEST QUERY
- const auto queryKey3 = getWakeLockQueryKey(position, uids1, conditionName);
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-
- // TEST QUERY
- const auto queryKey4 = getWakeLockQueryKey(position, uids2, conditionName);
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp b/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
deleted file mode 100644
index 93b2783..0000000
--- a/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto alarm = config.add_alarm();
- alarm->set_id(123456);
- alarm->set_offset_millis(TimeUnitToBucketSizeInMillis(TEN_MINUTES));
- alarm->set_period_millis(TimeUnitToBucketSizeInMillis(ONE_HOUR));
-
- alarm = config.add_alarm();
- alarm->set_id(654321);
- alarm->set_offset_millis(TimeUnitToBucketSizeInMillis(FIVE_MINUTES));
- alarm->set_period_millis(TimeUnitToBucketSizeInMillis(THIRTY_MINUTES));
- return config;
-}
-
-} // namespace
-
-TEST(AlarmE2eTest, TestMultipleAlarms) {
- auto config = CreateStatsdConfig();
- int64_t bucketStartTimeNs = 10000000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(2u, processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers.size());
-
- auto alarmTracker1 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[0];
- auto alarmTracker2 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[1];
-
- int64_t alarmTimestampSec0 = bucketStartTimeNs / NS_PER_SEC + 10 * 60;
- int64_t alarmTimestampSec1 = bucketStartTimeNs / NS_PER_SEC + 5 * 60;
- EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec());
- EXPECT_EQ(alarmTimestampSec1, alarmTracker2->getAlarmTimestampSec());
-
- // Alarm fired.
- const int64_t alarmFiredTimestampSec0 = alarmTimestampSec1 + 5;
- auto alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(alarmFiredTimestampSec0));
- ASSERT_EQ(1u, alarmSet.size());
- processor->onPeriodicAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
- EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec());
- EXPECT_EQ(alarmTimestampSec1 + 30 * 60, alarmTracker2->getAlarmTimestampSec());
-
- // Alarms fired very late.
- const int64_t alarmFiredTimestampSec1 = alarmTimestampSec0 + 2 * 60 * 60 + 125;
- alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(alarmFiredTimestampSec1));
- ASSERT_EQ(2u, alarmSet.size());
- processor->onPeriodicAlarmFired(alarmFiredTimestampSec1 * NS_PER_SEC, alarmSet);
- EXPECT_EQ(alarmTimestampSec0 + 60 * 60 * 3, alarmTracker1->getAlarmTimestampSec());
- EXPECT_EQ(alarmTimestampSec1 + 30 * 60 * 5, alarmTracker2->getAlarmTimestampSec());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
deleted file mode 100644
index af9436b..0000000
--- a/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(int num_buckets, int threshold, int refractory_period_sec) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-
- *config.add_atom_matcher() = wakelockAcquireMatcher;
-
- auto countMetric = config.add_count_metric();
- countMetric->set_id(123456);
- countMetric->set_what(wakelockAcquireMatcher.id());
- *countMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- countMetric->set_bucket(FIVE_MINUTES);
-
- auto alert = config.add_alert();
- alert->set_id(StringToId("alert"));
- alert->set_metric_id(123456);
- alert->set_num_buckets(num_buckets);
- alert->set_refractory_period_secs(refractory_period_sec);
- alert->set_trigger_if_sum_gt(threshold);
- return config;
-}
-
-} // namespace
-
-TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket) {
- const int num_buckets = 1;
- const int threshold = 3;
- const int refractory_period_sec = 10;
- auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
- const uint64_t alert_id = config.alert(0).id();
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- std::vector<int> attributionUids1 = {111};
- std::vector<string> attributionTags1 = {"App1"};
- std::vector<int> attributionUids2 = {111, 222};
- std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
- std::vector<int> attributionUids3 = {111, 333};
- std::vector<string> attributionTags3 = {"App1", "App3"};
- std::vector<int> attributionUids4 = {222, 333};
- std::vector<string> attributionTags4 = {"GMSCoreModule1", "App3"};
- std::vector<int> attributionUids5 = {222};
- std::vector<string> attributionTags5 = {"GMSCoreModule1"};
-
- FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)111));
- HashableDimensionKey whatKey1({fieldValue1});
- MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
- FieldValue fieldValue2(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)222));
- HashableDimensionKey whatKey2({fieldValue2});
- MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids4, attributionTags4,
- "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids2, attributionTags2,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids5, attributionTags5,
- "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids3, attributionTags3,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids5, attributionTags5,
- "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- // Fired alarm and refractory period end timestamp updated.
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 5, attributionUids1, attributionTags1,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + bucketStartTimeNs / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 100, attributionUids1, attributionTags1,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + bucketStartTimeNs / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs - 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs - 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids4,
- attributionTags4, "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids5,
- attributionTags5, "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 3, attributionUids5,
- attributionTags5, "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 4, attributionUids5,
- attributionTags5, "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 4) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-}
-
-TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets) {
- const int num_buckets = 3;
- const int threshold = 3;
- const int refractory_period_sec = 10;
- auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
- const uint64_t alert_id = config.alert(0).id();
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- std::vector<int> attributionUids1 = {111};
- std::vector<string> attributionTags1 = {"App1"};
- std::vector<int> attributionUids2 = {111, 222};
- std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
-
- FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)111));
- HashableDimensionKey whatKey1({fieldValue1});
- MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids2, attributionTags2,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Fired alarm and refractory period end timestamp updated.
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids1, attributionTags1,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 2, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 3 * bucketSizeNs + 2) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-}
-
-TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written) {
- const int num_buckets = 1;
- const int threshold = 0;
- const int refractory_period_sec = 86400 * 365; // 1 year
- auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
- const int64_t alert_id = config.alert(0).id();
-
- int64_t bucketStartTimeNs = 10000000000;
-
- int configUid = 2000;
- int64_t configId = 1000;
- ConfigKey cfgKey(configUid, configId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- metadata::StatsMetadataList result;
- int64_t mockWallClockNs = 1584991200 * NS_PER_SEC;
- int64_t mockElapsedTimeNs = bucketStartTimeNs + 5000 * NS_PER_SEC;
- processor->WriteMetadataToProto(mockWallClockNs, mockElapsedTimeNs, &result);
-
- ASSERT_EQ(result.stats_metadata_size(), 0);
-}
-
-TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk) {
- const int num_buckets = 1;
- const int threshold = 0;
- const int refractory_period_sec = 86400 * 365; // 1 year
- auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
- const int64_t alert_id = config.alert(0).id();
-
- int64_t bucketStartTimeNs = 10000000000;
-
- int configUid = 2000;
- int64_t configId = 1000;
- ConfigKey cfgKey(configUid, configId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- std::vector<int> attributionUids1 = {111};
- std::vector<string> attributionTags1 = {"App1"};
- std::vector<int> attributionUids2 = {111, 222};
- std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
-
- FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)111));
- HashableDimensionKey whatKey1({fieldValue1});
- MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 2) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- metadata::StatsMetadataList result;
- int64_t mockWallClockNs = 1584991200 * NS_PER_SEC;
- int64_t mockElapsedTimeNs = bucketStartTimeNs + 5000 * NS_PER_SEC;
- processor->WriteMetadataToProto(mockWallClockNs, mockElapsedTimeNs, &result);
-
- metadata::StatsMetadata statsMetadata = result.stats_metadata(0);
- ASSERT_EQ(result.stats_metadata_size(), 1);
- EXPECT_EQ(statsMetadata.config_key().config_id(), configId);
- EXPECT_EQ(statsMetadata.config_key().uid(), configUid);
-
- metadata::AlertMetadata alertMetadata = statsMetadata.alert_metadata(0);
- ASSERT_EQ(statsMetadata.alert_metadata_size(), 1);
- EXPECT_EQ(alertMetadata.alert_id(), alert_id);
- metadata::AlertDimensionKeyedData keyedData = alertMetadata.alert_dim_keyed_data(0);
- ASSERT_EQ(alertMetadata.alert_dim_keyed_data_size(), 1);
- EXPECT_EQ(keyedData.last_refractory_ends_sec(),
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1) -
- mockElapsedTimeNs / NS_PER_SEC +
- mockWallClockNs / NS_PER_SEC);
-
- metadata::MetricDimensionKey metadataDimKey = keyedData.dimension_key();
- metadata::FieldValue dimKeyInWhat = metadataDimKey.dimension_key_in_what(0);
- EXPECT_EQ(dimKeyInWhat.field().tag(), fieldValue1.mField.getTag());
- EXPECT_EQ(dimKeyInWhat.field().field(), fieldValue1.mField.getField());
- EXPECT_EQ(dimKeyInWhat.value_int(), fieldValue1.mValue.int_value);
-}
-
-TEST(AnomalyDetectionE2eTest, TestCountMetric_load_refractory_from_disk) {
- const int num_buckets = 1;
- const int threshold = 0;
- const int refractory_period_sec = 86400 * 365; // 1 year
- auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
- const int64_t alert_id = config.alert(0).id();
-
- int64_t bucketStartTimeNs = 10000000000;
-
- int configUid = 2000;
- int64_t configId = 1000;
- ConfigKey cfgKey(configUid, configId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- std::vector<int> attributionUids1 = {111};
- std::vector<string> attributionTags1 = {"App1"};
- std::vector<int> attributionUids2 = {111, 222};
- std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
-
- FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)111));
- HashableDimensionKey whatKey1({fieldValue1});
- MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 2) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- int64_t mockWallClockNs = 1584991200 * NS_PER_SEC;
- int64_t mockElapsedTimeNs = bucketStartTimeNs + 5000 * NS_PER_SEC;
- processor->SaveMetadataToDisk(mockWallClockNs, mockElapsedTimeNs);
-
- auto processor2 = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- int64_t mockElapsedTimeSinceBoot = 10 * NS_PER_SEC;
- processor2->LoadMetadataFromDisk(mockWallClockNs, mockElapsedTimeSinceBoot);
-
- sp<AnomalyTracker> anomalyTracker2 =
- processor2->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
- EXPECT_EQ(anomalyTracker2->getRefractoryPeriodEndsSec(dimensionKey1) -
- mockElapsedTimeSinceBoot / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1) -
- mockElapsedTimeNs / NS_PER_SEC);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
deleted file mode 100644
index 95e3010..0000000
--- a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/anomaly/DurationAnomalyTracker.h"
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(int num_buckets,
- uint64_t threshold_ns,
- DurationMetric::AggregationType aggregationType,
- bool nesting) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenIsOffPredicate;
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- FieldMatcher dimensions = CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- dimensions.add_child()->set_field(3); // The wakelock tag is set in field 3 of the wakelock.
- *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
- holdingWakelockPredicate.mutable_simple_predicate()->set_count_nesting(nesting);
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("WakelockDuration"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->set_condition(screenIsOffPredicate.id());
- durationMetric->set_aggregation_type(aggregationType);
- *durationMetric->mutable_dimensions_in_what() =
- CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- durationMetric->set_bucket(FIVE_MINUTES);
-
- auto alert = config.add_alert();
- alert->set_id(StringToId("alert"));
- alert->set_metric_id(StringToId("WakelockDuration"));
- alert->set_num_buckets(num_buckets);
- alert->set_refractory_period_secs(2);
- alert->set_trigger_if_sum_gt(threshold_ns);
- return config;
-}
-
-std::vector<int> attributionUids1 = {111, 222};
-std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1"};
-
-std::vector<int> attributionUids2 = {111, 222};
-std::vector<string> attributionTags2 = {"App2", "GMSCoreModule1"};
-
-std::vector<int> attributionUids3 = {222};
-std::vector<string> attributionTags3 = {"GMSCoreModule1"};
-
-MetricDimensionKey dimensionKey1(
- HashableDimensionKey({FieldValue(Field(util::WAKELOCK_STATE_CHANGED,
- (int32_t)0x02010101),
- Value((int32_t)111))}),
- DEFAULT_DIMENSION_KEY);
-
-MetricDimensionKey dimensionKey2(
- HashableDimensionKey({FieldValue(Field(util::WAKELOCK_STATE_CHANGED,
- (int32_t)0x02010101), Value((int32_t)222))}),
- DEFAULT_DIMENSION_KEY);
-
-} // namespace
-
-TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
- const int num_buckets = 1;
- const uint64_t threshold_ns = NS_PER_SEC;
- auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, true);
- const uint64_t alert_id = config.alert(0).id();
- const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
-
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- auto screen_on_event = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- auto screen_off_event = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 10, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screen_on_event.get());
- processor->OnLogEvent(screen_off_event.get());
-
- // Acquire wakelock wl1.
- auto acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 11, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 11 + threshold_ns) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Release wakelock wl1. No anomaly detected. Alarm cancelled at the "release" event.
- auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 101, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire wakelock wl1 within bucket #0.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 110, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 110 + threshold_ns - 90) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Release wakelock wl1. One anomaly detected.
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + NS_PER_SEC + 109,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire wakelock wl1.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + NS_PER_SEC + 112,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- // Wakelock has been hold longer than the threshold in bucket #0. The alarm is set at the
- // end of the refractory period.
- const int64_t alarmFiredTimestampSec0 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
- (uint32_t)alarmFiredTimestampSec0);
-
- // Anomaly alarm fired.
- auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(alarmFiredTimestampSec0));
- ASSERT_EQ(1u, alarmSet.size());
- processor->onAnomalyAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Release wakelock wl1.
- release_event =
- CreateReleaseWakelockEvent(alarmFiredTimestampSec0 * NS_PER_SEC + NS_PER_SEC + 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- // Within refractory period. No more anomaly detected.
- EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire wakelock wl1.
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC - 11,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(acquire_event.get());
- const int64_t alarmFiredTimestampSec1 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC) / NS_PER_SEC,
- (uint64_t)alarmFiredTimestampSec1);
-
- // Release wakelock wl1.
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(alarmFiredTimestampSec1));
- ASSERT_EQ(0u, alarmSet.size());
-
- // Acquire wakelock wl1 near the end of bucket #0.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 2,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- // Release the event at early bucket #1.
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + NS_PER_SEC - 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- // Anomaly detected when stopping the alarm. The refractory period does not change.
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Condition changes to false.
- screen_on_event =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 20,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- processor->OnLogEvent(screen_on_event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 30,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(acquire_event.get());
- // The condition is false. Do not start the alarm.
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Condition turns true.
- screen_off_event =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screen_off_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + threshold_ns) / NS_PER_SEC,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- // Condition turns to false.
- screen_on_event =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- processor->OnLogEvent(screen_on_event.get());
- // Condition turns to false. Cancelled the alarm.
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- // Detected one anomaly.
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Condition turns to true again.
- screen_off_event =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 2,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screen_off_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 2 + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-}
-
-TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets) {
- const int num_buckets = 3;
- const uint64_t threshold_ns = NS_PER_SEC;
- auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, true);
- const uint64_t alert_id = config.alert(0).id();
- const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
-
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- auto screen_off_event = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screen_off_event.get());
-
- // Acquire wakelock "wc1" in bucket #0.
- auto acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - NS_PER_SEC / 2 - 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Release wakelock "wc1" in bucket #0.
- auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire wakelock "wc1" in bucket #1.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + 100,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire wakelock "wc2" in bucket #2.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
- attributionUids3, attributionTags3, "wl2");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2,
- anomalyTracker->getAlarmTimestampSec(dimensionKey2));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- // Release wakelock "wc2" in bucket #2.
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC,
- attributionUids3, attributionTags3, "wl2");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- // Acquire wakelock "wc1" in bucket #2.
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Release wakelock "wc1" in bucket #2.
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2.5 * NS_PER_SEC,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec +
- (int64_t)(bucketStartTimeNs + 2 * bucketSizeNs + 2.5 * NS_PER_SEC) /
- NS_PER_SEC +
- 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs - NS_PER_SEC + 4,
- attributionUids3, attributionTags3, "wl2");
- processor->OnLogEvent(acquire_event.get());
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs - NS_PER_SEC + 5,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ((bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey2));
-
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs + 2,
- attributionUids3, attributionTags3, "wl2");
- processor->OnLogEvent(release_event.get());
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs + 6,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
- // The buckets are not messed up across dimensions. Only one dimension has anomaly triggered.
- EXPECT_EQ(refractory_period_sec + (int64_t)(bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC +
- 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-}
-
-TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period) {
- const int num_buckets = 2;
- const uint64_t threshold_ns = 3 * NS_PER_SEC;
- auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, false);
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
-
- const uint64_t alert_id = config.alert(0).id();
- const uint32_t refractory_period_sec = 3 * bucketSizeNs / NS_PER_SEC;
- config.mutable_alert(0)->set_refractory_period_secs(refractory_period_sec);
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- auto screen_off_event = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screen_off_event.get());
-
- // Acquire wakelock "wc1" in bucket #0.
- auto acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 100,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire the wakelock "wc1" again.
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2 * NS_PER_SEC + 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- // The alarm does not change.
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Anomaly alarm fired late.
- const int64_t firedAlarmTimestampNs = bucketStartTimeNs + 2 * bucketSizeNs - NS_PER_SEC;
- auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(firedAlarmTimestampNs / NS_PER_SEC));
- ASSERT_EQ(1u, alarmSet.size());
- processor->onAnomalyAlarmFired(firedAlarmTimestampNs, alarmSet);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- // Within the refractory period. No anomaly.
- EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // A new wakelock, but still within refractory period.
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 10 * NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1");
- // Still in the refractory period. No anomaly.
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 5,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 4,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 3,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
deleted file mode 100644
index 4c2caa9..0000000
--- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <iostream>
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(const Position position) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- auto attributionNodeMatcher =
- wakelockAcquireMatcher.mutable_simple_atom_matcher()->add_field_value_matcher();
- attributionNodeMatcher->set_field(1);
- attributionNodeMatcher->set_position(Position::ANY);
- auto uidMatcher = attributionNodeMatcher->mutable_matches_tuple()->add_field_value_matcher();
- uidMatcher->set_field(1); // uid field.
- uidMatcher->set_eq_string("com.android.gmscore");
-
- *config.add_atom_matcher() = wakelockAcquireMatcher;
-
- auto countMetric = config.add_count_metric();
- countMetric->set_id(123456);
- countMetric->set_what(wakelockAcquireMatcher.id());
- *countMetric->mutable_dimensions_in_what() =
- CreateAttributionUidAndTagDimensions(
- util::WAKELOCK_STATE_CHANGED, {position});
- countMetric->set_bucket(FIVE_MINUTES);
- return config;
-}
-
-// GMS core node is in the middle.
-std::vector<int> attributionUids1 = {111, 222, 333};
-std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1", "App3"};
-
-// GMS core node is the last one.
-std::vector<int> attributionUids2 = {111, 333, 222};
-std::vector<string> attributionTags2 = {"App1", "App3", "GMSCoreModule1"};
-
-// GMS core node is the first one.
-std::vector<int> attributionUids3 = {222, 333};
-std::vector<string> attributionTags3 = {"GMSCoreModule1", "App3"};
-
-// Single GMS core node.
-std::vector<int> attributionUids4 = {222};
-std::vector<string> attributionTags4 = {"GMSCoreModule1"};
-
-// GMS core has another uid.
-std::vector<int> attributionUids5 = {111, 444, 333};
-std::vector<string> attributionTags5 = {"App1", "GMSCoreModule2", "App3"};
-
-// Multiple GMS core nodes.
-std::vector<int> attributionUids6 = {444, 222};
-std::vector<string> attributionTags6 = {"GMSCoreModule2", "GMSCoreModule1"};
-
-// No GMS core nodes
-std::vector<int> attributionUids7 = {111, 333};
-std::vector<string> attributionTags7 = {"App1", "App3"};
-
-std::vector<int> attributionUids8 = {111};
-std::vector<string> attributionTags8 = {"App1"};
-
-// GMS core node with isolated uid.
-const int isolatedUid = 666;
-std::vector<int> attributionUids9 = {isolatedUid};
-std::vector<string> attributionTags9 = {"GMSCoreModule3"};
-
-std::vector<int> attributionUids10 = {isolatedUid};
-std::vector<string> attributionTags10 = {"GMSCoreModule1"};
-
-} // namespace
-
-TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid) {
- auto config = CreateStatsdConfig(Position::FIRST);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- // Here it assumes that GMS core has two uids.
- processor->getUidMap()->updateMap(
- 1, {222, 444, 111, 333}, {1, 1, 2, 2},
- {String16("v1"), String16("v1"), String16("v2"), String16("v2")},
- {String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"),
- String16("APP3")},
- {String16(""), String16(""), String16(""), String16("")});
-
- std::vector<std::unique_ptr<LogEvent>> events;
- // Events 1~4 are in the 1st bucket.
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 200, attributionUids2,
- attributionTags2, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
- attributionUids3, attributionTags3, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs, attributionUids4,
- attributionTags4, "wl1"));
-
- // Events 5~8 are in the 3rd bucket.
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
- attributionUids5, attributionTags5, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
- attributionUids6, attributionTags6, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - 2,
- attributionUids7, attributionTags7, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs,
- attributionUids8, attributionTags8, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1,
- attributionUids9, attributionTags9, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 100,
- attributionUids9, attributionTags9, "wl2"));
- events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs - 1, 222,
- isolatedUid, true /*is_create*/));
- events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs + 10, 222,
- isolatedUid, false /*is_create*/));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(countMetrics.data_size(), 4);
-
- auto data = countMetrics.data(0);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111, "App1");
- ASSERT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).count(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).count(), 1);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
-
- data = countMetrics.data(1);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ASSERT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).count(), 1);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = countMetrics.data(2);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule3");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + 3 * bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 4 * bucketSizeNs);
-
- data = countMetrics.data(3);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 444,
- "GMSCoreModule2");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
-}
-
-TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain) {
- auto config = CreateStatsdConfig(Position::ALL);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- // Here it assumes that GMS core has two uids.
- processor->getUidMap()->updateMap(
- 1, {222, 444, 111, 333}, {1, 1, 2, 2},
- {String16("v1"), String16("v1"), String16("v2"), String16("v2")},
- {String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"),
- String16("APP3")},
- {String16(""), String16(""), String16(""), String16("")});
-
- std::vector<std::unique_ptr<LogEvent>> events;
- // Events 1~4 are in the 1st bucket.
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 200, attributionUids2,
- attributionTags2, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
- attributionUids3, attributionTags3, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs, attributionUids4,
- attributionTags4, "wl1"));
-
- // Events 5~8 are in the 3rd bucket.
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
- attributionUids5, attributionTags5, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
- attributionUids6, attributionTags6, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - 2,
- attributionUids7, attributionTags7, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs,
- attributionUids8, attributionTags8, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1,
- attributionUids10, attributionTags10, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 100,
- attributionUids10, attributionTags10, "wl2"));
- events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs - 1, 222,
- isolatedUid, true /*is_create*/));
- events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs + 10, 222,
- isolatedUid, false /*is_create*/));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(countMetrics.data_size(), 6);
-
- auto data = countMetrics.data(0);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(1, data.bucket_info(1).count());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
- data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 222);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 333);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
- util::WAKELOCK_STATE_CHANGED, 333, "App3");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
-
- data = countMetrics.data(2);
- ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 444);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
- util::WAKELOCK_STATE_CHANGED, 444,
- "GMSCoreModule2");
- ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 222);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
- util::WAKELOCK_STATE_CHANGED, 111, "App1");
- ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 222);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 333);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
- util::WAKELOCK_STATE_CHANGED, 333, "App3");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(4);
- ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
- util::WAKELOCK_STATE_CHANGED, 111, "App1");
- ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 333);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
- util::WAKELOCK_STATE_CHANGED, 333, "App3");
- ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 222);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(5);
- ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
- util::WAKELOCK_STATE_CHANGED, 111, "App1");
- ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 444);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
- util::WAKELOCK_STATE_CHANGED, 444,
- "GMSCoreModule2");
- ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 333);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
- util::WAKELOCK_STATE_CHANGED, 333, "App3");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp b/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
deleted file mode 100644
index 0bce0ba..0000000
--- a/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(int num_buckets, int threshold) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-
- *config.add_atom_matcher() = wakelockAcquireMatcher;
-
- auto countMetric = config.add_count_metric();
- countMetric->set_id(123456);
- countMetric->set_what(wakelockAcquireMatcher.id());
- *countMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- countMetric->set_bucket(FIVE_MINUTES);
-
- auto alert = config.add_alert();
- alert->set_id(StringToId("alert"));
- alert->set_metric_id(123456);
- alert->set_num_buckets(num_buckets);
- alert->set_refractory_period_secs(10);
- alert->set_trigger_if_sum_gt(threshold);
-
- // Two hours
- config.set_ttl_in_seconds(2 * 3600);
- return config;
-}
-
-} // namespace
-
-TEST(ConfigTtlE2eTest, TestCountMetric) {
- const int num_buckets = 1;
- const int threshold = 3;
- auto config = CreateStatsdConfig(num_buckets, threshold);
- const uint64_t alert_id = config.alert(0).id();
- const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<int> attributionUids1 = {111};
- std::vector<string> attributionTags1 = {"App1"};
-
- FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)111));
- HashableDimensionKey whatKey1({fieldValue1});
- MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
- FieldValue fieldValue2(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)222));
- HashableDimensionKey whatKey2({fieldValue2});
- MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids1,
- attributionTags1, "wl2");
- processor->OnLogEvent(event.get());
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 25 * bucketSizeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
-
- EXPECT_EQ((int64_t)(bucketStartTimeNs + 25 * bucketSizeNs + 2 + 2 * 3600 * NS_PER_SEC),
- processor->mMetricsManagers.begin()->second->getTtlEndNs());
-
- // Clear the data stored on disk as a result of the ttl.
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 25 * bucketSizeNs + 3, false, true,
- ADB_DUMP, FAST, &buffer);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
deleted file mode 100644
index 04eb400..0000000
--- a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/state/StateManager.h"
-#include "src/state/StateTracker.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-/**
- * Tests the initial condition and condition after the first log events for
- * count metrics with either a combination condition or simple condition.
- *
- * Metrics should be initialized with condition kUnknown (given that the
- * predicate is using the default InitialValue of UNKNOWN). The condition should
- * be updated to either kFalse or kTrue if a condition event is logged for all
- * children conditions.
- */
-TEST(CountMetricE2eTest, TestInitialConditionChanges) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
-
- auto syncStartMatcher = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = syncStartMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
- *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
-
- auto screenOnPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = screenOnPredicate;
-
- auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
- *config.add_predicate() = deviceUnpluggedPredicate;
-
- auto screenOnOnBatteryPredicate = config.add_predicate();
- screenOnOnBatteryPredicate->set_id(StringToId("screenOnOnBatteryPredicate"));
- screenOnOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenOnPredicate, screenOnOnBatteryPredicate);
- addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOnOnBatteryPredicate);
-
- // CountSyncStartWhileScreenOnOnBattery (CombinationCondition)
- CountMetric* countMetric1 = config.add_count_metric();
- countMetric1->set_id(StringToId("CountSyncStartWhileScreenOnOnBattery"));
- countMetric1->set_what(syncStartMatcher.id());
- countMetric1->set_condition(screenOnOnBatteryPredicate->id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- // CountSyncStartWhileOnBattery (SimpleCondition)
- CountMetric* countMetric2 = config.add_count_metric();
- countMetric2->set_id(StringToId("CountSyncStartWhileOnBatterySliceScreen"));
- countMetric2->set_what(syncStartMatcher.id());
- countMetric2->set_condition(deviceUnpluggedPredicate.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- EXPECT_EQ(2, metricsManager->mAllMetricProducers.size());
-
- sp<MetricProducer> metricProducer1 = metricsManager->mAllMetricProducers[0];
- sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[1];
-
- EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
- auto screenOnEvent =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 30, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
- EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
- auto pluggedUsbEvent = CreateBatteryStateChangedEvent(
- bucketStartTimeNs + 50, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
- processor->OnLogEvent(pluggedUsbEvent.get());
- EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kFalse, metricProducer2->mCondition);
-
- auto pluggedNoneEvent = CreateBatteryStateChangedEvent(
- bucketStartTimeNs + 70, BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
- processor->OnLogEvent(pluggedNoneEvent.get());
- EXPECT_EQ(ConditionState::kTrue, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kTrue, metricProducer2->mCondition);
-}
-
-/**
-* Test a count metric that has one slice_by_state with no primary fields.
-*
-* Once the CountMetricProducer is initialized, it has one atom id in
-* mSlicedStateAtoms and no entries in mStateGroupMap.
-
-* One StateTracker tracks the state atom, and it has one listener which is the
-* CountMetricProducer that was initialized.
-*/
-TEST(CountMetricE2eTest, TestSlicedState) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto syncStartMatcher = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = syncStartMatcher;
-
- auto state = CreateScreenState();
- *config.add_state() = state;
-
- // Create count metric that slices by screen state.
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(syncStartMatcher.id());
- countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- countMetric->add_slice_by_state(state.id());
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that CountMetricProducer was initialized correctly.
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10 (minutes)
- |-----------------------------|-----------------------------|--
- x x x x x x (syncStartEvents)
- | | (ScreenIsOnEvent)
- | | (ScreenIsOffEvent)
- | (ScreenDozeEvent)
- */
- // Initialize log events - first bucket.
- std::vector<int> attributionUids1 = {123};
- std::vector<string> attributionTags1 = {"App1"};
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 50 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 1:00
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 75 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 1:25
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 150 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 2:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 200 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 3:30
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 250 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 4:20
-
- // Initialize log events - second bucket.
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 350 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 6:00
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 6:50
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 450 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 7:40
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 475 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 8:05
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 500 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN)); // 8:30
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 520 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 8:50
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(3, countMetrics.data_size());
-
- // For each CountMetricData, check StateValue info is correct and buckets
- // have correct counts.
- auto data = countMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(2, data.bucket_info(1).count());
-
- data = countMetrics.data(2);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(1, data.bucket_info(1).count());
-}
-
-/**
- * Test a count metric that has one slice_by_state with a mapping and no
- * primary fields.
- *
- * Once the CountMetricProducer is initialized, it has one atom id in
- * mSlicedStateAtoms and has one entry per state value in mStateGroupMap.
- *
- * One StateTracker tracks the state atom, and it has one listener which is the
- * CountMetricProducer that was initialized.
- */
-TEST(CountMetricE2eTest, TestSlicedStateWithMap) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto syncStartMatcher = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = syncStartMatcher;
-
- int64_t screenOnId = 4444;
- int64_t screenOffId = 9876;
- auto state = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
- *config.add_state() = state;
-
- // Create count metric that slices by screen state with on/off map.
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(syncStartMatcher.id());
- countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- countMetric->add_slice_by_state(state.id());
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- // Check that CountMetricProducer was initialized correctly.
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
-
- StateMap map = state.map();
- for (auto group : map.group()) {
- for (auto value : group.value()) {
- EXPECT_EQ(metricProducer->mStateGroupMap.at(SCREEN_STATE_ATOM_ID).at(value),
- group.group_id());
- }
- }
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10 (minutes)
- |-----------------------------|-----------------------------|--
- x x x x x x x x x (syncStartEvents)
- -----------------------------------------------------------SCREEN_OFF events
- | | (ScreenStateOffEvent = 1)
- | | (ScreenStateDozeEvent = 3)
- | (ScreenStateDozeSuspendEvent =
- 4)
- -----------------------------------------------------------SCREEN_ON events
- | | (ScreenStateOnEvent = 2)
- | (ScreenStateVrEvent = 5)
- | (ScreenStateOnSuspendEvent = 6)
- */
- // Initialize log events - first bucket.
- std::vector<int> attributionUids1 = {123};
- std::vector<string> attributionTags1 = {"App1"};
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 20 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 0:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 30 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 0:40
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 60 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 1:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 90 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:40
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 120 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 2:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 150 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 180 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_VR)); // 3:10
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 200 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 3:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 210 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 3:40
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 250 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 4:20
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 280 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 4:50
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 285 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 4:55
-
- // Initialize log events - second bucket.
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 360 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 6:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 390 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND)); // 6:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 430 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND)); // 7:20
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 440 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 7:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 540 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 9:10
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 570 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 9:40
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(3, countMetrics.data_size());
-
- // For each CountMetricData, check StateValue info is correct and buckets
- // have correct counts.
- auto data = countMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(1, data.bucket_info(1).count());
-
- data = countMetrics.data(2);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(4, data.bucket_info(0).count());
- EXPECT_EQ(2, data.bucket_info(1).count());
-}
-
-/**
-* Test a count metric that has one slice_by_state with a primary field.
-
-* Once the CountMetricProducer is initialized, it should have one
-* MetricStateLink stored. State querying using a non-empty primary key
-* should also work as intended.
-*/
-TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto appCrashMatcher =
- CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
- *config.add_atom_matcher() = appCrashMatcher;
-
- auto state = CreateUidProcessState();
- *config.add_state() = state;
-
- // Create count metric that slices by uid process state.
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(appCrashMatcher.id());
- countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- countMetric->add_slice_by_state(state.id());
- MetricStateLink* stateLink = countMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
- // Check that CountMetricProducer was initialized correctly.
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
- ASSERT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
-
- /*
- NOTE: "1" or "2" represents the uid associated with the state/app crash event
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10
- |------------------------|-------------------------|--
- 1 1 1 1 1 2 1 1 2 (AppCrashEvents)
- -----------------------------------------------------PROCESS STATE events
- 1 2 (TopEvent = 1002)
- 1 1 (ForegroundServiceEvent = 1003)
- 2 (ImportantBackgroundEvent = 1006)
- 1 1 1 (ImportantForegroundEvent = 1005)
-
- Based on the diagram above, an AppCrashEvent querying for process state value would return:
- - StateTracker::kStateUnknown
- - Important foreground
- - Top
- - Important foreground
- - Foreground service
- - Top (both the app crash and state still have matching uid = 2)
-
- - Foreground service
- - Foreground service
- - Important background
- */
- // Initialize log events - first bucket.
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/)); // 0:30
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 30 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 0:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/)); // 1:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 90 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 1:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 120 * NS_PER_SEC, 1 /*uid*/)); // 2:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 150 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 2:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 200 * NS_PER_SEC, 1 /*uid*/)); // 3:30
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 210 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 3:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 250 * NS_PER_SEC, 1 /*uid*/)); // 4:20
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 280 * NS_PER_SEC, 2 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 4:50
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 285 * NS_PER_SEC, 2 /*uid*/)); // 4:55
-
- // Initialize log events - second bucket.
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 360 * NS_PER_SEC, 1 /*uid*/)); // 6:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 390 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 6:40
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 430 * NS_PER_SEC, 2 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND)); // 7:20
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 440 * NS_PER_SEC, 1 /*uid*/)); // 7:30
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 540 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 9:10
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 570 * NS_PER_SEC, 2 /*uid*/)); // 9:40
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(5, countMetrics.data_size());
-
- // For each CountMetricData, check StateValue info is correct and buckets
- // have correct counts.
- auto data = countMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, data.bucket_info(0).count());
-
- data = countMetrics.data(2);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(2, data.bucket_info(1).count());
-
- data = countMetrics.data(3);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, data.bucket_info(0).count());
-
- data = countMetrics.data(4);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-}
-
-TEST(CountMetricE2eTest, TestMultipleSlicedStates) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto appCrashMatcher =
- CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
- *config.add_atom_matcher() = appCrashMatcher;
-
- int64_t screenOnId = 4444;
- int64_t screenOffId = 9876;
- auto state1 = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
- *config.add_state() = state1;
- auto state2 = CreateUidProcessState();
- *config.add_state() = state2;
-
- // Create count metric that slices by screen state with on/off map and
- // slices by uid process state.
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(appCrashMatcher.id());
- countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- countMetric->add_slice_by_state(state1.id());
- countMetric->add_slice_by_state(state2.id());
- MetricStateLink* stateLink = countMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that StateTrackers were properly initialized.
- EXPECT_EQ(2, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
- // Check that CountMetricProducer was initialized correctly.
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 2);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(1), UID_PROCESS_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
- ASSERT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
-
- StateMap map = state1.map();
- for (auto group : map.group()) {
- for (auto value : group.value()) {
- EXPECT_EQ(metricProducer->mStateGroupMap.at(SCREEN_STATE_ATOM_ID).at(value),
- group.group_id());
- }
- }
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10 (minutes)
- |------------------------|------------------------|--
- 1 1 1 1 1 2 1 1 2 (AppCrashEvents)
- ---------------------------------------------------SCREEN_OFF events
- | | (ScreenOffEvent = 1)
- | | (ScreenDozeEvent = 3)
- ---------------------------------------------------SCREEN_ON events
- | | (ScreenOnEvent = 2)
- | (ScreenOnSuspendEvent = 6)
- ---------------------------------------------------PROCESS STATE events
- 1 2 (TopEvent = 1002)
- 1 (ForegroundServiceEvent = 1003)
- 2 (ImportantBackgroundEvent = 1006)
- 1 1 1 (ImportantForegroundEvent = 1005)
-
- Based on the diagram above, Screen State / Process State pairs for each
- AppCrashEvent are:
- - StateTracker::kStateUnknown / important foreground
- - off / important foreground
- - off / Top
- - on / important foreground
- - off / important foreground
- - off / top
-
- - off / important foreground
- - off / foreground service
- - on / important background
-
- */
- // Initialize log events - first bucket.
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 5 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 0:15
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/)); // 0:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 30 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 0:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/)); // 1:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 90 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 1:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 90 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 120 * NS_PER_SEC, 1 /*uid*/)); // 2:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 150 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 2:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 160 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:50
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 200 * NS_PER_SEC, 1 /*uid*/)); // 3:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 210 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 3:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 250 * NS_PER_SEC, 1 /*uid*/)); // 4:20
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 280 * NS_PER_SEC, 2 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 4:50
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 285 * NS_PER_SEC, 2 /*uid*/)); // 4:55
-
- // Initialize log events - second bucket.
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 360 * NS_PER_SEC, 1 /*uid*/)); // 6:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 380 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 6:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 390 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND)); // 6:40
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 420 * NS_PER_SEC, 2 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND)); // 7:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 440 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 7:30
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 450 * NS_PER_SEC, 1 /*uid*/)); // 7:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 520 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 8:50
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 540 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 9:10
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 570 * NS_PER_SEC, 2 /*uid*/)); // 9:40
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(6, countMetrics.data_size());
-
- // For each CountMetricData, check StateValue info is correct and buckets
- // have correct counts.
- auto data = countMetrics.data(0);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1, data.slice_by_state(0).value());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(1);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(2);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(1).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(3);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(1).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, data.bucket_info(0).count());
-
- data = countMetrics.data(4);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(1).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(5);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(2, data.bucket_info(0).count());
- EXPECT_EQ(1, data.bucket_info(1).count());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
deleted file mode 100644
index 4efb038..0000000
--- a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
+++ /dev/null
@@ -1,1473 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/state/StateTracker.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-TEST(DurationMetricE2eTest, TestOneBucket) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = screenOffMatcher;
-
- auto durationPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = durationPredicate;
-
- int64_t metricId = 123456;
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(metricId);
- durationMetric->set_what(durationPredicate.id());
- durationMetric->set_bucket(FIVE_MINUTES);
- durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- const int64_t baseTimeNs = 0; // 0:00
- const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC; // 0:01
- const int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
-
- std::unique_ptr<LogEvent> event;
-
- // Screen is off at start of bucket.
- event = CreateScreenStateChangedEvent(configAddedTimeNs,
- android::view::DISPLAY_STATE_OFF); // 0:01
- processor->OnLogEvent(event.get());
-
- // Turn screen on.
- const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC; // 0:11
- event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(event.get());
-
- // Turn off screen 30 seconds after turning on.
- const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC; // 0:41
- event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(event.get());
-
- event = CreateScreenBrightnessChangedEvent(durationEndNs + 1 * NS_PER_SEC, 64); // 0:42
- processor->OnLogEvent(event.get());
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
- ADB_DUMP, FAST, &buffer); // 5:01
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(durationEndNs - durationStartNs, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestTwoBuckets) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = screenOffMatcher;
-
- auto durationPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = durationPredicate;
-
- int64_t metricId = 123456;
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(metricId);
- durationMetric->set_what(durationPredicate.id());
- durationMetric->set_bucket(FIVE_MINUTES);
- durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- const int64_t baseTimeNs = 0; // 0:00
- const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC; // 0:01
- const int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
-
- std::unique_ptr<LogEvent> event;
-
- // Screen is off at start of bucket.
- event = CreateScreenStateChangedEvent(configAddedTimeNs,
- android::view::DISPLAY_STATE_OFF); // 0:01
- processor->OnLogEvent(event.get());
-
- // Turn screen on.
- const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC; // 0:11
- event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(event.get());
-
- // Turn off screen 30 seconds after turning on.
- const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC; // 0:41
- event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(event.get());
-
- event = CreateScreenBrightnessChangedEvent(durationEndNs + 1 * NS_PER_SEC, 64); // 0:42
- processor->OnLogEvent(event.get());
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, false,
- true, ADB_DUMP, FAST, &buffer); // 10:01
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(0, bucketInfo.bucket_num());
- EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
- EXPECT_EQ(configAddedTimeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithActivation) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = screenOffMatcher;
- *config.add_atom_matcher() = crashMatcher;
-
- auto durationPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = durationPredicate;
-
- int64_t metricId = 123456;
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(metricId);
- durationMetric->set_what(durationPredicate.id());
- durationMetric->set_bucket(FIVE_MINUTES);
- durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(crashMatcher.id());
- event_activation1->set_ttl_seconds(30); // 30 secs.
-
- const int64_t bucketStartTimeNs = 10000000000;
- const int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config); // 0:00
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- ASSERT_EQ(eventActivationMap.size(), 1u);
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- std::unique_ptr<LogEvent> event;
-
- // Turn screen off.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * NS_PER_SEC,
- android::view::DISPLAY_STATE_OFF); // 0:02
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 2 * NS_PER_SEC);
-
- // Turn screen on.
- const int64_t durationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC; // 0:05
- event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), durationStartNs);
-
- // Activate metric.
- const int64_t activationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC; // 0:10
- const int64_t activationEndNs =
- activationStartNs + event_activation1->ttl_seconds() * NS_PER_SEC; // 0:40
- event = CreateAppCrashEvent(activationStartNs, 111);
- processor.OnLogEvent(event.get(), activationStartNs);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- // Expire activation.
- const int64_t expirationNs = activationEndNs + 7 * NS_PER_SEC;
- event = CreateScreenBrightnessChangedEvent(expirationNs, 64); // 0:47
- processor.OnLogEvent(event.get(), expirationNs);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- ASSERT_EQ(eventActivationMap.size(), 1u);
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- // Turn off screen 10 seconds after activation expiration.
- const int64_t durationEndNs = activationEndNs + 10 * NS_PER_SEC; // 0:50
- event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
- processor.OnLogEvent(event.get(), durationEndNs);
-
- // Turn screen on.
- const int64_t duration2StartNs = durationEndNs + 5 * NS_PER_SEC; // 0:55
- event = CreateScreenStateChangedEvent(duration2StartNs, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), duration2StartNs);
-
- // Turn off screen.
- const int64_t duration2EndNs = duration2StartNs + 10 * NS_PER_SEC; // 1:05
- event = CreateScreenStateChangedEvent(duration2EndNs, android::view::DISPLAY_STATE_OFF);
- processor.OnLogEvent(event.get(), duration2EndNs);
-
- // Activate metric.
- const int64_t activation2StartNs = duration2EndNs + 5 * NS_PER_SEC; // 1:10
- const int64_t activation2EndNs =
- activation2StartNs + event_activation1->ttl_seconds() * NS_PER_SEC; // 1:40
- event = CreateAppCrashEvent(activation2StartNs, 211);
- processor.OnLogEvent(event.get(), activation2StartNs);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, activation2StartNs);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
- ADB_DUMP, FAST, &buffer); // 5:01
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(0, bucketInfo.bucket_num());
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(expirationNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_EQ(expirationNs - durationStartNs, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithCondition) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *config.add_predicate() = isInBackgroundPredicate;
-
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("WakelockDuration"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->set_condition(isInBackgroundPredicate.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- ConfigKey cfgKey;
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_TRUE(eventActivationMap.empty());
-
- int appUid = 123;
- vector<int> attributionUids1 = {appUid};
- vector<string> attributionTags1 = {"App1"};
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
- attributionTags1,
- "wl1"); // 0:10
- processor->OnLogEvent(event.get());
-
- event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid); // 0:22
- processor->OnLogEvent(event.get());
-
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
- appUid); // 3:15
- processor->OnLogEvent(event.get());
-
- event = CreateReleaseWakelockEvent(bucketStartTimeNs + 4 * 60 * NS_PER_SEC, attributionUids1,
- attributionTags1,
- "wl1"); // 4:00
- processor->OnLogEvent(event.get());
-
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
-
- // Validate bucket info.
- ASSERT_EQ(1, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_EQ((2 * 60 + 53) * NS_PER_SEC, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedCondition) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- // The predicate is dimensioning by first attribution node by uid.
- FieldMatcher dimensions = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED,
- {Position::FIRST});
- *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
- *config.add_predicate() = isInBackgroundPredicate;
-
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("WakelockDuration"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->set_condition(isInBackgroundPredicate.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- // The metric is dimensioning by first attribution node and only by uid.
- *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // Links between wakelock state atom and condition of app is in background.
- auto links = durationMetric->add_links();
- links->set_condition(isInBackgroundPredicate.id());
- auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(util::WAKELOCK_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
- util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
-
- ConfigKey cfgKey;
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_TRUE(eventActivationMap.empty());
-
- int appUid = 123;
- std::vector<int> attributionUids1 = {appUid};
- std::vector<string> attributionTags1 = {"App1"};
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
- attributionTags1, "wl1"); // 0:10
- processor->OnLogEvent(event.get());
-
- event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid); // 0:22
- processor->OnLogEvent(event.get());
-
- event = CreateReleaseWakelockEvent(bucketStartTimeNs + 60 * NS_PER_SEC, attributionUids1,
- attributionTags1, "wl1"); // 1:00
- processor->OnLogEvent(event.get());
-
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
- appUid); // 3:15
- processor->OnLogEvent(event.get());
-
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- // Validate dimension value.
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, appUid);
- // Validate bucket info.
- ASSERT_EQ(1, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_EQ(38 * NS_PER_SEC, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
- *config.add_atom_matcher() = screenOnMatcher;
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- // The predicate is dimensioning by first attribution node by uid.
- FieldMatcher dimensions = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED,
- {Position::FIRST});
- *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
- *config.add_predicate() = isInBackgroundPredicate;
-
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("WakelockDuration"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->set_condition(isInBackgroundPredicate.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- // The metric is dimensioning by first attribution node and only by uid.
- *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // Links between wakelock state atom and condition of app is in background.
- auto links = durationMetric->add_links();
- links->set_condition(isInBackgroundPredicate.id());
- auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(util::WAKELOCK_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
- util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(durationMetric->id());
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(screenOnMatcher.id());
- event_activation1->set_ttl_seconds(60 * 2); // 2 minutes.
-
- ConfigKey cfgKey;
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- ASSERT_EQ(eventActivationMap.size(), 1u);
- EXPECT_TRUE(eventActivationMap.find(4) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- int appUid = 123;
- std::vector<int> attributionUids1 = {appUid};
- std::vector<string> attributionTags1 = {"App1"};
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
- attributionTags1, "wl1"); // 0:10
- processor->OnLogEvent(event.get());
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid); // 0:22
- processor->OnLogEvent(event.get());
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- const int64_t durationStartNs = bucketStartTimeNs + 30 * NS_PER_SEC; // 0:30
- event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(event.get());
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- const int64_t durationEndNs =
- durationStartNs + (event_activation1->ttl_seconds() + 30) * NS_PER_SEC; // 3:00
- event = CreateAppCrashEvent(durationEndNs, 333);
- processor->OnLogEvent(event.get());
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
- appUid); // 3:15
- processor->OnLogEvent(event.get());
-
- event = CreateReleaseWakelockEvent(bucketStartTimeNs + (4 * 60 + 17) * NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1"); // 4:17
- processor->OnLogEvent(event.get());
-
- event = CreateMoveToBackgroundEvent(bucketStartTimeNs + (4 * 60 + 20) * NS_PER_SEC,
- appUid); // 4:20
- processor->OnLogEvent(event.get());
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + (4 * 60 + 25) * NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1"); // 4:25
- processor->OnLogEvent(event.get());
-
- const int64_t duration2StartNs = bucketStartTimeNs + (4 * 60 + 30) * NS_PER_SEC; // 4:30
- event = CreateScreenStateChangedEvent(duration2StartNs, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(event.get());
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, duration2StartNs);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- // Validate dimension value.
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, appUid);
- // Validate bucket info.
- ASSERT_EQ(2, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(durationEndNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
-
- bucketInfo = data.bucket_info(1);
- EXPECT_EQ(durationEndNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - duration2StartNs, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedState) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
-
- auto batterySaverModePredicate = CreateBatterySaverModePredicate();
- *config.add_predicate() = batterySaverModePredicate;
-
- auto screenState = CreateScreenState();
- *config.add_state() = screenState;
-
- // Create duration metric that slices by screen state.
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("DurationBatterySaverModeSliceScreen"));
- durationMetric->set_what(batterySaverModePredicate.id());
- durationMetric->add_slice_by_state(screenState.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // Initialize StatsLogProcessor.
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- uint64_t bucketStartTimeNs = 10000000000; // 0:10
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- EXPECT_TRUE(metricsManager->isActive());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricProducer->mIsActive);
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10 (minutes)
- |-----------------------------|-----------------------------|--
- ON OFF ON (BatterySaverMode)
- | | | (ScreenIsOnEvent)
- | | (ScreenIsOffEvent)
- | (ScreenDozeEvent)
- */
- // Initialize log events.
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 10 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 0:20
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 20 * NS_PER_SEC)); // 0:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 50 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:00
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 80 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 1:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 120 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:10
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 200 * NS_PER_SEC)); // 3:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 250 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 4:20
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 280 * NS_PER_SEC)); // 4:50
-
- // Bucket boundary.
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 310 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 5:20
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 360 * NS_PER_SEC,
- true /* include current partial bucket */, true, ADB_DUMP, FAST,
- &buffer); // 6:10
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(3, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(110 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(2);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
- *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
- *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
-
- auto batterySaverModePredicate = CreateBatterySaverModePredicate();
- *config.add_predicate() = batterySaverModePredicate;
-
- auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
- *config.add_predicate() = deviceUnpluggedPredicate;
-
- auto screenState = CreateScreenState();
- *config.add_state() = screenState;
-
- // Create duration metric that has a condition and slices by screen state.
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("DurationBatterySaverModeOnBatterySliceScreen"));
- durationMetric->set_what(batterySaverModePredicate.id());
- durationMetric->set_condition(deviceUnpluggedPredicate.id());
- durationMetric->add_slice_by_state(screenState.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // Initialize StatsLogProcessor.
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- uint64_t bucketStartTimeNs = 10000000000; // 0:10
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- EXPECT_TRUE(metricsManager->isActive());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricProducer->mIsActive);
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 (minutes)
- |---------------------------------------|------------------
- ON OFF ON (BatterySaverMode)
- T F T (DeviceUnpluggedPredicate)
- | | | (ScreenIsOnEvent)
- | | | (ScreenIsOffEvent)
- | (ScreenDozeEvent)
- */
- // Initialize log events.
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 20 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 0:30
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 60 * NS_PER_SEC)); // 1:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 80 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:30
- events.push_back(
- CreateBatteryStateChangedEvent(bucketStartTimeNs + 110 * NS_PER_SEC,
- BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE)); // 2:00
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 145 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:35
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 170 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 3:00
- events.push_back(
- CreateBatteryStateChangedEvent(bucketStartTimeNs + 180 * NS_PER_SEC,
- BatteryPluggedStateEnum::BATTERY_PLUGGED_USB)); // 3:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 200 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 3:30
- events.push_back(
- CreateBatteryStateChangedEvent(bucketStartTimeNs + 230 * NS_PER_SEC,
- BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE)); // 4:00
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 260 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 4:30
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 280 * NS_PER_SEC)); // 4:50
-
- // Bucket boundary.
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 320 * NS_PER_SEC)); // 5:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 380 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 6:30
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 410 * NS_PER_SEC,
- true /* include current partial bucket */, true, ADB_DUMP, FAST,
- &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(3, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(45 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(45 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(60 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(2);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedStateMapped) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
-
- auto batterySaverModePredicate = CreateBatterySaverModePredicate();
- *config.add_predicate() = batterySaverModePredicate;
-
- int64_t screenOnId = 4444;
- int64_t screenOffId = 9876;
- auto screenStateWithMap = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
- *config.add_state() = screenStateWithMap;
-
- // Create duration metric that slices by mapped screen state.
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("DurationBatterySaverModeSliceScreenMapped"));
- durationMetric->set_what(batterySaverModePredicate.id());
- durationMetric->add_slice_by_state(screenStateWithMap.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // Initialize StatsLogProcessor.
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- uint64_t bucketStartTimeNs = 10000000000; // 0:10
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- EXPECT_TRUE(metricsManager->isActive());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricProducer->mIsActive);
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10 (minutes)
- |-----------------------------|-----------------------------|--
- ON OFF ON (BatterySaverMode)
- ---------------------------------------------------------SCREEN_OFF events
- | | (ScreenStateOffEvent = 1)
- | (ScreenStateDozeEvent = 3)
- | (ScreenStateDozeSuspendEvent = 4)
- ---------------------------------------------------------SCREEN_ON events
- | | | (ScreenStateOnEvent = 2)
- | (ScreenStateVrEvent = 5)
- | (ScreenStateOnSuspendEvent = 6)
- */
- // Initialize log events.
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 10 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 0:20
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 20 * NS_PER_SEC)); // 0:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 70 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:20
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 100 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 1:50
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 120 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 170 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_VR)); // 3:00
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 200 * NS_PER_SEC)); // 3:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 250 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 4:20
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 280 * NS_PER_SEC)); // 4:50
-
- // Bucket boundary 5:10.
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 320 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 5:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 390 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND)); // 6:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 430 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND)); // 7:20
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 490 * NS_PER_SEC,
- true /* include current partial bucket */, true, ADB_DUMP, FAST,
- &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(2, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(130 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(110 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(500 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(80 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(500 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto uidProcessState = CreateUidProcessState();
- *config.add_state() = uidProcessState;
-
- // Create duration metric that slices by uid process state.
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("DurationHoldingWakelockSliceUidProcessState"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->add_slice_by_state(uidProcessState.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // The state has only one primary field (uid).
- auto stateLink = durationMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-
- // Initialize StatsLogProcessor.
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- uint64_t bucketStartTimeNs = 10000000000; // 0:10
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // This config is rejected because the dimension in what fields are not a superset of the sliced
- // state primary fields.
- ASSERT_EQ(processor->mMetricsManagers.size(), 0);
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto uidProcessState = CreateUidProcessState();
- *config.add_state() = uidProcessState;
-
- // Create duration metric that slices by uid process state.
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("DurationPartialWakelockPerTagUidSliceProcessState"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->add_slice_by_state(uidProcessState.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // The metric is dimensioning by first uid of attribution node and tag.
- *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidAndOtherDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST}, {3 /* tag */});
- // The state has only one primary field (uid).
- auto stateLink = durationMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-
- // Initialize StatsLogProcessor.
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- uint64_t bucketStartTimeNs = 10000000000; // 0:10
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- EXPECT_TRUE(metricsManager->isActive());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricProducer->mIsActive);
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
- // Initialize log events.
- int appUid1 = 1001;
- int appUid2 = 1002;
- std::vector<int> attributionUids1 = {appUid1};
- std::vector<string> attributionTags1 = {"App1"};
-
- std::vector<int> attributionUids2 = {appUid2};
- std::vector<string> attributionTags2 = {"App2"};
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 10 * NS_PER_SEC, appUid1,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 0:20
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 20 * NS_PER_SEC,
- attributionUids1, attributionTags1,
- "wakelock1")); // 0:30
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 25 * NS_PER_SEC,
- attributionUids1, attributionTags1,
- "wakelock2")); // 0:35
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 30 * NS_PER_SEC,
- attributionUids2, attributionTags2,
- "wakelock1")); // 0:40
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 35 * NS_PER_SEC,
- attributionUids2, attributionTags2,
- "wakelock2")); // 0:45
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 50 * NS_PER_SEC, appUid2,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND)); // 1:00
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 60 * NS_PER_SEC, appUid1,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND)); // 1:10
- events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 100 * NS_PER_SEC,
- attributionUids2, attributionTags2,
- "wakelock1")); // 1:50
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 120 * NS_PER_SEC, appUid2,
- android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 2:10
- events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 200 * NS_PER_SEC,
- attributionUids1, attributionTags1,
- "wakelock2")); // 3:30
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 320 * NS_PER_SEC,
- true /* include current partial bucket */, true, ADB_DUMP, FAST,
- &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(9, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
- "wakelock1");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(1);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
- "wakelock1");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(240 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(330 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(2);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
- "wakelock2");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(35 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(3);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
- "wakelock2");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(140 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(4);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
- "wakelock1");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(5);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
- "wakelock1");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(6);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
- "wakelock2");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(15 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(7);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
- "wakelock2");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
- data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(180 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(330 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(8);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
- "wakelock2");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
deleted file mode 100644
index 1be2612..0000000
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ /dev/null
@@ -1,624 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-const int64_t metricId = 123456;
-const int32_t ATOM_TAG = util::SUBSYSTEM_SLEEP_STATE;
-
-StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type,
- bool useCondition = true) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
- auto atomMatcher = CreateSimpleAtomMatcher("TestMatcher", ATOM_TAG);
- *config.add_atom_matcher() = atomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenIsOffPredicate;
-
- auto gaugeMetric = config.add_gauge_metric();
- gaugeMetric->set_id(metricId);
- gaugeMetric->set_what(atomMatcher.id());
- if (useCondition) {
- gaugeMetric->set_condition(screenIsOffPredicate.id());
- }
- gaugeMetric->set_sampling_type(sampling_type);
- gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
- *gaugeMetric->mutable_dimensions_in_what() =
- CreateDimensions(ATOM_TAG, {1 /* subsystem name */});
- gaugeMetric->set_bucket(FIVE_MINUTES);
- gaugeMetric->set_max_pull_delay_sec(INT_MAX);
- config.set_hash_strings_in_metric_report(false);
-
- return config;
-}
-
-} // namespaces
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) {
- auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor =
- CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- // When creating the config, the gauge metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& nextPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- // Pulling alarm arrives on time and reset the sequential pulling alarm.
- processor->informPullAlarmFired(nextPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
-
- auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- processor->informPullAlarmFired(nextPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
-
- processor->informPullAlarmFired(nextPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
-
- screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- processor->informPullAlarmFired(nextPullTimeNs + 3);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- processor->informPullAlarmFired(nextPullTimeNs + 2);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, nextPullTimeNs);
-
- processor->informPullAlarmFired(nextPullTimeNs + 2);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
- ASSERT_GT((int)gaugeMetrics.data_size(), 1);
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(6, data.bucket_info_size());
-
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(2).atom_size());
- ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(3).atom_size());
- ASSERT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 1, data.bucket_info(3).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(3).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(3).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(4).atom_size());
- ASSERT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(4).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(4).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(4).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(5).atom_size());
- ASSERT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs + 2, data.bucket_info(5).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(5).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(5).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(5).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(5).atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) {
- auto config = CreateStatsdConfig(GaugeMetric::CONDITION_CHANGE_TO_TRUE);
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor =
- CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
- screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 3,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 10,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
- ASSERT_GT((int)gaugeMetrics.data_size(), 1);
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(3, data.bucket_info_size());
-
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 100, data.bucket_info(1).elapsed_timestamp_nanos(0));
- EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(2, data.bucket_info(2).atom_size());
- ASSERT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 10, data.bucket_info(2).elapsed_timestamp_nanos(1));
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
- EXPECT_TRUE(data.bucket_info(2).atom(1).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(2).atom(1).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) {
- auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor =
- CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- // When creating the config, the gauge metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& nextPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- // Pulling alarm arrives one bucket size late.
- processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 11,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- // Pulling alarm arrives more than one bucket size late.
- processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs + 12);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
- ASSERT_GT((int)gaugeMetrics.data_size(), 1);
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(3, data.bucket_info_size());
-
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- EXPECT_EQ(configAddedTimeNs + 3 * bucketSizeNs + 11,
- data.bucket_info(1).elapsed_timestamp_nanos(0));
- EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(2).atom_size());
- ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs + 12, data.bucket_info(2).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation) {
- auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
-
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = batterySaverStartMatcher;
- const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
- auto metric_activation = config.add_metric_activation();
- metric_activation->set_metric_id(metricId);
- metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
- auto event_activation = metric_activation->add_event_activation();
- event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
- event_activation->set_ttl_seconds(ttlNs / 1000000000);
-
- ConfigKey cfgKey;
- auto processor =
- CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // When creating the config, the gauge metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& nextPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
- // Pulling alarm arrives on time and reset the sequential pulling alarm.
- // Event should not be kept.
- processor->informPullAlarmFired(nextPullTimeNs + 1); // 15 mins + 1 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // Activate the metric. A pull occurs upon activation.
- const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
- auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
- processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // This event should be kept. 2 total.
- processor->informPullAlarmFired(nextPullTimeNs + 1); // 20 mins + 1 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
-
- // This event should be kept. 3 total.
- processor->informPullAlarmFired(nextPullTimeNs + 2); // 25 mins + 2 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
-
- // Create random event to deactivate metric.
- auto deactivationEvent = CreateScreenBrightnessChangedEvent(activationNs + ttlNs + 1, 50);
- processor->OnLogEvent(deactivationEvent.get());
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // Event should not be kept. 3 total.
- processor->informPullAlarmFired(nextPullTimeNs + 3);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
-
- processor->informPullAlarmFired(nextPullTimeNs + 2);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
- ASSERT_GT((int)gaugeMetrics.data_size(), 0);
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(3, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- ASSERT_EQ(1, bucketInfo.atom_size());
- ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
- EXPECT_EQ(activationNs, bucketInfo.elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
-
- bucketInfo = data.bucket_info(1);
- ASSERT_EQ(1, bucketInfo.atom_size());
- ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, bucketInfo.elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
-
- bucketInfo = data.bucket_info(2);
- ASSERT_EQ(1, bucketInfo.atom_size());
- ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, bucketInfo.elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
- EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
- bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(MillisToNano(NanoToMillis(activationNs + ttlNs + 1)),
- bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) {
- auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
-
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(),
- ATOM_TAG);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()->second->
- mAllMetricProducers[0]->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- // When creating the config, the gauge metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& nextPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
- // Pulling alarm arrives on time and reset the sequential pulling alarm.
- processor->informPullAlarmFired(nextPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
-
- processor->informPullAlarmFired(nextPullTimeNs + 4);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs,
- nextPullTimeNs);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(
- reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
- ASSERT_GT((int)gaugeMetrics.data_size(), 0);
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(3, data.bucket_info_size());
-
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, data.bucket_info(1).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(2).atom_size());
- ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 4, data.bucket_info(2).elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, data.bucket_info(2).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
deleted file mode 100644
index a40a948..0000000
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfigForPushedEvent(const GaugeMetric::SamplingType sampling_type) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
- auto atomMatcher = CreateSimpleAtomMatcher("", util::APP_START_OCCURRED);
- *config.add_atom_matcher() = atomMatcher;
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
- *config.add_predicate() = isInBackgroundPredicate;
-
- auto gaugeMetric = config.add_gauge_metric();
- gaugeMetric->set_id(123456);
- gaugeMetric->set_what(atomMatcher.id());
- gaugeMetric->set_condition(isInBackgroundPredicate.id());
- gaugeMetric->mutable_gauge_fields_filter()->set_include_all(false);
- gaugeMetric->set_sampling_type(sampling_type);
- auto fieldMatcher = gaugeMetric->mutable_gauge_fields_filter()->mutable_fields();
- fieldMatcher->set_field(util::APP_START_OCCURRED);
- fieldMatcher->add_child()->set_field(3); // type (enum)
- fieldMatcher->add_child()->set_field(4); // activity_name(str)
- fieldMatcher->add_child()->set_field(7); // activity_start_msec(int64)
- *gaugeMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::APP_START_OCCURRED, {1 /* uid field */ });
- gaugeMetric->set_bucket(FIVE_MINUTES);
-
- auto links = gaugeMetric->add_links();
- links->set_condition(isInBackgroundPredicate.id());
- auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(util::APP_START_OCCURRED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- auto dimensionCondition = links->mutable_fields_in_condition();
- dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- dimensionCondition->add_child()->set_field(1); // uid field.
- return config;
-}
-
-std::unique_ptr<LogEvent> CreateAppStartOccurredEvent(
- uint64_t timestampNs, const int uid, const string& pkg_name,
- AppStartOccurred::TransitionType type, const string& activity_name,
- const string& calling_pkg_name, const bool is_instant_app, int64_t activity_start_msec) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::APP_START_OCCURRED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, pkg_name.c_str());
- AStatsEvent_writeInt32(statsEvent, type);
- AStatsEvent_writeString(statsEvent, activity_name.c_str());
- AStatsEvent_writeString(statsEvent, calling_pkg_name.c_str());
- AStatsEvent_writeInt32(statsEvent, is_instant_app);
- AStatsEvent_writeInt32(statsEvent, activity_start_msec);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-} // namespace
-
-TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
- for (const auto& sampling_type :
- {GaugeMetric::FIRST_N_SAMPLES, GaugeMetric::RANDOM_ONE_SAMPLE}) {
- auto config = CreateStatsdConfigForPushedEvent(sampling_type);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor =
- CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- int appUid1 = 123;
- int appUid2 = 456;
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid1));
- events.push_back(
- CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid1));
- events.push_back(
- CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid1));
- events.push_back(
- CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100, appUid1));
-
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 10, appUid1, "app1", AppStartOccurred::WARM, "activity_name1",
- "calling_pkg_name1", true /*is_instant_app*/, 101 /*activity_start_msec*/));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 20, appUid1, "app1", AppStartOccurred::HOT, "activity_name2",
- "calling_pkg_name2", true /*is_instant_app*/, 102 /*activity_start_msec*/));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 30, appUid1, "app1", AppStartOccurred::COLD, "activity_name3",
- "calling_pkg_name3", true /*is_instant_app*/, 103 /*activity_start_msec*/));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + bucketSizeNs + 30, appUid1, "app1", AppStartOccurred::WARM,
- "activity_name4", "calling_pkg_name4", true /*is_instant_app*/,
- 104 /*activity_start_msec*/));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 2 * bucketSizeNs, appUid1, "app1", AppStartOccurred::COLD,
- "activity_name5", "calling_pkg_name5", true /*is_instant_app*/,
- 105 /*activity_start_msec*/));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 2 * bucketSizeNs + 10, appUid1, "app1", AppStartOccurred::HOT,
- "activity_name6", "calling_pkg_name6", false /*is_instant_app*/,
- 106 /*activity_start_msec*/));
-
- events.push_back(
- CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 10, appUid2));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 2 * bucketSizeNs + 10, appUid2, "app2", AppStartOccurred::COLD,
- "activity_name7", "calling_pkg_name7", true /*is_instant_app*/,
- 201 /*activity_start_msec*/));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(),
- &gaugeMetrics);
- ASSERT_EQ(2, gaugeMetrics.data_size());
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(util::APP_START_OCCURRED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(appUid1, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(3, data.bucket_info_size());
- if (sampling_type == GaugeMetric::FIRST_N_SAMPLES) {
- ASSERT_EQ(2, data.bucket_info(0).atom_size());
- ASSERT_EQ(2, data.bucket_info(0).elapsed_timestamp_nanos_size());
- ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
- data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::HOT,
- data.bucket_info(0).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name2",
- data.bucket_info(0).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(102L,
- data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
- EXPECT_EQ(AppStartOccurred::COLD,
- data.bucket_info(0).atom(1).app_start_occurred().type());
- EXPECT_EQ("activity_name3",
- data.bucket_info(0).atom(1).app_start_occurred().activity_name());
- EXPECT_EQ(103L,
- data.bucket_info(0).atom(1).app_start_occurred().activity_start_millis());
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
- data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::WARM,
- data.bucket_info(1).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name4",
- data.bucket_info(1).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(104L,
- data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
-
- ASSERT_EQ(2, data.bucket_info(2).atom_size());
- ASSERT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
- data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::COLD,
- data.bucket_info(2).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name5",
- data.bucket_info(2).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(105L,
- data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
- EXPECT_EQ(AppStartOccurred::HOT,
- data.bucket_info(2).atom(1).app_start_occurred().type());
- EXPECT_EQ("activity_name6",
- data.bucket_info(2).atom(1).app_start_occurred().activity_name());
- EXPECT_EQ(106L,
- data.bucket_info(2).atom(1).app_start_occurred().activity_start_millis());
- } else {
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
- data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::HOT,
- data.bucket_info(0).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name2",
- data.bucket_info(0).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(102L,
- data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
- data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::WARM,
- data.bucket_info(1).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name4",
- data.bucket_info(1).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(104L,
- data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
-
- ASSERT_EQ(1, data.bucket_info(2).atom_size());
- ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
- data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::COLD,
- data.bucket_info(2).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name5",
- data.bucket_info(2).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(105L,
- data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
- }
-
- data = gaugeMetrics.data(1);
-
- EXPECT_EQ(data.dimensions_in_what().field(), util::APP_START_OCCURRED);
- ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(appUid2, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
- data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::COLD, data.bucket_info(0).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name7",
- data.bucket_info(0).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(201L, data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
- }
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
deleted file mode 100644
index e320419..0000000
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ /dev/null
@@ -1,1833 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-
- *config.add_atom_matcher() = saverModeMatcher;
- *config.add_atom_matcher() = crashMatcher;
- *config.add_atom_matcher() = screenOnMatcher;
-
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(crashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- auto event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
-
- return config;
-}
-
-StatsdConfig CreateStatsdConfigWithOneDeactivation() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
-
- *config.add_atom_matcher() = saverModeMatcher;
- *config.add_atom_matcher() = crashMatcher;
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher;
-
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(crashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
- auto event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
-
- return config;
-}
-
-StatsdConfig CreateStatsdConfigWithTwoDeactivations() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
- auto brightnessChangedMatcher2 = CreateScreenBrightnessChangedAtomMatcher();
- brightnessChangedMatcher2.set_id(StringToId("ScreenBrightnessChanged2"));
-
- *config.add_atom_matcher() = saverModeMatcher;
- *config.add_atom_matcher() = crashMatcher;
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher2;
-
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(crashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
- auto event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
- event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
-
- return config;
-}
-
-StatsdConfig CreateStatsdConfigWithSameDeactivations() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
-
- *config.add_atom_matcher() = saverModeMatcher;
- *config.add_atom_matcher() = crashMatcher;
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher;
-
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(crashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
- auto event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
- event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
-
- return config;
-}
-
-StatsdConfig CreateStatsdConfigWithTwoMetricsTwoDeactivations() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- auto foregroundMatcher = CreateMoveToForegroundAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
- auto brightnessChangedMatcher2 = CreateScreenBrightnessChangedAtomMatcher();
- brightnessChangedMatcher2.set_id(StringToId("ScreenBrightnessChanged2"));
-
- *config.add_atom_matcher() = saverModeMatcher;
- *config.add_atom_matcher() = crashMatcher;
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher2;
- *config.add_atom_matcher() = foregroundMatcher;
-
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(crashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- int64_t metricId2 = 234567;
- countMetric = config.add_count_metric();
- countMetric->set_id(metricId2);
- countMetric->set_what(foregroundMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
- auto event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
- event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
-
- metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId2);
- event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
- event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
- event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
-
- return config;
-}
-
-} // namespace
-
-TEST(MetricActivationE2eTest, TestCountMetric) {
- auto config = CreateStatsdConfig();
-
- int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
- // triggered by screen on event (tracker index 2).
- ASSERT_EQ(eventActivationMap.size(), 2u);
- EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
- std::unique_ptr<LogEvent> event;
-
- event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 0);
-
- // Activated by battery save mode.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
- // First processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
- // Activated by screen on event.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
- // 2nd processed event.
- // The activation by screen_on event expires, but the one by battery save mode is still active.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- // No new broadcast since the config should still be active.
- EXPECT_EQ(broadcastCount, 1);
-
- // 3rd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
- // All activations expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
- // Re-activate metric via screen on.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
- android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
- // 4th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(4, countMetrics.data_size());
-
- auto data = countMetrics.data(0);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation) {
- auto config = CreateStatsdConfigWithOneDeactivation();
-
- int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
- // triggered by screen on event (tracker index 2).
- ASSERT_EQ(eventActivationMap.size(), 2u);
- EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- ASSERT_EQ(eventDeactivationMap.size(), 1u);
- EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
- ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- std::unique_ptr<LogEvent> event;
-
- event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 0);
-
- // Activated by battery save mode.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // First processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
- // Activated by screen on event.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // 2nd processed event.
- // The activation by screen_on event expires, but the one by battery save mode is still active.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- // No new broadcast since the config should still be active.
- EXPECT_EQ(broadcastCount, 1);
-
- // 3rd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
- // All activations expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // Re-activate metric via screen on.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
- android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // 4th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // 5th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 777);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
-
- // Cancel battery saver mode activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60, 64);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // Screen-on activation expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 888);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 999);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 5);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // Cancel battery saver mode activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 16, 140);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 16);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 6);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(5, countMetrics.data_size());
-
- auto data = countMetrics.data(0);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 13,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(4);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 13,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations) {
- auto config = CreateStatsdConfigWithTwoDeactivations();
-
- int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
- // triggered by screen on event (tracker index 2).
- ASSERT_EQ(eventActivationMap.size(), 2u);
- EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- ASSERT_EQ(eventDeactivationMap.size(), 2u);
- EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
- EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
- ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
- ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- std::unique_ptr<LogEvent> event;
-
- event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 0);
-
- // Activated by battery save mode.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // First processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
- // Activated by screen on event.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // 2nd processed event.
- // The activation by screen_on event expires, but the one by battery save mode is still active.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- // No new broadcast since the config should still be active.
- EXPECT_EQ(broadcastCount, 1);
-
- // 3rd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
- // All activations expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // Re-activate metric via screen on.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
- android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // 4th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // 5th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 777);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
-
- // Cancel battery saver mode and screen on activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60, 64);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // Screen-on activation expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 888);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 999);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 5);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // Cancel battery saver mode and screen on activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 16, 140);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 16);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 6);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(5, countMetrics.data_size());
-
- auto data = countMetrics.data(0);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(4);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation) {
- auto config = CreateStatsdConfigWithSameDeactivations();
-
- int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
- // triggered by screen on event (tracker index 2).
- ASSERT_EQ(eventActivationMap.size(), 2u);
- EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- ASSERT_EQ(eventDeactivationMap.size(), 1u);
- EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
- ASSERT_EQ(eventDeactivationMap[3].size(), 2u);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[3][1], eventActivationMap[2]);
- EXPECT_EQ(broadcastCount, 0);
-
- std::unique_ptr<LogEvent> event;
-
- // Event that should be ignored.
- event = CreateAppCrashEvent(bucketStartTimeNs + 1, 111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 1);
-
- // Activate metric via screen on for 2 minutes.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 10, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 10);
-
- // 1st processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
- // Enable battery saver mode activation for 5 minutes.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 + 10);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 + 10);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 10);
-
- // 2nd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 + 40, 333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 + 40);
-
- // Cancel battery saver mode and screen on activation.
- int64_t firstDeactivation = bucketStartTimeNs + NS_PER_SEC * 61;
- event = CreateScreenBrightnessChangedEvent(firstDeactivation, 64);
- processor.OnLogEvent(event.get(), firstDeactivation);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-
- // Should be ignored
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 61 + 80, 444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 61 + 80);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-
- // 3rd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 80, 555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 80);
-
- // Cancel battery saver mode activation.
- int64_t secondDeactivation = bucketStartTimeNs + NS_PER_SEC * 60 * 13;
- event = CreateScreenBrightnessChangedEvent(secondDeactivation, 140);
- processor.OnLogEvent(event.get(), secondDeactivation);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-
- // Should be ignored.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13 + 80, 666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13 + 80);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(3, countMetrics.data_size());
-
- auto data = countMetrics.data(0);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(555, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(secondDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations) {
- auto config = CreateStatsdConfigWithTwoMetricsTwoDeactivations();
-
- int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 2);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
- sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[1];
- auto& eventActivationMap2 = metricProducer2->mEventActivationMap;
- auto& eventDeactivationMap2 = metricProducer2->mEventDeactivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_FALSE(metricProducer2->mIsActive);
- // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
- // triggered by screen on event (tracker index 2).
- ASSERT_EQ(eventActivationMap.size(), 2u);
- EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- ASSERT_EQ(eventDeactivationMap.size(), 2u);
- EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
- EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
- ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
- ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- ASSERT_EQ(eventActivationMap2.size(), 2u);
- EXPECT_TRUE(eventActivationMap2.find(0) != eventActivationMap2.end());
- EXPECT_TRUE(eventActivationMap2.find(2) != eventActivationMap2.end());
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- ASSERT_EQ(eventDeactivationMap2.size(), 2u);
- EXPECT_TRUE(eventDeactivationMap2.find(3) != eventDeactivationMap2.end());
- EXPECT_TRUE(eventDeactivationMap2.find(4) != eventDeactivationMap2.end());
- ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
- ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- std::unique_ptr<LogEvent> event;
-
- event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + 5, 1111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_FALSE(metricProducer2->mIsActive);
- EXPECT_EQ(broadcastCount, 0);
-
- // Activated by battery save mode.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // First processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + 15, 2222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
- // Activated by screen on event.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // 2nd processed event.
- // The activation by screen_on event expires, but the one by battery save mode is still active.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 3333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
- // No new broadcast since the config should still be active.
- EXPECT_EQ(broadcastCount, 1);
-
- // 3rd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 4444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
- // All activations expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 5555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
- EXPECT_FALSE(metricsManager->isActive());
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_FALSE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // Re-activate metric via screen on.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
- android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // 4th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 6666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // 5th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 777);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 7777);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
-
- // Cancel battery saver mode and screen on activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60, 64);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
- EXPECT_FALSE(metricsManager->isActive());
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_FALSE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // Screen-on activation expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 888);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 8888);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_FALSE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 999);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 9999);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 5);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // Cancel battery saver mode and screen on activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 16, 140);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 16);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 6);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_FALSE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(2, reports.reports(0).metrics_size());
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
-
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(5, countMetrics.data_size());
-
- auto data = countMetrics.data(0);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(4);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- countMetrics.clear_data();
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(1).count_metrics(), &countMetrics);
- ASSERT_EQ(5, countMetrics.data_size());
-
- data = countMetrics.data(0);
- EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(2222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(3333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(4444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(6666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(4);
- EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(7777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
deleted file mode 100644
index 5e77ee0..0000000
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-namespace {
-
-StatsdConfig CreateStatsdConfig() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
- auto appCrashMatcher = CreateProcessCrashAtomMatcher();
- *config.add_atom_matcher() = appCrashMatcher;
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidDimensions(
- util::SYNC_STATE_CHANGED, {Position::FIRST});
- syncDimension->add_child()->set_field(2 /* name field*/);
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
-
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- *config.add_predicate() = isInBackgroundPredicate;
-
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(StringToId("combinationPredicate"));
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isInBackgroundPredicate, combinationPredicate);
-
- auto countMetric = config.add_count_metric();
- countMetric->set_id(StringToId("AppCrashes"));
- countMetric->set_what(appCrashMatcher.id());
- countMetric->set_condition(combinationPredicate->id());
- // The metric is dimensioning by uid only.
- *countMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, {1});
- countMetric->set_bucket(FIVE_MINUTES);
-
- // Links between crash atom and condition of app is in syncing.
- auto links = countMetric->add_links();
- links->set_condition(isSyncingPredicate.id());
- auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
- util::SYNC_STATE_CHANGED, {Position::FIRST});
-
- // Links between crash atom and condition of app is in background.
- links = countMetric->add_links();
- links->set_condition(isInBackgroundPredicate.id());
- dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- auto dimensionCondition = links->mutable_fields_in_condition();
- dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- dimensionCondition->add_child()->set_field(1); // uid field.
- return config;
-}
-} // namespace
-
-// If we want to test multiple dump data, we must do it in separate tests, because in the e2e tests,
-// we should use the real API which will clear the data after dump data is called.
-TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) {
- auto config = CreateStatsdConfig();
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- int appUid = 123;
- auto crashEvent1 = CreateAppCrashEvent(bucketStartTimeNs + 1, appUid);
- auto crashEvent2 = CreateAppCrashEvent(bucketStartTimeNs + 201, appUid);
- auto crashEvent3 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 101, appUid);
-
- auto crashEvent4 = CreateAppCrashEvent(bucketStartTimeNs + 51, appUid);
- auto crashEvent5 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 299, appUid);
- auto crashEvent6 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 2001, appUid);
-
- auto crashEvent7 = CreateAppCrashEvent(bucketStartTimeNs + 16, appUid);
- auto crashEvent8 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 249, appUid);
-
- auto crashEvent9 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 351, appUid);
- auto crashEvent10 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 2, appUid);
-
- auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 2, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- auto screenTurnedOnEvent2 =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
- std::vector<int> attributionUids = {appUid, appUid + 1};
- std::vector<string> attributionTags = {"App1", "GMSCoreModule1"};
-
- auto syncOnEvent1 = CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids,
- attributionTags, "ReadEmail");
- auto syncOffEvent1 = CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids,
- attributionTags, "ReadEmail");
- auto syncOnEvent2 = CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs + 2000,
- attributionUids, attributionTags, "ReadDoc");
-
- auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid);
- auto moveToForegroundEvent1 =
- CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid);
-
- auto moveToBackgroundEvent2 =
- CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid);
- auto moveToForegroundEvent2 =
- CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs - 1, appUid);
-
- /*
- bucket #1 bucket #2
-
-
- | | | | | | | | | | (crashEvents)
- |-------------------------------------|-----------------------------------|---------
-
- | | (MoveToBkground)
-
- | | (MoveToForeground)
-
- | | (SyncIsOn)
- | (SyncIsOff)
- | | (ScreenIsOn)
- | (ScreenIsOff)
- */
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(std::move(crashEvent1));
- events.push_back(std::move(crashEvent2));
- events.push_back(std::move(crashEvent3));
- events.push_back(std::move(crashEvent4));
- events.push_back(std::move(crashEvent5));
- events.push_back(std::move(crashEvent6));
- events.push_back(std::move(crashEvent7));
- events.push_back(std::move(crashEvent8));
- events.push_back(std::move(crashEvent9));
- events.push_back(std::move(crashEvent10));
- events.push_back(std::move(screenTurnedOnEvent));
- events.push_back(std::move(screenTurnedOffEvent));
- events.push_back(std::move(screenTurnedOnEvent2));
- events.push_back(std::move(syncOnEvent1));
- events.push_back(std::move(syncOffEvent1));
- events.push_back(std::move(syncOnEvent2));
- events.push_back(std::move(moveToBackgroundEvent1));
- events.push_back(std::move(moveToForegroundEvent1));
- events.push_back(std::move(moveToBackgroundEvent2));
- events.push_back(std::move(moveToForegroundEvent2));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
- auto data = reports.reports(0).metrics(0).count_metrics().data(0);
- // Validate dimension value.
- EXPECT_EQ(data.dimensions_in_what().field(), util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- // Uid field.
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
-}
-
-TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2) {
- auto config = CreateStatsdConfig();
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- int appUid = 123;
- auto crashEvent1 = CreateAppCrashEvent(bucketStartTimeNs + 1, appUid);
- auto crashEvent2 = CreateAppCrashEvent(bucketStartTimeNs + 201, appUid);
- auto crashEvent3 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 101, appUid);
-
- auto crashEvent4 = CreateAppCrashEvent(bucketStartTimeNs + 51, appUid);
- auto crashEvent5 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 299, appUid);
- auto crashEvent6 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 2001, appUid);
-
- auto crashEvent7 = CreateAppCrashEvent(bucketStartTimeNs + 16, appUid);
- auto crashEvent8 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 249, appUid);
-
- auto crashEvent9 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 351, appUid);
- auto crashEvent10 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 2, appUid);
-
- auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 2, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- auto screenTurnedOnEvent2 =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
- std::vector<int> attributionUids = {appUid, appUid + 1};
- std::vector<string> attributionTags = {"App1", "GMSCoreModule1"};
-
- auto syncOnEvent1 = CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids,
- attributionTags, "ReadEmail");
- auto syncOffEvent1 = CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids,
- attributionTags, "ReadEmail");
- auto syncOnEvent2 = CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs + 2000,
- attributionUids, attributionTags, "ReadDoc");
-
- auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid);
- auto moveToForegroundEvent1 =
- CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid);
-
- auto moveToBackgroundEvent2 =
- CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid);
- auto moveToForegroundEvent2 =
- CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs - 1, appUid);
-
- /*
- bucket #1 bucket #2
-
-
- | | | | | | | | | | (crashEvents)
- |-------------------------------------|-----------------------------------|---------
-
- | | (MoveToBkground)
-
- | | (MoveToForeground)
-
- | | (SyncIsOn)
- | (SyncIsOff)
- | | (ScreenIsOn)
- | (ScreenIsOff)
- */
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(std::move(crashEvent1));
- events.push_back(std::move(crashEvent2));
- events.push_back(std::move(crashEvent3));
- events.push_back(std::move(crashEvent4));
- events.push_back(std::move(crashEvent5));
- events.push_back(std::move(crashEvent6));
- events.push_back(std::move(crashEvent7));
- events.push_back(std::move(crashEvent8));
- events.push_back(std::move(crashEvent9));
- events.push_back(std::move(crashEvent10));
- events.push_back(std::move(screenTurnedOnEvent));
- events.push_back(std::move(screenTurnedOffEvent));
- events.push_back(std::move(screenTurnedOnEvent2));
- events.push_back(std::move(syncOnEvent1));
- events.push_back(std::move(syncOffEvent1));
- events.push_back(std::move(syncOnEvent2));
- events.push_back(std::move(moveToBackgroundEvent1));
- events.push_back(std::move(moveToForegroundEvent1));
- events.push_back(std::move(moveToBackgroundEvent2));
- events.push_back(std::move(moveToForegroundEvent2));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
-
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 2);
- EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
- EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(1).count(), 3);
- auto data = reports.reports(0).metrics(0).count_metrics().data(0);
- // Validate dimension value.
- EXPECT_EQ(data.dimensions_in_what().field(), util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- // Uid field.
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
deleted file mode 100644
index 783f31c..0000000
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <android/binder_ibinder.h>
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/StatsService.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using::ndk::SharedRefBase;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-namespace {
-const string kApp1 = "app1.sharing.1";
-const int kConfigKey = 789130123; // Randomly chosen to avoid collisions with existing configs.
-const int kCallingUid = 0; // Randomly chosen
-
-void SendConfig(shared_ptr<StatsService>& service, const StatsdConfig& config) {
- string str;
- config.SerializeToString(&str);
- std::vector<int8_t> configAsVec(str.begin(), str.end());
- service->addConfiguration(kConfigKey, configAsVec, kCallingUid);
-}
-
-ConfigMetricsReport GetReports(sp<StatsLogProcessor> processor, int64_t timestamp,
- bool include_current = false) {
- vector<uint8_t> output;
- ConfigKey configKey(AIBinder_getCallingUid(), kConfigKey);
- processor->onDumpReport(configKey, timestamp, include_current /* include_current_bucket*/,
- true /* erase_data */, ADB_DUMP, NO_TIME_CONSTRAINTS, &output);
- ConfigMetricsReportList reports;
- reports.ParseFromArray(output.data(), output.size());
- EXPECT_EQ(1, reports.reports_size());
- return reports.reports(kCallingUid);
-}
-
-StatsdConfig MakeConfig() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto appCrashMatcher = CreateProcessCrashAtomMatcher();
- *config.add_atom_matcher() = appCrashMatcher;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(StringToId("AppCrashes"));
- countMetric->set_what(appCrashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- return config;
-}
-
-StatsdConfig MakeValueMetricConfig(int64_t minTime) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
-
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto valueMetric = config.add_value_metric();
- valueMetric->set_id(123456);
- valueMetric->set_what(pulledAtomMatcher.id());
- *valueMetric->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- *valueMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
- valueMetric->set_bucket(FIVE_MINUTES);
- valueMetric->set_min_bucket_size_nanos(minTime);
- valueMetric->set_use_absolute_value_on_reset(true);
- valueMetric->set_skip_zero_diff_output(false);
- return config;
-}
-
-StatsdConfig MakeGaugeMetricConfig(int64_t minTime) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
-
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto gaugeMetric = config.add_gauge_metric();
- gaugeMetric->set_id(123456);
- gaugeMetric->set_what(pulledAtomMatcher.id());
- gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
- *gaugeMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
- gaugeMetric->set_bucket(FIVE_MINUTES);
- gaugeMetric->set_min_bucket_size_nanos(minTime);
- return config;
-}
-} // anonymous namespace
-
-TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- SendConfig(service, MakeConfig());
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 2, 100).get());
-
- ConfigMetricsReport report = GetReports(service->mProcessor, start + 3);
- // Expect no metrics since the bucket has not finished yet.
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(0, report.metrics(0).count_metrics().data_size());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- SendConfig(service, MakeConfig());
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- // Force the uidmap to update at timestamp 2.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
- // This is a new installation, so there shouldn't be a split (should be same as the without
- // split case).
- service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
- String16(""));
- // Goes into the second bucket.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
-
- ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(0, report.metrics(0).count_metrics().data_size());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- SendConfig(service, MakeConfig());
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
- service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
- {String16("")});
-
- // Force the uidmap to update at timestamp 2.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
- service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
- String16(""));
- // Goes into the second bucket.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
-
- ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
- EXPECT_TRUE(report.metrics(0)
- .count_metrics()
- .data(0)
- .bucket_info(0)
- .has_start_bucket_elapsed_nanos());
- EXPECT_TRUE(report.metrics(0)
- .count_metrics()
- .data(0)
- .bucket_info(0)
- .has_end_bucket_elapsed_nanos());
- EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- SendConfig(service, MakeConfig());
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
- service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
- {String16("")});
-
- // Force the uidmap to update at timestamp 2.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
- service->mUidMap->removeApp(start + 2, String16(kApp1.c_str()), 1);
- // Goes into the second bucket.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
-
- ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
- EXPECT_TRUE(report.metrics(0)
- .count_metrics()
- .data(0)
- .bucket_info(0)
- .has_start_bucket_elapsed_nanos());
- EXPECT_TRUE(report.metrics(0)
- .count_metrics()
- .data(0)
- .bucket_info(0)
- .has_end_bucket_elapsed_nanos());
- EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- SendConfig(service, MakeConfig());
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- // Goes into the first bucket
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + NS_PER_SEC, 100).get());
- int64_t bootCompleteTimeNs = start + 2 * NS_PER_SEC;
- service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
- // Goes into the second bucket.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3 * NS_PER_SEC, 100).get());
-
- ConfigMetricsReport report = GetReports(service->mProcessor, start + 4 * NS_PER_SEC);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
- EXPECT_TRUE(report.metrics(0)
- .count_metrics()
- .data(0)
- .bucket_info(0)
- .has_start_bucket_elapsed_nanos());
- EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)),
- report.metrics(0).count_metrics().data(0).bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
-}
-
-TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
- // Partial buckets don't occur when app is first installed.
- service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
- SendConfig(service, MakeValueMetricConfig(0));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
- int64_t appUpgradeTimeNs = 5 * 60 * NS_PER_SEC + start + 2 * NS_PER_SEC;
- service->mUidMap->updateApp(appUpgradeTimeNs, String16(kApp1.c_str()), 1, 2, String16("v2"),
- String16(""));
-
- ConfigMetricsReport report =
- GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(0, report.metrics(0).value_metrics().skipped_size());
-
- // The fake subsystem state sleep puller returns two atoms.
- ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
- ASSERT_EQ(2, report.metrics(0).value_metrics().data(0).bucket_info_size());
- EXPECT_EQ(MillisToNano(NanoToMillis(appUpgradeTimeNs)),
- report.metrics(0).value_metrics().data(0).bucket_info(1).end_bucket_elapsed_nanos());
-}
-
-TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
- // Partial buckets don't occur when app is first installed.
- service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
- SendConfig(service, MakeValueMetricConfig(60 * NS_PER_SEC /* One minute */));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2 * NS_PER_SEC;
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
- service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
- String16(""));
-
- ConfigMetricsReport report =
- GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).value_metrics().skipped_size());
- EXPECT_TRUE(report.metrics(0).value_metrics().skipped(0).has_start_bucket_elapsed_nanos());
- // Can't test the start time since it will be based on the actual time when the pulling occurs.
- EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)),
- report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos());
-
- ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size());
-}
-
-TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- // Initial pull will fail since puller is not registered.
- SendConfig(service, MakeValueMetricConfig(0));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
-
- int64_t bootCompleteTimeNs = start + NS_PER_SEC;
- service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
-
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-
- ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
- backfillStartEndTimestamp(&report);
-
- // First bucket is dropped due to the initial pull failing
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).value_metrics().skipped_size());
- EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)),
- report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos());
-
- // The fake subsystem state sleep puller returns two atoms.
- ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size());
- EXPECT_EQ(
- MillisToNano(NanoToMillis(bootCompleteTimeNs)),
- report.metrics(0).value_metrics().data(0).bucket_info(0).start_bucket_elapsed_nanos());
-}
-
-TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
- // Partial buckets don't occur when app is first installed.
- service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
- SendConfig(service, MakeGaugeMetricConfig(0));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
- service->mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2,
- String16("v2"), String16(""));
-
- ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
- backfillStartEndTimestamp(&report);
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
- // The fake subsystem state sleep puller returns two atoms.
- ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
- ASSERT_EQ(2, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
-}
-
-TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- // Partial buckets don't occur when app is first installed.
- service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
- SendConfig(service, MakeGaugeMetricConfig(60 * NS_PER_SEC /* One minute */));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2;
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
- service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
- String16(""));
-
- ConfigMetricsReport report =
- GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
- backfillStartEndTimestamp(&report);
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).gauge_metrics().skipped_size());
- // Can't test the start time since it will be based on the actual time when the pulling occurs.
- EXPECT_TRUE(report.metrics(0).gauge_metrics().skipped(0).has_start_bucket_elapsed_nanos());
- EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)),
- report.metrics(0).gauge_metrics().skipped(0).end_bucket_elapsed_nanos());
- ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
-}
-
-TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- // Initial pull will fail since puller hasn't been registered.
- SendConfig(service, MakeGaugeMetricConfig(0));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
-
- int64_t bootCompleteTimeNs = start + NS_PER_SEC;
- service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
-
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-
- ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
- // The fake subsystem state sleep puller returns two atoms.
- ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
- // No data in the first bucket, so nothing is reported
- ASSERT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
- EXPECT_EQ(
- MillisToNano(NanoToMillis(bootCompleteTimeNs)),
- report.metrics(0).gauge_metrics().data(0).bucket_info(0).start_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
deleted file mode 100644
index 4d39282..0000000
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ /dev/null
@@ -1,679 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-const int64_t metricId = 123456;
-
-StatsdConfig CreateStatsdConfig(bool useCondition = true) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenIsOffPredicate;
-
- auto valueMetric = config.add_value_metric();
- valueMetric->set_id(metricId);
- valueMetric->set_what(pulledAtomMatcher.id());
- if (useCondition) {
- valueMetric->set_condition(screenIsOffPredicate.id());
- }
- *valueMetric->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- *valueMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
- valueMetric->set_bucket(FIVE_MINUTES);
- valueMetric->set_use_absolute_value_on_reset(true);
- valueMetric->set_skip_zero_diff_output(false);
- valueMetric->set_max_pull_delay_sec(INT_MAX);
- return config;
-}
-
-StatsdConfig CreateStatsdConfigWithStates() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
-
- auto pulledAtomMatcher = CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
- *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
-
- auto screenOnPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = screenOnPredicate;
-
- auto screenOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenOffPredicate;
-
- auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
- *config.add_predicate() = deviceUnpluggedPredicate;
-
- auto screenOnOnBatteryPredicate = config.add_predicate();
- screenOnOnBatteryPredicate->set_id(StringToId("screenOnOnBatteryPredicate"));
- screenOnOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenOnPredicate, screenOnOnBatteryPredicate);
- addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOnOnBatteryPredicate);
-
- auto screenOffOnBatteryPredicate = config.add_predicate();
- screenOffOnBatteryPredicate->set_id(StringToId("ScreenOffOnBattery"));
- screenOffOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenOffPredicate, screenOffOnBatteryPredicate);
- addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOffOnBatteryPredicate);
-
- const State screenState =
- CreateScreenStateWithSimpleOnOffMap(/*screen on id=*/321, /*screen off id=*/123);
- *config.add_state() = screenState;
-
- // ValueMetricSubsystemSleepWhileScreenOnOnBattery
- auto valueMetric1 = config.add_value_metric();
- valueMetric1->set_id(metricId);
- valueMetric1->set_what(pulledAtomMatcher.id());
- valueMetric1->set_condition(screenOnOnBatteryPredicate->id());
- *valueMetric1->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- valueMetric1->set_bucket(FIVE_MINUTES);
- valueMetric1->set_use_absolute_value_on_reset(true);
- valueMetric1->set_skip_zero_diff_output(false);
- valueMetric1->set_max_pull_delay_sec(INT_MAX);
-
- // ValueMetricSubsystemSleepWhileScreenOffOnBattery
- ValueMetric* valueMetric2 = config.add_value_metric();
- valueMetric2->set_id(StringToId("ValueMetricSubsystemSleepWhileScreenOffOnBattery"));
- valueMetric2->set_what(pulledAtomMatcher.id());
- valueMetric2->set_condition(screenOffOnBatteryPredicate->id());
- *valueMetric2->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- valueMetric2->set_bucket(FIVE_MINUTES);
- valueMetric2->set_use_absolute_value_on_reset(true);
- valueMetric2->set_skip_zero_diff_output(false);
- valueMetric2->set_max_pull_delay_sec(INT_MAX);
-
- // ValueMetricSubsystemSleepWhileOnBatterySliceScreen
- ValueMetric* valueMetric3 = config.add_value_metric();
- valueMetric3->set_id(StringToId("ValueMetricSubsystemSleepWhileOnBatterySliceScreen"));
- valueMetric3->set_what(pulledAtomMatcher.id());
- valueMetric3->set_condition(deviceUnpluggedPredicate.id());
- *valueMetric3->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- valueMetric3->add_slice_by_state(screenState.id());
- valueMetric3->set_bucket(FIVE_MINUTES);
- valueMetric3->set_use_absolute_value_on_reset(true);
- valueMetric3->set_skip_zero_diff_output(false);
- valueMetric3->set_max_pull_delay_sec(INT_MAX);
- return config;
-}
-
-} // namespace
-
-/**
- * Tests the initial condition and condition after the first log events for
- * value metrics with either a combination condition or simple condition.
- *
- * Metrics should be initialized with condition kUnknown (given that the
- * predicate is using the default InitialValue of UNKNOWN). The condition should
- * be updated to either kFalse or kTrue if a condition event is logged for all
- * children conditions.
- */
-TEST(ValueMetricE2eTest, TestInitialConditionChanges) {
- StatsdConfig config = CreateStatsdConfigWithStates();
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- int32_t tagId = util::SUBSYSTEM_SLEEP_STATE;
- auto processor =
- CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(), tagId);
-
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- EXPECT_EQ(3, metricsManager->mAllMetricProducers.size());
-
- // Combination condition metric - screen on and device unplugged
- sp<MetricProducer> metricProducer1 = metricsManager->mAllMetricProducers[0];
- // Simple condition metric - device unplugged
- sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[2];
-
- EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
- auto screenOnEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 30, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
- EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 40, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
- EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
- auto pluggedUsbEvent = CreateBatteryStateChangedEvent(
- configAddedTimeNs + 50, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
- processor->OnLogEvent(pluggedUsbEvent.get());
- EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kFalse, metricProducer2->mCondition);
-
- auto pluggedNoneEvent = CreateBatteryStateChangedEvent(
- configAddedTimeNs + 70, BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
- processor->OnLogEvent(pluggedNoneEvent.get());
- EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kTrue, metricProducer2->mCondition);
-}
-
-TEST(ValueMetricE2eTest, TestPulledEvents) {
- auto config = CreateStatsdConfig();
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(),
- util::SUBSYSTEM_SLEEP_STATE);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- // When creating the config, the value metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& expectedPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
-
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- auto screenOnEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 65, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 75, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- // Pulling alarm arrives on time and reset the sequential pulling alarm.
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
- screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 2 * bucketSizeNs + 15,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 4 * bucketSizeNs + 11,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::ValueMetricDataWrapper valueMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
- ASSERT_GT((int)valueMetrics.data_size(), 1);
-
- auto data = valueMetrics.data(0);
- EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- // We have 4 buckets, the first one was incomplete since the condition was unknown.
- ASSERT_EQ(4, data.bucket_info_size());
-
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(0).values_size());
-
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(1).values_size());
-
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(2).values_size());
-
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(3).values_size());
-}
-
-TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
- auto config = CreateStatsdConfig();
- int64_t baseTimeNs = getElapsedRealtimeNs();
- // 10 mins == 2 bucket durations.
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(),
- util::SUBSYSTEM_SLEEP_STATE);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- // When creating the config, the value metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& expectedPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
-
- // Screen off/on/off events.
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- auto screenOnEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 65, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 75, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- // Pulling alarm arrives late by 2 buckets and 1 ns. 2 buckets late is too far away in the
- // future, data will be skipped.
- processor->informPullAlarmFired(expectedPullTimeNs + 2 * bucketSizeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
-
- // This screen state change will start a new bucket.
- screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 4 * bucketSizeNs + 65,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- // The alarm is delayed but we already created a bucket thanks to the screen state condition.
- // This bucket does not have to be skipped since the alarm arrives in time for the next bucket.
- processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 6 * bucketSizeNs + 31,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 8 * bucketSizeNs, expectedPullTimeNs);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 9 * bucketSizeNs, expectedPullTimeNs);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 9 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::ValueMetricDataWrapper valueMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
- ASSERT_GT((int)valueMetrics.data_size(), 1);
-
- auto data = valueMetrics.data(0);
- EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(3, data.bucket_info_size());
-
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(0).values_size());
-
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(1).values_size());
-
- EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 10 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(2).values_size());
-}
-
-TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation) {
- auto config = CreateStatsdConfig(false);
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
- auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = batterySaverStartMatcher;
- const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
- auto metric_activation = config.add_metric_activation();
- metric_activation->set_metric_id(metricId);
- metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
- auto event_activation = metric_activation->add_event_activation();
- event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
- event_activation->set_ttl_seconds(ttlNs / 1000000000);
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(),
- util::SUBSYSTEM_SLEEP_STATE);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // When creating the config, the value metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& expectedPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
-
- // Pulling alarm arrives on time and reset the sequential pulling alarm.
- processor->informPullAlarmFired(expectedPullTimeNs + 1); // 15 mins + 1 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // Activate the metric. A pull occurs here
- const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
- auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
- processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1); // 20 mins + 1 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, expectedPullTimeNs);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 2); // 25 mins + 2 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
-
- // Create random event to deactivate metric.
- auto deactivationEvent = CreateScreenBrightnessChangedEvent(activationNs + ttlNs + 1, 50);
- processor->OnLogEvent(deactivationEvent.get());
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- processor->informPullAlarmFired(expectedPullTimeNs + 3);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, expectedPullTimeNs);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 4);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::ValueMetricDataWrapper valueMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
- ASSERT_GT((int)valueMetrics.data_size(), 0);
-
- auto data = valueMetrics.data(0);
- EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- // We have 2 full buckets, the two surrounding the activation are dropped.
- ASSERT_EQ(2, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- ASSERT_EQ(1, bucketInfo.values_size());
-
- bucketInfo = data.bucket_info(1);
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- ASSERT_EQ(1, bucketInfo.values_size());
-}
-
-/**
- * Test initialization of a simple value metric that is sliced by a state.
- *
- * ValueCpuUserTimePerScreenState
- */
-TEST(ValueMetricE2eTest, TestInitWithSlicedState) {
- // Create config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
-
- auto screenState = CreateScreenState();
- *config.add_state() = screenState;
-
- // Create value metric that slices by screen state without a map.
- int64_t metricId = 123456;
- auto valueMetric = config.add_value_metric();
- valueMetric->set_id(metricId);
- valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- valueMetric->set_what(pulledAtomMatcher.id());
- *valueMetric->mutable_value_field() =
- CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
- valueMetric->add_slice_by_state(screenState.id());
- valueMetric->set_max_pull_delay_sec(INT_MAX);
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- // Check that ValueMetricProducer was initialized correctly.
- ASSERT_EQ(1U, processor->mMetricsManagers.size());
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(1, metricsManager->mAllMetricProducers.size());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(1, metricProducer->mSlicedStateAtoms.size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, metricProducer->mSlicedStateAtoms.at(0));
- ASSERT_EQ(0, metricProducer->mStateGroupMap.size());
-}
-
-/**
- * Test initialization of a value metric that is sliced by state and has
- * dimensions_in_what.
- *
- * ValueCpuUserTimePerUidPerUidProcessState
- */
-TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions) {
- // Create config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto cpuTimePerUidMatcher =
- CreateSimpleAtomMatcher("CpuTimePerUidMatcher", util::CPU_TIME_PER_UID);
- *config.add_atom_matcher() = cpuTimePerUidMatcher;
-
- auto uidProcessState = CreateUidProcessState();
- *config.add_state() = uidProcessState;
-
- // Create value metric that slices by screen state with a complete map.
- int64_t metricId = 123456;
- auto valueMetric = config.add_value_metric();
- valueMetric->set_id(metricId);
- valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- valueMetric->set_what(cpuTimePerUidMatcher.id());
- *valueMetric->mutable_value_field() =
- CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
- *valueMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
- valueMetric->add_slice_by_state(uidProcessState.id());
- MetricStateLink* stateLink = valueMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
- valueMetric->set_max_pull_delay_sec(INT_MAX);
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
- // Check that ValueMetricProducer was initialized correctly.
- ASSERT_EQ(1U, processor->mMetricsManagers.size());
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(1, metricsManager->mAllMetricProducers.size());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(1, metricProducer->mSlicedStateAtoms.size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, metricProducer->mSlicedStateAtoms.at(0));
- ASSERT_EQ(0, metricProducer->mStateGroupMap.size());
-}
-
-/**
- * Test initialization of a value metric that is sliced by state and has
- * dimensions_in_what.
- *
- * ValueCpuUserTimePerUidPerUidProcessState
- */
-TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions) {
- // Create config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto cpuTimePerUidMatcher =
- CreateSimpleAtomMatcher("CpuTimePerUidMatcher", util::CPU_TIME_PER_UID);
- *config.add_atom_matcher() = cpuTimePerUidMatcher;
-
- auto uidProcessState = CreateUidProcessState();
- *config.add_state() = uidProcessState;
-
- // Create value metric that slices by screen state with a complete map.
- int64_t metricId = 123456;
- auto valueMetric = config.add_value_metric();
- valueMetric->set_id(metricId);
- valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- valueMetric->set_what(cpuTimePerUidMatcher.id());
- *valueMetric->mutable_value_field() =
- CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
- valueMetric->add_slice_by_state(uidProcessState.id());
- MetricStateLink* stateLink = valueMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
- valueMetric->set_max_pull_delay_sec(INT_MAX);
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // No StateTrackers are initialized.
- EXPECT_EQ(0, StateManager::getInstance().getStateTrackersCount());
-
- // Config initialization fails.
- ASSERT_EQ(0, processor->mMetricsManagers.size());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
deleted file mode 100644
index 52bc222..0000000
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(DurationMetric::AggregationType aggregationType) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenIsOffPredicate;
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- // The predicate is dimensioning by any attribution node and both by uid and tag.
- FieldMatcher dimensions = CreateAttributionUidAndTagDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST, Position::LAST});
- // Also slice by the wakelock tag
- dimensions.add_child()->set_field(3); // The wakelock tag is set in field 3 of the wakelock.
- *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("WakelockDuration"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->set_condition(screenIsOffPredicate.id());
- durationMetric->set_aggregation_type(aggregationType);
- // The metric is dimensioning by first attribution node and only by uid.
- *durationMetric->mutable_dimensions_in_what() =
- CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- durationMetric->set_bucket(FIVE_MINUTES);
- return config;
-}
-
-std::vector<int> attributionUids1 = {111, 222, 222};
-std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1", "GMSCoreModule2"};
-
-std::vector<int> attributionUids2 = {111, 222, 222};
-std::vector<string> attributionTags2 = {"App2", "GMSCoreModule1", "GMSCoreModule2"};
-
-/*
-Events:
-Screen off is met from (200ns,1 min+500ns].
-Acquire event for wl1 from 2ns to 1min+2ns
-Acquire event for wl2 from 1min-10ns to 2min-15ns
-*/
-void FeedEvents(StatsdConfig config, sp<StatsLogProcessor> processor) {
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- auto screenTurnedOnEvent2 =
- CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 500,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
- auto acquireEvent1 = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- auto releaseEvent1 = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2,
- attributionUids1, attributionTags1, "wl1");
- auto acquireEvent2 = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 10,
- attributionUids2, attributionTags2, "wl2");
- auto releaseEvent2 = CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs - 15,
- attributionUids2, attributionTags2, "wl2");
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(std::move(screenTurnedOnEvent));
- events.push_back(std::move(screenTurnedOffEvent));
- events.push_back(std::move(screenTurnedOnEvent2));
- events.push_back(std::move(acquireEvent1));
- events.push_back(std::move(acquireEvent2));
- events.push_back(std::move(releaseEvent1));
- events.push_back(std::move(releaseEvent2));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-}
-
-} // namespace
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::SUM);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- // Only 1 dimension output. The tag dimension in the predicate has been aggregated.
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
-
- auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
- // Validate dimension value.
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111);
- // Validate bucket info.
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
- data = reports.reports(0).metrics(0).duration_metrics().data(0);
- // The wakelock holding interval starts from the screen off event and to the end of the 1st
- // bucket.
- EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs - 200);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::SUM);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
- // Dump the report after the end of 2nd bucket.
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
- auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
- // Validate dimension value.
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111);
- // Two output buckets.
- // The wakelock holding interval in the 1st bucket starts from the screen off event and to
- // the end of the 1st bucket.
- EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(),
- bucketStartTimeNs + bucketSizeNs - (bucketStartTimeNs + 200));
- // The wakelock holding interval in the 2nd bucket starts at the beginning of the bucket and
- // ends at the second screen on event.
- EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 500UL);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::SUM);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 90,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
- attributionUids1, attributionTags1, "wl3"));
- events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs + 100,
- attributionUids1, attributionTags1, "wl3"));
- sortLogEventsByTimestamp(&events);
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
- auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111);
- // The last wakelock holding spans 4 buckets.
- EXPECT_EQ((unsigned long long)data.bucket_info(2).duration_nanos(), bucketSizeNs - 100);
- EXPECT_EQ((unsigned long long)data.bucket_info(3).duration_nanos(), bucketSizeNs);
- EXPECT_EQ((unsigned long long)data.bucket_info(4).duration_nanos(), bucketSizeNs);
- EXPECT_EQ((unsigned long long)data.bucket_info(5).duration_nanos(), 100UL);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
-
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(reports.reports_size(), 1);
-
- // When using ProtoOutputStream, if nothing written to a sub msg, it won't be treated as
- // one. It was previsouly 1 because we had a fake onDumpReport which calls add_metric() by
- // itself.
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- ASSERT_EQ(0, reports.reports(0).metrics(0).duration_metrics().data_size());
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
- // Dump the report after the end of 2nd bucket. One dimension with one bucket.
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
- auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
- // Validate dimension value.
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111);
- // The max is acquire event for wl1 to screen off start.
- EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs + 2 - 200);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 90,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
- attributionUids1, attributionTags1, "wl3"));
- events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs + 100,
- attributionUids1, attributionTags1, "wl3"));
- sortLogEventsByTimestamp(&events);
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
- auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111);
- // The last wakelock holding spans 4 buckets.
- EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 3 * bucketSizeNs);
- EXPECT_EQ((unsigned long long)data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + 5 * bucketSizeNs);
- EXPECT_EQ((unsigned long long)data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 6 * bucketSizeNs);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
deleted file mode 100644
index 85a6088..0000000
--- a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/external/StatsCallbackPuller.h"
-
-#include <aidl/android/os/BnPullAtomCallback.h>
-#include <aidl/android/os/IPullAtomResultReceiver.h>
-#include <aidl/android/util/StatsEventParcel.h>
-#include <android/binder_interface_utils.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <chrono>
-#include <thread>
-#include <vector>
-
-#include "../metrics/metrics_test_helper.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::os::BnPullAtomCallback;
-using aidl::android::os::IPullAtomResultReceiver;
-using aidl::android::util::StatsEventParcel;
-using ::ndk::SharedRefBase;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-using std::this_thread::sleep_for;
-using testing::Contains;
-
-namespace {
-int pullTagId = -12;
-bool pullSuccess;
-vector<int64_t> values;
-int64_t pullDelayNs;
-int64_t pullTimeoutNs;
-int64_t pullCoolDownNs;
-std::thread pullThread;
-
-AStatsEvent* createSimpleEvent(int64_t value) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, pullTagId);
- AStatsEvent_writeInt64(event, value);
- AStatsEvent_build(event);
- return event;
-}
-
-void executePull(const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
- // Convert stats_events into StatsEventParcels.
- vector<StatsEventParcel> parcels;
- for (int i = 0; i < values.size(); i++) {
- AStatsEvent* event = createSimpleEvent(values[i]);
- size_t size;
- uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
-
- StatsEventParcel p;
- // vector.assign() creates a copy, but this is inevitable unless
- // stats_event.h/c uses a vector as opposed to a buffer.
- p.buffer.assign(buffer, buffer + size);
- parcels.push_back(std::move(p));
- AStatsEvent_release(event);
- }
-
- sleep_for(std::chrono::nanoseconds(pullDelayNs));
- resultReceiver->pullFinished(pullTagId, pullSuccess, parcels);
-}
-
-class FakePullAtomCallback : public BnPullAtomCallback {
-public:
- Status onPullAtom(int atomTag,
- const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override {
- // Force pull to happen in separate thread to simulate binder.
- pullThread = std::thread(executePull, resultReceiver);
- return Status::ok();
- }
-};
-
-class StatsCallbackPullerTest : public ::testing::Test {
-public:
- StatsCallbackPullerTest() {
- }
-
- void SetUp() override {
- pullSuccess = false;
- pullDelayNs = 0;
- values.clear();
- pullTimeoutNs = 10000000000LL; // 10 seconds.
- pullCoolDownNs = 1000000000; // 1 second.
- }
-
- void TearDown() override {
- if (pullThread.joinable()) {
- pullThread.join();
- }
- values.clear();
- }
-};
-} // Anonymous namespace.
-
-TEST_F(StatsCallbackPullerTest, PullSuccess) {
- shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
- int64_t value = 43;
- pullSuccess = true;
- values.push_back(value);
-
- StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- int64_t startTimeNs = getElapsedRealtimeNs();
- EXPECT_TRUE(puller.PullInternal(&dataHolder));
- int64_t endTimeNs = getElapsedRealtimeNs();
-
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_LT(startTimeNs, dataHolder[0]->GetElapsedTimestampNs());
- EXPECT_GT(endTimeNs, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(value, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-TEST_F(StatsCallbackPullerTest, PullFail) {
- shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
- pullSuccess = false;
- int64_t value = 1234;
- values.push_back(value);
-
- StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
-
- vector<shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.PullInternal(&dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsCallbackPullerTest, PullTimeout) {
- shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
- pullSuccess = true;
- pullDelayNs = MillisToNano(5); // 5ms.
- pullTimeoutNs = 10000; // 10 microseconds.
- int64_t value = 4321;
- values.push_back(value);
-
- StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
-
- vector<shared_ptr<LogEvent>> dataHolder;
- int64_t startTimeNs = getElapsedRealtimeNs();
- // Returns true to let StatsPuller code evaluate the timeout.
- EXPECT_TRUE(puller.PullInternal(&dataHolder));
- int64_t endTimeNs = getElapsedRealtimeNs();
- int64_t actualPullDurationNs = endTimeNs - startTimeNs;
-
- // Pull should take at least the timeout amount of time, but should stop early because the delay
- // is bigger.
- EXPECT_LT(pullTimeoutNs, actualPullDurationNs);
- EXPECT_GT(pullDelayNs, actualPullDurationNs);
- ASSERT_EQ(0, dataHolder.size());
-
- // Let the pull return and make sure that the dataHolder is not modified.
- pullThread.join();
- ASSERT_EQ(0, dataHolder.size());
-}
-
-// Register a puller and ensure that the timeout logic works.
-TEST_F(StatsCallbackPullerTest, RegisterAndTimeout) {
- shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
- pullSuccess = true;
- pullDelayNs = MillisToNano(5); // 5 ms.
- pullTimeoutNs = 10000; // 10 microsseconds.
- int64_t value = 4321;
- int32_t uid = 123;
- values.push_back(value);
-
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- pullerManager->RegisterPullAtomCallback(uid, pullTagId, pullCoolDownNs, pullTimeoutNs,
- vector<int32_t>(), cb);
- vector<shared_ptr<LogEvent>> dataHolder;
- int64_t startTimeNs = getElapsedRealtimeNs();
- // Returns false, since StatsPuller code will evaluate the timeout.
- EXPECT_FALSE(pullerManager->Pull(pullTagId, {uid}, startTimeNs, &dataHolder));
- int64_t endTimeNs = getElapsedRealtimeNs();
- int64_t actualPullDurationNs = endTimeNs - startTimeNs;
-
- // Pull should take at least the timeout amount of time, but should stop early because the delay
- // is bigger. Make sure that the time is closer to the timeout, than to the intended delay.
- EXPECT_LT(pullTimeoutNs, actualPullDurationNs);
- EXPECT_GT(pullDelayNs / 5, actualPullDurationNs);
- ASSERT_EQ(0, dataHolder.size());
-
- // Let the pull return and make sure that the dataHolder is not modified.
- pullThread.join();
- ASSERT_EQ(0, dataHolder.size());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/external/StatsPullerManager_test.cpp b/cmds/statsd/tests/external/StatsPullerManager_test.cpp
deleted file mode 100644
index c76e85e..0000000
--- a/cmds/statsd/tests/external/StatsPullerManager_test.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/external/StatsPullerManager.h"
-
-#include <aidl/android/os/IPullAtomResultReceiver.h>
-#include <aidl/android/util/StatsEventParcel.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using aidl::android::util::StatsEventParcel;
-using ::ndk::SharedRefBase;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-int pullTagId1 = 10101;
-int pullTagId2 = 10102;
-int uid1 = 9999;
-int uid2 = 8888;
-ConfigKey configKey(50, 12345);
-ConfigKey badConfigKey(60, 54321);
-int unregisteredUid = 98765;
-int64_t coolDownNs = NS_PER_SEC;
-int64_t timeoutNs = NS_PER_SEC / 2;
-
-AStatsEvent* createSimpleEvent(int32_t atomId, int32_t value) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, atomId);
- AStatsEvent_writeInt32(event, value);
- AStatsEvent_build(event);
- return event;
-}
-
-class FakePullAtomCallback : public BnPullAtomCallback {
-public:
- FakePullAtomCallback(int32_t uid) : mUid(uid){};
- Status onPullAtom(int atomTag,
- const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override {
- vector<StatsEventParcel> parcels;
- AStatsEvent* event = createSimpleEvent(atomTag, mUid);
- size_t size;
- uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
-
- StatsEventParcel p;
- // vector.assign() creates a copy, but this is inevitable unless
- // stats_event.h/c uses a vector as opposed to a buffer.
- p.buffer.assign(buffer, buffer + size);
- parcels.push_back(std::move(p));
- AStatsEvent_release(event);
- resultReceiver->pullFinished(atomTag, /*success*/ true, parcels);
- return Status::ok();
- }
- int32_t mUid;
-};
-
-class FakePullUidProvider : public PullUidProvider {
-public:
- vector<int32_t> getPullAtomUids(int atomId) override {
- if (atomId == pullTagId1) {
- return {uid2, uid1};
- } else if (atomId == pullTagId2) {
- return {uid2};
- }
- return {};
- }
-};
-
-sp<StatsPullerManager> createPullerManagerAndRegister() {
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- shared_ptr<FakePullAtomCallback> cb1 = SharedRefBase::make<FakePullAtomCallback>(uid1);
- pullerManager->RegisterPullAtomCallback(uid1, pullTagId1, coolDownNs, timeoutNs, {}, cb1, true);
- shared_ptr<FakePullAtomCallback> cb2 = SharedRefBase::make<FakePullAtomCallback>(uid2);
- pullerManager->RegisterPullAtomCallback(uid2, pullTagId1, coolDownNs, timeoutNs, {}, cb2, true);
- pullerManager->RegisterPullAtomCallback(uid1, pullTagId2, coolDownNs, timeoutNs, {}, cb1, true);
- return pullerManager;
-}
-} // anonymous namespace
-
-TEST(StatsPullerManagerTest, TestPullInvalidUid) {
- sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
-
- vector<shared_ptr<LogEvent>> data;
- EXPECT_FALSE(pullerManager->Pull(pullTagId1, {unregisteredUid}, /*timestamp =*/1, &data, true));
-}
-
-TEST(StatsPullerManagerTest, TestPullChoosesCorrectUid) {
- sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
-
- vector<shared_ptr<LogEvent>> data;
- EXPECT_TRUE(pullerManager->Pull(pullTagId1, {uid1}, /*timestamp =*/1, &data, true));
- ASSERT_EQ(data.size(), 1);
- EXPECT_EQ(data[0]->GetTagId(), pullTagId1);
- ASSERT_EQ(data[0]->getValues().size(), 1);
- EXPECT_EQ(data[0]->getValues()[0].mValue.int_value, uid1);
-}
-
-TEST(StatsPullerManagerTest, TestPullInvalidConfigKey) {
- sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
- sp<FakePullUidProvider> uidProvider = new FakePullUidProvider();
- pullerManager->RegisterPullUidProvider(configKey, uidProvider);
-
- vector<shared_ptr<LogEvent>> data;
- EXPECT_FALSE(pullerManager->Pull(pullTagId1, badConfigKey, /*timestamp =*/1, &data, true));
-}
-
-TEST(StatsPullerManagerTest, TestPullConfigKeyGood) {
- sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
- sp<FakePullUidProvider> uidProvider = new FakePullUidProvider();
- pullerManager->RegisterPullUidProvider(configKey, uidProvider);
-
- vector<shared_ptr<LogEvent>> data;
- EXPECT_TRUE(pullerManager->Pull(pullTagId1, configKey, /*timestamp =*/1, &data, true));
- EXPECT_EQ(data[0]->GetTagId(), pullTagId1);
- ASSERT_EQ(data[0]->getValues().size(), 1);
- EXPECT_EQ(data[0]->getValues()[0].mValue.int_value, uid2);
-}
-
-TEST(StatsPullerManagerTest, TestPullConfigKeyNoPullerWithUid) {
- sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
- sp<FakePullUidProvider> uidProvider = new FakePullUidProvider();
- pullerManager->RegisterPullUidProvider(configKey, uidProvider);
-
- vector<shared_ptr<LogEvent>> data;
- EXPECT_FALSE(pullerManager->Pull(pullTagId2, configKey, /*timestamp =*/1, &data, true));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/tests/external/StatsPuller_test.cpp b/cmds/statsd/tests/external/StatsPuller_test.cpp
deleted file mode 100644
index 55a9036..0000000
--- a/cmds/statsd/tests/external/StatsPuller_test.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <chrono>
-#include <thread>
-#include <vector>
-
-#include "../metrics/metrics_test_helper.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-using std::this_thread::sleep_for;
-using testing::Contains;
-
-namespace {
-int pullTagId = 10014;
-
-bool pullSuccess;
-vector<std::shared_ptr<LogEvent>> pullData;
-long pullDelayNs;
-
-class FakePuller : public StatsPuller {
-public:
- FakePuller()
- : StatsPuller(pullTagId, /*coolDownNs=*/MillisToNano(10), /*timeoutNs=*/MillisToNano(5)){};
-
-private:
- bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override {
- (*data) = pullData;
- sleep_for(std::chrono::nanoseconds(pullDelayNs));
- return pullSuccess;
- }
-};
-
-FakePuller puller;
-
-std::unique_ptr<LogEvent> createSimpleEvent(int64_t eventTimeNs, int64_t value) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, pullTagId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
- AStatsEvent_writeInt64(statsEvent, value);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-class StatsPullerTest : public ::testing::Test {
-public:
- StatsPullerTest() {
- }
-
- void SetUp() override {
- puller.ForceClearCache();
- pullSuccess = false;
- pullDelayNs = 0;
- pullData.clear();
- }
-};
-
-} // Anonymous namespace.
-
-TEST_F(StatsPullerTest, PullSuccess) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = true;
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
- sleep_for(std::chrono::milliseconds(11));
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- pullSuccess = true;
-
- EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(2222L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(44, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-TEST_F(StatsPullerTest, PullFailAfterSuccess) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = true;
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
- sleep_for(std::chrono::milliseconds(11));
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- pullSuccess = false;
- dataHolder.clear();
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-
- // Fails due to hitting the cool down.
- pullSuccess = true;
- dataHolder.clear();
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-// Test pull takes longer than timeout, 2nd pull happens shorter than cooldown
-TEST_F(StatsPullerTest, PullTakeTooLongAndPullFast) {
- pullData.push_back(createSimpleEvent(1111L, 33));
- pullSuccess = true;
- // timeout is 5ms
- pullDelayNs = MillisToNano(6);
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
- pullDelayNs = 0;
-
- pullSuccess = true;
- dataHolder.clear();
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullFail) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = false;
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullTakeTooLong) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = true;
- pullDelayNs = MillisToNano(6);
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullTooFast) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = true;
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- pullSuccess = true;
-
- dataHolder.clear();
- EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-TEST_F(StatsPullerTest, PullFailsAndTooFast) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = false;
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- pullSuccess = true;
-
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullSameEventTime) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = true;
- int64_t eventTimeNs = getElapsedRealtimeNs();
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_TRUE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- // Sleep to ensure the cool down expires.
- sleep_for(std::chrono::milliseconds(11));
- pullSuccess = true;
-
- dataHolder.clear();
- EXPECT_TRUE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-// Test pull takes longer than timeout, 2nd pull happens at same event time
-TEST_F(StatsPullerTest, PullTakeTooLongAndPullSameEventTime) {
- pullData.push_back(createSimpleEvent(1111L, 33));
- pullSuccess = true;
- int64_t eventTimeNs = getElapsedRealtimeNs();
- // timeout is 5ms
- pullDelayNs = MillisToNano(6);
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-
- // Sleep to ensure the cool down expires. 6ms is taken by the delay, so only 5 is needed here.
- sleep_for(std::chrono::milliseconds(5));
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
- pullDelayNs = 0;
-
- pullSuccess = true;
- dataHolder.clear();
- EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullFailsAndPullSameEventTime) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = false;
- int64_t eventTimeNs = getElapsedRealtimeNs();
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-
- // Sleep to ensure the cool down expires.
- sleep_for(std::chrono::milliseconds(11));
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- pullSuccess = true;
-
- EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp
deleted file mode 100644
index a21dc87..0000000
--- a/cmds/statsd/tests/external/puller_util_test.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "external/puller_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "../metrics/metrics_test_helper.h"
-#include "FieldValue.h"
-#include "annotations.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using std::shared_ptr;
-using std::vector;
-/*
- * Test merge isolated and host uid
- */
-namespace {
-const int uidAtomTagId = 100;
-const vector<int> additiveFields = {3};
-const int nonUidAtomTagId = 200;
-const int timestamp = 1234;
-const int isolatedUid1 = 30;
-const int isolatedUid2 = 40;
-const int isolatedNonAdditiveData = 32;
-const int isolatedAdditiveData = 31;
-const int hostUid = 20;
-const int hostNonAdditiveData = 22;
-const int hostAdditiveData = 21;
-const int attributionAtomTagId = 300;
-
-sp<MockUidMap> makeMockUidMap() {
- return makeMockUidMapForOneHost(hostUid, {isolatedUid1, isolatedUid2});
-}
-
-} // anonymous namespace
-
-TEST(PullerUtilTest, MergeNoDimension) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->22->31
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
- isolatedAdditiveData),
-
- // 20->22->21
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
- hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
- ASSERT_EQ(1, (int)data.size());
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MergeWithDimension) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->32->31
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 20->32->21
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
- hostAdditiveData),
-
- // 20->22->21
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
- hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, NoMergeHostUidOnly) {
- vector<shared_ptr<LogEvent>> data = {
- // 20->32->31
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 20->22->21
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
- hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, IsolatedUidOnly) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->32->31
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 30->22->21
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
- hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- // 20->32->31
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-
- // 20->22->21
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUid) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->32->31
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 31->32->21
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid2, isolatedNonAdditiveData,
- hostAdditiveData),
-
- // 20->32->21
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
- hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
- ASSERT_EQ(1, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
- actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, NoNeedToMerge) {
- vector<shared_ptr<LogEvent>> data = {
- // 32->31
- CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 22->21
- CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, hostNonAdditiveData,
- hostAdditiveData),
-
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, nonUidAtomTagId, {} /*no additive fields*/);
-
- ASSERT_EQ(2, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(2, actualFieldValues->size());
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(1).mValue.int_value);
-
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(2, actualFieldValues->size());
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(1).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MergeNoDimensionAttributionChain) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->tag1->400->tag2->22->31
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
- {"tag1", "tag2"}, hostNonAdditiveData, isolatedAdditiveData),
-
- // 20->tag1->400->tag2->22->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
- {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
- ASSERT_EQ(1, (int)data.size());
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MergeWithDimensionAttributionChain) {
- vector<shared_ptr<LogEvent>> data = {
- // 200->tag1->30->tag2->32->31
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, isolatedUid1},
- {"tag1", "tag2"}, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 200->tag1->20->tag2->32->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid},
- {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
-
- // 200->tag1->20->tag2->22->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid},
- {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, NoMergeHostUidOnlyAttributionChain) {
- vector<shared_ptr<LogEvent>> data = {
- // 20->tag1->400->tag2->32->31
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
- {"tag1", "tag2"}, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 20->tag1->400->tag2->22->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
- {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, IsolatedUidOnlyAttributionChain) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->tag1->400->tag2->32->31
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
- {"tag1", "tag2"}, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 30->tag1->400->tag2->22->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
- {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- // 20->tag1->400->tag2->32->31
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-
- // 20->tag1->400->tag2->22->21
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUidAttributionChain) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->tag1->400->tag2->32->31
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
- {"tag1", "tag2"}, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 31->tag1->400->tag2->32->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid2, 400},
- {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
-
- // 20->tag1->400->tag2->32->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
- {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
- ASSERT_EQ(1, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
- actualFieldValues->at(5).mValue.int_value);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
deleted file mode 100644
index 428c46f..0000000
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/guardrail/StatsdStats.h"
-#include "statslog_statsdtest.h"
-#include "tests/statsd_test_util.h"
-
-#include <gtest/gtest.h>
-#include <vector>
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-TEST(StatsdStatsTest, TestValidConfigAdd) {
- StatsdStats stats;
- ConfigKey key(0, 12345);
- const int metricsCount = 10;
- const int conditionsCount = 20;
- const int matchersCount = 30;
- const int alertsCount = 10;
- stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
- true /*valid config*/);
- vector<uint8_t> output;
- stats.dumpStats(&output, false /*reset stats*/);
-
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport = report.config_stats(0);
- EXPECT_EQ(0, configReport.uid());
- EXPECT_EQ(12345, configReport.id());
- EXPECT_EQ(metricsCount, configReport.metric_count());
- EXPECT_EQ(conditionsCount, configReport.condition_count());
- EXPECT_EQ(matchersCount, configReport.matcher_count());
- EXPECT_EQ(alertsCount, configReport.alert_count());
- EXPECT_EQ(true, configReport.is_valid());
- EXPECT_FALSE(configReport.has_deletion_time_sec());
-}
-
-TEST(StatsdStatsTest, TestInvalidConfigAdd) {
- StatsdStats stats;
- ConfigKey key(0, 12345);
- const int metricsCount = 10;
- const int conditionsCount = 20;
- const int matchersCount = 30;
- const int alertsCount = 10;
- stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
- false /*bad config*/);
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
-
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport = report.config_stats(0);
- // The invalid config should be put into icebox with a deletion time.
- EXPECT_TRUE(configReport.has_deletion_time_sec());
-}
-
-TEST(StatsdStatsTest, TestConfigRemove) {
- StatsdStats stats;
- ConfigKey key(0, 12345);
- const int metricsCount = 10;
- const int conditionsCount = 20;
- const int matchersCount = 30;
- const int alertsCount = 10;
- stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
- true);
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport = report.config_stats(0);
- EXPECT_FALSE(configReport.has_deletion_time_sec());
-
- stats.noteConfigRemoved(key);
- stats.dumpStats(&output, false);
- good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport2 = report.config_stats(0);
- EXPECT_TRUE(configReport2.has_deletion_time_sec());
-}
-
-TEST(StatsdStatsTest, TestSubStats) {
- StatsdStats stats;
- ConfigKey key(0, 12345);
- stats.noteConfigReceived(key, 2, 3, 4, 5, {std::make_pair(123, 456)}, true);
-
- stats.noteMatcherMatched(key, StringToId("matcher1"));
- stats.noteMatcherMatched(key, StringToId("matcher1"));
- stats.noteMatcherMatched(key, StringToId("matcher2"));
-
- stats.noteConditionDimensionSize(key, StringToId("condition1"), 250);
- stats.noteConditionDimensionSize(key, StringToId("condition1"), 240);
-
- stats.noteMetricDimensionSize(key, StringToId("metric1"), 201);
- stats.noteMetricDimensionSize(key, StringToId("metric1"), 202);
-
- stats.noteAnomalyDeclared(key, StringToId("alert1"));
- stats.noteAnomalyDeclared(key, StringToId("alert1"));
- stats.noteAnomalyDeclared(key, StringToId("alert2"));
-
- // broadcast-> 2
- stats.noteBroadcastSent(key);
- stats.noteBroadcastSent(key);
-
- // data drop -> 1
- stats.noteDataDropped(key, 123);
-
- // dump report -> 3
- stats.noteMetricsReportSent(key, 0);
- stats.noteMetricsReportSent(key, 0);
- stats.noteMetricsReportSent(key, 0);
-
- // activation_time_sec -> 2
- stats.noteActiveStatusChanged(key, true);
- stats.noteActiveStatusChanged(key, true);
-
- // deactivation_time_sec -> 1
- stats.noteActiveStatusChanged(key, false);
-
- vector<uint8_t> output;
- stats.dumpStats(&output, true); // Dump and reset stats
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport = report.config_stats(0);
- ASSERT_EQ(2, configReport.broadcast_sent_time_sec_size());
- ASSERT_EQ(1, configReport.data_drop_time_sec_size());
- ASSERT_EQ(1, configReport.data_drop_bytes_size());
- EXPECT_EQ(123, configReport.data_drop_bytes(0));
- ASSERT_EQ(3, configReport.dump_report_time_sec_size());
- ASSERT_EQ(3, configReport.dump_report_data_size_size());
- ASSERT_EQ(2, configReport.activation_time_sec_size());
- ASSERT_EQ(1, configReport.deactivation_time_sec_size());
- ASSERT_EQ(1, configReport.annotation_size());
- EXPECT_EQ(123, configReport.annotation(0).field_int64());
- EXPECT_EQ(456, configReport.annotation(0).field_int32());
-
- ASSERT_EQ(2, configReport.matcher_stats_size());
- // matcher1 is the first in the list
- if (configReport.matcher_stats(0).id() == StringToId("matcher1")) {
- EXPECT_EQ(2, configReport.matcher_stats(0).matched_times());
- EXPECT_EQ(1, configReport.matcher_stats(1).matched_times());
- EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(1).id());
- } else {
- // matcher1 is the second in the list.
- EXPECT_EQ(1, configReport.matcher_stats(0).matched_times());
- EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(0).id());
-
- EXPECT_EQ(2, configReport.matcher_stats(1).matched_times());
- EXPECT_EQ(StringToId("matcher1"), configReport.matcher_stats(1).id());
- }
-
- ASSERT_EQ(2, configReport.alert_stats_size());
- bool alert1first = configReport.alert_stats(0).id() == StringToId("alert1");
- EXPECT_EQ(StringToId("alert1"), configReport.alert_stats(alert1first ? 0 : 1).id());
- EXPECT_EQ(2, configReport.alert_stats(alert1first ? 0 : 1).alerted_times());
- EXPECT_EQ(StringToId("alert2"), configReport.alert_stats(alert1first ? 1 : 0).id());
- EXPECT_EQ(1, configReport.alert_stats(alert1first ? 1 : 0).alerted_times());
-
- ASSERT_EQ(1, configReport.condition_stats_size());
- EXPECT_EQ(StringToId("condition1"), configReport.condition_stats(0).id());
- EXPECT_EQ(250, configReport.condition_stats(0).max_tuple_counts());
-
- ASSERT_EQ(1, configReport.metric_stats_size());
- EXPECT_EQ(StringToId("metric1"), configReport.metric_stats(0).id());
- EXPECT_EQ(202, configReport.metric_stats(0).max_tuple_counts());
-
- // after resetting the stats, some new events come
- stats.noteMatcherMatched(key, StringToId("matcher99"));
- stats.noteConditionDimensionSize(key, StringToId("condition99"), 300);
- stats.noteMetricDimensionSize(key, StringToId("metric99tion99"), 270);
- stats.noteAnomalyDeclared(key, StringToId("alert99"));
-
- // now the config stats should only contain the stats about the new event.
- stats.dumpStats(&output, false);
- good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport2 = report.config_stats(0);
- ASSERT_EQ(1, configReport2.matcher_stats_size());
- EXPECT_EQ(StringToId("matcher99"), configReport2.matcher_stats(0).id());
- EXPECT_EQ(1, configReport2.matcher_stats(0).matched_times());
-
- ASSERT_EQ(1, configReport2.condition_stats_size());
- EXPECT_EQ(StringToId("condition99"), configReport2.condition_stats(0).id());
- EXPECT_EQ(300, configReport2.condition_stats(0).max_tuple_counts());
-
- ASSERT_EQ(1, configReport2.metric_stats_size());
- EXPECT_EQ(StringToId("metric99tion99"), configReport2.metric_stats(0).id());
- EXPECT_EQ(270, configReport2.metric_stats(0).max_tuple_counts());
-
- ASSERT_EQ(1, configReport2.alert_stats_size());
- EXPECT_EQ(StringToId("alert99"), configReport2.alert_stats(0).id());
- EXPECT_EQ(1, configReport2.alert_stats(0).alerted_times());
-}
-
-TEST(StatsdStatsTest, TestAtomLog) {
- StatsdStats stats;
- time_t now = time(nullptr);
- // old event, we get it from the stats buffer. should be ignored.
- stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, 1000);
-
- stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, now + 1);
- stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, now + 2);
- stats.noteAtomLogged(util::APP_CRASH_OCCURRED, now + 3);
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
-
- ASSERT_EQ(2, report.atom_stats_size());
- bool sensorAtomGood = false;
- bool dropboxAtomGood = false;
-
- for (const auto& atomStats : report.atom_stats()) {
- if (atomStats.tag() == util::SENSOR_STATE_CHANGED && atomStats.count() == 3) {
- sensorAtomGood = true;
- }
- if (atomStats.tag() == util::APP_CRASH_OCCURRED && atomStats.count() == 1) {
- dropboxAtomGood = true;
- }
- }
-
- EXPECT_TRUE(dropboxAtomGood);
- EXPECT_TRUE(sensorAtomGood);
-}
-
-TEST(StatsdStatsTest, TestNonPlatformAtomLog) {
- StatsdStats stats;
- time_t now = time(nullptr);
- int newAtom1 = StatsdStats::kMaxPushedAtomId + 1;
- int newAtom2 = StatsdStats::kMaxPushedAtomId + 2;
-
- stats.noteAtomLogged(newAtom1, now + 1);
- stats.noteAtomLogged(newAtom1, now + 2);
- stats.noteAtomLogged(newAtom2, now + 3);
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
-
- ASSERT_EQ(2, report.atom_stats_size());
- bool newAtom1Good = false;
- bool newAtom2Good = false;
-
- for (const auto& atomStats : report.atom_stats()) {
- if (atomStats.tag() == newAtom1 && atomStats.count() == 2) {
- newAtom1Good = true;
- }
- if (atomStats.tag() == newAtom2 && atomStats.count() == 1) {
- newAtom2Good = true;
- }
- }
-
- EXPECT_TRUE(newAtom1Good);
- EXPECT_TRUE(newAtom2Good);
-}
-
-TEST(StatsdStatsTest, TestPullAtomStats) {
- StatsdStats stats;
-
- stats.updateMinPullIntervalSec(util::DISK_SPACE, 3333L);
- stats.updateMinPullIntervalSec(util::DISK_SPACE, 2222L);
- stats.updateMinPullIntervalSec(util::DISK_SPACE, 4444L);
-
- stats.notePull(util::DISK_SPACE);
- stats.notePullTime(util::DISK_SPACE, 1111L);
- stats.notePullDelay(util::DISK_SPACE, 1111L);
- stats.notePull(util::DISK_SPACE);
- stats.notePullTime(util::DISK_SPACE, 3333L);
- stats.notePullDelay(util::DISK_SPACE, 3335L);
- stats.notePull(util::DISK_SPACE);
- stats.notePullFromCache(util::DISK_SPACE);
- stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, true);
- stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, false);
- stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, true);
- stats.notePullBinderCallFailed(util::DISK_SPACE);
- stats.notePullUidProviderNotFound(util::DISK_SPACE);
- stats.notePullerNotFound(util::DISK_SPACE);
- stats.notePullerNotFound(util::DISK_SPACE);
- stats.notePullTimeout(util::DISK_SPACE, 3000L, 6000L);
- stats.notePullTimeout(util::DISK_SPACE, 4000L, 7000L);
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
-
- ASSERT_EQ(1, report.pulled_atom_stats_size());
-
- EXPECT_EQ(util::DISK_SPACE, report.pulled_atom_stats(0).atom_id());
- EXPECT_EQ(3, report.pulled_atom_stats(0).total_pull());
- EXPECT_EQ(1, report.pulled_atom_stats(0).total_pull_from_cache());
- EXPECT_EQ(2222L, report.pulled_atom_stats(0).min_pull_interval_sec());
- EXPECT_EQ(2222L, report.pulled_atom_stats(0).average_pull_time_nanos());
- EXPECT_EQ(3333L, report.pulled_atom_stats(0).max_pull_time_nanos());
- EXPECT_EQ(2223L, report.pulled_atom_stats(0).average_pull_delay_nanos());
- EXPECT_EQ(3335L, report.pulled_atom_stats(0).max_pull_delay_nanos());
- EXPECT_EQ(2L, report.pulled_atom_stats(0).registered_count());
- EXPECT_EQ(1L, report.pulled_atom_stats(0).unregistered_count());
- EXPECT_EQ(1L, report.pulled_atom_stats(0).binder_call_failed());
- EXPECT_EQ(1L, report.pulled_atom_stats(0).failed_uid_provider_not_found());
- EXPECT_EQ(2L, report.pulled_atom_stats(0).puller_not_found());
- ASSERT_EQ(2, report.pulled_atom_stats(0).pull_atom_metadata_size());
- EXPECT_EQ(3000L, report.pulled_atom_stats(0).pull_atom_metadata(0).pull_timeout_uptime_millis());
- EXPECT_EQ(4000L, report.pulled_atom_stats(0).pull_atom_metadata(1).pull_timeout_uptime_millis());
- EXPECT_EQ(6000L, report.pulled_atom_stats(0).pull_atom_metadata(0)
- .pull_timeout_elapsed_millis());
- EXPECT_EQ(7000L, report.pulled_atom_stats(0).pull_atom_metadata(1)
- .pull_timeout_elapsed_millis());
-}
-
-TEST(StatsdStatsTest, TestAtomMetricsStats) {
- StatsdStats stats;
- time_t now = time(nullptr);
- // old event, we get it from the stats buffer. should be ignored.
- stats.noteBucketDropped(1000L);
-
- stats.noteBucketBoundaryDelayNs(1000L, -1L);
- stats.noteBucketBoundaryDelayNs(1000L, -10L);
- stats.noteBucketBoundaryDelayNs(1000L, 2L);
-
- stats.noteBucketBoundaryDelayNs(1001L, 1L);
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
-
- ASSERT_EQ(2, report.atom_metric_stats().size());
-
- auto atomStats = report.atom_metric_stats(0);
- EXPECT_EQ(1000L, atomStats.metric_id());
- EXPECT_EQ(1L, atomStats.bucket_dropped());
- EXPECT_EQ(-10L, atomStats.min_bucket_boundary_delay_ns());
- EXPECT_EQ(2L, atomStats.max_bucket_boundary_delay_ns());
-
- auto atomStats2 = report.atom_metric_stats(1);
- EXPECT_EQ(1001L, atomStats2.metric_id());
- EXPECT_EQ(0L, atomStats2.bucket_dropped());
- EXPECT_EQ(0L, atomStats2.min_bucket_boundary_delay_ns());
- EXPECT_EQ(1L, atomStats2.max_bucket_boundary_delay_ns());
-}
-
-TEST(StatsdStatsTest, TestAnomalyMonitor) {
- StatsdStats stats;
- stats.noteRegisteredAnomalyAlarmChanged();
- stats.noteRegisteredAnomalyAlarmChanged();
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
-
- EXPECT_EQ(2, report.anomaly_alarm_stats().alarms_registered());
-}
-
-TEST(StatsdStatsTest, TestTimestampThreshold) {
- StatsdStats stats;
- vector<int32_t> timestamps;
- for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
- timestamps.push_back(i);
- }
- ConfigKey key(0, 12345);
- stats.noteConfigReceived(key, 2, 3, 4, 5, {}, true);
-
- for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
- stats.noteDataDropped(key, timestamps[i]);
- stats.noteBroadcastSent(key, timestamps[i]);
- stats.noteMetricsReportSent(key, 0, timestamps[i]);
- stats.noteActiveStatusChanged(key, true, timestamps[i]);
- stats.noteActiveStatusChanged(key, false, timestamps[i]);
- }
-
- int32_t newTimestamp = 10000;
-
- // now it should trigger removing oldest timestamp
- stats.noteDataDropped(key, 123, 10000);
- stats.noteBroadcastSent(key, 10000);
- stats.noteMetricsReportSent(key, 0, 10000);
- stats.noteActiveStatusChanged(key, true, 10000);
- stats.noteActiveStatusChanged(key, false, 10000);
-
- EXPECT_TRUE(stats.mConfigStats.find(key) != stats.mConfigStats.end());
- const auto& configStats = stats.mConfigStats[key];
-
- size_t maxCount = StatsdStats::kMaxTimestampCount;
- ASSERT_EQ(maxCount, configStats->broadcast_sent_time_sec.size());
- ASSERT_EQ(maxCount, configStats->data_drop_time_sec.size());
- ASSERT_EQ(maxCount, configStats->dump_report_stats.size());
- ASSERT_EQ(maxCount, configStats->activation_time_sec.size());
- ASSERT_EQ(maxCount, configStats->deactivation_time_sec.size());
-
- // the oldest timestamp is the second timestamp in history
- EXPECT_EQ(1, configStats->broadcast_sent_time_sec.front());
- EXPECT_EQ(1, configStats->data_drop_bytes.front());
- EXPECT_EQ(1, configStats->dump_report_stats.front().first);
- EXPECT_EQ(1, configStats->activation_time_sec.front());
- EXPECT_EQ(1, configStats->deactivation_time_sec.front());
-
- // the last timestamp is the newest timestamp.
- EXPECT_EQ(newTimestamp, configStats->broadcast_sent_time_sec.back());
- EXPECT_EQ(newTimestamp, configStats->data_drop_time_sec.back());
- EXPECT_EQ(123, configStats->data_drop_bytes.back());
- EXPECT_EQ(newTimestamp, configStats->dump_report_stats.back().first);
- EXPECT_EQ(newTimestamp, configStats->activation_time_sec.back());
- EXPECT_EQ(newTimestamp, configStats->deactivation_time_sec.back());
-}
-
-TEST(StatsdStatsTest, TestSystemServerCrash) {
- StatsdStats stats;
- vector<int32_t> timestamps;
- for (int i = 0; i < StatsdStats::kMaxSystemServerRestarts; i++) {
- timestamps.push_back(i);
- stats.noteSystemServerRestart(timestamps[i]);
- }
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
- const int maxCount = StatsdStats::kMaxSystemServerRestarts;
- ASSERT_EQ(maxCount, (int)report.system_restart_sec_size());
-
- stats.noteSystemServerRestart(StatsdStats::kMaxSystemServerRestarts + 1);
- output.clear();
- stats.dumpStats(&output, false);
- EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
- ASSERT_EQ(maxCount, (int)report.system_restart_sec_size());
- EXPECT_EQ(StatsdStats::kMaxSystemServerRestarts + 1, report.system_restart_sec(maxCount - 1));
-}
-
-TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit) {
- StatsdStats stats;
- int uid1 = 1;
- int uid2 = 2;
- stats.noteActivationBroadcastGuardrailHit(uid1, 10);
- stats.noteActivationBroadcastGuardrailHit(uid1, 20);
-
- // Test that we only keep 20 timestamps.
- for (int i = 0; i < 100; i++) {
- stats.noteActivationBroadcastGuardrailHit(uid2, i);
- }
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
-
- ASSERT_EQ(2, report.activation_guardrail_stats_size());
- bool uid1Good = false;
- bool uid2Good = false;
- for (const auto& guardrailTimes : report.activation_guardrail_stats()) {
- if (uid1 == guardrailTimes.uid()) {
- uid1Good = true;
- ASSERT_EQ(2, guardrailTimes.guardrail_met_sec_size());
- EXPECT_EQ(10, guardrailTimes.guardrail_met_sec(0));
- EXPECT_EQ(20, guardrailTimes.guardrail_met_sec(1));
- } else if (uid2 == guardrailTimes.uid()) {
- int maxCount = StatsdStats::kMaxTimestampCount;
- uid2Good = true;
- ASSERT_EQ(maxCount, guardrailTimes.guardrail_met_sec_size());
- for (int i = 0; i < maxCount; i++) {
- EXPECT_EQ(100 - maxCount + i, guardrailTimes.guardrail_met_sec(i));
- }
- } else {
- FAIL() << "Unexpected uid.";
- }
- }
- EXPECT_TRUE(uid1Good);
- EXPECT_TRUE(uid2Good);
-}
-
-TEST(StatsdStatsTest, TestAtomErrorStats) {
- StatsdStats stats;
-
- int pushAtomTag = 100;
- int pullAtomTag = 1000;
- int numErrors = 10;
-
- for (int i = 0; i < numErrors; i++) {
- // We must call noteAtomLogged as well because only those pushed atoms
- // that have been logged will have stats printed about them in the
- // proto.
- stats.noteAtomLogged(pushAtomTag, /*timeSec=*/0);
- stats.noteAtomError(pushAtomTag, /*pull=*/false);
-
- stats.noteAtomError(pullAtomTag, /*pull=*/true);
- }
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
-
- // Check error count = numErrors for push atom
- ASSERT_EQ(1, report.atom_stats_size());
- const auto& pushedAtomStats = report.atom_stats(0);
- EXPECT_EQ(pushAtomTag, pushedAtomStats.tag());
- EXPECT_EQ(numErrors, pushedAtomStats.error_count());
-
- // Check error count = numErrors for pull atom
- ASSERT_EQ(1, report.pulled_atom_stats_size());
- const auto& pulledAtomStats = report.pulled_atom_stats(0);
- EXPECT_EQ(pullAtomTag, pulledAtomStats.atom_id());
- EXPECT_EQ(numErrors, pulledAtomStats.atom_error_count());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/indexed_priority_queue_test.cpp b/cmds/statsd/tests/indexed_priority_queue_test.cpp
deleted file mode 100644
index 3a65456..0000000
--- a/cmds/statsd/tests/indexed_priority_queue_test.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/anomaly/indexed_priority_queue.h"
-
-#include <gtest/gtest.h>
-
-using namespace android::os::statsd;
-
-/** struct for template in indexed_priority_queue */
-struct AATest : public RefBase {
- AATest(uint32_t val, std::string a, std::string b) : val(val), a(a), b(b) {
- }
-
- const int val;
- const std::string a;
- const std::string b;
-
- struct Smaller {
- bool operator()(const sp<const AATest> a, const sp<const AATest> b) const {
- return (a->val < b->val);
- }
- };
-};
-
-#ifdef __ANDROID__
-TEST(indexed_priority_queue, empty_and_size) {
- std::string emptyMetricId;
- std::string emptyDimensionId;
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- sp<const AATest> aa4 = new AATest{4, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa8 = new AATest{8, emptyMetricId, emptyDimensionId};
-
- ASSERT_EQ(0u, ipq.size());
- EXPECT_TRUE(ipq.empty());
-
- ipq.push(aa4);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_FALSE(ipq.empty());
-
- ipq.push(aa8);
- ASSERT_EQ(2u, ipq.size());
- EXPECT_FALSE(ipq.empty());
-
- ipq.remove(aa4);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_FALSE(ipq.empty());
-
- ipq.remove(aa8);
- ASSERT_EQ(0u, ipq.size());
- EXPECT_TRUE(ipq.empty());
-}
-
-TEST(indexed_priority_queue, top) {
- std::string emptyMetricId;
- std::string emptyDimensionId;
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- sp<const AATest> aa2 = new AATest{2, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa4 = new AATest{4, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa8 = new AATest{8, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa12 = new AATest{12, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa16 = new AATest{16, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa20 = new AATest{20, emptyMetricId, emptyDimensionId};
-
- EXPECT_EQ(ipq.top(), nullptr);
-
- // add 8, 4, 12
- ipq.push(aa8);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.push(aa12);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.push(aa4);
- EXPECT_EQ(ipq.top(), aa4);
-
- // remove 12, 4
- ipq.remove(aa12);
- EXPECT_EQ(ipq.top(), aa4);
-
- ipq.remove(aa4);
- EXPECT_EQ(ipq.top(), aa8);
-
- // add 16, 2, 20
- ipq.push(aa16);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.push(aa2);
- EXPECT_EQ(ipq.top(), aa2);
-
- ipq.push(aa20);
- EXPECT_EQ(ipq.top(), aa2);
-
- // remove 2, 20, 16, 8
- ipq.remove(aa2);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.remove(aa20);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.remove(aa16);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.remove(aa8);
- EXPECT_EQ(ipq.top(), nullptr);
-}
-
-TEST(indexed_priority_queue, push_same_aa) {
- std::string emptyMetricId;
- std::string emptyDimensionId;
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- sp<const AATest> aa4_a = new AATest{4, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa4_b = new AATest{4, emptyMetricId, emptyDimensionId};
-
- ipq.push(aa4_a);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4_a));
- EXPECT_FALSE(ipq.contains(aa4_b));
-
- ipq.push(aa4_a);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4_a));
- EXPECT_FALSE(ipq.contains(aa4_b));
-
- ipq.push(aa4_b);
- ASSERT_EQ(2u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4_a));
- EXPECT_TRUE(ipq.contains(aa4_b));
-}
-
-TEST(indexed_priority_queue, remove_nonexistant) {
- std::string emptyMetricId;
- std::string emptyDimensionId;
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- sp<const AATest> aa4 = new AATest{4, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa5 = new AATest{5, emptyMetricId, emptyDimensionId};
-
- ipq.push(aa4);
- ipq.remove(aa5);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4));
- EXPECT_FALSE(ipq.contains(aa5));
-}
-
-TEST(indexed_priority_queue, remove_same_aa) {
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- std::string emptyMetricId;
- std::string emptyDimensionId;
- sp<const AATest> aa4_a = new AATest{4, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa4_b = new AATest{4, emptyMetricId, emptyDimensionId};
-
- ipq.push(aa4_a);
- ipq.push(aa4_b);
- ASSERT_EQ(2u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4_a));
- EXPECT_TRUE(ipq.contains(aa4_b));
-
- ipq.remove(aa4_b);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4_a));
- EXPECT_FALSE(ipq.contains(aa4_b));
-
- ipq.remove(aa4_a);
- ASSERT_EQ(0u, ipq.size());
- EXPECT_FALSE(ipq.contains(aa4_a));
- EXPECT_FALSE(ipq.contains(aa4_b));
-}
-
-TEST(indexed_priority_queue, nulls) {
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
-
- EXPECT_TRUE(ipq.empty());
- EXPECT_FALSE(ipq.contains(nullptr));
-
- ipq.push(nullptr);
- EXPECT_TRUE(ipq.empty());
- EXPECT_FALSE(ipq.contains(nullptr));
-
- ipq.remove(nullptr);
- EXPECT_TRUE(ipq.empty());
- EXPECT_FALSE(ipq.contains(nullptr));
-}
-
-TEST(indexed_priority_queue, pop) {
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- std::string emptyMetricId;
- std::string emptyDimensionId;
- sp<const AATest> a = new AATest{1, emptyMetricId, emptyDimensionId};
- sp<const AATest> b = new AATest{2, emptyMetricId, emptyDimensionId};
- sp<const AATest> c = new AATest{3, emptyMetricId, emptyDimensionId};
-
- ipq.push(c);
- ipq.push(b);
- ipq.push(a);
- ASSERT_EQ(3u, ipq.size());
-
- ipq.pop();
- ASSERT_EQ(2u, ipq.size());
- EXPECT_FALSE(ipq.contains(a));
- EXPECT_TRUE(ipq.contains(b));
- EXPECT_TRUE(ipq.contains(c));
-
- ipq.pop();
- ASSERT_EQ(1u, ipq.size());
- EXPECT_FALSE(ipq.contains(a));
- EXPECT_FALSE(ipq.contains(b));
- EXPECT_TRUE(ipq.contains(c));
-
- ipq.pop();
- ASSERT_EQ(0u, ipq.size());
- EXPECT_FALSE(ipq.contains(a));
- EXPECT_FALSE(ipq.contains(b));
- EXPECT_FALSE(ipq.contains(c));
- EXPECT_TRUE(ipq.empty());
-
- ipq.pop(); // pop an empty queue
- EXPECT_TRUE(ipq.empty());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/log_event/LogEventQueue_test.cpp b/cmds/statsd/tests/log_event/LogEventQueue_test.cpp
deleted file mode 100644
index a15f95b..0000000
--- a/cmds/statsd/tests/log_event/LogEventQueue_test.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "logd/LogEventQueue.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <thread>
-
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace android;
-using namespace testing;
-
-using std::unique_ptr;
-
-namespace {
-
-std::unique_ptr<LogEvent> makeLogEvent(uint64_t timestampNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, 10);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-} // anonymous namespace
-
-#ifdef __ANDROID__
-TEST(LogEventQueue_test, TestGoodConsumer) {
- LogEventQueue queue(50);
- int64_t timeBaseNs = 100;
- std::thread writer([&queue, timeBaseNs] {
- for (int i = 0; i < 100; i++) {
- int64_t oldestEventNs;
- bool success = queue.push(makeLogEvent(timeBaseNs + i * 1000), &oldestEventNs);
- EXPECT_TRUE(success);
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
- }
- });
-
- std::thread reader([&queue, timeBaseNs] {
- for (int i = 0; i < 100; i++) {
- auto event = queue.waitPop();
- EXPECT_TRUE(event != nullptr);
- // All events are in right order.
- EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs());
- }
- });
-
- reader.join();
- writer.join();
-}
-
-TEST(LogEventQueue_test, TestSlowConsumer) {
- LogEventQueue queue(50);
- int64_t timeBaseNs = 100;
- std::thread writer([&queue, timeBaseNs] {
- int failure_count = 0;
- int64_t oldestEventNs;
- for (int i = 0; i < 100; i++) {
- bool success = queue.push(makeLogEvent(timeBaseNs + i * 1000), &oldestEventNs);
- if (!success) failure_count++;
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
- }
-
- // There is some remote chance that reader thread not get chance to run before writer thread
- // ends. That's why the following comparison is not "==".
- // There will be at least 45 events lost due to overflow.
- EXPECT_TRUE(failure_count >= 45);
- // The oldest event must be at least the 6th event.
- EXPECT_TRUE(oldestEventNs <= (100 + 5 * 1000));
- });
-
- std::thread reader([&queue, timeBaseNs] {
- // The consumer quickly processed 5 events, then it got stuck (not reading anymore).
- for (int i = 0; i < 5; i++) {
- auto event = queue.waitPop();
- EXPECT_TRUE(event != nullptr);
- // All events are in right order.
- EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs());
- }
- });
-
- reader.join();
- writer.join();
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/metadata_util_test.cpp b/cmds/statsd/tests/metadata_util_test.cpp
deleted file mode 100644
index 7707890..0000000
--- a/cmds/statsd/tests/metadata_util_test.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <gtest/gtest.h>
-
-#include "metadata_util.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-TEST(MetadataUtilTest, TestWriteAndReadMetricDimensionKey) {
- HashableDimensionKey dim;
- HashableDimensionKey dim2;
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 1, 3};
- int pos4[] = {2, 0, 0};
- Field field1(10, pos1, 2);
- Field field2(10, pos2, 2);
- Field field3(10, pos3, 2);
- Field field4(10, pos4, 0);
-
- Value value1((int32_t)10025);
- Value value2("tag");
- Value value3((int32_t)987654);
- Value value4((int32_t)99999);
-
- dim.addValue(FieldValue(field1, value1));
- dim.addValue(FieldValue(field2, value2));
- dim.addValue(FieldValue(field3, value3));
- dim.addValue(FieldValue(field4, value4));
-
- dim2.addValue(FieldValue(field1, value1));
- dim2.addValue(FieldValue(field2, value2));
-
- MetricDimensionKey dimKey(dim, dim2);
-
- metadata::MetricDimensionKey metadataDimKey;
- writeMetricDimensionKeyToMetadataDimensionKey(dimKey, &metadataDimKey);
-
- MetricDimensionKey loadedDimKey = loadMetricDimensionKeyFromProto(metadataDimKey);
-
- ASSERT_EQ(loadedDimKey, dimKey);
- ASSERT_EQ(std::hash<MetricDimensionKey>{}(loadedDimKey),
- std::hash<MetricDimensionKey>{}(dimKey));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
deleted file mode 100644
index bb8e7bf..0000000
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ /dev/null
@@ -1,476 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/CountMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-namespace {
-const ConfigKey kConfigKey(0, 12345);
-
-void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId, string uid) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeString(statsEvent, uid.c_str());
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-} // namespace
-
-// Setup for parameterized tests.
-class CountMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(CountMetricProducerTest_PartialBucket,
- CountMetricProducerTest_PartialBucket,
- testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-TEST(CountMetricProducerTest, TestFirstBucket) {
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2);
- EXPECT_EQ(600500000000, countProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(10, countProducer.mCurrentBucketNum);
- EXPECT_EQ(660000000005, countProducer.getCurrentBucketEndTimeNs());
-}
-
-TEST(CountMetricProducerTest, TestNonDimensionalEvents) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
- int tagId = 1;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, bucketStartTimeNs, bucketStartTimeNs);
-
- // 2 events in bucket 1.
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
-
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // Flushes at event #2.
- countProducer.flushIfNeededLocked(bucketStartTimeNs + 2);
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
- // Flushes.
- countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
- EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- countProducer.mPastBuckets.end());
- const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets.size());
- EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(2LL, buckets[0].mCount);
-
- // 1 matched event happens in bucket 2.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 2, tagId);
-
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-
- countProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
- ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
- EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- countProducer.mPastBuckets.end());
- ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- const auto& bucketInfo2 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1];
- EXPECT_EQ(bucket2StartTimeNs, bucketInfo2.mBucketStartNs);
- EXPECT_EQ(bucket2StartTimeNs + bucketSizeNs, bucketInfo2.mBucketEndNs);
- EXPECT_EQ(1LL, bucketInfo2.mCount);
-
- // nothing happens in bucket 3. we should not record anything for bucket 3.
- countProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
- ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
- EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- countProducer.mPastBuckets.end());
- const auto& buckets3 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(2UL, buckets3.size());
-}
-
-TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
- bucketStartTimeNs, bucketStartTimeNs);
-
- countProducer.onConditionChanged(true, bucketStartTimeNs);
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, /*atomId=*/1);
- countProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
-
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
- countProducer.onConditionChanged(false /*new condition*/, bucketStartTimeNs + 2);
-
- // Upon this match event, the matched event1 is flushed.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 10, /*atomId=*/1);
- countProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
- countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
- EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- countProducer.mPastBuckets.end());
-
- const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets.size());
- const auto& bucketInfo = buckets[0];
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
- EXPECT_EQ(1LL, bucketInfo.mCount);
-}
-
-TEST(CountMetricProducerTest, TestEventsWithSlicedCondition) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
- int tagId = 1;
- int conditionTagId = 2;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
- MetricConditionLink* link = metric.add_links();
- link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
- buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
- buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 10, tagId, /*uid=*/"222");
-
- ConditionKey key1;
- key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
- getMockedDimensionKey(conditionTagId, 2, "111")};
-
- ConditionKey key2;
- key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
- getMockedDimensionKey(conditionTagId, 2, "222")};
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
-
- EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
-
- CountMetricProducer countProducer(kConfigKey, metric, 0 /*condition tracker index*/,
- {ConditionState::kUnknown}, wizard, bucketStartTimeNs,
- bucketStartTimeNs);
-
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- countProducer.flushIfNeededLocked(bucketStartTimeNs + 1);
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
- countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
- EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- countProducer.mPastBuckets.end());
- const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets.size());
- const auto& bucketInfo = buckets[0];
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
- EXPECT_EQ(1LL, bucketInfo.mCount);
-}
-
-TEST_P(CountMetricProducerTest_PartialBucket, TestSplitInCurrentBucket) {
- sp<AlarmMonitor> alarmMonitor;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int64_t eventTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
-
- int tagId = 1;
- int conditionTagId = 2;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- Alert alert;
- alert.set_num_buckets(3);
- alert.set_trigger_if_sum_gt(2);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
- bucketStartTimeNs, bucketStartTimeNs);
-
- sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
- EXPECT_TRUE(anomalyTracker != nullptr);
-
- // Bucket is not flushed yet.
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
- EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- // App upgrade or boot complete forces bucket flush.
- // Check that there's a past bucket and the bucket end is not adjusted.
- switch (GetParam()) {
- case APP_UPGRADE:
- countProducer.notifyAppUpgrade(eventTimeNs);
- break;
- case BOOT_COMPLETE:
- countProducer.onStatsdInitCompleted(eventTimeNs);
- break;
- }
- ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(eventTimeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
- EXPECT_EQ(0, countProducer.getCurrentBucketNum());
- EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs);
- // Anomaly tracker only contains full buckets.
- EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- int64_t lastEndTimeNs = countProducer.getCurrentBucketEndTimeNs();
- // Next event occurs in same bucket as partial bucket created.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 59 * NS_PER_SEC + 10, tagId, /*uid=*/"222");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
- ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, countProducer.getCurrentBucketNum());
- EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- // Third event in following bucket.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + 62 * NS_PER_SEC + 10, tagId, /*uid=*/"333");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(lastEndTimeNs, countProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, countProducer.getCurrentBucketNum());
- EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-}
-
-TEST_P(CountMetricProducerTest_PartialBucket, TestSplitInNextBucket) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int64_t eventTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
-
- int tagId = 1;
- int conditionTagId = 2;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
- bucketStartTimeNs, bucketStartTimeNs);
-
- // Bucket is flushed yet.
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
- // App upgrade or boot complete forces bucket flush.
- // Check that there's a past bucket and the bucket end is not adjusted since the upgrade
- // occurred after the bucket end time.
- switch (GetParam()) {
- case APP_UPGRADE:
- countProducer.notifyAppUpgrade(eventTimeNs);
- break;
- case BOOT_COMPLETE:
- countProducer.onStatsdInitCompleted(eventTimeNs);
- break;
- }
- ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
- EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs);
-
- // Next event occurs in same bucket as partial bucket created.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 70 * NS_PER_SEC + 10, tagId, /*uid=*/"222");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
- ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-
- // Third event in following bucket.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + 121 * NS_PER_SEC + 10, tagId, /*uid=*/"333");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ((int64_t)eventTimeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketEndNs);
-}
-
-TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced) {
- sp<AlarmMonitor> alarmMonitor;
- Alert alert;
- alert.set_id(11);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(2);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 1;
- alert.set_refractory_period_secs(refPeriodSec);
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, bucketStartTimeNs, bucketStartTimeNs);
-
- sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
-
- int tagId = 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + 2 * bucketSizeNs + 1, tagId);
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event4, bucketStartTimeNs + 3 * bucketSizeNs + 1, tagId);
- LogEvent event5(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event5, bucketStartTimeNs + 3 * bucketSizeNs + 2, tagId);
- LogEvent event6(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event6, bucketStartTimeNs + 3 * bucketSizeNs + 3, tagId);
- LogEvent event7(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event7, bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC, tagId);
-
- // Two events in bucket #0.
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
- EXPECT_EQ(2L, countProducer.mCurrentSlicedCounter->begin()->second);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
- // One event in bucket #2. No alarm as bucket #0 is trashed out.
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
- EXPECT_EQ(1L, countProducer.mCurrentSlicedCounter->begin()->second);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
- // Two events in bucket #3.
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event5);
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event6);
- ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
- EXPECT_EQ(3L, countProducer.mCurrentSlicedCounter->begin()->second);
- // Anomaly at event 6 is within refractory period. The alarm is at event 5 timestamp not event 6
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event5.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event7);
- ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
- EXPECT_EQ(4L, countProducer.mCurrentSlicedCounter->begin()->second);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event7.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-}
-
-TEST(CountMetricProducerTest, TestOneWeekTimeUnit) {
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_WEEK);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- int64_t oneDayNs = 24 * 60 * 60 * 1e9;
- int64_t fiveWeeksNs = 5 * 7 * oneDayNs;
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /* meaning no condition */, {}, wizard,
- oneDayNs, fiveWeeksNs);
-
- int64_t fiveWeeksOneDayNs = fiveWeeksNs + oneDayNs;
-
- EXPECT_EQ(fiveWeeksNs, countProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(4, countProducer.mCurrentBucketNum);
- EXPECT_EQ(fiveWeeksOneDayNs, countProducer.getCurrentBucketEndTimeNs());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
deleted file mode 100644
index 05cfa37b..0000000
--- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/DurationMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "src/condition/ConditionWizard.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace android::os::statsd;
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-} // namespace
-
-// Setup for parameterized tests.
-class DurationMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(DurationMetricProducerTest_PartialBucket,
- DurationMetricProducerTest_PartialBucket,
- testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-TEST(DurationMetricTrackerTest, TestFirstBucket) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /*no condition*/, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2);
-
- EXPECT_EQ(600500000000, durationProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(10, durationProducer.mCurrentBucketNum);
- EXPECT_EQ(660000000005, durationProducer.getCurrentBucketEndTimeNs());
-}
-
-TEST(DurationMetricTrackerTest, TestNoCondition) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- int tagId = 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + bucketSizeNs + 2, tagId);
-
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /*no condition*/, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
- ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
- EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- durationProducer.mPastBuckets.end());
- const auto& buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(2UL, buckets.size());
- EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(bucketSizeNs - 1LL, buckets[0].mDuration);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[1].mBucketEndNs);
- EXPECT_EQ(2LL, buckets[1].mDuration);
-}
-
-TEST(DurationMetricTrackerTest, TestNonSlicedCondition) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- int tagId = 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 1, tagId);
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
-
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(
- kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
- 1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
- wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
- durationProducer.mCondition = ConditionState::kFalse;
-
- EXPECT_FALSE(durationProducer.mCondition);
- EXPECT_FALSE(durationProducer.isConditionSliced());
-
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
-
- durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
- durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
- ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
- EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- durationProducer.mPastBuckets.end());
- const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets2.size());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
- EXPECT_EQ(1LL, buckets2[0].mDuration);
-}
-
-TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- int tagId = 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 1, tagId);
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
-
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(
- kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
- 1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
- wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- EXPECT_EQ(ConditionState::kUnknown, durationProducer.mCondition);
- EXPECT_FALSE(durationProducer.isConditionSliced());
-
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
-
- durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
- durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
- ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
- const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets2.size());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
- EXPECT_EQ(1LL, buckets2[0].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDuration) {
- /**
- * The duration starts from the first bucket, through the two partial buckets (10-70sec),
- * another bucket, and ends at the beginning of the next full bucket.
- * Expected buckets:
- * - [10,25]: 14 secs
- * - [25,70]: All 45 secs
- * - [70,130]: All 60 secs
- * - [130, 210]: Only 5 secs (event ended at 135sec)
- */
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int tagId = 1;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, startTimeNs, tagId);
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
- EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
- switch (GetParam()) {
- case APP_UPGRADE:
- durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- ASSERT_EQ(1UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- std::vector<DurationBucket> buckets =
- durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(partialBucketSplitTimeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(partialBucketSplitTimeNs - startTimeNs, buckets[0].mDuration);
- EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, durationProducer.getCurrentBucketNum());
-
- // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
- int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, endTimeNs, tagId);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(3UL, buckets.size());
- EXPECT_EQ(partialBucketSplitTimeNs, buckets[1].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketEndNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - partialBucketSplitTimeNs, buckets[1].mDuration);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[2].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
- EXPECT_EQ(bucketSizeNs, buckets[2].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDurationWithSplitInFollowingBucket) {
- /**
- * Expected buckets (start at 11s, upgrade at 75s, end at 135s):
- * - [10,70]: 59 secs
- * - [70,75]: 5 sec
- * - [75,130]: 55 secs
- */
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int tagId = 1;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, startTimeNs, tagId);
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
- EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
- switch (GetParam()) {
- case APP_UPGRADE:
- durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- ASSERT_EQ(2UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- std::vector<DurationBucket> buckets =
- durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs, buckets[0].mDuration);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs);
- EXPECT_EQ(partialBucketSplitTimeNs, buckets[1].mBucketEndNs);
- EXPECT_EQ(partialBucketSplitTimeNs - (bucketStartTimeNs + bucketSizeNs), buckets[1].mDuration);
- EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, durationProducer.getCurrentBucketNum());
-
- // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
- int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, endTimeNs, tagId);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(3UL, buckets.size());
- EXPECT_EQ(partialBucketSplitTimeNs, buckets[2].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs - partialBucketSplitTimeNs,
- buckets[2].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDurationAnomaly) {
- sp<AlarmMonitor> alarmMonitor;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int tagId = 1;
-
- // Setup metric with alert.
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
- Alert alert;
- alert.set_num_buckets(3);
- alert.set_trigger_if_sum_gt(2);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- sp<AnomalyTracker> anomalyTracker = durationProducer.addAnomalyTracker(alert, alarmMonitor);
- EXPECT_TRUE(anomalyTracker != nullptr);
-
- int64_t startTimeNs = bucketStartTimeNs + 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, startTimeNs, tagId);
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
- switch (GetParam()) {
- case APP_UPGRADE:
- durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
-
- // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
- int64_t endTimeNs = startTimeNs + 65 * NS_PER_SEC;
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, endTimeNs, tagId);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs,
- anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestMaxDuration) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int tagId = 1;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- int64_t startTimeNs = bucketStartTimeNs + 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, startTimeNs, tagId);
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
- EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
- switch (GetParam()) {
- case APP_UPGRADE:
- durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, durationProducer.getCurrentBucketNum());
-
- // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
- int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, endTimeNs, tagId);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
- std::vector<DurationBucket> buckets =
- durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets.size());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int tagId = 1;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- int64_t startTimeNs = bucketStartTimeNs + 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, startTimeNs, tagId);
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
- EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
- switch (GetParam()) {
- case APP_UPGRADE:
- durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, durationProducer.getCurrentBucketNum());
-
- // Stop occurs in the same partial bucket as created for the app upgrade.
- int64_t endTimeNs = startTimeNs + 115 * NS_PER_SEC;
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, endTimeNs, tagId);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
- std::vector<DurationBucket> buckets =
- durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets.size());
- EXPECT_EQ(partialBucketSplitTimeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
deleted file mode 100644
index dfbb9da..0000000
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/EventMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-namespace {
-void makeLogEvent(LogEvent* logEvent, int32_t atomId, int64_t timestampNs, string str) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeString(statsEvent, str.c_str());
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-} // anonymous namespace
-
-TEST(EventMetricProducerTest, TestNoCondition) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
- EventMetric metric;
- metric.set_id(1);
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 2);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, bucketStartTimeNs);
-
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-
- // Check dump report content.
- ProtoOutputStream output;
- std::set<string> strSet;
- eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/,
- true /*erase data*/, FAST, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_event_metrics());
- ASSERT_EQ(2, report.event_metrics().data_size());
- EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos());
- EXPECT_EQ(bucketStartTimeNs + 2, report.event_metrics().data(1).elapsed_timestamp_nanos());
-}
-
-TEST(EventMetricProducerTest, TestEventsWithNonSlicedCondition) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
- EventMetric metric;
- metric.set_id(1);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
- {ConditionState::kUnknown}, wizard, bucketStartTimeNs);
-
- eventProducer.onConditionChanged(true /*condition*/, bucketStartTimeNs);
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
-
- eventProducer.onConditionChanged(false /*condition*/, bucketStartTimeNs + 2);
-
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-
- // Check dump report content.
- ProtoOutputStream output;
- std::set<string> strSet;
- eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/,
- true /*erase data*/, FAST, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_event_metrics());
- ASSERT_EQ(1, report.event_metrics().data_size());
- EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos());
-}
-
-TEST(EventMetricProducerTest, TestEventsWithSlicedCondition) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
- int tagId = 1;
- int conditionTagId = 2;
-
- EventMetric metric;
- metric.set_id(1);
- metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
- MetricConditionLink* link = metric.add_links();
- link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
- buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
- buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1, "111");
- ConditionKey key1;
- key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
- getMockedDimensionKey(conditionTagId, 2, "111")};
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10, "222");
- ConditionKey key2;
- key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
- getMockedDimensionKey(conditionTagId, 2, "222")};
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- // Condition is false for first event.
- EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
- // Condition is true for second event.
- EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
-
- EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
- {ConditionState::kUnknown}, wizard, bucketStartTimeNs);
-
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-
- // Check dump report content.
- ProtoOutputStream output;
- std::set<string> strSet;
- eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/,
- true /*erase data*/, FAST, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_event_metrics());
- ASSERT_EQ(1, report.event_metrics().data_size());
- EXPECT_EQ(bucketStartTimeNs + 10, report.event_metrics().data(0).elapsed_timestamp_nanos());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
deleted file mode 100644
index 5997bed..0000000
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ /dev/null
@@ -1,865 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/GaugeMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "logd/LogEvent.h"
-#include "metrics_test_helper.h"
-#include "src/matchers/SimpleLogMatchingTracker.h"
-#include "src/metrics/MetricProducer.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-using std::make_shared;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-const int tagId = 1;
-const int64_t metricId = 123;
-const int64_t atomMatcherId = 678;
-const int logEventMatcherIndex = 0;
-const int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
-const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
-const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
-const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
-const int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
-
-shared_ptr<LogEvent> makeLogEvent(int32_t atomId, int64_t timestampNs, int32_t value1, string str1,
- int32_t value2) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, value1);
- AStatsEvent_writeString(statsEvent, str1.c_str());
- AStatsEvent_writeInt32(statsEvent, value2);
-
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-} // anonymous namespace
-
-// Setup for parameterized tests.
-class GaugeMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(GaugeMetricProducerTest_PartialBucket,
- GaugeMetricProducerTest_PartialBucket,
- testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-/*
- * Tests that the first bucket works correctly
- */
-TEST(GaugeMetricProducerTest, TestFirstBucket) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_gauge_fields_filter()->set_include_all(false);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(1);
- gaugeFieldMatcher->add_child()->set_field(3);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- // statsd started long ago.
- // The metric starts in the middle of the bucket
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, -1, -1,
- tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- EXPECT_EQ(600500000000, gaugeProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(10, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(660000000005, gaugeProducer.getCurrentBucketEndTimeNs());
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_gauge_fields_filter()->set_include_all(false);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(1);
- gaugeFieldMatcher->add_child()->set_field(3);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(makeLogEvent(tagId, eventTimeNs + 10, 3, "some value", 11));
- return true;
- }));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(makeLogEvent(tagId, bucket2StartTimeNs + 1, 10, "some value", 11));
-
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(10, it->mValue.int_value);
- it++;
- EXPECT_EQ(11, it->mValue.int_value);
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(3, gaugeProducer.mPastBuckets.begin()
- ->second.back()
- .mGaugeAtoms.front()
- .mFields->begin()
- ->mValue.int_value);
-
- allData.clear();
- allData.push_back(makeLogEvent(tagId, bucket3StartTimeNs + 10, 24, "some value", 25));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(24, it->mValue.int_value);
- it++;
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(25, it->mValue.int_value);
- // One dimension.
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
- it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(10L, it->mValue.int_value);
- it++;
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(11L, it->mValue.int_value);
-
- gaugeProducer.flushIfNeededLocked(bucket4StartTimeNs);
- ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
- // One dimension.
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- ASSERT_EQ(3UL, gaugeProducer.mPastBuckets.begin()->second.size());
- it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(24L, it->mValue.int_value);
- it++;
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(25L, it->mValue.int_value);
-}
-
-TEST_P(GaugeMetricProducerTest_PartialBucket, TestPushedEvents) {
- sp<AlarmMonitor> alarmMonitor;
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_gauge_fields_filter()->set_include_all(true);
-
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(metricId);
- alert.set_trigger_if_sum_gt(25);
- alert.set_num_buckets(100);
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard,
- -1 /* -1 means no pulling */, -1, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
- EXPECT_TRUE(anomalyTracker != nullptr);
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- EXPECT_EQ(1UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
-
- switch (GetParam()) {
- case APP_UPGRADE:
- gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- EXPECT_EQ(0UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(partialBucketSplitTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
- EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- // Partial buckets are not sent to anomaly tracker.
- EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- // Create an event in the same partial bucket.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 1, 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
- EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(partialBucketSplitTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
- EXPECT_EQ((int64_t)partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- // Partial buckets are not sent to anomaly tracker.
- EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- // Next event should trigger creation of new bucket and send previous full bucket to anomaly
- // tracker.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(&event3, tagId, bucketStartTimeNs + 65 * NS_PER_SEC, 1, 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- EXPECT_EQ(1L, gaugeProducer.mCurrentBucketNum);
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ((int64_t)bucketStartTimeNs + bucketSizeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- // Next event should trigger creation of new bucket.
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(&event4, tagId, bucketStartTimeNs + 125 * NS_PER_SEC, 1, 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
- EXPECT_EQ(2L, gaugeProducer.mCurrentBucketNum);
- ASSERT_EQ(3UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-}
-
-TEST_P(GaugeMetricProducerTest_PartialBucket, TestPulled) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(2);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- .WillOnce(Return(false))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 2));
- return true;
- }));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
-
- switch (GetParam()) {
- case APP_UPGRADE:
- gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(partialBucketSplitTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
- EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(2, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + bucketSizeNs + 1, 3));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(3, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_max_pull_delay_sec(INT_MAX);
- metric.set_split_bucket_for_app_upgrade(false);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(2);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Return(false));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
-
- gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- ASSERT_EQ(0UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(bucketStartTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(2);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- int64_t conditionChangeNs = bucketStartTimeNs + 8;
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, conditionChangeNs, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs + 10, 100));
- return true;
- }));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
- {ConditionState::kUnknown}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, -1, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- gaugeProducer.onConditionChanged(true, conditionChangeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(100, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
- ASSERT_EQ(0UL, gaugeProducer.mPastBuckets.size());
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(110, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(100, gaugeProducer.mPastBuckets.begin()
- ->second.back()
- .mGaugeAtoms.front()
- .mFields->begin()
- ->mValue.int_value);
-
- gaugeProducer.onConditionChanged(false, bucket2StartTimeNs + 10);
- gaugeProducer.flushIfNeededLocked(bucket3StartTimeNs + 10);
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(110L, gaugeProducer.mPastBuckets.begin()
- ->second.back()
- .mGaugeAtoms.front()
- .mFields->begin()
- ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
- const int conditionTag = 65;
- GaugeMetric metric;
- metric.set_id(1111111);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_gauge_fields_filter()->set_include_all(true);
- metric.set_condition(StringToId("APP_DIED"));
- metric.set_max_pull_delay_sec(INT_MAX);
- auto dim = metric.mutable_dimensions_in_what();
- dim->set_field(tagId);
- dim->add_child()->set_field(1);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*wizard, query(_, _, _))
- .WillRepeatedly(
- Invoke([](const int conditionIndex, const ConditionKey& conditionParameters,
- const bool isPartialLink) {
- int pos[] = {1, 0, 0};
- Field f(conditionTag, pos, 0);
- HashableDimensionKey key;
- key.mutableValues()->emplace_back(f, Value((int32_t)1000000));
-
- return ConditionState::kTrue;
- }));
-
- int64_t sliceConditionChangeNs = bucketStartTimeNs + 8;
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, sliceConditionChangeNs, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs + 10, 1000, 100));
- return true;
- }));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
- {ConditionState::kUnknown}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, -1, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- gaugeProducer.onSlicedConditionMayChange(true, sliceConditionChangeNs);
-
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- const auto& key = gaugeProducer.mCurrentSlicedBucket->begin()->first;
- ASSERT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1000, key.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-
- ASSERT_EQ(0UL, gaugeProducer.mPastBuckets.size());
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1000, 110));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
- sp<AlarmMonitor> alarmMonitor;
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Return(false));
-
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(2);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(metricId);
- alert.set_trigger_if_sum_gt(25);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 60;
- alert.set_refractory_period_secs(refPeriodSec);
- sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
-
- int tagId = 1;
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 13));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(13L, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
- std::shared_ptr<LogEvent> event2 =
- CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + bucketSizeNs + 20, 15);
-
- allData.clear();
- allData.push_back(event2);
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(15L, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC) + refPeriodSec);
-
- allData.clear();
- allData.push_back(
- CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 10, 26));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 2 * bucketSizeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(26L, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-
- // This event does not have the gauge field. Thus the current bucket value is 0.
- allData.clear();
- allData.push_back(CreateNoValuesLogEvent(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 3 * bucketSizeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->empty());
-}
-
-TEST(GaugeMetricProducerTest, TestPullOnTrigger) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
- metric.mutable_gauge_fields_filter()->set_include_all(false);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(1);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 4));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 5));
- return true;
- }))
- .WillOnce(Return(true));
-
- int triggerId = 5;
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
- triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
-
- LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 20);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
- ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- triggerEvent.setElapsedTimestampNs(bucket2StartTimeNs + 1);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.size());
- EXPECT_EQ(4, gaugeProducer.mPastBuckets.begin()
- ->second.back()
- .mGaugeAtoms[0]
- .mFields->begin()
- ->mValue.int_value);
- EXPECT_EQ(5, gaugeProducer.mPastBuckets.begin()
- ->second.back()
- .mGaugeAtoms[1]
- .mFields->begin()
- ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
- metric.mutable_gauge_fields_filter()->set_include_all(true);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto dimensionMatcher = metric.mutable_dimensions_in_what();
- // use field 1 as dimension.
- dimensionMatcher->set_field(tagId);
- dimensionMatcher->add_child()->set_field(1);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 3, 4));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 5));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 6));
- return true;
- }))
- .WillOnce(Return(true));
-
- int triggerId = 5;
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
- triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 3);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
- ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->size());
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 20);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
- ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- triggerEvent.setElapsedTimestampNs(bucket2StartTimeNs + 1);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.size());
- auto bucketIt = gaugeProducer.mPastBuckets.begin();
- ASSERT_EQ(1UL, bucketIt->second.back().mGaugeAtoms.size());
- EXPECT_EQ(3, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
- EXPECT_EQ(4, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
- bucketIt++;
- ASSERT_EQ(2UL, bucketIt->second.back().mGaugeAtoms.size());
- EXPECT_EQ(4, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
- EXPECT_EQ(5, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
- EXPECT_EQ(6, bucketIt->second.back().mGaugeAtoms[1].mFields->begin()->mValue.int_value);
-}
-
-/*
- * Test that BUCKET_TOO_SMALL dump reason is logged when a flushed bucket size
- * is smaller than the "min_bucket_size_nanos" specified in the metric config.
- */
-TEST(GaugeMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(FIVE_MINUTES);
- metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
- metric.set_min_bucket_size_nanos(10000000000); // 10 seconds
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 3, _, _))
- // Bucket start.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 10));
- return true;
- }));
-
- int triggerId = 5;
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
- triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 3);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- gaugeProducer.onDumpReport(bucketStartTimeNs + 9000000, true /* include recent buckets */, true,
- FAST /* dump_latency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_gauge_metrics());
- ASSERT_EQ(0, report.gauge_metrics().data_size());
- ASSERT_EQ(1, report.gauge_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.gauge_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000),
- report.gauge_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.gauge_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.gauge_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000), dropEvent.drop_time_millis());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
deleted file mode 100644
index fda3daa..0000000
--- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/duration_helper/MaxDurationTracker.h"
-#include "src/condition/ConditionWizard.h"
-#include "metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-using namespace android::os::statsd;
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-const int TagId = 1;
-
-const HashableDimensionKey eventKey = getMockedDimensionKey(TagId, 0, "1");
-const HashableDimensionKey conditionKey = getMockedDimensionKey(TagId, 4, "1");
-const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
-const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-const int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
-TEST(MaxDurationTrackerTest, TestSimpleMaxDuration) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
- const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
- const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
-
- int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- tracker.noteStart(key1, true, bucketStartTimeNs, ConditionKey());
- // Event starts again. This would not change anything as it already starts.
- tracker.noteStart(key1, true, bucketStartTimeNs + 3, ConditionKey());
- // Stopped.
- tracker.noteStop(key1, bucketStartTimeNs + 10, false);
-
- // Another event starts in this bucket.
- tracker.noteStart(key2, true, bucketStartTimeNs + 20, ConditionKey());
- tracker.noteStop(key2, bucketStartTimeNs + 40, false /*stop all*/);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(20LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(MaxDurationTrackerTest, TestStopAll) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
- const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
- const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
-
- int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- tracker.noteStart(key1, true, bucketStartTimeNs + 1, ConditionKey());
-
- // Another event starts in this bucket.
- tracker.noteStart(key2, true, bucketStartTimeNs + 20, ConditionKey());
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 40, &buckets);
- tracker.noteStopAll(bucketStartTimeNs + bucketSizeNs + 40);
- EXPECT_TRUE(tracker.mInfos.empty());
- EXPECT_TRUE(buckets.find(eventKey) == buckets.end());
-
- tracker.flushIfNeeded(bucketStartTimeNs + 3 * bucketSizeNs + 40, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(bucketSizeNs + 40 - 1, buckets[eventKey][0].mDuration);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[eventKey][0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[eventKey][0].mBucketEndNs);
-}
-
-TEST(MaxDurationTrackerTest, TestCrossBucketBoundary) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
- const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
- const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
-
- int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- // The event starts.
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + 1, ConditionKey());
-
- // Starts again. Does not DEFAULT_DIMENSION_KEY anything.
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + bucketSizeNs + 1,
- ConditionKey());
-
- // The event stops at early 4th bucket.
- // Notestop is called from DurationMetricProducer's onMatchedLogEvent, which calls
- // flushIfneeded.
- tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 20, &buckets);
- tracker.noteStop(DEFAULT_DIMENSION_KEY, bucketStartTimeNs + (3 * bucketSizeNs) + 20,
- false /*stop all*/);
- EXPECT_TRUE(buckets.find(eventKey) == buckets.end());
-
- tracker.flushIfNeeded(bucketStartTimeNs + 4 * bucketSizeNs, &buckets);
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ((3 * bucketSizeNs) + 20 - 1, buckets[eventKey][0].mDuration);
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, buckets[eventKey][0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 4 * bucketSizeNs, buckets[eventKey][0].mBucketEndNs);
-}
-
-TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
- const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
- const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
-
- int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- // 2 starts
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + 1, ConditionKey());
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + 10, ConditionKey());
- // one stop
- tracker.noteStop(DEFAULT_DIMENSION_KEY, bucketStartTimeNs + 20, false /*stop all*/);
-
- tracker.flushIfNeeded(bucketStartTimeNs + (2 * bucketSizeNs) + 1, &buckets);
- // Because of nesting, still not stopped.
- EXPECT_TRUE(buckets.find(eventKey) == buckets.end());
-
- // real stop now.
- tracker.noteStop(DEFAULT_DIMENSION_KEY,
- bucketStartTimeNs + (2 * bucketSizeNs) + 5, false);
- tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 1, &buckets);
-
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(2 * bucketSizeNs + 5 - 1, buckets[eventKey][0].mDuration);
-}
-
-TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) {
- const HashableDimensionKey conditionDimKey = key1;
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey conditionKey1;
- MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 1, "1");
- conditionKey1[StringToId("APP_BACKGROUND")] = conditionDimKey;
-
- /**
- Start in first bucket, stop in second bucket. Condition turns on and off in the first bucket
- and again turns on and off in the second bucket.
- */
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
- int64_t conditionStarts1 = bucketStartTimeNs + 11 * NS_PER_SEC;
- int64_t conditionStops1 = bucketStartTimeNs + 14 * NS_PER_SEC;
- int64_t conditionStarts2 = bucketStartTimeNs + bucketSizeNs + 5 * NS_PER_SEC;
- int64_t conditionStops2 = conditionStarts2 + 10 * NS_PER_SEC;
- int64_t eventStopTimeNs = conditionStops2 + 8 * NS_PER_SEC;
-
- int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
- 0, bucketStartTimeNs, bucketSizeNs, true, false, {});
- EXPECT_TRUE(tracker.mAnomalyTrackers.empty());
-
- tracker.noteStart(key1, false, eventStartTimeNs, conditionKey1);
- tracker.noteConditionChanged(key1, true, conditionStarts1);
- tracker.noteConditionChanged(key1, false, conditionStops1);
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- ASSERT_EQ(0U, buckets.size());
-
- tracker.noteConditionChanged(key1, true, conditionStarts2);
- tracker.noteConditionChanged(key1, false, conditionStops2);
- tracker.noteStop(key1, eventStopTimeNs, false);
- tracker.flushIfNeeded(bucketStartTimeNs + 2 * bucketSizeNs + 1, &buckets);
- ASSERT_EQ(1U, buckets.size());
- vector<DurationBucket> item = buckets.begin()->second;
- ASSERT_EQ(1UL, item.size());
- EXPECT_EQ((int64_t)(13LL * NS_PER_SEC), item[0].mDuration);
-}
-
-TEST(MaxDurationTrackerTest, TestAnomalyDetection) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey conditionKey1;
- MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 2, "maps");
- conditionKey1[StringToId("APP_BACKGROUND")] = conditionKey;
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = 13000000000;
- int64_t durationTimeNs = 2 * 1000;
-
- int64_t metricId = 1;
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 45;
- alert.set_refractory_period_secs(refPeriodSec);
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
- {anomalyTracker});
-
- tracker.noteStart(key1, true, eventStartTimeNs, conditionKey1);
- sp<const InternalAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(53ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
-
- // Remove the anomaly alarm when the duration is no longer fully met.
- tracker.noteConditionChanged(key1, false, eventStartTimeNs + 15 * NS_PER_SEC);
- ASSERT_EQ(0U, anomalyTracker->mAlarms.size());
-
- // Since the condition was off for 10 seconds, the anomaly should trigger 10 sec later.
- tracker.noteConditionChanged(key1, true, eventStartTimeNs + 25 * NS_PER_SEC);
- ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(63ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
-}
-
-// This tests that we correctly compute the predicted time of an anomaly assuming that the current
-// state continues forward as-is.
-TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey conditionKey1;
- MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 2, "maps");
- conditionKey1[StringToId("APP_BACKGROUND")] = conditionKey;
- ConditionKey conditionKey2;
- conditionKey2[StringToId("APP_BACKGROUND")] = getMockedDimensionKey(TagId, 4, "2");
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- /**
- * Suppose we have two sub-dimensions that we're taking the MAX over. In the first of these
- * nested dimensions, we enter the pause state after 3 seconds. When we resume, the second
- * dimension has already been running for 4 seconds. Thus, we have 40-4=36 seconds remaining
- * before we trigger the anomaly.
- */
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 5 * NS_PER_SEC; // Condition is off at start.
- int64_t conditionStarts1 = bucketStartTimeNs + 11 * NS_PER_SEC;
- int64_t conditionStops1 = bucketStartTimeNs + 14 * NS_PER_SEC;
- int64_t conditionStarts2 = bucketStartTimeNs + 20 * NS_PER_SEC;
- int64_t eventStartTimeNs2 = conditionStarts2 - 4 * NS_PER_SEC;
-
- int64_t metricId = 1;
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 45;
- alert.set_refractory_period_secs(refPeriodSec);
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
- {anomalyTracker});
-
- tracker.noteStart(key1, false, eventStartTimeNs, conditionKey1);
- tracker.noteConditionChanged(key1, true, conditionStarts1);
- tracker.noteConditionChanged(key1, false, conditionStops1);
- tracker.noteStart(key2, true, eventStartTimeNs2, conditionKey2); // Condition is on already.
- tracker.noteConditionChanged(key1, true, conditionStarts2);
- ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
- auto alarm = anomalyTracker->mAlarms.begin()->second;
- int64_t anomalyFireTimeSec = alarm->timestampSec;
- EXPECT_EQ(conditionStarts2 + 36 * NS_PER_SEC,
- (long long)anomalyFireTimeSec * NS_PER_SEC);
-
- // Now we test the calculation now that there's a refractory period.
- // At the correct time, declare the anomaly. This will set a refractory period. Make sure it
- // gets correctly taken into account in future predictAnomalyTimestampNs calculations.
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarms({alarm});
- anomalyTracker->informAlarmsFired(anomalyFireTimeSec * NS_PER_SEC, firedAlarms);
- ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
- int64_t refractoryPeriodEndsSec = anomalyFireTimeSec + refPeriodSec;
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), refractoryPeriodEndsSec);
-
- // Now stop and start again. Make sure the new predictAnomalyTimestampNs takes into account
- // the refractory period correctly.
- int64_t eventStopTimeNs = anomalyFireTimeSec * NS_PER_SEC + 10;
- tracker.noteStop(key1, eventStopTimeNs, false);
- tracker.noteStop(key2, eventStopTimeNs, false);
- tracker.noteStart(key1, true, eventStopTimeNs + 1000000, conditionKey1);
- // Anomaly is ongoing, but we're still in the refractory period.
- ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ(refractoryPeriodEndsSec, (long long)(alarm->timestampSec));
-
- // Makes sure it is correct after the refractory period is over.
- tracker.noteStop(key1, eventStopTimeNs + 2000000, false);
- int64_t justBeforeRefPeriodNs = (refractoryPeriodEndsSec - 2) * NS_PER_SEC;
- tracker.noteStart(key1, true, justBeforeRefPeriodNs, conditionKey1);
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ(justBeforeRefPeriodNs + 40 * NS_PER_SEC,
- (unsigned long long)(alarm->timestampSec * NS_PER_SEC));
-}
-
-// Suppose that within one tracker there are two dimensions A and B.
-// Suppose A starts, then B starts, and then A stops. We still need to set an anomaly based on the
-// elapsed duration of B.
-TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey conditionKey1;
- MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 2, "maps");
- conditionKey1[StringToId("APP_BACKGROUND")] = conditionKey;
- ConditionKey conditionKey2;
- conditionKey2[StringToId("APP_BACKGROUND")] = getMockedDimensionKey(TagId, 4, "2");
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- /**
- * Suppose we have two sub-dimensions that we're taking the MAX over. In the first of these
- * nested dimensions, are started for 8 seconds. When we stop, the other nested dimension has
- * been started for 5 seconds. So we can only allow 35 more seconds from now.
- */
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs1 = bucketStartTimeNs + 5 * NS_PER_SEC; // Condition is off at start.
- int64_t eventStopTimeNs1 = bucketStartTimeNs + 13 * NS_PER_SEC;
- int64_t eventStartTimeNs2 = bucketStartTimeNs + 8 * NS_PER_SEC;
-
- int64_t metricId = 1;
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 45;
- alert.set_refractory_period_secs(refPeriodSec);
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
- {anomalyTracker});
-
- tracker.noteStart(key1, true, eventStartTimeNs1, conditionKey1);
- tracker.noteStart(key2, true, eventStartTimeNs2, conditionKey2);
- tracker.noteStop(key1, eventStopTimeNs1, false);
- ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
- auto alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ(eventStopTimeNs1 + 35 * NS_PER_SEC,
- (unsigned long long)(alarm->timestampSec * NS_PER_SEC));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
deleted file mode 100644
index 1d6f7de..0000000
--- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/duration_helper/OringDurationTracker.h"
-#include "src/condition/ConditionWizard.h"
-#include "metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-const int TagId = 1;
-const int64_t metricId = 123;
-const HashableDimensionKey eventKey = getMockedDimensionKey(TagId, 0, "event");
-
-const HashableDimensionKey kConditionKey1 = getMockedDimensionKey(TagId, 1, "maps");
-const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-const int64_t bucketSizeNs = 30 * NS_PER_SEC;
-
-TEST(OringDurationTrackerTest, TestDurationOverlap) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t durationTimeNs = 2 * 1000;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false,
- bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
- false, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
- EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
- tracker.noteStart(kEventKey1, true, eventStartTimeNs + 10, ConditionKey()); // overlapping wl
- EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
- tracker.flushIfNeeded(eventStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(durationTimeNs, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationNested) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
- tracker.noteStart(kEventKey1, true, eventStartTimeNs + 10, ConditionKey()); // overlapping wl
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2000, false);
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2003, false);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(2003LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestStopAll) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const std::vector<HashableDimensionKey> kConditionKey1 =
- {getMockedDimensionKey(TagId, 1, "maps")};
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
- tracker.noteStart(kEventKey2, true, eventStartTimeNs + 10, ConditionKey()); // overlapping wl
-
- tracker.noteStopAll(eventStartTimeNs + 2003);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(2003LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestCrossBucketBoundary) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t durationTimeNs = 2 * 1000;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
- EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
- tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs, &buckets);
- tracker.noteStart(kEventKey1, true, eventStartTimeNs + 2 * bucketSizeNs, ConditionKey());
- EXPECT_EQ((long long)(bucketStartTimeNs + 2 * bucketSizeNs), tracker.mLastStartTime);
-
- ASSERT_EQ(2u, buckets[eventKey].size());
- EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
- EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2 * bucketSizeNs + 10, false);
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2 * bucketSizeNs + 12, false);
- tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 12, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(2u, buckets[eventKey].size());
- EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
- EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationConditionChange) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey key1;
- key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
-
- EXPECT_CALL(*wizard, query(_, key1, _)) // #4
- .WillOnce(Return(ConditionState::kFalse));
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t durationTimeNs = 2 * 1000;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false,
- bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
- true, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
-
- tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 5);
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(5LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationConditionChange2) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey key1;
- key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
-
- EXPECT_CALL(*wizard, query(_, key1, _))
- .Times(2)
- .WillOnce(Return(ConditionState::kFalse))
- .WillOnce(Return(ConditionState::kTrue));
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t durationTimeNs = 2 * 1000;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false,
- bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
- true, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
- // condition to false; record duration 5n
- tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 5);
- // condition to true.
- tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 1000);
- // 2nd duration: 1000ns
- tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(1005LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey key1;
- key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
-
- EXPECT_CALL(*wizard, query(_, key1, _)) // #4
- .WillOnce(Return(ConditionState::kFalse));
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
- tracker.noteStart(kEventKey1, true, eventStartTimeNs + 2, key1);
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + 3, false);
-
- tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 15);
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2003, false);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(15LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- alert.set_refractory_period_secs(1);
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
-
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
- {anomalyTracker});
-
- // Nothing in the past bucket.
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, eventStartTimeNs, ConditionKey());
- EXPECT_EQ((long long)(alert.trigger_if_sum_gt() + eventStartTimeNs),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
-
- tracker.noteStop(DEFAULT_DIMENSION_KEY, eventStartTimeNs + 3, false);
- ASSERT_EQ(0u, buckets[eventKey].size());
-
- int64_t event1StartTimeNs = eventStartTimeNs + 10;
- tracker.noteStart(kEventKey1, true, event1StartTimeNs, ConditionKey());
- // No past buckets. The anomaly will happen in bucket #0.
- EXPECT_EQ((long long)(event1StartTimeNs + alert.trigger_if_sum_gt() - 3),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, event1StartTimeNs));
-
- int64_t event1StopTimeNs = eventStartTimeNs + bucketSizeNs + 10;
- tracker.flushIfNeeded(event1StopTimeNs, &buckets);
- tracker.noteStop(kEventKey1, event1StopTimeNs, false);
-
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(3LL + bucketStartTimeNs + bucketSizeNs - eventStartTimeNs - 10,
- buckets[eventKey][0].mDuration);
-
- const int64_t bucket0Duration = 3ULL + bucketStartTimeNs + bucketSizeNs - eventStartTimeNs - 10;
- const int64_t bucket1Duration = eventStartTimeNs + 10 - bucketStartTimeNs;
-
- // One past buckets. The anomaly will happen in bucket #1.
- int64_t event2StartTimeNs = eventStartTimeNs + bucketSizeNs + 15;
- tracker.noteStart(kEventKey1, true, event2StartTimeNs, ConditionKey());
- EXPECT_EQ((long long)(event2StartTimeNs + alert.trigger_if_sum_gt() - bucket0Duration -
- bucket1Duration),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, event2StartTimeNs));
- tracker.noteStop(kEventKey1, event2StartTimeNs + 1, false);
-
- // Only one past buckets is applicable. Bucket +0 should be trashed. The anomaly will happen in
- // bucket #2.
- int64_t event3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs - 9 * NS_PER_SEC;
- tracker.noteStart(kEventKey1, true, event3StartTimeNs, ConditionKey());
- EXPECT_EQ((long long)(event3StartTimeNs + alert.trigger_if_sum_gt() - bucket1Duration - 1LL),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, event3StartTimeNs));
-}
-
-TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp2) {
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(5 * NS_PER_SEC);
- alert.set_num_buckets(1);
- alert.set_refractory_period_secs(20);
-
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketNum = 0;
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, DEFAULT_METRIC_DIMENSION_KEY, wizard, 1,
-
- true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
- bucketSizeNs, true, false, {anomalyTracker});
-
- int64_t eventStartTimeNs = bucketStartTimeNs + 9 * NS_PER_SEC;
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, eventStartTimeNs, ConditionKey());
- // Anomaly happens in the bucket #1.
- EXPECT_EQ((long long)(bucketStartTimeNs + 14 * NS_PER_SEC),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
-
- tracker.noteStop(DEFAULT_DIMENSION_KEY, bucketStartTimeNs + 14 * NS_PER_SEC, false);
-
- EXPECT_EQ((long long)(bucketStartTimeNs + 34 * NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY));
-
- int64_t event2StartTimeNs = bucketStartTimeNs + 22 * NS_PER_SEC;
- EXPECT_EQ((long long)(bucketStartTimeNs + 34 * NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY));
- EXPECT_EQ((long long)(bucketStartTimeNs + 35 * NS_PER_SEC),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, event2StartTimeNs));
-}
-
-TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp3) {
- // Test the cases where the refractory period is smaller than the bucket size, longer than
- // the bucket size, and longer than 2x of the anomaly detection window.
- for (int j = 0; j < 3; j++) {
- int64_t thresholdNs = j * bucketSizeNs + 5 * NS_PER_SEC;
- for (int i = 0; i <= 7; ++i) {
-
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(thresholdNs);
- alert.set_num_buckets(3);
- alert.set_refractory_period_secs(
- bucketSizeNs / NS_PER_SEC / 2 + i * bucketSizeNs / NS_PER_SEC);
-
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketNum = 101;
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, DEFAULT_METRIC_DIMENSION_KEY, wizard,
- 1, true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
- bucketSizeNs, true, false, {anomalyTracker});
-
- int64_t eventStartTimeNs = bucketStartTimeNs + 9 * NS_PER_SEC;
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, eventStartTimeNs, ConditionKey());
- EXPECT_EQ((long long)(eventStartTimeNs + thresholdNs),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
- int64_t eventStopTimeNs = eventStartTimeNs + thresholdNs + NS_PER_SEC;
- tracker.noteStop(DEFAULT_DIMENSION_KEY, eventStopTimeNs, false);
-
- int64_t refractoryPeriodEndSec =
- anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY);
- EXPECT_EQ(eventStopTimeNs / (int64_t)NS_PER_SEC + alert.refractory_period_secs(),
- refractoryPeriodEndSec);
-
- // Acquire and release a wakelock in the next bucket.
- int64_t event2StartTimeNs = eventStopTimeNs + bucketSizeNs;
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, event2StartTimeNs, ConditionKey());
- int64_t event2StopTimeNs = event2StartTimeNs + 4 * NS_PER_SEC;
- tracker.noteStop(DEFAULT_DIMENSION_KEY, event2StopTimeNs, false);
-
- // Test the alarm prediction works well when seeing another wakelock start event.
- for (int k = 0; k <= 2; ++k) {
- int64_t event3StartTimeNs = event2StopTimeNs + NS_PER_SEC + k * bucketSizeNs;
- int64_t alarmTimestampNs =
- tracker.predictAnomalyTimestampNs(*anomalyTracker, event3StartTimeNs);
- EXPECT_GT(alarmTimestampNs, 0u);
- EXPECT_GE(alarmTimestampNs, event3StartTimeNs);
- EXPECT_GE(alarmTimestampNs, refractoryPeriodEndSec *(int64_t) NS_PER_SEC);
- }
- }
- }
-}
-
-TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 45;
- alert.set_refractory_period_secs(refPeriodSec);
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
-
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true /*nesting*/,
- bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
- false, false, {anomalyTracker});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
- tracker.noteStop(kEventKey1, eventStartTimeNs + 10, false);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
- EXPECT_TRUE(tracker.mStarted.empty());
- EXPECT_EQ(10LL, tracker.mStateKeyDurationMap[DEFAULT_DIMENSION_KEY].mDuration); // 10ns
-
- ASSERT_EQ(0u, tracker.mStarted.size());
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs + 20, ConditionKey());
- ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
- EXPECT_EQ((long long)(52ULL * NS_PER_SEC), // (10s + 1s + 1ns + 20ns) - 10ns + 40s, rounded up
- (long long)(anomalyTracker->mAlarms.begin()->second->timestampSec * NS_PER_SEC));
- // The alarm is set to fire at 52s, and when it does, an anomaly would be declared. However,
- // because this is a unit test, the alarm won't actually fire at all. Since the alarm fails
- // to fire in time, the anomaly is instead caught when noteStop is called, at around 71s.
- tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 25, &buckets);
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2 * bucketSizeNs + 25, false);
- EXPECT_EQ(anomalyTracker->getSumOverPastBuckets(eventKey), (long long)(bucketSizeNs));
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey),
- std::ceil((eventStartTimeNs + 2 * bucketSizeNs + 25.0) / NS_PER_SEC + refPeriodSec));
-}
-
-TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 45;
- alert.set_refractory_period_secs(refPeriodSec);
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- ConditionKey conkey;
- conkey[StringToId("APP_BACKGROUND")] = kConditionKey1;
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs = 30 * NS_PER_SEC;
-
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true /*nesting*/,
- bucketStartTimeNs, 0, bucketStartTimeNs, bucketSizeNs, false,
- false, {anomalyTracker});
-
- tracker.noteStart(kEventKey1, true, 15 * NS_PER_SEC, conkey); // start key1
- ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
- sp<const InternalAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(55ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
- tracker.noteStop(kEventKey1, 17 * NS_PER_SEC, false); // stop key1 (2 seconds later)
- ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
- tracker.noteStart(kEventKey1, true, 22 * NS_PER_SEC, conkey); // start key1 again
- ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
- tracker.noteStart(kEventKey2, true, 32 * NS_PER_SEC, conkey); // start key2
- ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
- tracker.noteStop(kEventKey1, 47 * NS_PER_SEC, false); // stop key1
- ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
- // Now, at 60s, which is 38s after key1 started again, we have reached 40s of 'on' time.
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarms({alarm});
- anomalyTracker->informAlarmsFired(62 * NS_PER_SEC, firedAlarms);
- ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 62U + refPeriodSec);
-
- tracker.noteStop(kEventKey2, 69 * NS_PER_SEC, false); // stop key2
- ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 62U + refPeriodSec);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
deleted file mode 100644
index 5666501..0000000
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ /dev/null
@@ -1,5061 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/ValueMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "src/matchers/SimpleLogMatchingTracker.h"
-#include "src/metrics/MetricProducer.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::make_shared;
-using std::set;
-using std::shared_ptr;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-const int tagId = 1;
-const int64_t metricId = 123;
-const int64_t atomMatcherId = 678;
-const int logEventMatcherIndex = 0;
-const int64_t bucketStartTimeNs = 10000000000;
-const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
-const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
-const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
-const int64_t bucket5StartTimeNs = bucketStartTimeNs + 4 * bucketSizeNs;
-const int64_t bucket6StartTimeNs = bucketStartTimeNs + 5 * bucketSizeNs;
-double epsilon = 0.001;
-
-static void assertPastBucketValuesSingleKey(
- const std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>>& mPastBuckets,
- const std::initializer_list<int>& expectedValuesList,
- const std::initializer_list<int64_t>& expectedDurationNsList,
- const std::initializer_list<int64_t>& expectedStartTimeNsList,
- const std::initializer_list<int64_t>& expectedEndTimeNsList) {
- vector<int> expectedValues(expectedValuesList);
- vector<int64_t> expectedDurationNs(expectedDurationNsList);
- vector<int64_t> expectedStartTimeNs(expectedStartTimeNsList);
- vector<int64_t> expectedEndTimeNs(expectedEndTimeNsList);
-
- ASSERT_EQ(expectedValues.size(), expectedDurationNs.size());
- ASSERT_EQ(expectedValues.size(), expectedStartTimeNs.size());
- ASSERT_EQ(expectedValues.size(), expectedEndTimeNs.size());
-
- if (expectedValues.size() == 0) {
- ASSERT_EQ(0, mPastBuckets.size());
- return;
- }
-
- ASSERT_EQ(1, mPastBuckets.size());
- ASSERT_EQ(expectedValues.size(), mPastBuckets.begin()->second.size());
-
- const vector<ValueBucket>& buckets = mPastBuckets.begin()->second;
- for (int i = 0; i < expectedValues.size(); i++) {
- EXPECT_EQ(expectedValues[i], buckets[i].values[0].long_value)
- << "Values differ at index " << i;
- EXPECT_EQ(expectedDurationNs[i], buckets[i].mConditionTrueNs)
- << "Condition duration value differ at index " << i;
- EXPECT_EQ(expectedStartTimeNs[i], buckets[i].mBucketStartNs)
- << "Start time differs at index " << i;
- EXPECT_EQ(expectedEndTimeNs[i], buckets[i].mBucketEndNs)
- << "End time differs at index " << i;
- }
-}
-
-} // anonymous namespace
-
-class ValueMetricProducerTestHelper {
-public:
- static sp<ValueMetricProducer> createValueProducerNoConditions(
- sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
- .WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
- .WillRepeatedly(Return());
-
- sp<ValueMetricProducer> valueProducer =
- new ValueMetricProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
- bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- valueProducer->prepareFirstBucket();
- return valueProducer;
- }
-
- static sp<ValueMetricProducer> createValueProducerWithCondition(
- sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
- ConditionState conditionAfterFirstBucketPrepared) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
- .WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
- .WillRepeatedly(Return());
-
- sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
- kConfigKey, metric, 0 /*condition index*/, {ConditionState::kUnknown}, wizard,
- logEventMatcherIndex, eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer->prepareFirstBucket();
- valueProducer->mCondition = conditionAfterFirstBucketPrepared;
- return valueProducer;
- }
-
- static sp<ValueMetricProducer> createValueProducerWithState(
- sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
- vector<int32_t> slicedStateAtoms,
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
- .WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
- .WillRepeatedly(Return());
-
- sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
- kConfigKey, metric, -1 /* no condition */, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager, {},
- {}, slicedStateAtoms, stateGroupMap);
- valueProducer->prepareFirstBucket();
- return valueProducer;
- }
-
- static sp<ValueMetricProducer> createValueProducerWithConditionAndState(
- sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
- vector<int32_t> slicedStateAtoms,
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap,
- ConditionState conditionAfterFirstBucketPrepared) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
- .WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
- .WillRepeatedly(Return());
-
- sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
- kConfigKey, metric, 0 /* condition tracker index */, {ConditionState::kUnknown},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager, {}, {}, slicedStateAtoms, stateGroupMap);
- valueProducer->prepareFirstBucket();
- valueProducer->mCondition = conditionAfterFirstBucketPrepared;
- return valueProducer;
- }
-
- static ValueMetric createMetric() {
- ValueMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_value_field()->set_field(tagId);
- metric.mutable_value_field()->add_child()->set_field(2);
- metric.set_max_pull_delay_sec(INT_MAX);
- return metric;
- }
-
- static ValueMetric createMetricWithCondition() {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_condition(StringToId("SCREEN_ON"));
- return metric;
- }
-
- static ValueMetric createMetricWithState(string state) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.add_slice_by_state(StringToId(state));
- return metric;
- }
-
- static ValueMetric createMetricWithConditionAndState(string state) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_condition(StringToId("SCREEN_ON"));
- metric.add_slice_by_state(StringToId(state));
- return metric;
- }
-};
-
-// Setup for parameterized tests.
-class ValueMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(ValueMetricProducerTest_PartialBucket,
- ValueMetricProducerTest_PartialBucket,
- testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-/*
- * Tests that the first bucket works correctly
- */
-TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- int64_t startTimeBase = 11;
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- // statsd started long ago.
- // The metric starts in the middle of the bucket
- ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, -1,
- startTimeBase, 22, pullerManager);
- valueProducer.prepareFirstBucket();
-
- EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
- EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
- EXPECT_EQ(60 * NS_PER_SEC + startTimeBase,
- valueProducer.calcPreviousBucketEndTime(2 * 60 * NS_PER_SEC));
- EXPECT_EQ(2 * 60 * NS_PER_SEC + startTimeBase,
- valueProducer.calcPreviousBucketEndTime(3 * 60 * NS_PER_SEC));
-}
-
-/*
- * Tests that the first bucket works correctly
- */
-TEST(ValueMetricProducerTest, TestFirstBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- // statsd started long ago.
- // The metric starts in the middle of the bucket
- ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, -1, 5,
- 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
- valueProducer.prepareFirstBucket();
-
- EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
- EXPECT_EQ(660000000005, valueProducer.getCurrentBucketEndTimeNs());
-}
-
-/*
- * Tests pulled atoms with no conditions
- */
-TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(8, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(23, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(12, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
- EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(36, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(13, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(3UL, valueProducer->mPastBuckets.begin()->second.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
- EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
- EXPECT_EQ(13, valueProducer->mPastBuckets.begin()->second[2].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[2].mConditionTrueNs);
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2;
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Initialize bucket.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
- return true;
- }))
- // Partial bucket.
- .WillOnce(Invoke([partialBucketSplitTimeNs](
- int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
- data->clear();
- data->push_back(
- CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs + 8, 5));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- // First bucket ends.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 2));
- valueProducer->onDataPulled(allData, /** success */ true, bucket2StartTimeNs);
-
- // Partial buckets created in 2nd bucket.
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, valueProducer->getCurrentBucketNum());
-
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1, 3},
- {bucketSizeNs, partialBucketSplitTimeNs - bucket2StartTimeNs},
- {bucketStartTimeNs, bucket2StartTimeNs},
- {bucket2StartTimeNs, partialBucketSplitTimeNs});
-}
-
-/*
- * Tests pulled atoms with filtering
- */
-TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- auto keyValue = atomMatcher.add_field_value_matcher();
- keyValue->set_field(1);
- keyValue->set_eq_int(3);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 3, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
- kConfigKey, metric, -1 /*-1 meaning no condition*/, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- valueProducer->prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 3, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(8, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket3StartTimeNs + 1, 4, 23));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // No new data seen, so data has been cleared.
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(8, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 3, 36));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- // the base was reset
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(36, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.begin()->second.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-}
-
-/*
- * Tests pulled atoms with no conditions and take absolute value after reset
- */
-TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_use_absolute_value_on_reset(true);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Return(true));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(10, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(10, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(36, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(26, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
- EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
- EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
-}
-
-/*
- * Tests pulled atoms with no conditions and take zero value after reset
- */
-TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Return(false));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(10, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(36, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(26, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-}
-
-/*
- * Test pulled event with non sliced condition.
- */
-TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8); // First condition change.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1); // Second condition change.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 130));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket3StartTimeNs + 1); // Third condition change.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 180));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- // startUpdated:false sum:0 start:100
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(110, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(10, curInterval.value.long_value);
-
- valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(20, curInterval.value.long_value);
- EXPECT_EQ(false, curBaseInfo.hasBase);
-
- valueProducer->onConditionChanged(true, bucket3StartTimeNs + 1);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10, 20}, {bucketSizeNs - 8, 1},
- {bucketStartTimeNs, bucket2StartTimeNs},
- {bucket2StartTimeNs, bucket3StartTimeNs});
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPushedEvents) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 150;
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10},
- {partialBucketSplitTimeNs - bucketStartTimeNs},
- {bucketStartTimeNs}, {partialBucketSplitTimeNs});
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, valueProducer.getCurrentBucketNum());
-
- // Event arrives after the bucket split.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 20);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10},
- {partialBucketSplitTimeNs - bucketStartTimeNs},
- {bucketStartTimeNs}, {partialBucketSplitTimeNs});
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, valueProducer.getCurrentBucketNum());
-
- // Next value should create a new bucket.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event3, tagId, bucket2StartTimeNs + 5 * NS_PER_SEC, 10);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10, 20},
- {partialBucketSplitTimeNs - bucketStartTimeNs,
- bucket2StartTimeNs - partialBucketSplitTimeNs},
- {bucketStartTimeNs, partialBucketSplitTimeNs},
- {partialBucketSplitTimeNs, bucket2StartTimeNs});
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, valueProducer.getCurrentBucketNum());
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValue) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 150;
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- .WillOnce(Return(true))
- .WillOnce(Invoke([partialBucketSplitTimeNs](
- int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 120));
- return true;
- }));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 100));
-
- valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, valueProducer.getCurrentBucketNum());
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {150}, {bucket2StartTimeNs},
- {partialBucketSplitTimeNs});
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 150));
- valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- EXPECT_EQ(bucket3StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(2, valueProducer.getCurrentBucketNum());
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20, 30}, {150, bucketSizeNs - 150},
- {bucket2StartTimeNs, partialBucketSplitTimeNs},
- {partialBucketSplitTimeNs, bucket3StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_split_bucket_for_app_upgrade(false);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Return(true));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 100));
-
- valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-
- valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150);
- ASSERT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1); // Condition change to true time.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs,
- bucket2StartTimeNs - 100); // Condition change to false time.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs - 100, 120));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
-
- valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100);
- EXPECT_FALSE(valueProducer->mCondition);
-
- int64_t partialBucketSplitTimeNs = bucket2StartTimeNs - 50;
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- // Expect one full buckets already done and starting a partial bucket.
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, valueProducer->getCurrentBucketNum());
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20},
- {(bucket2StartTimeNs - 100) - (bucketStartTimeNs + 1)},
- {bucketStartTimeNs}, {partialBucketSplitTimeNs});
- EXPECT_FALSE(valueProducer->mCondition);
-}
-
-TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(30, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {30}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
- logEventMatcherIndex, eventMatcherWizard, -1,
- bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
- valueProducer.mCondition = ConditionState::kFalse;
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has 1 slice
- ASSERT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
-
- valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(20, curInterval.value.long_value);
-
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event3, tagId, bucketStartTimeNs + 30, 30);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(50, curInterval.value.long_value);
-
- valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35);
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event4, tagId, bucketStartTimeNs + 40, 40);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(50, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {50}, {20}, {bucketStartTimeNs},
- {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestAnomalyDetection) {
- sp<AlarmMonitor> alarmMonitor;
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(metricId);
- alert.set_trigger_if_sum_gt(130);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 3;
- alert.set_refractory_period_secs(refPeriodSec);
-
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard,
- -1 /*not pulled*/, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 1 * NS_PER_SEC, 10);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 2 + NS_PER_SEC, 20);
-
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event3, tagId,
- bucketStartTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, 130);
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event4, tagId,
- bucketStartTimeNs + 3 * bucketSizeNs + 1 * NS_PER_SEC, 1);
-
- LogEvent event5(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event5, tagId,
- bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC, 150);
-
- LogEvent event6(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event6, tagId,
- bucketStartTimeNs + 3 * bucketSizeNs + 10 * NS_PER_SEC, 160);
-
- // Two events in bucket #0.
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
- // Value sum == 30 <= 130.
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
- // One event in bucket #2. No alarm as bucket #0 is trashed out.
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- // Value sum == 130 <= 130.
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
- // Three events in bucket #3.
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
- // Anomaly at event 4 since Value sum == 131 > 130!
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event4.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event5);
- // Event 5 is within 3 sec refractory period. Thus last alarm timestamp is still event4.
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event4.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event6);
- // Anomaly at event 6 since Value sum == 160 > 130 and after refractory period.
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event6.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-}
-
-// Test value metric no condition, the pull on bucket boundary come in time and too late
-TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Return(true));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- // pull 1
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- // startUpdated:true sum:0 start:11
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- // pull 2 at correct time
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- // tartUpdated:false sum:12
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(23, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs},
- {bucket2StartTimeNs}, {bucket3StartTimeNs});
-
- // pull 3 come late.
- // The previous bucket gets closed with error. (Has start value 23, no ending)
- // Another bucket gets closed with error. (No start, but ending with 36)
- // The new bucket is back to normal.
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket6StartTimeNs + 1, 36));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket6StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- // startUpdated:false sum:12
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(36, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs},
- {bucket2StartTimeNs}, {bucket3StartTimeNs});
- // The 1st bucket is dropped because of no data
- // The 3rd bucket is dropped due to multiple buckets being skipped.
- ASSERT_EQ(2, valueProducer->mSkippedBuckets.size());
-
- EXPECT_EQ(bucketStartTimeNs, valueProducer->mSkippedBuckets[0].bucketStartTimeNs);
- EXPECT_EQ(bucket2StartTimeNs, valueProducer->mSkippedBuckets[0].bucketEndTimeNs);
- ASSERT_EQ(1, valueProducer->mSkippedBuckets[0].dropEvents.size());
- EXPECT_EQ(NO_DATA, valueProducer->mSkippedBuckets[0].dropEvents[0].reason);
- EXPECT_EQ(bucket2StartTimeNs, valueProducer->mSkippedBuckets[0].dropEvents[0].dropTimeNs);
-
- EXPECT_EQ(bucket3StartTimeNs, valueProducer->mSkippedBuckets[1].bucketStartTimeNs);
- EXPECT_EQ(bucket6StartTimeNs, valueProducer->mSkippedBuckets[1].bucketEndTimeNs);
- ASSERT_EQ(1, valueProducer->mSkippedBuckets[1].dropEvents.size());
- EXPECT_EQ(MULTIPLE_BUCKETS_SKIPPED, valueProducer->mSkippedBuckets[1].dropEvents[0].reason);
- EXPECT_EQ(bucket6StartTimeNs, valueProducer->mSkippedBuckets[1].dropEvents[0].dropTimeNs);
-}
-
-/*
- * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
- * was delivered late.
- */
-TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8); // First condition change.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }))
- // condition becomes false
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1); // Second condition change.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- // pull on bucket boundary come late, condition change happens before it
- valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- EXPECT_EQ(false, curBaseInfo.hasBase);
-
- // Now the alarm is delivered.
- // since the condition turned to off before this pull finish, it has no effect
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
-}
-
-/*
- * Test pulled event with non sliced condition. The pull on boundary come late, after the condition
- * change to false, and then true again. This is due to alarm delivered late.
- */
-TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }))
- // condition becomes false
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
- return true;
- }))
- // condition becomes true again
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 25);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 25, 130));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- // startUpdated:false sum:0 start:100
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- // pull on bucket boundary come late, condition change happens before it
- valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
-
- // condition changed to true again, before the pull alarm is delivered
- valueProducer->onConditionChanged(true, bucket2StartTimeNs + 25);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(130, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
-
- // Now the alarm is delivered, but it is considered late, the data will be used
- // for the new bucket since it was just pulled.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 50, 140));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 50);
-
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(140, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(10, curInterval.value.long_value);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs, 160));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- assertPastBucketValuesSingleKey(
- valueProducer->mPastBuckets, {20, 30}, {bucketSizeNs - 8, bucketSizeNs - 24},
- {bucketStartTimeNs, bucket2StartTimeNs}, {bucket2StartTimeNs, bucket3StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_aggregation_type(ValueMetric::MIN);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_aggregation_type(ValueMetric::MAX);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(20, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_aggregation_type(ValueMetric::AVG);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 15);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval;
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(1, curInterval.sampleSize);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(25, curInterval.value.long_value);
- EXPECT_EQ(2, curInterval.sampleSize);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer.mPastBuckets.size());
- ASSERT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
-
- EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value -
- 12.5) < epsilon);
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_aggregation_type(ValueMetric::SUM);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 15);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(25, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {25}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_aggregation_type(ValueMetric::MIN);
- metric.set_use_diff(true);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(10, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 15);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(5, curInterval.value.long_value);
-
- // no change in data.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 15);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(15, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(0, curInterval.value.long_value);
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 15);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(15, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(0, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {5}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_value_field()->add_child()->set_field(3);
- metric.set_aggregation_type(ValueMetric::MIN);
- metric.set_use_diff(true);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateThreeValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10, 20);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateThreeValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 1, 15, 22);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(10, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(20, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(5, curInterval.value.long_value);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(2, curInterval.value.long_value);
-
- // no change in first value field
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateThreeValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 1, 15, 25);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(15, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(25, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- CreateThreeValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 1, 15, 29);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(15, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(29, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
-
- ASSERT_EQ(1UL, valueProducer.mPastBuckets.size());
- ASSERT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
- ASSERT_EQ(2UL, valueProducer.mPastBuckets.begin()->second[0].values.size());
- ASSERT_EQ(1UL, valueProducer.mPastBuckets.begin()->second[1].values.size());
-
- EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[0].mConditionTrueNs);
- EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].valueIndex[0]);
- EXPECT_EQ(2, valueProducer.mPastBuckets.begin()->second[0].values[1].long_value);
- EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[0].valueIndex[1]);
-
- EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[1].mConditionTrueNs);
- EXPECT_EQ(3, valueProducer.mPastBuckets.begin()->second[1].values[0].long_value);
- EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[1].valueIndex[0]);
-}
-
-/*
- * Tests zero default base.
- */
-TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
- metric.set_use_zero_default_base(true);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- auto iter = valueProducer->mCurrentSlicedBucket.begin();
- auto& interval1 = iter->second[0];
- auto iterBase = valueProducer->mCurrentBaseInfo.begin();
- auto& baseInfo1 = iterBase->second[0];
- EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(3, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
- vector<shared_ptr<LogEvent>> allData;
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 2, 4));
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(11, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(8, interval1.value.long_value);
-
- auto it = valueProducer->mCurrentSlicedBucket.begin();
- for (; it != valueProducer->mCurrentSlicedBucket.end(); it++) {
- if (it != iter) {
- break;
- }
- }
- auto itBase = valueProducer->mCurrentBaseInfo.begin();
- for (; itBase != valueProducer->mCurrentBaseInfo.end(); it++) {
- if (itBase != iterBase) {
- break;
- }
- }
- EXPECT_TRUE(it != iter);
- EXPECT_TRUE(itBase != iterBase);
- auto& interval2 = it->second[0];
- auto& baseInfo2 = itBase->second[0];
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(4, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_EQ(4, interval2.value.long_value);
-
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
- auto iterator = valueProducer->mPastBuckets.begin();
- EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
- EXPECT_EQ(8, iterator->second[0].values[0].long_value);
- iterator++;
- EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
- EXPECT_EQ(4, iterator->second[0].values[0].long_value);
-}
-
-/*
- * Tests using zero default base with failed pull.
- */
-TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
- metric.set_use_zero_default_base(true);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- const auto& it = valueProducer->mCurrentSlicedBucket.begin();
- ValueMetricProducer::Interval& interval1 = it->second[0];
- ValueMetricProducer::BaseInfo& baseInfo1 =
- valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat())->second[0];
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(3, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
- vector<shared_ptr<LogEvent>> allData;
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 2, 4));
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(11, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(8, interval1.value.long_value);
-
- auto it2 = valueProducer->mCurrentSlicedBucket.begin();
- for (; it2 != valueProducer->mCurrentSlicedBucket.end(); it2++) {
- if (it2 != it) {
- break;
- }
- }
- EXPECT_TRUE(it2 != it);
- ValueMetricProducer::Interval& interval2 = it2->second[0];
- ValueMetricProducer::BaseInfo& baseInfo2 =
- valueProducer->mCurrentBaseInfo.find(it2->first.getDimensionKeyInWhat())->second[0];
- EXPECT_EQ(2, it2->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(4, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_EQ(4, interval2.value.long_value);
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-
- // next pull somehow did not happen, skip to end of bucket 3
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 2, 5));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(5, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 2, 13));
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 1, 5));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs);
-
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Get new references now that entries have been deleted from the map
- const auto& it3 = valueProducer->mCurrentSlicedBucket.begin();
- const auto& it4 = std::next(valueProducer->mCurrentSlicedBucket.begin());
- ASSERT_EQ(it3->second.size(), 1);
- ASSERT_EQ(it4->second.size(), 1);
- ValueMetricProducer::Interval& interval3 = it3->second[0];
- ValueMetricProducer::Interval& interval4 = it4->second[0];
- ValueMetricProducer::BaseInfo& baseInfo3 =
- valueProducer->mCurrentBaseInfo.find(it3->first.getDimensionKeyInWhat())->second[0];
- ValueMetricProducer::BaseInfo& baseInfo4 =
- valueProducer->mCurrentBaseInfo.find(it4->first.getDimensionKeyInWhat())->second[0];
-
- EXPECT_EQ(true, baseInfo3.hasBase);
- EXPECT_EQ(5, baseInfo3.base.long_value);
- EXPECT_EQ(false, interval3.hasValue);
- EXPECT_EQ(5, interval3.value.long_value);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- EXPECT_EQ(true, baseInfo4.hasBase);
- EXPECT_EQ(13, baseInfo4.base.long_value);
- EXPECT_EQ(false, interval4.hasValue);
- EXPECT_EQ(8, interval4.value.long_value);
-
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-}
-
-/*
- * Tests trim unused dimension key if no new data is seen in an entire bucket.
- */
-TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- auto iter = valueProducer->mCurrentSlicedBucket.begin();
- auto& interval1 = iter->second[0];
- auto iterBase = valueProducer->mCurrentBaseInfo.begin();
- auto& baseInfo1 = iterBase->second[0];
- EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(3, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 2, 4));
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(11, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(8, interval1.value.long_value);
- EXPECT_FALSE(interval1.seenNewData);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-
- auto it = valueProducer->mCurrentSlicedBucket.begin();
- for (; it != valueProducer->mCurrentSlicedBucket.end(); it++) {
- if (it != iter) {
- break;
- }
- }
- auto itBase = valueProducer->mCurrentBaseInfo.begin();
- for (; itBase != valueProducer->mCurrentBaseInfo.end(); it++) {
- if (itBase != iterBase) {
- break;
- }
- }
- EXPECT_TRUE(it != iter);
- EXPECT_TRUE(itBase != iterBase);
- auto interval2 = it->second[0];
- auto baseInfo2 = itBase->second[0];
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(4, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_FALSE(interval2.seenNewData);
-
- // next pull somehow did not happen, skip to end of bucket 3
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 2, 5));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
- // Only one interval left. One was trimmed.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- interval2 = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- baseInfo2 = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(5, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_FALSE(interval2.seenNewData);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 2, 14));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs);
-
- interval2 = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- baseInfo2 = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(14, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_FALSE(interval2.seenNewData);
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
- auto iterator = valueProducer->mPastBuckets.begin();
- EXPECT_EQ(bucket4StartTimeNs, iterator->second[0].mBucketStartNs);
- EXPECT_EQ(bucket5StartTimeNs, iterator->second[0].mBucketEndNs);
- EXPECT_EQ(9, iterator->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
- iterator++;
- EXPECT_EQ(bucketStartTimeNs, iterator->second[0].mBucketStartNs);
- EXPECT_EQ(bucket2StartTimeNs, iterator->second[0].mBucketEndNs);
- EXPECT_EQ(8, iterator->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- // Used by onConditionChanged.
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo& curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
-
- vector<shared_ptr<LogEvent>> allData;
- valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8); // Condition change to true.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }))
- .WillOnce(Return(false));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo& curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 20);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 50));
- return false;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1); // Condition change to false.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Don't directly set mCondition; the real code never does that. Go through regular code path
- // to avoid unexpected behaviors.
- // valueProducer->mCondition = ConditionState::kTrue;
- valueProducer->onConditionChanged(true, bucketStartTimeNs);
-
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 1);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_condition(StringToId("SCREEN_ON"));
- metric.set_max_pull_delay_sec(0);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 120));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Max delay is set to 0 so pull will exceed max delay.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
- ValueMetricProducer valueProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
- logEventMatcherIndex, eventMatcherWizard, tagId,
- bucket2StartTimeNs, bucket2StartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
- valueProducer.mCondition = ConditionState::kFalse;
-
- // Event should be skipped since it is from previous bucket.
- // Pull should not be called.
- valueProducer.onConditionChanged(true, bucketStartTimeNs);
- ASSERT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
-}
-
-TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
- valueProducer->mHasGlobalBase = false;
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
- valueProducer->mHasGlobalBase = true;
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-}
-
-/*
- * Tests that a bucket is marked invalid when a condition change pull fails.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // First onConditionChanged
- .WillOnce(Return(false))
- // Second onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kTrue);
-
- // Bucket start.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-
- // This will fail and should invalidate the whole bucket since we do not have all the data
- // needed to compute the metric value when the screen was on.
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
-
- // Bucket end.
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 140));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
-
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
- // Contains base from last pull which was successful.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(140, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 10, false /* include partial bucket */, true,
- FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 2), dropEvent.drop_time_millis());
-}
-
-/*
- * Tests that a bucket is marked invalid when the guardrail is hit.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 2, _, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- for (int i = 0; i < 2000; i++) {
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, i));
- }
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 2);
- EXPECT_EQ(true, valueProducer->mCurrentBucketIsSkipped);
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(0UL, valueProducer->mSkippedBuckets.size());
-
- // Bucket 2 start.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // First bucket added to mSkippedBuckets after flush.
- ASSERT_EQ(1UL, valueProducer->mSkippedBuckets.size());
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 10000, false /* include recent buckets */,
- true, FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::DIMENSION_GUARDRAIL_REACHED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 2), dropEvent.drop_time_millis());
-}
-
-/*
- * Tests that a bucket is marked invalid when the bucket's initial pull fails.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 2);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 120));
- return true;
- }))
- // Second onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kTrue);
-
- // Bucket start.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 110));
- valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs);
-
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
-
- // Bucket end.
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 140));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
-
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
- // Contains base from last pull which was successful.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(140, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 10000, false /* include recent buckets */,
- true, FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 2), dropEvent.drop_time_millis());
-}
-
-/*
- * Tests that a bucket is marked invalid when the bucket's final pull fails
- * (i.e. failed pull on bucket boundary).
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 2);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 120));
- return true;
- }))
- // Second onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kTrue);
-
- // Bucket start.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
-
- // Bucket end.
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 140));
- valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
-
- valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
-
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
- // Last pull failed so base has been reset.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 10000, false /* include recent buckets */,
- true, FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), dropEvent.drop_time_millis());
-}
-
-TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- // Start bucket.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- // Bucket 2 start.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-
- // Bucket 3 empty.
- allData.clear();
- allData.push_back(CreateNoValuesLogEvent(tagId, bucket3StartTimeNs + 1));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // Data has been trimmed.
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-}
-
-TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- // Empty pull.
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 11);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 2));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 12);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 5));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 11);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 12);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- // End of bucket
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- // Data is empty, base should be reset.
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(5, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-
- // End of bucket
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 2));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // Key 1 should be reset since in not present in the most pull.
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- auto iterator = valueProducer->mCurrentSlicedBucket.begin();
- auto baseInfoIter = valueProducer->mCurrentBaseInfo.begin();
- EXPECT_EQ(true, baseInfoIter->second[0].hasBase);
- EXPECT_EQ(2, baseInfoIter->second[0].base.long_value);
- EXPECT_EQ(false, iterator->second[0].hasValue);
- iterator++;
- baseInfoIter++;
- EXPECT_EQ(false, baseInfoIter->second[0].hasBase);
- EXPECT_EQ(1, baseInfoIter->second[0].base.long_value);
- EXPECT_EQ(false, iterator->second[0].hasValue);
-
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestFullBucketResetWhenLastBucketInvalid) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + bucketSizeNs / 2;
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Initialization.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }))
- // notifyAppUpgrade.
- .WillOnce(Invoke([partialBucketSplitTimeNs](
- int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
- ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
-
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, valueProducer->getCurrentBucketNum());
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9},
- {partialBucketSplitTimeNs - bucketStartTimeNs},
- {bucketStartTimeNs}, {partialBucketSplitTimeNs});
- ASSERT_EQ(1UL, valueProducer->mCurrentFullBucket.size());
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 4));
- // Pull fails and arrives late.
- valueProducer->onDataPulled(allData, /** fails */ false, bucket3StartTimeNs + 1);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9},
- {partialBucketSplitTimeNs - bucketStartTimeNs},
- {bucketStartTimeNs}, {partialBucketSplitTimeNs});
- ASSERT_EQ(1, valueProducer->mSkippedBuckets.size());
- ASSERT_EQ(2, valueProducer->mSkippedBuckets[0].dropEvents.size());
- EXPECT_EQ(PULL_FAILED, valueProducer->mSkippedBuckets[0].dropEvents[0].reason);
- EXPECT_EQ(MULTIPLE_BUCKETS_SKIPPED, valueProducer->mSkippedBuckets[0].dropEvents[1].reason);
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mSkippedBuckets[0].bucketStartTimeNs);
- EXPECT_EQ(bucket3StartTimeNs, valueProducer->mSkippedBuckets[0].bucketEndTimeNs);
- ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
-}
-
-TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Second onConditionChanged.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 5));
- return true;
- }))
- // Third onConditionChanged.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket3StartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 10, 7));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
-
- valueProducer->onConditionChanged(false, bucketStartTimeNs);
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
- // End of first bucket
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 4));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
- valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(5, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
-
- valueProducer->onConditionChanged(false, bucket3StartTimeNs + 10);
-
- // Bucket should have been completed.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10},
- {bucket2StartTimeNs}, {bucket3StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // Bucket should have been completed.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- // Initialization.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // Bucket should have been completed.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestBucketBoundariesOnPartialBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2;
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Initialization.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }))
- // notifyAppUpgrade.
- .WillOnce(Invoke([partialBucketSplitTimeNs](
- int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
-
- // Bucket should have been completed.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // First on condition changed.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }))
- // Second on condition changed.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 12);
-
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(2, curInterval.value.long_value);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
-
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {2}, {bucketStartTimeNs},
- {bucket2StartTimeNs});
-}
-
-// TODO: b/145705635 fix or delete this test
-TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // First condition change.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }))
- // 2nd condition change.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 8);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
- return true;
- }))
- // 3rd condition change.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
- valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 3, 10));
- valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs + 3);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
- valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
-
- valueProducer->onConditionChanged(false, bucket2StartTimeNs + 8);
- valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs, 30));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // There was not global base available so all buckets are invalid.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {});
-}
-
-TEST(ValueMetricProducerTest, TestPullNeededFastDump) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- // Initial pull.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
- return true;
- }));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
-
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true,
- FAST, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- // Bucket is invalid since we did not pull when dump report was called.
- ASSERT_EQ(0, report.value_metrics().data_size());
-}
-
-TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
- // Initial pull.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
- return true;
- }));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 1, tagId, 2, 2));
- valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer.onDumpReport(bucket4StartTimeNs, false /* include recent buckets */, true, FAST,
- &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- // Previous bucket is part of the report.
- ASSERT_EQ(1, report.value_metrics().data_size());
- EXPECT_EQ(0, report.value_metrics().data(0).bucket_info(0).bucket_num());
-}
-
-TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Initial pull.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(
- CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 10, tagId, 3, 3));
- return true;
- }));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
-
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- ASSERT_EQ(1, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().data(0).bucket_info_size());
- EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 30);
-
- // Bucket should have been completed.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
- return true;
- }))
- // condition becomes false
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 20));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(20, curInterval.value.long_value);
-
- // Now the alarm is delivered. Condition is off though.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {50 - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _, _))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
- // Now the alarm is delivered. Condition is off though.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Now the alarm is delivered. Condition is off though.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // Condition was always false.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {});
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
- return true;
- }))
- .WillOnce(Return(false));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
-
- // Now the alarm is delivered. Condition is off though.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // No buckets, we had a failure.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {});
-}
-
-/*
- * Test that DUMP_REPORT_REQUESTED dump reason is logged.
- *
- * For the bucket to be marked invalid during a dump report requested,
- * three things must be true:
- * - we want to include the current partial bucket
- * - we need a pull (metric is pulled and condition is true)
- * - the dump latency must be FAST
- */
-
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequested) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 20, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20, 10));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 20);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucketStartTimeNs + 40, true /* include recent buckets */, true,
- FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late condition
- * change event (i.e. the condition change occurs in the wrong bucket).
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWrongBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 50, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
- // Bucket boundary pull.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 15));
- valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-
- // Late condition change event.
- valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(1, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(2, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(1);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late accumulate
- * event (i.e. the accumulate events call occurs in the wrong bucket).
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWrongBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 100);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 100, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
- // Bucket boundary pull.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 15));
- valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs - 100, 20));
-
- // Late accumulateEvents event.
- valueProducer->accumulateEvents(allData, bucket2StartTimeNs - 100, bucket2StartTimeNs - 100);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(1, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that CONDITION_UNKNOWN dump reason is logged due to an unknown condition
- * when a metric is initialized.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10000);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 100, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 10000;
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that PULL_FAILED dump reason is logged due to a pull failure in
- * #pullAndMatchEventsLocked.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
- return true;
- }))
- // Dump report requested, pull fails.
- .WillOnce(Return(false));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 10000;
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that MULTIPLE_BUCKETS_SKIPPED dump reason is logged when a log event
- * skips over more than one bucket.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenMultipleBucketsSkipped) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket4StartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1000, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
- // Condition change event that skips forward by three buckets.
- valueProducer->onConditionChanged(false, bucket4StartTimeNs + 10);
-
- int64_t dumpTimeNs = bucket4StartTimeNs + 1000;
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(dumpTimeNs, true /* include current buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(2, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket4StartTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::MULTIPLE_BUCKETS_SKIPPED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket4StartTimeNs + 10), dropEvent.drop_time_millis());
-
- // This bucket is skipped because a dumpReport with include current buckets is called.
- // This creates a new bucket from bucket4StartTimeNs to dumpTimeNs in which we have no data
- // since the condition is false for the entire bucket interval.
- EXPECT_EQ(NanoToMillis(bucket4StartTimeNs),
- report.value_metrics().skipped(1).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpTimeNs),
- report.value_metrics().skipped(1).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(1).drop_event_size());
-
- dropEvent = report.value_metrics().skipped(1).drop_event(0);
- EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that BUCKET_TOO_SMALL dump reason is logged when a flushed bucket size
- * is smaller than the "min_bucket_size_nanos" specified in the metric config.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- metric.set_min_bucket_size_nanos(10000000000); // 10 seconds
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 9000000);
- data->clear();
- data->push_back(
- CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 9000000, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 9000000;
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that NO_DATA dump reason is logged when a flushed bucket contains no data.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenDataUnavailable) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kFalse);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 10000000000; // 10 seconds
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include current bucket */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that all buckets are dropped due to condition unknown until the first onConditionChanged.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestConditionUnknownMultipleBuckets) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10 * NS_PER_SEC);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(
- tagId, bucket2StartTimeNs + 10 * NS_PER_SEC, 10));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 15 * NS_PER_SEC);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(
- tagId, bucket2StartTimeNs + 15 * NS_PER_SEC, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
-
- // Bucket should be dropped because of condition unknown.
- int64_t appUpgradeTimeNs = bucketStartTimeNs + 5 * NS_PER_SEC;
- valueProducer->notifyAppUpgrade(appUpgradeTimeNs);
-
- // Bucket also dropped due to condition unknown
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 3));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // This bucket is also dropped due to condition unknown.
- int64_t conditionChangeTimeNs = bucket2StartTimeNs + 10 * NS_PER_SEC;
- valueProducer->onConditionChanged(true, conditionChangeTimeNs);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucket2StartTimeNs + 15 * NS_PER_SEC; // 15 seconds
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include current bucket */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(3, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(appUpgradeTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(appUpgradeTimeNs), dropEvent.drop_time_millis());
-
- EXPECT_EQ(NanoToMillis(appUpgradeTimeNs),
- report.value_metrics().skipped(1).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(1).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(1).drop_event_size());
-
- dropEvent = report.value_metrics().skipped(1).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), dropEvent.drop_time_millis());
-
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(2).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(2).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(2).drop_event_size());
-
- dropEvent = report.value_metrics().skipped(2).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(conditionChangeTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that a skipped bucket is logged when a forced bucket split occurs when the previous bucket
- * was not flushed in time.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenForceBucketSplitBeforeBucketFlush) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
- return true;
- }))
- // App Update.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1000);
- data->clear();
- data->push_back(
- CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1000, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition changed event
- int64_t conditionChangeTimeNs = bucketStartTimeNs + 10;
- valueProducer->onConditionChanged(true, conditionChangeTimeNs);
-
- // App update event.
- int64_t appUpdateTimeNs = bucket2StartTimeNs + 1000;
- valueProducer->notifyAppUpgrade(appUpdateTimeNs);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucket2StartTimeNs + 10000000000; // 10 seconds
- valueProducer->onDumpReport(dumpReportTimeNs, false /* include current buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(1, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- ASSERT_EQ(1, report.value_metrics().data(0).bucket_info_size());
- auto data = report.value_metrics().data(0);
- ASSERT_EQ(0, data.bucket_info(0).bucket_num());
- EXPECT_EQ(5, data.bucket_info(0).values(0).value_long());
-
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(appUpdateTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(appUpdateTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test multiple bucket drop events in the same bucket.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 1000;
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
- FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(2, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 10), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(1);
- EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that the number of logged bucket drop events is capped at the maximum.
- * The maximum is currently 10 and is set in MetricProducer::maxDropEventsReached().
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // First condition change event.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- for (int i = 0; i < 2000; i++) {
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, i));
- }
- return true;
- }))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 220);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 220, 10));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
-
- // First condition change event causes guardrail to be reached.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
- // 2-10 condition change events result in failed pulls.
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 30);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 70);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 90);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 100);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 150);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 170);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 190);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 200);
-
- // Condition change event 11
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 220);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 1000;
- // Because we already have 10 dump events in the current bucket,
- // this case should not be added to the list of dump events.
- valueProducer->onDumpReport(bucketStartTimeNs + 1000, true /* include recent buckets */, true,
- FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(10, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 10), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(1);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 30), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(2);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 50), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(3);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 70), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(4);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 90), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(5);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 100), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(6);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 150), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(7);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 170), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(8);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 190), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(9);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 200), dropEvent.drop_time_millis());
-}
-
-/*
- * Test metric with a simple sliced state
- * - Increasing values
- * - Using diff
- * - Second field is value field
- */
-TEST(ValueMetricProducerTest, TestSlicedState) {
- // Set up ValueMetricProducer.
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE");
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // ValueMetricProducer initialized.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }))
- // Screen state change to ON.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 5);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 5, 5));
- return true;
- }))
- // Screen state change to OFF.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 9));
- return true;
- }))
- // Screen state change to ON.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 15);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 15, 21));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 30));
- return true;
- }));
-
- StateManager::getInstance().clear();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithState(
- pullerManager, metric, {util::SCREEN_STATE_CHANGED}, {});
- EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
- // Set up StateManager and check that StateTrackers are initialized.
- StateManager::getInstance().registerListener(SCREEN_STATE_ATOM_ID, valueProducer);
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- // Bucket status after metric initialized.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- auto it = valueProducer->mCurrentSlicedBucket.begin();
- auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(3, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, kStateUnknown}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after screen state change kStateUnknown->ON.
- auto screenEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 5, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(5, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, kStateUnknown}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Bucket status after screen state change ON->OFF.
- screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 10,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(9, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, ON}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(4, it->second[0].value.long_value);
- // Value for dimension, state key {{}, kStateUnknown}
- it++;
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Bucket status after screen state change OFF->ON.
- screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 15,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(21, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, OFF}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(12, it->second[0].value.long_value);
- // Value for dimension, state key {{}, ON}
- it++;
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(4, it->second[0].value.long_value);
- // Value for dimension, state key {{}, kStateUnknown}
- it++;
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Start dump report and check output.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucketStartTimeNs + 50, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(3, report.value_metrics().data_size());
-
- auto data = report.value_metrics().data(0);
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
-
- data = report.value_metrics().data(1);
- ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
- EXPECT_EQ(13, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
-
- data = report.value_metrics().data(2);
- ASSERT_EQ(1, report.value_metrics().data(2).bucket_info_size());
- EXPECT_EQ(12, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
-}
-
-/*
- * Test metric with sliced state with map
- * - Increasing values
- * - Using diff
- * - Second field is value field
- */
-TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
- // Set up ValueMetricProducer.
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE_ONOFF");
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // ValueMetricProducer initialized.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }))
- // Screen state change to ON.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 5);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 5, 5));
- return true;
- }))
- // Screen state change to VR has no pull because it is in the same
- // state group as ON.
-
- // Screen state change to ON has no pull because it is in the same
- // state group as VR.
-
- // Screen state change to OFF.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 15);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 15, 21));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 30));
- return true;
- }));
-
- const StateMap& stateMap =
- CreateScreenStateOnOffMap(/*screen on id=*/321, /*screen off id=*/123);
- const StateMap_StateGroup screenOnGroup = stateMap.group(0);
- const StateMap_StateGroup screenOffGroup = stateMap.group(1);
-
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
- for (auto group : stateMap.group()) {
- for (auto value : group.value()) {
- stateGroupMap[SCREEN_STATE_ATOM_ID][value] = group.group_id();
- }
- }
-
- StateManager::getInstance().clear();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithState(
- pullerManager, metric, {util::SCREEN_STATE_CHANGED}, stateGroupMap);
-
- // Set up StateManager and check that StateTrackers are initialized.
- StateManager::getInstance().registerListener(SCREEN_STATE_ATOM_ID, valueProducer);
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- // Bucket status after metric initialized.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- auto it = valueProducer->mCurrentSlicedBucket.begin();
- auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(3, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, {kStateUnknown}}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after screen state change kStateUnknown->ON.
- auto screenEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 5, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(5, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(screenOnGroup.group_id(),
- itBase->second[0].currentState.getValues()[0].mValue.long_value);
- // Value for dimension, state key {{}, kStateUnknown}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Bucket status after screen state change ON->VR.
- // Both ON and VR are in the same state group, so the base should not change.
- screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 10,
- android::view::DisplayStateEnum::DISPLAY_STATE_VR);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(5, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(screenOnGroup.group_id(),
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, kStateUnknown}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Bucket status after screen state change VR->ON.
- // Both ON and VR are in the same state group, so the base should not change.
- screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 12,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(5, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(screenOnGroup.group_id(),
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, kStateUnknown}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Bucket status after screen state change VR->OFF.
- screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 15,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(21, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(screenOffGroup.group_id(),
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, ON GROUP}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(screenOnGroup.group_id(),
- it->first.getStateValuesKey().getValues()[0].mValue.long_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(16, it->second[0].value.long_value);
- // Value for dimension, state key {{}, kStateUnknown}
- it++;
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Start dump report and check output.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucketStartTimeNs + 50, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(3, report.value_metrics().data_size());
-
- auto data = report.value_metrics().data(0);
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, data.slice_by_state(0).value());
-
- data = report.value_metrics().data(1);
- ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
- EXPECT_EQ(16, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOnGroup.group_id(), data.slice_by_state(0).group_id());
-
- data = report.value_metrics().data(2);
- ASSERT_EQ(1, report.value_metrics().data(2).bucket_info_size());
- EXPECT_EQ(9, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffGroup.group_id(), data.slice_by_state(0).group_id());
-}
-
-/*
- * Test metric that slices by state with a primary field and has dimensions
- * - Increasing values
- * - Using diff
- * - Second field is value field
- */
-TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
- // Set up ValueMetricProducer.
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("UID_PROCESS_STATE");
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-
- MetricStateLink* stateLink = metric.add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateDimensions(tagId, {1 /* uid */});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // ValueMetricProducer initialized.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 2 /*uid*/, 7));
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1 /*uid*/, 3));
- return true;
- }))
- // Uid 1 process state change from kStateUnknown -> Foreground
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
- data->clear();
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 20, 1 /*uid*/, 6));
-
- // This event should be skipped.
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 20, 2 /*uid*/, 8));
- return true;
- }))
- // Uid 2 process state change from kStateUnknown -> Background
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 40);
- data->clear();
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 40, 2 /*uid*/, 9));
-
- // This event should be skipped.
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 40, 1 /*uid*/, 12));
- return true;
- }))
- // Uid 1 process state change from Foreground -> Background
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 20);
- data->clear();
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 20, 1 /*uid*/, 13));
-
- // This event should be skipped.
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 20, 2 /*uid*/, 11));
- return true;
- }))
- // Uid 1 process state change from Background -> Foreground
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 40);
- data->clear();
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 40, 1 /*uid*/, 17));
-
- // This event should be skipped.
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 40, 2 /*uid */, 15));
- return true;
- }))
- // Dump report pull.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 50);
- data->clear();
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 50, 2 /*uid*/, 20));
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 50, 1 /*uid*/, 21));
- return true;
- }));
-
- StateManager::getInstance().clear();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithState(
- pullerManager, metric, {UID_PROCESS_STATE_ATOM_ID}, {});
-
- // Set up StateManager and check that StateTrackers are initialized.
- StateManager::getInstance().registerListener(UID_PROCESS_STATE_ATOM_ID, valueProducer);
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
- // Bucket status after metric initialized.
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {uid 1}.
- auto it = valueProducer->mCurrentSlicedBucket.begin();
- auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(3, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{uid 1}, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
- // Base for dimension key {uid 2}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(7, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{uid 2}, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after uid 1 process state change kStateUnknown -> Foreground.
- auto uidProcessEvent = CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 20, 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND);
- StateManager::getInstance().onLogEvent(*uidProcessEvent);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {uid 1}.
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(6, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 1, kStateUnknown}.
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(3, it->second[0].value.long_value);
-
- // Base for dimension key {uid 2}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(7, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 2, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1, it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after uid 2 process state change kStateUnknown -> Background.
- uidProcessEvent = CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 40, 2 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND);
- StateManager::getInstance().onLogEvent(*uidProcessEvent);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {uid 1}.
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(6, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 1, kStateUnknown}.
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1, it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(3, it->second[0].value.long_value);
-
- // Base for dimension key {uid 2}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(9, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 2, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1, it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Pull at end of first bucket.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs, 1 /*uid*/, 10));
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs, 2 /*uid*/, 15));
- valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-
- // Buckets flushed after end of first bucket.
- // None of the buckets should have a value.
- ASSERT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(4UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
- // Base for dimension key {uid 2}.
- it = valueProducer->mCurrentSlicedBucket.begin();
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(15, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 2, BACKGROUND}.
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Base for dimension key {uid 1}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(10, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 1, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* kStateTracker::kUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Value for key {uid 1, FOREGROUND}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Value for key {uid 2, kStateUnknown}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* kStateTracker::kUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after uid 1 process state change from Foreground -> Background.
- uidProcessEvent = CreateUidProcessStateChangedEvent(
- bucket2StartTimeNs + 20, 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND);
- StateManager::getInstance().onLogEvent(*uidProcessEvent);
-
- ASSERT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(4UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
- // Base for dimension key {uid 2}.
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(15, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 2, BACKGROUND}.
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
- // Base for dimension key {uid 1}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(13, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 1, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
- // Value for key {uid 1, FOREGROUND}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(3, it->second[0].value.long_value);
- // Value for key {uid 2, kStateUnknown}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after uid 1 process state change Background->Foreground.
- uidProcessEvent = CreateUidProcessStateChangedEvent(
- bucket2StartTimeNs + 40, 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND);
- StateManager::getInstance().onLogEvent(*uidProcessEvent);
-
- ASSERT_EQ(5UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
- // Base for dimension key {uid 2}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(15, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 2, BACKGROUND}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Base for dimension key {uid 1}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(17, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 1, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Value for key {uid 1, BACKGROUND}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(4, it->second[0].value.long_value);
-
- // Value for key {uid 1, FOREGROUND}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(3, it->second[0].value.long_value);
-
- // Value for key {uid 2, kStateUnknown}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-
- // Start dump report and check output.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 50, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(5, report.value_metrics().data_size());
-
- auto data = report.value_metrics().data(0);
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(4, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
-
- data = report.value_metrics().data(1);
- ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
- EXPECT_EQ(2, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, data.slice_by_state(0).value());
-
- data = report.value_metrics().data(2);
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(2, report.value_metrics().data(2).bucket_info_size());
- EXPECT_EQ(4, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
- EXPECT_EQ(7, report.value_metrics().data(2).bucket_info(1).values(0).value_long());
-
- data = report.value_metrics().data(3);
- ASSERT_EQ(1, report.value_metrics().data(3).bucket_info_size());
- EXPECT_EQ(3, report.value_metrics().data(3).bucket_info(0).values(0).value_long());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, data.slice_by_state(0).value());
-
- data = report.value_metrics().data(4);
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(2, report.value_metrics().data(4).bucket_info_size());
- EXPECT_EQ(6, report.value_metrics().data(4).bucket_info(0).values(0).value_long());
- EXPECT_EQ(5, report.value_metrics().data(4).bucket_info(1).values(0).value_long());
-}
-
-TEST(ValueMetricProducerTest, TestSlicedStateWithCondition) {
- // Set up ValueMetricProducer.
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithConditionAndState(
- "BATTERY_SAVER_MODE_STATE");
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
- // Condition changed to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20 * NS_PER_SEC);
- data->clear();
- data->push_back(
- CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20 * NS_PER_SEC, 3));
- return true;
- }))
- // Battery saver mode state changed to OFF.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 30 * NS_PER_SEC);
- data->clear();
- data->push_back(
- CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30 * NS_PER_SEC, 5));
- return true;
- }))
- // Condition changed to false.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10 * NS_PER_SEC);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(
- tagId, bucket2StartTimeNs + 10 * NS_PER_SEC, 15));
- return true;
- }));
-
- StateManager::getInstance().clear();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithConditionAndState(
- pullerManager, metric, {util::BATTERY_SAVER_MODE_STATE_CHANGED}, {},
- ConditionState::kFalse);
- EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
- // Set up StateManager and check that StateTrackers are initialized.
- StateManager::getInstance().registerListener(util::BATTERY_SAVER_MODE_STATE_CHANGED,
- valueProducer);
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(
- util::BATTERY_SAVER_MODE_STATE_CHANGED));
-
- // Bucket status after battery saver mode ON event.
- // Condition is false so we do nothing.
- unique_ptr<LogEvent> batterySaverOnEvent =
- CreateBatterySaverOnEvent(/*timestamp=*/bucketStartTimeNs + 10 * NS_PER_SEC);
- StateManager::getInstance().onLogEvent(*batterySaverOnEvent);
- EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(0UL, valueProducer->mCurrentBaseInfo.size());
-
- // Bucket status after condition change to true.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 20 * NS_PER_SEC);
- // Base for dimension key {}
- ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
- std::unordered_map<HashableDimensionKey, std::vector<ValueMetricProducer::BaseInfo>>::iterator
- itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(3, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::ON,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {{}, -1}
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- std::unordered_map<MetricDimensionKey, std::vector<ValueMetricProducer::Interval>>::iterator
- it = valueProducer->mCurrentSlicedBucket.begin();
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after battery saver mode OFF event.
- unique_ptr<LogEvent> batterySaverOffEvent =
- CreateBatterySaverOffEvent(/*timestamp=*/bucketStartTimeNs + 30 * NS_PER_SEC);
- StateManager::getInstance().onLogEvent(*batterySaverOffEvent);
- // Base for dimension key {}
- ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
- itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(5, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::OFF,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {{}, ON}
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- it = valueProducer->mCurrentSlicedBucket.begin();
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::ON,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Pull at end of first bucket.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 11));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
- itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(11, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::OFF,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
-
- // Bucket 2 status after condition change to false.
- valueProducer->onConditionChanged(false, bucket2StartTimeNs + 10 * NS_PER_SEC);
- // Base for dimension key {}
- ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
- itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
- EXPECT_FALSE(itBase->second[0].hasBase);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::OFF,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {{}, OFF}
- ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
- it = valueProducer->mCurrentSlicedBucket.begin();
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::OFF,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(4, it->second[0].value.long_value);
-
- // Start dump report and check output.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 50 * NS_PER_SEC,
- true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
- &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(2, report.value_metrics().data_size());
-
- ValueMetricData data = report.value_metrics().data(0);
- EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(BatterySaverModeStateChanged::ON, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, data.bucket_info(0).values(0).value_long());
-
- data = report.value_metrics().data(1);
- EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(BatterySaverModeStateChanged::OFF, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(6, data.bucket_info(0).values(0).value_long());
- EXPECT_EQ(4, data.bucket_info(1).values(0).value_long());
-}
-
-/*
- * Test bucket splits when condition is unknown.
- */
-TEST(ValueMetricProducerTest, TestForcedBucketSplitWhenConditionUnknownSkipsBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric,
- ConditionState::kUnknown);
-
- // App update event.
- int64_t appUpdateTimeNs = bucketStartTimeNs + 1000;
- valueProducer->notifyAppUpgrade(appUpdateTimeNs);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 10000000000; // 10 seconds
- valueProducer->onDumpReport(dumpReportTimeNs, false /* include current buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(appUpdateTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(appUpdateTimeNs), dropEvent.drop_time_millis());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.cpp b/cmds/statsd/tests/metrics/metrics_test_helper.cpp
deleted file mode 100644
index 108df04b..0000000
--- a/cmds/statsd/tests/metrics/metrics_test_helper.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "metrics_test_helper.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-HashableDimensionKey getMockedDimensionKey(int tagId, int key, string value) {
- HashableDimensionKey dimension;
- int pos[] = {key, 0, 0};
- dimension.addValue(FieldValue(Field(tagId, pos, 0), Value(value)));
-
- return dimension;
-}
-
-HashableDimensionKey getMockedDimensionKeyLongValue(int tagId, int key, int64_t value) {
- HashableDimensionKey dimension;
- int pos[] = {key, 0, 0};
- dimension.addValue(FieldValue(Field(tagId, pos, 0), Value(value)));
-
- return dimension;
-}
-
-MetricDimensionKey getMockedMetricDimensionKey(int tagId, int key, string value) {
- return MetricDimensionKey(getMockedDimensionKey(tagId, key, value), DEFAULT_DIMENSION_KEY);
-}
-
-MetricDimensionKey getMockedStateDimensionKey(int tagId, int key, int64_t value) {
- return MetricDimensionKey(DEFAULT_DIMENSION_KEY,
- getMockedDimensionKeyLongValue(tagId, key, value));
-}
-
-void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher) {
- matcher->set_field(tagId);
-}
-
-void buildSimpleAtomFieldMatcher(const int tagId, const int fieldNum, FieldMatcher* matcher) {
- matcher->set_field(tagId);
- matcher->add_child()->set_field(fieldNum);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h
deleted file mode 100644
index eeb38a4..0000000
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-#pragma once
-
-#include "src/condition/ConditionWizard.h"
-#include "src/external/StatsPullerManager.h"
-#include "src/packages/UidMap.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class MockConditionWizard : public ConditionWizard {
-public:
- MOCK_METHOD3(query,
- ConditionState(const int conditionIndex, const ConditionKey& conditionParameters,
- const bool isPartialLink));
-};
-
-class MockStatsPullerManager : public StatsPullerManager {
-public:
- MOCK_METHOD5(RegisterReceiver,
- void(int tagId, const ConfigKey& key, wp<PullDataReceiver> receiver,
- int64_t nextPulltimeNs, int64_t intervalNs));
- MOCK_METHOD3(UnRegisterReceiver,
- void(int tagId, const ConfigKey& key, wp<PullDataReceiver> receiver));
- MOCK_METHOD5(Pull, bool(const int pullCode, const ConfigKey& key, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids));
- MOCK_METHOD5(Pull,
- bool(const int pullCode, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids));
- MOCK_METHOD2(RegisterPullUidProvider,
- void(const ConfigKey& configKey, wp<PullUidProvider> provider));
- MOCK_METHOD2(UnregisterPullUidProvider,
- void(const ConfigKey& configKey, wp<PullUidProvider> provider));
-};
-
-HashableDimensionKey getMockedDimensionKey(int tagId, int key, std::string value);
-MetricDimensionKey getMockedMetricDimensionKey(int tagId, int key, std::string value);
-
-HashableDimensionKey getMockedDimensionKeyLongValue(int tagId, int key, int64_t value);
-MetricDimensionKey getMockedStateDimensionKey(int tagId, int key, int64_t value);
-
-// Utils to build FieldMatcher proto for simple one-depth atoms.
-void buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum, FieldMatcher* matcher);
-void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
deleted file mode 100644
index e384b6a..0000000
--- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/shell/ShellSubscriber.h"
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <vector>
-
-#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
-#include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/shell/shell_data.pb.h"
-#include "stats_event.h"
-#include "tests/metrics/metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
-
-using namespace android::os::statsd;
-using android::sp;
-using std::vector;
-using testing::_;
-using testing::Invoke;
-using testing::NaggyMock;
-using testing::StrictMock;
-
-#ifdef __ANDROID__
-
-void runShellTest(ShellSubscription config, sp<MockUidMap> uidMap,
- sp<MockStatsPullerManager> pullerManager,
- const vector<std::shared_ptr<LogEvent>>& pushedEvents,
- const ShellData& expectedData) {
- // set up 2 pipes for read/write config and data
- int fds_config[2];
- ASSERT_EQ(0, pipe(fds_config));
-
- int fds_data[2];
- ASSERT_EQ(0, pipe(fds_data));
-
- size_t bufferSize = config.ByteSize();
- // write the config to pipe, first write size of the config
- write(fds_config[1], &bufferSize, sizeof(bufferSize));
- // then write config itself
- vector<uint8_t> buffer(bufferSize);
- config.SerializeToArray(&buffer[0], bufferSize);
- write(fds_config[1], buffer.data(), bufferSize);
- close(fds_config[1]);
-
- sp<ShellSubscriber> shellClient = new ShellSubscriber(uidMap, pullerManager);
-
- // mimic a binder thread that a shell subscriber runs on. it would block.
- std::thread reader([&shellClient, &fds_config, &fds_data] {
- shellClient->startNewSubscription(fds_config[0], fds_data[1], /*timeoutSec=*/-1);
- });
- reader.detach();
-
- // let the shell subscriber to receive the config from pipe.
- std::this_thread::sleep_for(100ms);
-
- if (pushedEvents.size() > 0) {
- // send a log event that matches the config.
- std::thread log_reader([&shellClient, &pushedEvents] {
- for (const auto& event : pushedEvents) {
- shellClient->onLogEvent(*event);
- }
- });
-
- log_reader.detach();
-
- if (log_reader.joinable()) {
- log_reader.join();
- }
- }
-
- // wait for the data to be written.
- std::this_thread::sleep_for(100ms);
-
- // Because we might receive heartbeats from statsd, consisting of data sizes
- // of 0, encapsulate reads within a while loop.
- bool readAtom = false;
- while (!readAtom) {
- // Read the atom size.
- size_t dataSize = 0;
- read(fds_data[0], &dataSize, sizeof(dataSize));
- if (dataSize == 0) continue;
- EXPECT_EQ(expectedData.ByteSize(), int(dataSize));
-
- // Read that much data in proto binary format.
- vector<uint8_t> dataBuffer(dataSize);
- EXPECT_EQ((int)dataSize, read(fds_data[0], dataBuffer.data(), dataSize));
-
- // Make sure the received bytes can be parsed to an atom.
- ShellData receivedAtom;
- EXPECT_TRUE(receivedAtom.ParseFromArray(dataBuffer.data(), dataSize) != 0);
-
- // Serialize the expected atom to byte array and compare to make sure
- // they are the same.
- vector<uint8_t> expectedAtomBuffer(expectedData.ByteSize());
- expectedData.SerializeToArray(expectedAtomBuffer.data(), expectedData.ByteSize());
- EXPECT_EQ(expectedAtomBuffer, dataBuffer);
-
- readAtom = true;
- }
-
- close(fds_data[0]);
- if (reader.joinable()) {
- reader.join();
- }
-}
-
-TEST(ShellSubscriberTest, testPushedSubscription) {
- sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- vector<std::shared_ptr<LogEvent>> pushedList;
-
- // Create the LogEvent from an AStatsEvent
- std::unique_ptr<LogEvent> logEvent = CreateScreenStateChangedEvent(
- 1000 /*timestamp*/, ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- pushedList.push_back(std::move(logEvent));
-
- // create a simple config to get screen events
- ShellSubscription config;
- config.add_pushed()->set_atom_id(29);
-
- // this is the expected screen event atom.
- ShellData shellData;
- shellData.add_atom()->mutable_screen_state_changed()->set_state(
- ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
- runShellTest(config, uidMap, pullerManager, pushedList, shellData);
-}
-
-namespace {
-
-int kUid1 = 1000;
-int kUid2 = 2000;
-
-int kCpuTime1 = 100;
-int kCpuTime2 = 200;
-
-ShellData getExpectedShellData() {
- ShellData shellData;
- auto* atom1 = shellData.add_atom()->mutable_cpu_active_time();
- atom1->set_uid(kUid1);
- atom1->set_time_millis(kCpuTime1);
-
- auto* atom2 = shellData.add_atom()->mutable_cpu_active_time();
- atom2->set_uid(kUid2);
- atom2->set_time_millis(kCpuTime2);
-
- return shellData;
-}
-
-ShellSubscription getPulledConfig() {
- ShellSubscription config;
- auto* pull_config = config.add_pulled();
- pull_config->mutable_matcher()->set_atom_id(10016);
- pull_config->set_freq_millis(2000);
- return config;
-}
-
-shared_ptr<LogEvent> makeCpuActiveTimeAtom(int32_t uid, int64_t timeMillis) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, 10016);
- AStatsEvent_overwriteTimestamp(statsEvent, 1111L);
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeInt64(statsEvent, timeMillis);
-
- std::shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-} // namespace
-
-TEST(ShellSubscriberTest, testPulledSubscription) {
- sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- const vector<int32_t> uids = {AID_SYSTEM};
- EXPECT_CALL(*pullerManager, Pull(10016, uids, _, _, _))
- .WillRepeatedly(Invoke([](int tagId, const vector<int32_t>&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
- data->clear();
- data->push_back(makeCpuActiveTimeAtom(/*uid=*/kUid1, /*timeMillis=*/kCpuTime1));
- data->push_back(makeCpuActiveTimeAtom(/*uid=*/kUid2, /*timeMillis=*/kCpuTime2));
- return true;
- }));
- runShellTest(getPulledConfig(), uidMap, pullerManager, vector<std::shared_ptr<LogEvent>>(),
- getExpectedShellData());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp
deleted file mode 100644
index 6516c15..0000000
--- a/cmds/statsd/tests/state/StateTracker_test.cpp
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "state/StateTracker.h"
-
-#include <gtest/gtest.h>
-#include <private/android_filesystem_config.h>
-
-#include "state/StateListener.h"
-#include "state/StateManager.h"
-#include "state/StateTracker.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const int32_t timestampNs = 1000;
-
-/**
- * Mock StateListener class for testing.
- * Stores primary key and state pairs.
- */
-class TestStateListener : public virtual StateListener {
-public:
- TestStateListener(){};
-
- virtual ~TestStateListener(){};
-
- struct Update {
- Update(const HashableDimensionKey& key, int state) : mKey(key), mState(state){};
- HashableDimensionKey mKey;
- int mState;
- };
-
- std::vector<Update> updates;
-
- void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey, const FieldValue& oldState,
- const FieldValue& newState) {
- updates.emplace_back(primaryKey, newState.mValue.int_value);
- }
-};
-
-int getStateInt(StateManager& mgr, int atomId, const HashableDimensionKey& queryKey) {
- FieldValue output;
- mgr.getStateValue(atomId, queryKey, &output);
- return output.mValue.int_value;
-}
-
-// START: build event functions.
-// Incorrect event - missing fields
-std::unique_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName,
- int state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, 1000);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, packageName.c_str());
- // Missing field 3 - using_alert_window.
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-// Incorrect event - exclusive state has wrong type
-std::unique_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::string& packageName) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, 1000);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, packageName.c_str());
- AStatsEvent_writeInt32(statsEvent, true); // using_alert_window
- AStatsEvent_writeString(statsEvent, "string"); // exclusive state: string instead of int
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-// END: build event functions.
-
-TEST(StateListenerTest, TestStateListenerWeakPointer) {
- sp<TestStateListener> listener = new TestStateListener();
- wp<TestStateListener> wListener = listener;
- listener = nullptr; // let go of listener
- EXPECT_TRUE(wListener.promote() == nullptr);
-}
-
-TEST(StateManagerTest, TestStateManagerGetInstance) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager& mgr = StateManager::getInstance();
- mgr.clear();
-
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-}
-
-TEST(StateManagerTest, TestOnLogEvent) {
- sp<MockUidMap> uidMap = makeMockUidMapForPackage("com.android.systemui", {10111});
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.updateLogSources(uidMap);
- // Add StateTracker by registering a listener.
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
-
- // log event using AID_ROOT
- std::unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
- timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- mgr.onLogEvent(*event);
-
- // check StateTracker was updated by querying for state
- HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-
- // log event using mocked uid
- event = CreateScreenStateChangedEvent(
- timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_OFF, 10111);
- mgr.onLogEvent(*event);
-
- // check StateTracker was updated by querying for state
- queryKey = DEFAULT_DIMENSION_KEY;
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-
- // log event using non-whitelisted uid
- event = CreateScreenStateChangedEvent(timestampNs,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON, 10112);
- mgr.onLogEvent(*event);
-
- // check StateTracker was NOT updated by querying for state
- queryKey = DEFAULT_DIMENSION_KEY;
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-
- // log event using AID_SYSTEM
- event = CreateScreenStateChangedEvent(
- timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON, AID_SYSTEM);
- mgr.onLogEvent(*event);
-
- // check StateTracker was updated by querying for state
- queryKey = DEFAULT_DIMENSION_KEY;
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-}
-
-/**
- * Test registering listeners to StateTrackers
- *
- * - StateManager will create a new StateTracker if it doesn't already exist
- * and then register the listener to the StateTracker.
- * - If a listener is already registered to a StateTracker, it is not added again.
- * - StateTrackers are only created for atoms that are state atoms.
- */
-TEST(StateTrackerTest, TestRegisterListener) {
- sp<TestStateListener> listener1 = new TestStateListener();
- sp<TestStateListener> listener2 = new TestStateListener();
- StateManager mgr;
-
- // Register listener to non-existing StateTracker
- EXPECT_EQ(0, mgr.getStateTrackersCount());
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Register listener to existing StateTracker
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(2, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Register already registered listener to existing StateTracker
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(2, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Register listener to non-state atom
- mgr.registerListener(util::BATTERY_LEVEL_CHANGED, listener2);
- EXPECT_EQ(2, mgr.getStateTrackersCount());
-}
-
-/**
- * Test unregistering listeners from StateTrackers
- *
- * - StateManager will unregister listeners from a StateTracker only if the
- * StateTracker exists and the listener is registered to the StateTracker.
- * - Once all listeners are removed from a StateTracker, the StateTracker
- * is also removed.
- */
-TEST(StateTrackerTest, TestUnregisterListener) {
- sp<TestStateListener> listener1 = new TestStateListener();
- sp<TestStateListener> listener2 = new TestStateListener();
- StateManager mgr;
-
- // Unregister listener from non-existing StateTracker
- EXPECT_EQ(0, mgr.getStateTrackersCount());
- mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener1);
- EXPECT_EQ(0, mgr.getStateTrackersCount());
- EXPECT_EQ(-1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Unregister non-registered listener from existing StateTracker
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
- mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener2);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Unregister second-to-last listener from StateTracker
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2);
- mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener1);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Unregister last listener from StateTracker
- mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener2);
- EXPECT_EQ(0, mgr.getStateTrackersCount());
- EXPECT_EQ(-1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-}
-
-/**
- * Test a binary state atom with nested counting.
- *
- * To go from an "ON" state to an "OFF" state with nested counting, we must see
- * an equal number of "OFF" events as "ON" events.
- * For example, ACQUIRE, ACQUIRE, RELEASE will still be in the ACQUIRE state.
- * ACQUIRE, ACQUIRE, RELEASE, RELEASE will be in the RELEASE state.
- */
-TEST(StateTrackerTest, TestStateChangeNested) {
- sp<TestStateListener> listener = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener);
-
- std::vector<int> attributionUids1 = {1000};
- std::vector<string> attributionTags1 = {"tag"};
-
- std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent(timestampNs, attributionUids1,
- attributionTags1, "wakelockName");
- mgr.onLogEvent(*event1);
- ASSERT_EQ(1, listener->updates.size());
- EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(1, listener->updates[0].mState);
- listener->updates.clear();
-
- std::unique_ptr<LogEvent> event2 = CreateAcquireWakelockEvent(
- timestampNs + 1000, attributionUids1, attributionTags1, "wakelockName");
- mgr.onLogEvent(*event2);
- ASSERT_EQ(0, listener->updates.size());
-
- std::unique_ptr<LogEvent> event3 = CreateReleaseWakelockEvent(
- timestampNs + 2000, attributionUids1, attributionTags1, "wakelockName");
- mgr.onLogEvent(*event3);
- ASSERT_EQ(0, listener->updates.size());
-
- std::unique_ptr<LogEvent> event4 = CreateReleaseWakelockEvent(
- timestampNs + 3000, attributionUids1, attributionTags1, "wakelockName");
- mgr.onLogEvent(*event4);
- ASSERT_EQ(1, listener->updates.size());
- EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(0, listener->updates[0].mState);
-}
-
-/**
- * Test a state atom with a reset state.
- *
- * If the reset state value is seen, every state in the map is set to the default
- * state and every listener is notified.
- */
-TEST(StateTrackerTest, TestStateChangeReset) {
- sp<TestStateListener> listener = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::BLE_SCAN_STATE_CHANGED, listener);
-
- std::vector<int> attributionUids1 = {1000};
- std::vector<string> attributionTags1 = {"tag1"};
- std::vector<int> attributionUids2 = {2000};
-
- std::unique_ptr<LogEvent> event1 =
- CreateBleScanStateChangedEvent(timestampNs, attributionUids1, attributionTags1,
- BleScanStateChanged::ON, false, false, false);
- mgr.onLogEvent(*event1);
- ASSERT_EQ(1, listener->updates.size());
- EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
- FieldValue stateFieldValue;
- mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, listener->updates[0].mKey, &stateFieldValue);
- EXPECT_EQ(BleScanStateChanged::ON, stateFieldValue.mValue.int_value);
- listener->updates.clear();
-
- std::unique_ptr<LogEvent> event2 =
- CreateBleScanStateChangedEvent(timestampNs + 1000, attributionUids2, attributionTags1,
- BleScanStateChanged::ON, false, false, false);
- mgr.onLogEvent(*event2);
- ASSERT_EQ(1, listener->updates.size());
- EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
- mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, listener->updates[0].mKey, &stateFieldValue);
- EXPECT_EQ(BleScanStateChanged::ON, stateFieldValue.mValue.int_value);
- listener->updates.clear();
-
- std::unique_ptr<LogEvent> event3 =
- CreateBleScanStateChangedEvent(timestampNs + 2000, attributionUids2, attributionTags1,
- BleScanStateChanged::RESET, false, false, false);
- mgr.onLogEvent(*event3);
- ASSERT_EQ(2, listener->updates.size());
- for (const TestStateListener::Update& update : listener->updates) {
- EXPECT_EQ(BleScanStateChanged::OFF, update.mState);
-
- mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, update.mKey, &stateFieldValue);
- EXPECT_EQ(BleScanStateChanged::OFF, stateFieldValue.mValue.int_value);
- }
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
- * updates listener for states without primary keys.
- */
-TEST(StateTrackerTest, TestStateChangeNoPrimaryFields) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
-
- // log event
- std::unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
- timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- mgr.onLogEvent(*event);
-
- // check listener was updated
- ASSERT_EQ(1, listener1->updates.size());
- EXPECT_EQ(DEFAULT_DIMENSION_KEY, listener1->updates[0].mKey);
- EXPECT_EQ(2, listener1->updates[0].mState);
-
- // check StateTracker was updated by querying for state
- HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
- * updates listener for states with one primary key.
- */
-TEST(StateTrackerTest, TestStateChangeOnePrimaryField) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener1);
-
- // log event
- std::unique_ptr<LogEvent> event = CreateUidProcessStateChangedEvent(
- timestampNs, 1000 /*uid*/, android::app::ProcessStateEnum::PROCESS_STATE_TOP);
- mgr.onLogEvent(*event);
-
- // check listener was updated
- ASSERT_EQ(1, listener1->updates.size());
- EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(1002, listener1->updates[0].mState);
-
- // check StateTracker was updated by querying for state
- HashableDimensionKey queryKey;
- getUidProcessKey(1000 /* uid */, &queryKey);
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
- getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey));
-}
-
-TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener1);
-
- // Log event.
- std::vector<int> attributionUids = {1001};
- std::vector<string> attributionTags = {"tag1"};
-
- std::unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(timestampNs, attributionUids,
- attributionTags, "wakelockName");
- mgr.onLogEvent(*event);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, mgr.getListenersCount(util::WAKELOCK_STATE_CHANGED));
-
- // Check listener was updated.
- ASSERT_EQ(1, listener1->updates.size());
- ASSERT_EQ(3, listener1->updates[0].mKey.getValues().size());
- EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value);
- EXPECT_EQ("wakelockName", listener1->updates[0].mKey.getValues()[2].mValue.str_value);
- EXPECT_EQ(WakelockStateChanged::ACQUIRE, listener1->updates[0].mState);
-
- // Check StateTracker was updated by querying for state.
- HashableDimensionKey queryKey;
- getPartialWakelockKey(1001 /* uid */, "wakelockName", &queryKey);
- EXPECT_EQ(WakelockStateChanged::ACQUIRE,
- getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey));
-
- // No state stored for this query key.
- HashableDimensionKey queryKey2;
- getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2);
- EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/,
- getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey2));
-
- // Partial query fails.
- HashableDimensionKey queryKey3;
- getPartialWakelockKey(1001 /* uid */, &queryKey3);
- EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/,
- getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey3));
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
- * updates listener for states with multiple primary keys.
- */
-TEST(StateTrackerTest, TestStateChangeMultiplePrimaryFields) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
-
- // log event
- std::unique_ptr<LogEvent> event = CreateOverlayStateChangedEvent(
- timestampNs, 1000 /* uid */, "package1", true /*using_alert_window*/,
- OverlayStateChanged::ENTERED);
- mgr.onLogEvent(*event);
-
- // check listener was updated
- ASSERT_EQ(1, listener1->updates.size());
- EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(1, listener1->updates[0].mState);
-
- // check StateTracker was updated by querying for state
- HashableDimensionKey queryKey;
- getOverlayKey(1000 /* uid */, "package1", &queryKey);
- EXPECT_EQ(OverlayStateChanged::ENTERED,
- getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey));
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged
- * when there is an error extracting state from log event. Listener is not
- * updated of state change.
- */
-TEST(StateTrackerTest, TestStateChangeEventError) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
-
- // log event
- std::shared_ptr<LogEvent> event1 =
- buildIncorrectOverlayEvent(1000 /* uid */, "package1", 1 /* state */);
- std::shared_ptr<LogEvent> event2 = buildOverlayEventBadStateType(1001 /* uid */, "package2");
-
- // check listener was updated
- mgr.onLogEvent(*event1);
- ASSERT_EQ(0, listener1->updates.size());
- mgr.onLogEvent(*event2);
- ASSERT_EQ(0, listener1->updates.size());
-}
-
-TEST(StateTrackerTest, TestStateQuery) {
- sp<TestStateListener> listener1 = new TestStateListener();
- sp<TestStateListener> listener2 = new TestStateListener();
- sp<TestStateListener> listener3 = new TestStateListener();
- sp<TestStateListener> listener4 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
- mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener2);
- mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener3);
- mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener4);
-
- std::unique_ptr<LogEvent> event1 = CreateUidProcessStateChangedEvent(
- timestampNs, 1000 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
- std::unique_ptr<LogEvent> event2 = CreateUidProcessStateChangedEvent(
- timestampNs + 1000, 1001 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE); // state value:
- // 1003
- std::unique_ptr<LogEvent> event3 = CreateUidProcessStateChangedEvent(
- timestampNs + 2000, 1002 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_PERSISTENT); // state value: 1000
- std::unique_ptr<LogEvent> event4 = CreateUidProcessStateChangedEvent(
- timestampNs + 3000, 1001 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
- std::unique_ptr<LogEvent> event5 = CreateScreenStateChangedEvent(
- timestampNs + 4000, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- std::unique_ptr<LogEvent> event6 = CreateOverlayStateChangedEvent(
- timestampNs + 5000, 1000 /*uid*/, "package1", true /*using_alert_window*/,
- OverlayStateChanged::ENTERED);
- std::unique_ptr<LogEvent> event7 = CreateOverlayStateChangedEvent(
- timestampNs + 6000, 1000 /*uid*/, "package2", true /*using_alert_window*/,
- OverlayStateChanged::EXITED);
-
- std::vector<int> attributionUids = {1005};
- std::vector<string> attributionTags = {"tag"};
-
- std::unique_ptr<LogEvent> event8 = CreateAcquireWakelockEvent(
- timestampNs + 7000, attributionUids, attributionTags, "wakelock1");
- std::unique_ptr<LogEvent> event9 = CreateReleaseWakelockEvent(
- timestampNs + 8000, attributionUids, attributionTags, "wakelock2");
-
- mgr.onLogEvent(*event1);
- mgr.onLogEvent(*event2);
- mgr.onLogEvent(*event3);
- mgr.onLogEvent(*event5);
- mgr.onLogEvent(*event5);
- mgr.onLogEvent(*event6);
- mgr.onLogEvent(*event7);
- mgr.onLogEvent(*event8);
- mgr.onLogEvent(*event9);
-
- // Query for UidProcessState of uid 1001
- HashableDimensionKey queryKey1;
- getUidProcessKey(1001, &queryKey1);
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
- getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
-
- // Query for UidProcessState of uid 1004 - not in state map
- HashableDimensionKey queryKey2;
- getUidProcessKey(1004, &queryKey2);
- EXPECT_EQ(-1, getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED,
- queryKey2)); // default state
-
- // Query for UidProcessState of uid 1001 - after change in state
- mgr.onLogEvent(*event4);
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
- getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
-
- // Query for ScreenState
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY));
-
- // Query for OverlayState of uid 1000, package name "package2"
- HashableDimensionKey queryKey3;
- getOverlayKey(1000, "package2", &queryKey3);
- EXPECT_EQ(OverlayStateChanged::EXITED,
- getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey3));
-
- // Query for WakelockState of uid 1005, tag 2
- HashableDimensionKey queryKey4;
- getPartialWakelockKey(1005, "wakelock2", &queryKey4);
- EXPECT_EQ(WakelockStateChanged::RELEASE,
- getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey4));
-
- // Query for WakelockState of uid 1005, tag 1
- HashableDimensionKey queryKey5;
- getPartialWakelockKey(1005, "wakelock1", &queryKey5);
- EXPECT_EQ(WakelockStateChanged::ACQUIRE,
- getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey5));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
deleted file mode 100644
index cee8372..0000000
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ /dev/null
@@ -1,1393 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "statsd_test_util.h"
-
-#include <aidl/android/util/StatsEventParcel.h>
-#include "stats_event.h"
-
-using aidl::android::util::StatsEventParcel;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsLogReport outputStreamToProto(ProtoOutputStream* proto) {
- vector<uint8_t> bytes;
- bytes.resize(proto->size());
- size_t pos = 0;
- sp<ProtoReader> reader = proto->data();
-
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- StatsLogReport report;
- report.ParseFromArray(bytes.data(), bytes.size());
- return report;
-}
-
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(atomId);
- return atom_matcher;
-}
-
-AtomMatcher CreateTemperatureAtomMatcher() {
- return CreateSimpleAtomMatcher("TemperatureMatcher", util::TEMPERATURE);
-}
-
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
- ScheduledJobStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::SCHEDULED_JOB_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(3); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateStartScheduledJobAtomMatcher() {
- return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
- ScheduledJobStateChanged::STARTED);
-}
-
-AtomMatcher CreateFinishScheduledJobAtomMatcher() {
- return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
- ScheduledJobStateChanged::FINISHED);
-}
-
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::SCREEN_BRIGHTNESS_CHANGED);
- return atom_matcher;
-}
-
-AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId("UidProcessStateChanged"));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::UID_PROCESS_STATE_CHANGED);
- return atom_matcher;
-}
-
-AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
- WakelockStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::WAKELOCK_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(4); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateAcquireWakelockAtomMatcher() {
- return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
-}
-
-AtomMatcher CreateReleaseWakelockAtomMatcher() {
- return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
-}
-
-AtomMatcher CreateBatterySaverModeStateChangedAtomMatcher(
- const string& name, BatterySaverModeStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(1); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateBatterySaverModeStartAtomMatcher() {
- return CreateBatterySaverModeStateChangedAtomMatcher(
- "BatterySaverModeStart", BatterySaverModeStateChanged::ON);
-}
-
-
-AtomMatcher CreateBatterySaverModeStopAtomMatcher() {
- return CreateBatterySaverModeStateChangedAtomMatcher(
- "BatterySaverModeStop", BatterySaverModeStateChanged::OFF);
-}
-
-AtomMatcher CreateBatteryStateChangedAtomMatcher(const string& name,
- BatteryPluggedStateEnum state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::PLUGGED_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(1); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateBatteryStateNoneMatcher() {
- return CreateBatteryStateChangedAtomMatcher("BatteryPluggedNone",
- BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
-}
-
-AtomMatcher CreateBatteryStateUsbMatcher() {
- return CreateBatteryStateChangedAtomMatcher("BatteryPluggedUsb",
- BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
-}
-
-AtomMatcher CreateScreenStateChangedAtomMatcher(
- const string& name, android::view::DisplayStateEnum state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::SCREEN_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(1); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateScreenTurnedOnAtomMatcher() {
- return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-}
-
-AtomMatcher CreateScreenTurnedOffAtomMatcher() {
- return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
- ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-}
-
-AtomMatcher CreateSyncStateChangedAtomMatcher(
- const string& name, SyncStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::SYNC_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(3); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateSyncStartAtomMatcher() {
- return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
-}
-
-AtomMatcher CreateSyncEndAtomMatcher() {
- return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
-}
-
-AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
- const string& name, ActivityForegroundStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(4); // Activity field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateMoveToBackgroundAtomMatcher() {
- return CreateActivityForegroundStateChangedAtomMatcher(
- "Background", ActivityForegroundStateChanged::BACKGROUND);
-}
-
-AtomMatcher CreateMoveToForegroundAtomMatcher() {
- return CreateActivityForegroundStateChangedAtomMatcher(
- "Foreground", ActivityForegroundStateChanged::FOREGROUND);
-}
-
-AtomMatcher CreateProcessLifeCycleStateChangedAtomMatcher(
- const string& name, ProcessLifeCycleStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(3); // Process state field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateProcessCrashAtomMatcher() {
- return CreateProcessLifeCycleStateChangedAtomMatcher(
- "Crashed", ProcessLifeCycleStateChanged::CRASHED);
-}
-
-Predicate CreateScheduledJobPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
- predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
- return predicate;
-}
-
-Predicate CreateBatterySaverModePredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("BatterySaverIsOn"));
- predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
- return predicate;
-}
-
-Predicate CreateDeviceUnpluggedPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("DeviceUnplugged"));
- predicate.mutable_simple_predicate()->set_start(StringToId("BatteryPluggedNone"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("BatteryPluggedUsb"));
- return predicate;
-}
-
-Predicate CreateScreenIsOnPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("ScreenIsOn"));
- predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
- return predicate;
-}
-
-Predicate CreateScreenIsOffPredicate() {
- Predicate predicate;
- predicate.set_id(1111123);
- predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
- return predicate;
-}
-
-Predicate CreateHoldingWakelockPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("HoldingWakelock"));
- predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
- return predicate;
-}
-
-Predicate CreateIsSyncingPredicate() {
- Predicate predicate;
- predicate.set_id(33333333333333);
- predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
- return predicate;
-}
-
-Predicate CreateIsInBackgroundPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("IsInBackground"));
- predicate.mutable_simple_predicate()->set_start(StringToId("Background"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("Foreground"));
- return predicate;
-}
-
-State CreateScreenState() {
- State state;
- state.set_id(StringToId("ScreenState"));
- state.set_atom_id(util::SCREEN_STATE_CHANGED);
- return state;
-}
-
-State CreateUidProcessState() {
- State state;
- state.set_id(StringToId("UidProcessState"));
- state.set_atom_id(util::UID_PROCESS_STATE_CHANGED);
- return state;
-}
-
-State CreateOverlayState() {
- State state;
- state.set_id(StringToId("OverlayState"));
- state.set_atom_id(util::OVERLAY_STATE_CHANGED);
- return state;
-}
-
-State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId) {
- State state;
- state.set_id(StringToId("ScreenStateOnOff"));
- state.set_atom_id(util::SCREEN_STATE_CHANGED);
-
- auto map = CreateScreenStateOnOffMap(screenOnId, screenOffId);
- *state.mutable_map() = map;
-
- return state;
-}
-
-State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) {
- State state;
- state.set_id(StringToId("ScreenStateSimpleOnOff"));
- state.set_atom_id(util::SCREEN_STATE_CHANGED);
-
- auto map = CreateScreenStateSimpleOnOffMap(screenOnId, screenOffId);
- *state.mutable_map() = map;
-
- return state;
-}
-
-StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId) {
- StateMap_StateGroup group;
- group.set_group_id(screenOnId);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_VR);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND);
- return group;
-}
-
-StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId) {
- StateMap_StateGroup group;
- group.set_group_id(screenOffId);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND);
- return group;
-}
-
-StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId) {
- StateMap_StateGroup group;
- group.set_group_id(screenOnId);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- return group;
-}
-
-StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId) {
- StateMap_StateGroup group;
- group.set_group_id(screenOffId);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- return group;
-}
-
-StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId) {
- StateMap map;
- *map.add_group() = CreateScreenStateOnGroup(screenOnId);
- *map.add_group() = CreateScreenStateOffGroup(screenOffId);
- return map;
-}
-
-StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) {
- StateMap map;
- *map.add_group() = CreateScreenStateSimpleOnGroup(screenOnId);
- *map.add_group() = CreateScreenStateSimpleOffGroup(screenOffId);
- return map;
-}
-
-void addPredicateToPredicateCombination(const Predicate& predicate,
- Predicate* combinationPredicate) {
- combinationPredicate->mutable_combination()->add_predicate(predicate.id());
-}
-
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
- const std::vector<Position>& positions) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const auto position : positions) {
- auto child = dimensions.add_child();
- child->set_field(1);
- child->set_position(position);
- child->add_child()->set_field(1);
- }
- return dimensions;
-}
-
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
- const std::vector<Position>& positions) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const auto position : positions) {
- auto child = dimensions.add_child();
- child->set_field(1);
- child->set_position(position);
- child->add_child()->set_field(1);
- child->add_child()->set_field(2);
- }
- return dimensions;
-}
-
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const int field : fields) {
- dimensions.add_child()->set_field(field);
- }
- return dimensions;
-}
-
-FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId,
- const std::vector<Position>& positions,
- const std::vector<int>& fields) {
- FieldMatcher dimensions = CreateAttributionUidDimensions(atomId, positions);
-
- for (const int field : fields) {
- dimensions.add_child()->set_field(field);
- }
- return dimensions;
-}
-
-// START: get primary key functions
-void getUidProcessKey(int uid, HashableDimensionKey* key) {
- int pos1[] = {1, 0, 0};
- Field field1(27 /* atom id */, pos1, 0 /* depth */);
- Value value1((int32_t)uid);
-
- key->addValue(FieldValue(field1, value1));
-}
-
-void getOverlayKey(int uid, string packageName, HashableDimensionKey* key) {
- int pos1[] = {1, 0, 0};
- int pos2[] = {2, 0, 0};
-
- Field field1(59 /* atom id */, pos1, 0 /* depth */);
- Field field2(59 /* atom id */, pos2, 0 /* depth */);
-
- Value value1((int32_t)uid);
- Value value2(packageName);
-
- key->addValue(FieldValue(field1, value1));
- key->addValue(FieldValue(field2, value2));
-}
-
-void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key) {
- int pos1[] = {1, 1, 1};
- int pos3[] = {2, 0, 0};
- int pos4[] = {3, 0, 0};
-
- Field field1(10 /* atom id */, pos1, 2 /* depth */);
-
- Field field3(10 /* atom id */, pos3, 0 /* depth */);
- Field field4(10 /* atom id */, pos4, 0 /* depth */);
-
- Value value1((int32_t)uid);
- Value value3((int32_t)1 /*partial*/);
- Value value4(tag);
-
- key->addValue(FieldValue(field1, value1));
- key->addValue(FieldValue(field3, value3));
- key->addValue(FieldValue(field4, value4));
-}
-
-void getPartialWakelockKey(int uid, HashableDimensionKey* key) {
- int pos1[] = {1, 1, 1};
- int pos3[] = {2, 0, 0};
-
- Field field1(10 /* atom id */, pos1, 2 /* depth */);
- Field field3(10 /* atom id */, pos3, 0 /* depth */);
-
- Value value1((int32_t)uid);
- Value value3((int32_t)1 /*partial*/);
-
- key->addValue(FieldValue(field1, value1));
- key->addValue(FieldValue(field3, value3));
-}
-// END: get primary key functions
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
- const vector<string>& attributionTags) {
- vector<const char*> cTags(attributionTags.size());
- for (int i = 0; i < cTags.size(); i++) {
- cTags[i] = attributionTags[i].c_str();
- }
-
- AStatsEvent_writeAttributionChain(statsEvent,
- reinterpret_cast<const uint32_t*>(attributionUids.data()),
- cTags.data(), attributionUids.size());
-}
-
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
- AStatsEvent_build(statsEvent);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
- logEvent->parseBuffer(buf, size);
-
- AStatsEvent_release(statsEvent);
-}
-
-void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- AStatsEvent_writeInt32(statsEvent, value1);
- AStatsEvent_writeInt32(statsEvent, value2);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2) {
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2);
- return logEvent;
-}
-
-void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2, int32_t value3) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- AStatsEvent_writeInt32(statsEvent, value1);
- AStatsEvent_writeInt32(statsEvent, value2);
- AStatsEvent_writeInt32(statsEvent, value3);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2, int32_t value3) {
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- CreateThreeValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2, value3);
- return logEvent;
-}
-
-void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
- int32_t value) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- AStatsEvent_writeInt32(statsEvent, value);
- AStatsEvent_writeInt32(statsEvent, value);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) {
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(logEvent.get(), atomId, eventTimeNs, value);
- return logEvent;
-}
-
-void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) {
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(logEvent.get(), atomId, eventTimeNs);
- return logEvent;
-}
-
-shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
- int data2) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
- AStatsEvent_writeInt32(statsEvent, data1);
- AStatsEvent_writeInt32(statsEvent, data2);
-
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
- const vector<int>& uids, const vector<string>& tags,
- int data1, int data2) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- writeAttribution(statsEvent, uids, tags);
- AStatsEvent_writeInt32(statsEvent, data1);
- AStatsEvent_writeInt32(statsEvent, data2);
-
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids) {
- sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
- EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(ReturnArg<0>());
- for (const int isolatedUid : isolatedUids) {
- EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
- }
-
- return uidMap;
-}
-
-sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids) {
- sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
- EXPECT_CALL(*uidMap, getAppUid(_)).Times(AnyNumber());
- EXPECT_CALL(*uidMap, getAppUid(pkg)).WillRepeatedly(Return(uids));
-
- return uidMap;
-}
-
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
- const android::view::DisplayStateEnum state,
- int loggerUid) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, state);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(loggerUid, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::ON);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::OFF);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs, const BatteryPluggedStateEnum state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SCREEN_BRIGHTNESS_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, level);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
- const vector<int>& attributionUids, const vector<string>& attributionTags,
- const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, jobName.c_str());
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName) {
- return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
- ScheduledJobStateChanged::STARTED, timestampNs);
-}
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName) {
- return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
- ScheduledJobStateChanged::FINISHED, timestampNs);
-}
-
-std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& wakelockName,
- const WakelockStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::WAKELOCK_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
- AStatsEvent_writeInt32(statsEvent, android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeString(statsEvent, wakelockName.c_str());
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeInt32(statsEvent, state);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, true);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& wakelockName) {
- return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
- wakelockName, WakelockStateChanged::ACQUIRE);
-}
-
-std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& wakelockName) {
- return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
- wakelockName, WakelockStateChanged::RELEASE);
-}
-
-std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
- uint64_t timestampNs, const int uid, const ActivityForegroundStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, "pkg_name");
- AStatsEvent_writeString(statsEvent, "class_name");
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid) {
- return CreateActivityForegroundStateChangedEvent(timestampNs, uid,
- ActivityForegroundStateChanged::BACKGROUND);
-}
-
-std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid) {
- return CreateActivityForegroundStateChangedEvent(timestampNs, uid,
- ActivityForegroundStateChanged::FOREGROUND);
-}
-
-std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name,
- const SyncStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, name.c_str());
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name) {
- return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
- SyncStateChanged::ON);
-}
-
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name) {
- return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
- SyncStateChanged::OFF);
-}
-
-std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
- uint64_t timestampNs, const int uid, const ProcessLifeCycleStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, "");
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid) {
- return CreateProcessLifeCycleStateChangedEvent(timestampNs, uid,
- ProcessLifeCycleStateChanged::CRASHED);
-}
-
-std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::APP_CRASH_OCCURRED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, "eventType");
- AStatsEvent_writeString(statsEvent, "processName");
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
- int isolatedUid, bool is_create) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::ISOLATED_UID_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, hostUid);
- AStatsEvent_writeInt32(statsEvent, isolatedUid);
- AStatsEvent_writeInt32(statsEvent, is_create);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
- uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::UID_PROCESS_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_IS_UID, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeInt32(statsEvent, state);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const BleScanStateChanged::State state,
- const bool filtered, const bool firstMatch,
- const bool opportunistic) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
- AStatsEvent_writeInt32(statsEvent, state);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, true);
- if (state == util::BLE_SCAN_STATE_CHANGED__STATE__RESET) {
- AStatsEvent_addInt32Annotation(statsEvent, ANNOTATION_ID_TRIGGER_STATE_RESET,
- util::BLE_SCAN_STATE_CHANGED__STATE__OFF);
- }
- AStatsEvent_writeBool(statsEvent, filtered); // filtered
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeBool(statsEvent, firstMatch); // first match
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeBool(statsEvent, opportunistic); // opportunistic
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
- const string& packageName,
- const bool usingAlertWindow,
- const OverlayStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_IS_UID, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeString(statsEvent, packageName.c_str());
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeBool(statsEvent, usingAlertWindow);
- AStatsEvent_writeInt32(statsEvent, state);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
- const StatsdConfig& config, const ConfigKey& key,
- const shared_ptr<IPullAtomCallback>& puller,
- const int32_t atomTag, const sp<UidMap> uidMap) {
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- if (puller != nullptr) {
- pullerManager->RegisterPullAtomCallback(/*uid=*/0, atomTag, NS_PER_SEC, NS_PER_SEC * 10, {},
- puller);
- }
- sp<AlarmMonitor> anomalyAlarmMonitor =
- new AlarmMonitor(1,
- [](const shared_ptr<IStatsCompanionService>&, int64_t){},
- [](const shared_ptr<IStatsCompanionService>&){});
- sp<AlarmMonitor> periodicAlarmMonitor =
- new AlarmMonitor(1,
- [](const shared_ptr<IStatsCompanionService>&, int64_t){},
- [](const shared_ptr<IStatsCompanionService>&){});
- sp<StatsLogProcessor> processor =
- new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseNs, [](const ConfigKey&) { return true; },
- [](const int&, const vector<int64_t>&) {return true;});
- processor->OnConfigUpdated(currentTimeNs, key, config);
- return processor;
-}
-
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
- std::sort(events->begin(), events->end(),
- [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
- return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
- });
-}
-
-int64_t StringToId(const string& str) {
- return static_cast<int64_t>(std::hash<std::string>()(str));
-}
-
-void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
- const int uid, const string& tag) {
- EXPECT_EQ(value.field(), atomId);
- ASSERT_EQ(value.value_tuple().dimensions_value_size(), 2);
- // Attribution field.
- EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
- // Uid field.
- ASSERT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
- uid);
- // Tag field.
- EXPECT_EQ(value.value_tuple().dimensions_value(1).field(), 3);
- EXPECT_EQ(value.value_tuple().dimensions_value(1).value_str(), tag);
-}
-
-void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
- EXPECT_EQ(value.field(), atomId);
- ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
- // Attribution field.
- EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
- // Uid only.
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(0).value_int(), uid);
-}
-
-void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
- EXPECT_EQ(value.field(), atomId);
- ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
- // Attribution field.
- EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(0).value_int(), uid);
-}
-
-void ValidateAttributionUidAndTagDimension(
- const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
- EXPECT_EQ(value.field(), atomId);
- ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
- // Attribution field.
- EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
- // Uid only.
- EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value_size());
- EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(0).field());
- EXPECT_EQ(uid, value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(0).value_int());
- EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(1).field());
- EXPECT_EQ(tag, value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(1).value_str());
-}
-
-void ValidateAttributionUidAndTagDimension(
- const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
- EXPECT_EQ(value.field(), atomId);
- ASSERT_EQ(1, value.value_tuple().dimensions_value_size());
- // Attribution field.
- EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
- // Uid only.
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value_size(), 2);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(0).value_int(), uid);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(1).field(), 2);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(1).value_str(), tag);
-}
-
-bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
- if (s1.field() != s2.field()) {
- return false;
- }
- if (s1.value_case() != s2.value_case()) {
- return false;
- }
- switch (s1.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- return (s1.value_str() == s2.value_str());
- case DimensionsValue::ValueCase::kValueInt:
- return s1.value_int() == s2.value_int();
- case DimensionsValue::ValueCase::kValueLong:
- return s1.value_long() == s2.value_long();
- case DimensionsValue::ValueCase::kValueBool:
- return s1.value_bool() == s2.value_bool();
- case DimensionsValue::ValueCase::kValueFloat:
- return s1.value_float() == s2.value_float();
- case DimensionsValue::ValueCase::kValueTuple: {
- if (s1.value_tuple().dimensions_value_size() !=
- s2.value_tuple().dimensions_value_size()) {
- return false;
- }
- bool allMatched = true;
- for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
- allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i));
- }
- return allMatched;
- }
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- default:
- return true;
- }
-}
-
-bool LessThan(const google::protobuf::RepeatedPtrField<StateValue>& s1,
- const google::protobuf::RepeatedPtrField<StateValue>& s2) {
- if (s1.size() != s2.size()) {
- return s1.size() < s2.size();
- }
- for (int i = 0; i < s1.size(); i++) {
- const StateValue& state1 = s1[i];
- const StateValue& state2 = s2[i];
- if (state1.atom_id() != state2.atom_id()) {
- return state1.atom_id() < state2.atom_id();
- }
- if (state1.value() != state2.value()) {
- return state1.value() < state2.value();
- }
- if (state1.group_id() != state2.group_id()) {
- return state1.group_id() < state2.group_id();
- }
- }
- return false;
-}
-
-bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
- if (s1.field() != s2.field()) {
- return s1.field() < s2.field();
- }
- if (s1.value_case() != s2.value_case()) {
- return s1.value_case() < s2.value_case();
- }
- switch (s1.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- return s1.value_str() < s2.value_str();
- case DimensionsValue::ValueCase::kValueInt:
- return s1.value_int() < s2.value_int();
- case DimensionsValue::ValueCase::kValueLong:
- return s1.value_long() < s2.value_long();
- case DimensionsValue::ValueCase::kValueBool:
- return (int)s1.value_bool() < (int)s2.value_bool();
- case DimensionsValue::ValueCase::kValueFloat:
- return s1.value_float() < s2.value_float();
- case DimensionsValue::ValueCase::kValueTuple: {
- if (s1.value_tuple().dimensions_value_size() !=
- s2.value_tuple().dimensions_value_size()) {
- return s1.value_tuple().dimensions_value_size() <
- s2.value_tuple().dimensions_value_size();
- }
- for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
- if (EqualsTo(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i))) {
- continue;
- } else {
- return LessThan(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i));
- }
- }
- return false;
- }
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- default:
- return false;
- }
-}
-
-bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
- if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
- return true;
- } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
- return false;
- }
-
- return LessThan(s1.stateValues, s2.stateValues);
-}
-
-void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
- DimensionsValue* dimension) {
- if (dimension->has_value_str_hash()) {
- auto it = str_map.find((uint64_t)(dimension->value_str_hash()));
- if (it != str_map.end()) {
- dimension->clear_value_str_hash();
- dimension->set_value_str(it->second);
- } else {
- ALOGE("Can not find the string hash: %llu",
- (unsigned long long)dimension->value_str_hash());
- }
- } else if (dimension->has_value_tuple()) {
- auto value_tuple = dimension->mutable_value_tuple();
- for (int i = 0; i < value_tuple->dimensions_value_size(); ++i) {
- backfillStringInDimension(str_map, value_tuple->mutable_dimensions_value(i));
- }
- }
-}
-
-void backfillStringInReport(ConfigMetricsReport *config_report) {
- std::map<uint64_t, string> str_map;
- for (const auto& str : config_report->strings()) {
- uint64_t hash = Hash64(str);
- if (str_map.find(hash) != str_map.end()) {
- ALOGE("String hash conflicts: %s %s", str.c_str(), str_map[hash].c_str());
- }
- str_map[hash] = str;
- }
- for (int i = 0; i < config_report->metrics_size(); ++i) {
- auto metric_report = config_report->mutable_metrics(i);
- if (metric_report->has_count_metrics()) {
- backfillStringInDimension(str_map, metric_report->mutable_count_metrics());
- } else if (metric_report->has_duration_metrics()) {
- backfillStringInDimension(str_map, metric_report->mutable_duration_metrics());
- } else if (metric_report->has_gauge_metrics()) {
- backfillStringInDimension(str_map, metric_report->mutable_gauge_metrics());
- } else if (metric_report->has_value_metrics()) {
- backfillStringInDimension(str_map, metric_report->mutable_value_metrics());
- }
- }
- // Backfill the package names.
- for (int i = 0 ; i < config_report->uid_map().snapshots_size(); ++i) {
- auto snapshot = config_report->mutable_uid_map()->mutable_snapshots(i);
- for (int j = 0 ; j < snapshot->package_info_size(); ++j) {
- auto package_info = snapshot->mutable_package_info(j);
- if (package_info->has_name_hash()) {
- auto it = str_map.find((uint64_t)(package_info->name_hash()));
- if (it != str_map.end()) {
- package_info->clear_name_hash();
- package_info->set_name(it->second);
- } else {
- ALOGE("Can not find the string package name hash: %llu",
- (unsigned long long)package_info->name_hash());
- }
-
- }
- }
- }
- // Backfill the app name in app changes.
- for (int i = 0 ; i < config_report->uid_map().changes_size(); ++i) {
- auto change = config_report->mutable_uid_map()->mutable_changes(i);
- if (change->has_app_hash()) {
- auto it = str_map.find((uint64_t)(change->app_hash()));
- if (it != str_map.end()) {
- change->clear_app_hash();
- change->set_app(it->second);
- } else {
- ALOGE("Can not find the string change app name hash: %llu",
- (unsigned long long)change->app_hash());
- }
- }
- }
-}
-
-void backfillStringInReport(ConfigMetricsReportList *config_report_list) {
- for (int i = 0; i < config_report_list->reports_size(); ++i) {
- backfillStringInReport(config_report_list->mutable_reports(i));
- }
-}
-
-bool backfillDimensionPath(const DimensionsValue& path,
- const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
- int* leafIndex,
- DimensionsValue* dimension) {
- dimension->set_field(path.field());
- if (path.has_value_tuple()) {
- for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
- if (!backfillDimensionPath(
- path.value_tuple().dimensions_value(i), leafValues, leafIndex,
- dimension->mutable_value_tuple()->add_dimensions_value())) {
- return false;
- }
- }
- } else {
- if (*leafIndex < 0 || *leafIndex >= leafValues.size()) {
- return false;
- }
- dimension->MergeFrom(leafValues.Get(*leafIndex));
- (*leafIndex)++;
- }
- return true;
-}
-
-bool backfillDimensionPath(const DimensionsValue& path,
- const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
- DimensionsValue* dimension) {
- int leafIndex = 0;
- return backfillDimensionPath(path, leafValues, &leafIndex, dimension);
-}
-
-void backfillDimensionPath(ConfigMetricsReportList *config_report_list) {
- for (int i = 0; i < config_report_list->reports_size(); ++i) {
- auto report = config_report_list->mutable_reports(i);
- for (int j = 0; j < report->metrics_size(); ++j) {
- auto metric_report = report->mutable_metrics(j);
- if (metric_report->has_dimensions_path_in_what() ||
- metric_report->has_dimensions_path_in_condition()) {
- auto whatPath = metric_report->dimensions_path_in_what();
- auto conditionPath = metric_report->dimensions_path_in_condition();
- if (metric_report->has_count_metrics()) {
- backfillDimensionPath(whatPath, conditionPath,
- metric_report->mutable_count_metrics());
- } else if (metric_report->has_duration_metrics()) {
- backfillDimensionPath(whatPath, conditionPath,
- metric_report->mutable_duration_metrics());
- } else if (metric_report->has_gauge_metrics()) {
- backfillDimensionPath(whatPath, conditionPath,
- metric_report->mutable_gauge_metrics());
- } else if (metric_report->has_value_metrics()) {
- backfillDimensionPath(whatPath, conditionPath,
- metric_report->mutable_value_metrics());
- }
- metric_report->clear_dimensions_path_in_what();
- metric_report->clear_dimensions_path_in_condition();
- }
- }
- }
-}
-
-void backfillStartEndTimestamp(StatsLogReport *report) {
- const int64_t timeBaseNs = report->time_base_elapsed_nano_seconds();
- const int64_t bucketSizeNs = report->bucket_size_nano_seconds();
- if (report->has_count_metrics()) {
- backfillStartEndTimestampForMetrics(
- timeBaseNs, bucketSizeNs, report->mutable_count_metrics());
- } else if (report->has_duration_metrics()) {
- backfillStartEndTimestampForMetrics(
- timeBaseNs, bucketSizeNs, report->mutable_duration_metrics());
- } else if (report->has_gauge_metrics()) {
- backfillStartEndTimestampForMetrics(
- timeBaseNs, bucketSizeNs, report->mutable_gauge_metrics());
- if (report->gauge_metrics().skipped_size() > 0) {
- backfillStartEndTimestampForSkippedBuckets(
- timeBaseNs, report->mutable_gauge_metrics());
- }
- } else if (report->has_value_metrics()) {
- backfillStartEndTimestampForMetrics(
- timeBaseNs, bucketSizeNs, report->mutable_value_metrics());
- if (report->value_metrics().skipped_size() > 0) {
- backfillStartEndTimestampForSkippedBuckets(
- timeBaseNs, report->mutable_value_metrics());
- }
- }
-}
-
-void backfillStartEndTimestamp(ConfigMetricsReport *config_report) {
- for (int j = 0; j < config_report->metrics_size(); ++j) {
- backfillStartEndTimestamp(config_report->mutable_metrics(j));
- }
-}
-
-void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
- for (int i = 0; i < config_report_list->reports_size(); ++i) {
- backfillStartEndTimestamp(config_report_list->mutable_reports(i));
- }
-}
-
-Status FakeSubsystemSleepCallback::onPullAtom(int atomTag,
- const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
- // Convert stats_events into StatsEventParcels.
- std::vector<StatsEventParcel> parcels;
- for (int i = 1; i < 3; i++) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, atomTag);
- std::string subsystemName = "subsystem_name_";
- subsystemName = subsystemName + std::to_string(i);
- AStatsEvent_writeString(event, subsystemName.c_str());
- AStatsEvent_writeString(event, "subsystem_subname foo");
- AStatsEvent_writeInt64(event, /*count= */ i);
- AStatsEvent_writeInt64(event, /*time_millis= */ i * 100);
- AStatsEvent_build(event);
- size_t size;
- uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
-
- StatsEventParcel p;
- // vector.assign() creates a copy, but this is inevitable unless
- // stats_event.h/c uses a vector as opposed to a buffer.
- p.buffer.assign(buffer, buffer + size);
- parcels.push_back(std::move(p));
- AStatsEvent_release(event);
- }
- resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
- return Status::ok();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
deleted file mode 100644
index 3dcf4ec..0000000
--- a/cmds/statsd/tests/statsd_test_util.h
+++ /dev/null
@@ -1,479 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-#include <aidl/android/os/BnPullAtomCallback.h>
-#include <aidl/android/os/IPullAtomCallback.h>
-#include <aidl/android/os/IPullAtomResultReceiver.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "src/StatsLogProcessor.h"
-#include "src/hash.h"
-#include "src/logd/LogEvent.h"
-#include "src/packages/UidMap.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "statslog_statsdtest.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using ::aidl::android::os::BnPullAtomCallback;
-using ::aidl::android::os::IPullAtomCallback;
-using ::aidl::android::os::IPullAtomResultReceiver;
-using android::util::ProtoReader;
-using google::protobuf::RepeatedPtrField;
-using Status = ::ndk::ScopedAStatus;
-
-const int SCREEN_STATE_ATOM_ID = util::SCREEN_STATE_CHANGED;
-const int UID_PROCESS_STATE_ATOM_ID = util::UID_PROCESS_STATE_CHANGED;
-
-enum BucketSplitEvent { APP_UPGRADE, BOOT_COMPLETE };
-
-class MockUidMap : public UidMap {
-public:
- MOCK_METHOD(int, getHostUidOrSelf, (int uid), (const));
- MOCK_METHOD(std::set<int32_t>, getAppUid, (const string& package), (const));
-};
-
-// Converts a ProtoOutputStream to a StatsLogReport proto.
-StatsLogReport outputStreamToProto(ProtoOutputStream* proto);
-
-// Create AtomMatcher proto to simply match a specific atom type.
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId);
-
-// Create AtomMatcher proto for temperature atom.
-AtomMatcher CreateTemperatureAtomMatcher();
-
-// Create AtomMatcher proto for scheduled job state changed.
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher();
-
-// Create AtomMatcher proto for starting a scheduled job.
-AtomMatcher CreateStartScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for a scheduled job is done.
-AtomMatcher CreateFinishScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for screen brightness state changed.
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher();
-
-// Create AtomMatcher proto for starting battery save mode.
-AtomMatcher CreateBatterySaverModeStartAtomMatcher();
-
-// Create AtomMatcher proto for stopping battery save mode.
-AtomMatcher CreateBatterySaverModeStopAtomMatcher();
-
-// Create AtomMatcher proto for battery state none mode.
-AtomMatcher CreateBatteryStateNoneMatcher();
-
-// Create AtomMatcher proto for battery state usb mode.
-AtomMatcher CreateBatteryStateUsbMatcher();
-
-// Create AtomMatcher proto for process state changed.
-AtomMatcher CreateUidProcessStateChangedAtomMatcher();
-
-// Create AtomMatcher proto for acquiring wakelock.
-AtomMatcher CreateAcquireWakelockAtomMatcher();
-
-// Create AtomMatcher proto for releasing wakelock.
-AtomMatcher CreateReleaseWakelockAtomMatcher() ;
-
-// Create AtomMatcher proto for screen turned on.
-AtomMatcher CreateScreenTurnedOnAtomMatcher();
-
-// Create AtomMatcher proto for screen turned off.
-AtomMatcher CreateScreenTurnedOffAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned on.
-AtomMatcher CreateSyncStartAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned off.
-AtomMatcher CreateSyncEndAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to background.
-AtomMatcher CreateMoveToBackgroundAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to foreground.
-AtomMatcher CreateMoveToForegroundAtomMatcher();
-
-// Create AtomMatcher proto for process crashes
-AtomMatcher CreateProcessCrashAtomMatcher() ;
-
-// Create Predicate proto for screen is on.
-Predicate CreateScreenIsOnPredicate();
-
-// Create Predicate proto for screen is off.
-Predicate CreateScreenIsOffPredicate();
-
-// Create Predicate proto for a running scheduled job.
-Predicate CreateScheduledJobPredicate();
-
-// Create Predicate proto for battery saver mode.
-Predicate CreateBatterySaverModePredicate();
-
-// Create Predicate proto for device unplogged mode.
-Predicate CreateDeviceUnpluggedPredicate();
-
-// Create Predicate proto for holding wakelock.
-Predicate CreateHoldingWakelockPredicate();
-
-// Create a Predicate proto for app syncing.
-Predicate CreateIsSyncingPredicate();
-
-// Create a Predicate proto for app is in background.
-Predicate CreateIsInBackgroundPredicate();
-
-// Create State proto for screen state atom.
-State CreateScreenState();
-
-// Create State proto for uid process state atom.
-State CreateUidProcessState();
-
-// Create State proto for overlay state atom.
-State CreateOverlayState();
-
-// Create State proto for screen state atom with on/off map.
-State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Create State proto for screen state atom with simple on/off map.
-State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Create StateGroup proto for ScreenState ON group
-StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId);
-
-// Create StateGroup proto for ScreenState OFF group
-StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId);
-
-// Create StateGroup proto for simple ScreenState ON group
-StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId);
-
-// Create StateGroup proto for simple ScreenState OFF group
-StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId);
-
-// Create StateMap proto for ScreenState ON/OFF map
-StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Create StateMap proto for simple ScreenState ON/OFF map
-StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Add a predicate to the predicate combination.
-void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination);
-
-// Create dimensions from primitive fields.
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields);
-
-// Create dimensions by attribution uid and tag.
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
- const std::vector<Position>& positions);
-
-// Create dimensions by attribution uid only.
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
- const std::vector<Position>& positions);
-
-FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId,
- const std::vector<Position>& positions,
- const std::vector<int>& fields);
-
-// START: get primary key functions
-// These functions take in atom field information and create FieldValues which are stored in the
-// given HashableDimensionKey.
-void getUidProcessKey(int uid, HashableDimensionKey* key);
-
-void getOverlayKey(int uid, string packageName, HashableDimensionKey* key);
-
-void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key);
-
-void getPartialWakelockKey(int uid, HashableDimensionKey* key);
-// END: get primary key functions
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
- const vector<string>& attributionTags);
-
-// Builds statsEvent to get buffer that is parsed into logEvent then releases statsEvent.
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent);
-
-shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2);
-
-void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2);
-
-shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2, int32_t value3);
-
-void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2, int32_t value3);
-
-// The repeated value log event helpers create a log event with two int fields, both
-// set to the same value. This is useful for testing metrics that are only interested
-// in the value of the second field but still need the first field to be populated.
-std::shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs,
- int32_t value);
-
-void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
- int32_t value);
-
-std::shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs);
-
-void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs);
-
-std::shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
- int data2);
-
-std::shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
- const vector<int>& uids,
- const vector<string>& tags, int data1, int data2);
-
-sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids);
-
-sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids);
-
-// Create log event for screen state changed.
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
- const android::view::DisplayStateEnum state,
- int loggerUid = 0);
-
-// Create log event for screen brightness state changed.
-std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level);
-
-// Create log event when scheduled job starts.
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName);
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName);
-
-// Create log event when battery saver starts.
-std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs);
-// Create log event when battery saver stops.
-std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs);
-
-// Create log event when battery state changes.
-std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs, const BatteryPluggedStateEnum state);
-
-// Create log event for app moving to background.
-std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid);
-
-// Create log event for app moving to foreground.
-std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid);
-
-// Create log event when the app sync starts.
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs, const vector<int>& uids,
- const vector<string>& tags, const string& name);
-
-// Create log event when the app sync ends.
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs, const vector<int>& uids,
- const vector<string>& tags, const string& name);
-
-// Create log event when the app sync ends.
-std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid);
-
-// Create log event for an app crash.
-std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid);
-
-// Create log event for acquiring wakelock.
-std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs, const vector<int>& uids,
- const vector<string>& tags,
- const string& wakelockName);
-
-// Create log event for releasing wakelock.
-std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs, const vector<int>& uids,
- const vector<string>& tags,
- const string& wakelockName);
-
-// Create log event for releasing wakelock.
-std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
- int isolatedUid, bool is_create);
-
-// Create log event for uid process state change.
-std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
- uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state);
-
-std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const BleScanStateChanged::State state,
- const bool filtered, const bool firstMatch,
- const bool opportunistic);
-
-std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
- const string& packageName,
- const bool usingAlertWindow,
- const OverlayStateChanged::State state);
-
-// Create a statsd log event processor upon the start time in seconds, config and key.
-sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
- const StatsdConfig& config, const ConfigKey& key,
- const shared_ptr<IPullAtomCallback>& puller = nullptr,
- const int32_t atomTag = 0 /*for puller only*/,
- const sp<UidMap> = new UidMap());
-
-// Util function to sort the log events by timestamp.
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events);
-
-int64_t StringToId(const string& str);
-
-void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
- const int uid, const string& tag);
-void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid);
-void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid);
-void ValidateAttributionUidAndTagDimension(
- const DimensionsValue& value, int atomId, int uid, const std::string& tag);
-void ValidateAttributionUidAndTagDimension(
- const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag);
-
-struct DimensionsPair {
- DimensionsPair(DimensionsValue m1, google::protobuf::RepeatedPtrField<StateValue> m2)
- : dimInWhat(m1), stateValues(m2){};
-
- DimensionsValue dimInWhat;
- google::protobuf::RepeatedPtrField<StateValue> stateValues;
-};
-
-bool LessThan(const StateValue& s1, const StateValue& s2);
-bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2);
-bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2);
-
-
-void backfillStartEndTimestamp(ConfigMetricsReport *config_report);
-void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list);
-
-void backfillStringInReport(ConfigMetricsReportList *config_report_list);
-void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
- DimensionsValue* dimension);
-
-template <typename T>
-void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
- T* metrics) {
- for (int i = 0; i < metrics->data_size(); ++i) {
- auto data = metrics->mutable_data(i);
- if (data->has_dimensions_in_what()) {
- backfillStringInDimension(str_map, data->mutable_dimensions_in_what());
- }
- if (data->has_dimensions_in_condition()) {
- backfillStringInDimension(str_map, data->mutable_dimensions_in_condition());
- }
- }
-}
-
-void backfillDimensionPath(ConfigMetricsReportList* config_report_list);
-
-bool backfillDimensionPath(const DimensionsValue& path,
- const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
- DimensionsValue* dimension);
-
-class FakeSubsystemSleepCallback : public BnPullAtomCallback {
-public:
- Status onPullAtom(int atomTag,
- const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override;
-};
-
-template <typename T>
-void backfillDimensionPath(const DimensionsValue& whatPath,
- const DimensionsValue& conditionPath,
- T* metricData) {
- for (int i = 0; i < metricData->data_size(); ++i) {
- auto data = metricData->mutable_data(i);
- if (data->dimension_leaf_values_in_what_size() > 0) {
- backfillDimensionPath(whatPath, data->dimension_leaf_values_in_what(),
- data->mutable_dimensions_in_what());
- data->clear_dimension_leaf_values_in_what();
- }
- if (data->dimension_leaf_values_in_condition_size() > 0) {
- backfillDimensionPath(conditionPath, data->dimension_leaf_values_in_condition(),
- data->mutable_dimensions_in_condition());
- data->clear_dimension_leaf_values_in_condition();
- }
- }
-}
-
-struct DimensionCompare {
- bool operator()(const DimensionsPair& s1, const DimensionsPair& s2) const {
- return LessThan(s1, s2);
- }
-};
-
-template <typename T>
-void sortMetricDataByDimensionsValue(const T& metricData, T* sortedMetricData) {
- std::map<DimensionsPair, int, DimensionCompare> dimensionIndexMap;
- for (int i = 0; i < metricData.data_size(); ++i) {
- dimensionIndexMap.insert(
- std::make_pair(DimensionsPair(metricData.data(i).dimensions_in_what(),
- metricData.data(i).slice_by_state()),
- i));
- }
- for (const auto& itr : dimensionIndexMap) {
- *sortedMetricData->add_data() = metricData.data(itr.second);
- }
-}
-
-template <typename T>
-void backfillStartEndTimestampForFullBucket(
- const int64_t timeBaseNs, const int64_t bucketSizeNs, T* bucket) {
- bucket->set_start_bucket_elapsed_nanos(timeBaseNs + bucketSizeNs * bucket->bucket_num());
- bucket->set_end_bucket_elapsed_nanos(
- timeBaseNs + bucketSizeNs * bucket->bucket_num() + bucketSizeNs);
- bucket->clear_bucket_num();
-}
-
-template <typename T>
-void backfillStartEndTimestampForPartialBucket(const int64_t timeBaseNs, T* bucket) {
- if (bucket->has_start_bucket_elapsed_millis()) {
- bucket->set_start_bucket_elapsed_nanos(
- MillisToNano(bucket->start_bucket_elapsed_millis()));
- bucket->clear_start_bucket_elapsed_millis();
- }
- if (bucket->has_end_bucket_elapsed_millis()) {
- bucket->set_end_bucket_elapsed_nanos(
- MillisToNano(bucket->end_bucket_elapsed_millis()));
- bucket->clear_end_bucket_elapsed_millis();
- }
-}
-
-template <typename T>
-void backfillStartEndTimestampForMetrics(const int64_t timeBaseNs, const int64_t bucketSizeNs,
- T* metrics) {
- for (int i = 0; i < metrics->data_size(); ++i) {
- auto data = metrics->mutable_data(i);
- for (int j = 0; j < data->bucket_info_size(); ++j) {
- auto bucket = data->mutable_bucket_info(j);
- if (bucket->has_bucket_num()) {
- backfillStartEndTimestampForFullBucket(timeBaseNs, bucketSizeNs, bucket);
- } else {
- backfillStartEndTimestampForPartialBucket(timeBaseNs, bucket);
- }
- }
- }
-}
-
-template <typename T>
-void backfillStartEndTimestampForSkippedBuckets(const int64_t timeBaseNs, T* metrics) {
- for (int i = 0; i < metrics->skipped_size(); ++i) {
- backfillStartEndTimestampForPartialBucket(timeBaseNs, metrics->mutable_skipped(i));
- }
-}
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/storage/StorageManager_test.cpp b/cmds/statsd/tests/storage/StorageManager_test.cpp
deleted file mode 100644
index 74eafbf..0000000
--- a/cmds/statsd/tests/storage/StorageManager_test.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <android-base/unique_fd.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include "src/storage/StorageManager.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-using testing::Contains;
-
-TEST(StorageManagerTest, TrainInfoReadWriteTest) {
- InstallTrainInfo trainInfo;
- trainInfo.trainVersionCode = 12345;
- trainInfo.trainName = "This is a train name #)$(&&$";
- trainInfo.status = 1;
- const char* expIds = "test_ids";
- trainInfo.experimentIds.assign(expIds, expIds + strlen(expIds));
-
- bool result;
-
- result = StorageManager::writeTrainInfo(trainInfo);
-
- EXPECT_TRUE(result);
-
- InstallTrainInfo trainInfoResult;
- result = StorageManager::readTrainInfo(trainInfo.trainName, trainInfoResult);
- EXPECT_TRUE(result);
-
- EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
- ASSERT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
- EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
- EXPECT_EQ(trainInfo.status, trainInfoResult.status);
- ASSERT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
- EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
-}
-
-TEST(StorageManagerTest, TrainInfoReadWriteTrainNameSizeOneTest) {
- InstallTrainInfo trainInfo;
- trainInfo.trainVersionCode = 12345;
- trainInfo.trainName = "{";
- trainInfo.status = 1;
- const char* expIds = "test_ids";
- trainInfo.experimentIds.assign(expIds, expIds + strlen(expIds));
-
- bool result;
-
- result = StorageManager::writeTrainInfo(trainInfo);
-
- EXPECT_TRUE(result);
-
- InstallTrainInfo trainInfoResult;
- result = StorageManager::readTrainInfo(trainInfo.trainName, trainInfoResult);
- EXPECT_TRUE(result);
-
- EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
- ASSERT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
- EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
- EXPECT_EQ(trainInfo.status, trainInfoResult.status);
- ASSERT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
- EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
-}
-
-TEST(StorageManagerTest, SortFileTest) {
- vector<StorageManager::FileInfo> list;
- // assume now sec is 500
- list.emplace_back("200_5000_123454", false, 20, 300);
- list.emplace_back("300_2000_123454_history", true, 30, 200);
- list.emplace_back("400_100009_123454_history", true, 40, 100);
- list.emplace_back("100_2000_123454", false, 50, 400);
-
- StorageManager::sortFiles(&list);
- EXPECT_EQ("200_5000_123454", list[0].mFileName);
- EXPECT_EQ("100_2000_123454", list[1].mFileName);
- EXPECT_EQ("400_100009_123454_history", list[2].mFileName);
- EXPECT_EQ("300_2000_123454_history", list[3].mFileName);
-}
-
-const string testDir = "/data/misc/stats-data/";
-const string file1 = testDir + "2557169347_1066_1";
-const string file2 = testDir + "2557169349_1066_1";
-const string file1_history = file1 + "_history";
-const string file2_history = file2 + "_history";
-
-bool prepareLocalHistoryTestFiles() {
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(
- open(file1.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)));
- if (fd != -1) {
- dprintf(fd, "content");
- } else {
- return false;
- }
-
- android::base::unique_fd fd2(TEMP_FAILURE_RETRY(
- open(file2.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)));
- if (fd2 != -1) {
- dprintf(fd2, "content");
- } else {
- return false;
- }
- return true;
-}
-
-void clearLocalHistoryTestFiles() {
- TEMP_FAILURE_RETRY(remove(file1.c_str()));
- TEMP_FAILURE_RETRY(remove(file2.c_str()));
- TEMP_FAILURE_RETRY(remove(file1_history.c_str()));
- TEMP_FAILURE_RETRY(remove(file2_history.c_str()));
-}
-
-bool fileExist(string name) {
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(name.c_str(), O_RDONLY | O_CLOEXEC)));
- return fd != -1;
-}
-
-/* The following AppendConfigReportTests test the 4 combinations of [whether erase data] [whether
- * the caller is adb] */
-TEST(StorageManagerTest, AppendConfigReportTest1) {
- EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
- ProtoOutputStream out;
- StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, false /*erase?*/,
- false /*isAdb?*/);
-
- EXPECT_FALSE(fileExist(file1));
- EXPECT_FALSE(fileExist(file2));
-
- EXPECT_TRUE(fileExist(file1_history));
- EXPECT_TRUE(fileExist(file2_history));
- clearLocalHistoryTestFiles();
-}
-
-TEST(StorageManagerTest, AppendConfigReportTest2) {
- EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
- ProtoOutputStream out;
- StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, true /*erase?*/,
- false /*isAdb?*/);
-
- EXPECT_FALSE(fileExist(file1));
- EXPECT_FALSE(fileExist(file2));
- EXPECT_FALSE(fileExist(file1_history));
- EXPECT_FALSE(fileExist(file2_history));
-
- clearLocalHistoryTestFiles();
-}
-
-TEST(StorageManagerTest, AppendConfigReportTest3) {
- EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
- ProtoOutputStream out;
- StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, false /*erase?*/,
- true /*isAdb?*/);
-
- EXPECT_TRUE(fileExist(file1));
- EXPECT_TRUE(fileExist(file2));
- EXPECT_FALSE(fileExist(file1_history));
- EXPECT_FALSE(fileExist(file2_history));
-
- clearLocalHistoryTestFiles();
-}
-
-TEST(StorageManagerTest, AppendConfigReportTest4) {
- EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
- ProtoOutputStream out;
- StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, true /*erase?*/,
- true /*isAdb?*/);
-
- EXPECT_FALSE(fileExist(file1));
- EXPECT_FALSE(fileExist(file2));
- EXPECT_FALSE(fileExist(file1_history));
- EXPECT_FALSE(fileExist(file2_history));
-
- clearLocalHistoryTestFiles();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp b/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp
deleted file mode 100644
index 32cecd3..0000000
--- a/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "utils/MultiConditionTrigger.h"
-
-#include <gtest/gtest.h>
-
-#include <chrono>
-#include <set>
-#include <thread>
-#include <vector>
-
-#ifdef __ANDROID__
-
-using namespace std;
-using std::this_thread::sleep_for;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-TEST(MultiConditionTrigger, TestMultipleConditions) {
- int numConditions = 5;
- string t1 = "t1", t2 = "t2", t3 = "t3", t4 = "t4", t5 = "t5";
- set<string> conditionNames = {t1, t2, t3, t4, t5};
-
- mutex lock;
- condition_variable cv;
- bool triggerCalled = false;
-
- // Mark done as true and notify in the done.
- MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled] {
- {
- lock_guard lg(lock);
- triggerCalled = true;
- }
- cv.notify_all();
- });
-
- vector<thread> threads;
- vector<int> done(numConditions, 0);
-
- int i = 0;
- for (const string& conditionName : conditionNames) {
- threads.emplace_back([&done, &conditionName, &trigger, i] {
- sleep_for(chrono::milliseconds(3));
- done[i] = 1;
- trigger.markComplete(conditionName);
- });
- i++;
- }
-
- unique_lock<mutex> unique_lk(lock);
- cv.wait(unique_lk, [&triggerCalled] {
- return triggerCalled;
- });
-
- for (i = 0; i < numConditions; i++) {
- EXPECT_EQ(done[i], 1);
- }
-
- for (i = 0; i < numConditions; i++) {
- threads[i].join();
- }
-}
-
-TEST(MultiConditionTrigger, TestNoConditions) {
- mutex lock;
- condition_variable cv;
- bool triggerCalled = false;
-
- MultiConditionTrigger trigger({}, [&lock, &cv, &triggerCalled] {
- {
- lock_guard lg(lock);
- triggerCalled = true;
- }
- cv.notify_all();
- });
-
- unique_lock<mutex> unique_lk(lock);
- cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
- EXPECT_TRUE(triggerCalled);
- // Ensure that trigger occurs immediately if no events need to be completed.
-}
-
-TEST(MultiConditionTrigger, TestMarkCompleteCalledBySameCondition) {
- string t1 = "t1", t2 = "t2";
- set<string> conditionNames = {t1, t2};
-
- mutex lock;
- condition_variable cv;
- bool triggerCalled = false;
-
- MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled] {
- {
- lock_guard lg(lock);
- triggerCalled = true;
- }
- cv.notify_all();
- });
-
- trigger.markComplete(t1);
- trigger.markComplete(t1);
-
- // Ensure that the trigger still hasn't fired.
- {
- lock_guard lg(lock);
- EXPECT_FALSE(triggerCalled);
- }
-
- trigger.markComplete(t2);
- unique_lock<mutex> unique_lk(lock);
- cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
- EXPECT_TRUE(triggerCalled);
-}
-
-TEST(MultiConditionTrigger, TestTriggerOnlyCalledOnce) {
- string t1 = "t1";
- set<string> conditionNames = {t1};
-
- mutex lock;
- condition_variable cv;
- bool triggerCalled = false;
- int triggerCount = 0;
-
- MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled, &triggerCount] {
- {
- lock_guard lg(lock);
- triggerCount++;
- triggerCalled = true;
- }
- cv.notify_all();
- });
-
- trigger.markComplete(t1);
-
- // Ensure that the trigger fired.
- {
- unique_lock<mutex> unique_lk(lock);
- cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
- EXPECT_TRUE(triggerCalled);
- EXPECT_EQ(triggerCount, 1);
- triggerCalled = false;
- }
-
- trigger.markComplete(t1);
-
- // Ensure that the trigger does not fire again.
- {
- unique_lock<mutex> unique_lk(lock);
- cv.wait_for(unique_lk, chrono::milliseconds(5), [&triggerCalled] { return triggerCalled; });
- EXPECT_FALSE(triggerCalled);
- EXPECT_EQ(triggerCount, 1);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tools/localtools/Android.bp b/cmds/statsd/tools/localtools/Android.bp
deleted file mode 100644
index 69a43a8..0000000
--- a/cmds/statsd/tools/localtools/Android.bp
+++ /dev/null
@@ -1,46 +0,0 @@
-java_binary_host {
- name: "statsd_localdrive",
- manifest: "localdrive_manifest.txt",
- srcs: [
- "src/com/android/statsd/shelltools/localdrive/*.java",
- "src/com/android/statsd/shelltools/Utils.java",
- ],
- static_libs: [
- "platformprotos",
- "guava",
- ],
-}
-
-java_library_host {
- name: "statsd_testdrive_lib",
- srcs: [
- "src/com/android/statsd/shelltools/testdrive/*.java",
- "src/com/android/statsd/shelltools/Utils.java",
- ],
- static_libs: [
- "platformprotos",
- "guava",
- ],
-}
-
-
-java_binary_host {
- name: "statsd_testdrive",
- manifest: "testdrive_manifest.txt",
- static_libs: [
- "statsd_testdrive_lib",
- ],
-}
-
-java_test_host {
- name: "statsd_testdrive_test",
- test_suites: ["general-tests"],
- srcs: ["test/com/android/statsd/shelltools/testdrive/*.java"],
- static_libs: [
- "statsd_testdrive_lib",
- "junit",
- "platformprotos",
- "guava",
- ],
-}
-
diff --git a/cmds/statsd/tools/localtools/TEST_MAPPING b/cmds/statsd/tools/localtools/TEST_MAPPING
deleted file mode 100644
index 7c8a3db..0000000
--- a/cmds/statsd/tools/localtools/TEST_MAPPING
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "presubmit": [
- {
- "name": "statsd_testdrive_test",
- "host": true
- }
- ]
-}
diff --git a/cmds/statsd/tools/localtools/localdrive_manifest.txt b/cmds/statsd/tools/localtools/localdrive_manifest.txt
deleted file mode 100644
index 035cea1..0000000
--- a/cmds/statsd/tools/localtools/localdrive_manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-class: com.android.statsd.shelltools.localdrive.LocalDrive
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java
deleted file mode 100644
index 6a74480..0000000
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.shelltools;
-
-import com.android.os.StatsLog.ConfigMetricsReportList;
-
-import com.google.common.io.Files;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Formatter;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Utilities for local use of statsd.
- */
-public class Utils {
-
- public static final String CMD_DUMP_REPORT = "cmd stats dump-report";
- public static final String CMD_LOG_APP_BREADCRUMB = "cmd stats log-app-breadcrumb";
- public static final String CMD_REMOVE_CONFIG = "cmd stats config remove";
- public static final String CMD_UPDATE_CONFIG = "cmd stats config update";
-
- public static final String SHELL_UID = "2000"; // Use shell, even if rooted.
-
- /**
- * Runs adb shell command with output directed to outputFile if non-null.
- */
- public static void runCommand(File outputFile, Logger logger, String... commands)
- throws IOException, InterruptedException {
- ProcessBuilder pb = new ProcessBuilder(commands);
- if (outputFile != null && outputFile.exists() && outputFile.canWrite()) {
- pb.redirectOutput(outputFile);
- }
- Process process = pb.start();
-
- // Capture any errors
- StringBuilder err = new StringBuilder();
- BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
- for (String line = br.readLine(); line != null; line = br.readLine()) {
- err.append(line).append('\n');
- }
- logger.severe(err.toString());
-
- // Check result
- if (process.waitFor() == 0) {
- logger.fine("Adb command successful.");
- } else {
- logger.severe("Abnormal adb shell termination for: " + String.join(",", commands));
- throw new RuntimeException("Error running adb command: " + err.toString());
- }
- }
-
- /**
- * Dumps the report from the device and converts it to a ConfigMetricsReportList.
- * Erases the data if clearData is true.
- * @param configId id of the config
- * @param clearData whether to erase the report data from statsd after getting the report.
- * @param useShellUid Pulls data for the {@link SHELL_UID} instead of the caller's uid.
- * @param logger Logger to log error messages
- * @return
- * @throws IOException
- * @throws InterruptedException
- */
- public static ConfigMetricsReportList getReportList(long configId, boolean clearData,
- boolean useShellUid, Logger logger, String deviceSerial)
- throws IOException, InterruptedException {
- try {
- File outputFile = File.createTempFile("statsdret", ".bin");
- outputFile.deleteOnExit();
- runCommand(
- outputFile,
- logger,
- "adb",
- "-s",
- deviceSerial,
- "shell",
- CMD_DUMP_REPORT,
- useShellUid ? SHELL_UID : "",
- String.valueOf(configId),
- clearData ? "" : "--keep_data",
- "--include_current_bucket",
- "--proto");
- ConfigMetricsReportList reportList =
- ConfigMetricsReportList.parseFrom(new FileInputStream(outputFile));
- return reportList;
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- logger.severe("Failed to fetch and parse the statsd output report. "
- + "Perhaps there is not a valid statsd config for the requested "
- + (useShellUid ? ("uid=" + SHELL_UID + ", ") : "")
- + "configId=" + configId
- + ".");
- throw (e);
- }
- }
-
- /**
- * Logs an AppBreadcrumbReported atom.
- * @param label which label to log for the app breadcrumb atom.
- * @param state which state to log for the app breadcrumb atom.
- * @param logger Logger to log error messages
- *
- * @throws IOException
- * @throws InterruptedException
- */
- public static void logAppBreadcrumb(int label, int state, Logger logger, String deviceSerial)
- throws IOException, InterruptedException {
- runCommand(
- null,
- logger,
- "adb",
- "-s",
- deviceSerial,
- "shell",
- CMD_LOG_APP_BREADCRUMB,
- String.valueOf(label),
- String.valueOf(state));
- }
- public static void setUpLogger(Logger logger, boolean debug) {
- ConsoleHandler handler = new ConsoleHandler();
- handler.setFormatter(new LocalToolsFormatter());
- logger.setUseParentHandlers(false);
- if (debug) {
- handler.setLevel(Level.ALL);
- logger.setLevel(Level.ALL);
- }
- logger.addHandler(handler);
- }
-
- /**
- * Attempt to determine whether tool will work with this statsd, i.e. whether statsd is
- * minCodename or higher.
- * Algorithm: true if (sdk >= minSdk) || (sdk == minSdk-1 && codeName.startsWith(minCodeName))
- * If all else fails, assume it will work (letting future commands deal with any errors).
- */
- public static boolean isAcceptableStatsd(Logger logger, int minSdk, String minCodename,
- String deviceSerial) {
- BufferedReader in = null;
- try {
- File outFileSdk = File.createTempFile("shelltools_sdk", "tmp");
- outFileSdk.deleteOnExit();
- runCommand(outFileSdk, logger,
- "adb", "-s", deviceSerial, "shell", "getprop", "ro.build.version.sdk");
- in = new BufferedReader(new InputStreamReader(new FileInputStream(outFileSdk)));
- // If NullPointerException/NumberFormatException/etc., just catch and return true.
- int sdk = Integer.parseInt(in.readLine().trim());
- if (sdk >= minSdk) {
- return true;
- } else if (sdk == minSdk - 1) { // Could be minSdk-1, or could be minSdk development.
- in.close();
- File outFileCode = File.createTempFile("shelltools_codename", "tmp");
- outFileCode.deleteOnExit();
- runCommand(outFileCode, logger,
- "adb", "-s", deviceSerial, "shell", "getprop", "ro.build.version.codename");
- in = new BufferedReader(new InputStreamReader(new FileInputStream(outFileCode)));
- return in.readLine().startsWith(minCodename);
- } else {
- return false;
- }
- } catch (Exception e) {
- logger.fine("Could not determine whether statsd version is compatibile "
- + "with tool: " + e.toString());
- } finally {
- try {
- if (in != null) {
- in.close();
- }
- } catch (IOException e) {
- logger.fine("Could not close temporary file: " + e.toString());
- }
- }
- // Could not determine whether statsd is acceptable version.
- // Just assume it is; if it isn't, we'll just get future errors via adb and deal with them.
- return true;
- }
-
- public static class LocalToolsFormatter extends Formatter {
- public String format(LogRecord record) {
- return record.getMessage() + "\n";
- }
- }
-
- /**
- * Parse the result of "adb devices" to return the list of connected devices.
- * @param logger Logger to log error messages
- * @return List of the serial numbers of the connected devices.
- */
- public static List<String> getDeviceSerials(Logger logger) {
- try {
- ArrayList<String> devices = new ArrayList<>();
- File outFile = File.createTempFile("device_serial", "tmp");
- outFile.deleteOnExit();
- Utils.runCommand(outFile, logger, "adb", "devices");
- List<String> outputLines = Files.readLines(outFile, Charset.defaultCharset());
- Pattern regex = Pattern.compile("^(.*)\tdevice$");
- for (String line : outputLines) {
- Matcher m = regex.matcher(line);
- if (m.find()) {
- devices.add(m.group(1));
- }
- }
- return devices;
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Failed to list connected devices: " + ex.getMessage());
- }
- return null;
- }
-
- /**
- * Returns ANDROID_SERIAL environment variable, or null if that is undefined or unavailable.
- * @param logger Destination of error messages.
- * @return String value of ANDROID_SERIAL environment variable, or null.
- */
- public static String getDefaultDevice(Logger logger) {
- try {
- return System.getenv("ANDROID_SERIAL");
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Failed to check ANDROID_SERIAL environment variable.",
- ex);
- }
- return null;
- }
-
- /**
- * Returns the device to use if one can be deduced, or null.
- * @param device Command-line specified device, or null.
- * @param connectedDevices List of all connected devices.
- * @param defaultDevice Environment-variable specified device, or null.
- * @param logger Destination of error messages.
- * @return Device to use, or null.
- */
- public static String chooseDevice(String device, List<String> connectedDevices,
- String defaultDevice, Logger logger) {
- if (connectedDevices == null || connectedDevices.isEmpty()) {
- logger.severe("No connected device.");
- return null;
- }
- if (device != null) {
- if (connectedDevices.contains(device)) {
- return device;
- }
- logger.severe("Device not connected: " + device);
- return null;
- }
- if (connectedDevices.size() == 1) {
- return connectedDevices.get(0);
- }
- if (defaultDevice != null) {
- if (connectedDevices.contains(defaultDevice)) {
- return defaultDevice;
- } else {
- logger.severe("ANDROID_SERIAL device is not connected: " + defaultDevice);
- return null;
- }
- }
- logger.severe("More than one device is connected. Choose one"
- + " with -s DEVICE_SERIAL or environment variable ANDROID_SERIAL.");
- return null;
- }
-}
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java
deleted file mode 100644
index ec3c7df..0000000
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.shelltools.localdrive;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.statsd.shelltools.Utils;
-
-import com.google.common.io.Files;
-import com.google.protobuf.TextFormat;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.List;
-import java.util.logging.Logger;
-
-/**
- * Tool for using statsd locally. Can upload a config and get the data. Handles
- * both binary and human-readable protos.
- * To make: make statsd_localdrive
- * To run: statsd_localdrive (i.e. ./out/host/linux-x86/bin/statsd_localdrive)
- */
-public class LocalDrive {
- private static final boolean DEBUG = false;
-
- public static final int MIN_SDK = 29;
- public static final String MIN_CODENAME = "Q";
-
- public static final long DEFAULT_CONFIG_ID = 56789;
-
- public static final String BINARY_FLAG = "--binary";
- public static final String CLEAR_DATA = "--clear";
- public static final String NO_UID_MAP_FLAG = "--no-uid-map";
-
- public static final String HELP_STRING =
- "Usage:\n\n" +
-
- "statsd_localdrive [-s DEVICE_SERIAL] upload CONFIG_FILE [CONFIG_ID] [--binary]\n" +
- " Uploads the given statsd config file (in binary or human-readable-text format).\n" +
- " If a config with this id already exists, removes it first.\n" +
- " CONFIG_FILE Location of config file on host.\n" +
- " CONFIG_ID Long ID to associate with this config. If absent, uses "
- + DEFAULT_CONFIG_ID + ".\n" +
- " --binary Config is in binary format; otherwise, assumed human-readable text.\n" +
- // Similar to: adb shell cmd stats config update SHELL_UID CONFIG_ID
- "\n" +
-
- "statsd_localdrive [-s DEVICE_SERIAL] update CONFIG_FILE [CONFIG_ID] [--binary]\n" +
- " Same as upload, but does not remove the old config first (if it already exists).\n" +
- // Similar to: adb shell cmd stats config update SHELL_UID CONFIG_ID
- "\n" +
-
- "statsd_localdrive [-s DEVICE_SERIAL] get-data [CONFIG_ID] [--clear] [--binary] [--no-uid-map]\n" +
- " Prints the output statslog data (in binary or human-readable-text format).\n" +
- " CONFIG_ID Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
- " --binary Output should be in binary, instead of default human-readable text.\n" +
- " Binary output can be redirected as usual (e.g. > FILENAME).\n" +
- " --no-uid-map Do not include the uid-map (the very lengthy uid<-->pkgName map).\n" +
- " --clear Erase the data from statsd afterwards. Does not remove the config.\n" +
- // Similar to: adb shell cmd stats dump-report SHELL_UID CONFIG_ID [--keep_data]
- // --include_current_bucket --proto
- "\n" +
-
- "statsd_localdrive [-s DEVICE_SERIAL] remove [CONFIG_ID]\n" +
- " Removes the config.\n" +
- " CONFIG_ID Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
- // Equivalent to: adb shell cmd stats config remove SHELL_UID CONFIG_ID
- "\n" +
-
- "statsd_localdrive [-s DEVICE_SERIAL] clear [CONFIG_ID]\n" +
- " Clears the data associated with the config.\n" +
- " CONFIG_ID Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
- // Similar to: adb shell cmd stats dump-report SHELL_UID CONFIG_ID
- // --include_current_bucket --proto
- "";
-
-
- private static final Logger sLogger = Logger.getLogger(LocalDrive.class.getName());
-
- /** Usage: make statsd_localdrive && statsd_localdrive */
- public static void main(String[] args) {
- Utils.setUpLogger(sLogger, DEBUG);
- if (args.length == 0) {
- printHelp();
- return;
- }
-
- int remainingArgsLength = args.length;
- String deviceSerial = null;
- if (args[0].equals("-s")) {
- if (args.length == 1) {
- printHelp();
- }
- deviceSerial = args[1];
- remainingArgsLength -= 2;
- }
-
- List<String> connectedDevices = Utils.getDeviceSerials(sLogger);
- deviceSerial = Utils.chooseDevice(deviceSerial, connectedDevices,
- Utils.getDefaultDevice(sLogger), sLogger);
- if (deviceSerial == null) {
- return;
- }
-
- if (!Utils.isAcceptableStatsd(sLogger, MIN_SDK, MIN_CODENAME, deviceSerial)) {
- sLogger.severe("LocalDrive only works with statsd versions for Android "
- + MIN_CODENAME + " or higher.");
- return;
- }
-
- int idx = args.length - remainingArgsLength;
- if (remainingArgsLength > 0) {
- switch (args[idx]) {
- case "clear":
- cmdClear(args, idx, deviceSerial);
- return;
- case "get-data":
- cmdGetData(args, idx, deviceSerial);
- return;
- case "remove":
- cmdRemove(args, idx);
- return;
- case "update":
- cmdUpdate(args, idx, deviceSerial);
- return;
- case "upload":
- cmdUpload(args, idx, deviceSerial);
- return;
- }
- }
- printHelp();
- }
-
- private static void printHelp() {
- sLogger.info(HELP_STRING);
- }
-
- // upload CONFIG_FILE [CONFIG_ID] [--binary]
- private static boolean cmdUpload(String[] args, int idx, String deviceSerial) {
- return updateConfig(args, idx, true, deviceSerial);
- }
-
- // update CONFIG_FILE [CONFIG_ID] [--binary]
- private static boolean cmdUpdate(String[] args, int idx, String deviceSerial) {
- return updateConfig(args, idx, false, deviceSerial);
- }
-
- private static boolean updateConfig(String[] args, int idx, boolean removeOldConfig,
- String deviceSerial) {
- int argCount = args.length - 1 - idx; // Used up one for upload/update.
-
- // Get CONFIG_FILE
- if (argCount < 1) {
- sLogger.severe("No config file provided.");
- printHelp();
- return false;
- }
- final String origConfigLocation = args[idx + 1];
- if (!new File(origConfigLocation).exists()) {
- sLogger.severe("Error - Cannot find the provided config file: " + origConfigLocation);
- return false;
- }
- argCount--;
-
- // Get --binary
- boolean binary = contains(args, idx + 2, BINARY_FLAG);
- if (binary) argCount --;
-
- // Get CONFIG_ID
- long configId;
- try {
- configId = getConfigId(argCount < 1, args, idx + 2);
- } catch (NumberFormatException e) {
- sLogger.severe("Invalid config id provided.");
- printHelp();
- return false;
- }
- sLogger.fine(String.format("updateConfig with %s %d %b %b",
- origConfigLocation, configId, binary, removeOldConfig));
-
- // Remove the old config.
- if (removeOldConfig) {
- try {
- Utils.runCommand(null, sLogger, "adb", "shell", Utils.CMD_REMOVE_CONFIG,
- Utils.SHELL_UID, String.valueOf(configId));
- Utils.getReportList(configId, true /* clearData */, true /* SHELL_UID */, sLogger,
- deviceSerial);
- } catch (InterruptedException | IOException e) {
- sLogger.severe("Failed to remove config: " + e.getMessage());
- return false;
- }
- }
-
- // Upload the config.
- String configLocation;
- if (binary) {
- configLocation = origConfigLocation;
- } else {
- StatsdConfig.Builder builder = StatsdConfig.newBuilder();
- try {
- TextFormat.merge(new FileReader(origConfigLocation), builder);
- } catch (IOException e) {
- sLogger.severe("Failed to read config file " + origConfigLocation + ": "
- + e.getMessage());
- return false;
- }
-
- try {
- File tempConfigFile = File.createTempFile("statsdconfig", ".config");
- tempConfigFile.deleteOnExit();
- Files.write(builder.build().toByteArray(), tempConfigFile);
- configLocation = tempConfigFile.getAbsolutePath();
- } catch (IOException e) {
- sLogger.severe("Failed to write temp config file: " + e.getMessage());
- return false;
- }
- }
- String remotePath = "/data/local/tmp/statsdconfig.config";
- try {
- Utils.runCommand(null, sLogger, "adb", "push", configLocation, remotePath);
- Utils.runCommand(null, sLogger, "adb", "shell", "cat", remotePath, "|",
- Utils.CMD_UPDATE_CONFIG, Utils.SHELL_UID, String.valueOf(configId));
- } catch (InterruptedException | IOException e) {
- sLogger.severe("Failed to update config: " + e.getMessage());
- return false;
- }
- return true;
- }
-
- // get-data [CONFIG_ID] [--clear] [--binary] [--no-uid-map]
- private static boolean cmdGetData(String[] args, int idx, String deviceSerial) {
- boolean binary = contains(args, idx + 1, BINARY_FLAG);
- boolean noUidMap = contains(args, idx + 1, NO_UID_MAP_FLAG);
- boolean clearData = contains(args, idx + 1, CLEAR_DATA);
-
- // Get CONFIG_ID
- int argCount = args.length - 1 - idx; // Used up one for get-data.
- if (binary) argCount--;
- if (noUidMap) argCount--;
- if (clearData) argCount--;
- long configId;
- try {
- configId = getConfigId(argCount < 1, args, idx + 1);
- } catch (NumberFormatException e) {
- sLogger.severe("Invalid config id provided.");
- printHelp();
- return false;
- }
- sLogger.fine(String.format("cmdGetData with %d %b %b %b",
- configId, clearData, binary, noUidMap));
-
- // Get the StatsLog
- // Even if the args request no modifications, we still parse it to make sure it's valid.
- ConfigMetricsReportList reportList;
- try {
- reportList = Utils.getReportList(configId, clearData, true /* SHELL_UID */, sLogger,
- deviceSerial);
- } catch (IOException | InterruptedException e) {
- sLogger.severe("Failed to get report list: " + e.getMessage());
- return false;
- }
- if (noUidMap) {
- ConfigMetricsReportList.Builder builder
- = ConfigMetricsReportList.newBuilder(reportList);
- // Clear the reports, then add them back without their UidMap.
- builder.clearReports();
- for (ConfigMetricsReport report : reportList.getReportsList()) {
- builder.addReports(ConfigMetricsReport.newBuilder(report).clearUidMap());
- }
- reportList = builder.build();
- }
-
- if (!binary) {
- sLogger.info(reportList.toString());
- } else {
- try {
- System.out.write(reportList.toByteArray());
- } catch (IOException e) {
- sLogger.severe("Failed to output binary statslog proto: "
- + e.getMessage());
- return false;
- }
- }
- return true;
- }
-
- // clear [CONFIG_ID]
- private static boolean cmdClear(String[] args, int idx, String deviceSerial) {
- // Get CONFIG_ID
- long configId;
- try {
- configId = getConfigId(false, args, idx + 1);
- } catch (NumberFormatException e) {
- sLogger.severe("Invalid config id provided.");
- printHelp();
- return false;
- }
- sLogger.fine(String.format("cmdClear with %d", configId));
-
- try {
- Utils.getReportList(configId, true /* clearData */, true /* SHELL_UID */, sLogger,
- deviceSerial);
- } catch (IOException | InterruptedException e) {
- sLogger.severe("Failed to get report list: " + e.getMessage());
- return false;
- }
- return true;
- }
-
- // remove [CONFIG_ID]
- private static boolean cmdRemove(String[] args, int idx) {
- // Get CONFIG_ID
- long configId;
- try {
- configId = getConfigId(false, args, idx + 1);
- } catch (NumberFormatException e) {
- sLogger.severe("Invalid config id provided.");
- printHelp();
- return false;
- }
- sLogger.fine(String.format("cmdRemove with %d", configId));
-
- try {
- Utils.runCommand(null, sLogger, "adb", "shell", Utils.CMD_REMOVE_CONFIG,
- Utils.SHELL_UID, String.valueOf(configId));
- } catch (InterruptedException | IOException e) {
- sLogger.severe("Failed to remove config: " + e.getMessage());
- return false;
- }
- return true;
- }
-
- /**
- * Searches through the array to see if it contains (precisely) the given value, starting
- * at the given firstIdx.
- */
- private static boolean contains(String[] array, int firstIdx, String value) {
- if (value == null) return false;
- if (firstIdx < 0) return false;
- for (int i = firstIdx; i < array.length; i++) {
- if (value.equals(array[i])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Gets the config id from args[idx], or returns DEFAULT_CONFIG_ID if args[idx] does not exist.
- * If justUseDefault, overrides and just uses DEFAULT_CONFIG_ID instead.
- */
- private static long getConfigId(boolean justUseDefault, String[] args, int idx)
- throws NumberFormatException {
- if (justUseDefault || args.length <= idx || idx < 0) {
- return DEFAULT_CONFIG_ID;
- }
- try {
- return Long.valueOf(args[idx]);
- } catch (NumberFormatException e) {
- sLogger.severe("Bad config id provided: " + args[idx]);
- throw e;
- }
- }
-}
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
deleted file mode 100644
index 51bcad1..0000000
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.shelltools.testdrive;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventMetric;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.PullAtomPackages;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.statsd.shelltools.Utils;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.io.Files;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class TestDrive {
-
- private static final int METRIC_ID_BASE = 1111;
- private static final long ATOM_MATCHER_ID_BASE = 1234567;
- private static final long APP_BREADCRUMB_MATCHER_ID = 1111111;
- private static final int PULL_ATOM_START = 10000;
- private static final int MAX_PLATFORM_ATOM_TAG = 100000;
- private static final int VENDOR_PULLED_ATOM_START_TAG = 150000;
- private static final long CONFIG_ID = 54321;
- private static final String[] ALLOWED_LOG_SOURCES = {
- "AID_GRAPHICS",
- "AID_INCIDENTD",
- "AID_STATSD",
- "AID_RADIO",
- "com.android.systemui",
- "com.android.vending",
- "AID_SYSTEM",
- "AID_ROOT",
- "AID_BLUETOOTH",
- "AID_LMKD",
- "com.android.managedprovisioning",
- "AID_MEDIA",
- "AID_NETWORK_STACK",
- "com.google.android.providers.media.module",
- };
- private static final String[] DEFAULT_PULL_SOURCES = {
- "AID_SYSTEM",
- "AID_RADIO"
- };
- private static final Logger LOGGER = Logger.getLogger(TestDrive.class.getName());
-
- @VisibleForTesting
- String mDeviceSerial = null;
- @VisibleForTesting
- Dumper mDumper = new BasicDumper();
-
- public static void main(String[] args) {
- final Configuration configuration = new Configuration();
- final TestDrive testDrive = new TestDrive();
- Utils.setUpLogger(LOGGER, false);
-
- if (!testDrive.processArgs(configuration, args,
- Utils.getDeviceSerials(LOGGER), Utils.getDefaultDevice(LOGGER))) {
- return;
- }
-
- final ConfigMetricsReportList reports = testDrive.testDriveAndGetReports(
- configuration.createConfig(), configuration.hasPulledAtoms(),
- configuration.hasPushedAtoms());
- if (reports != null) {
- configuration.dumpMetrics(reports, testDrive.mDumper);
- }
- }
-
- boolean processArgs(Configuration configuration, String[] args, List<String> connectedDevices,
- String defaultDevice) {
- if (args.length < 1) {
- LOGGER.severe("Usage: ./test_drive [-one] "
- + "[-p additional_allowed_package] "
- + "[-s DEVICE_SERIAL_NUMBER] "
- + "<atomId1> <atomId2> ... <atomIdN>");
- return false;
- }
-
- int first_arg = 0;
- // Consume all flags, which must precede all atoms
- for (; first_arg < args.length; ++first_arg) {
- String arg = args[first_arg];
- int remaining_args = args.length - first_arg;
- if (remaining_args >= 2 && arg.equals("-one")) {
- LOGGER.info("Creating one event metric to catch all pushed atoms.");
- configuration.mOnePushedAtomEvent = true;
- } else if (remaining_args >= 2 && arg.equals("-terse")) {
- LOGGER.info("Terse output format.");
- mDumper = new TerseDumper();
- } else if (remaining_args >= 3 && arg.equals("-p")) {
- configuration.mAdditionalAllowedPackage = args[++first_arg];
- } else if (remaining_args >= 3 && arg.equals("-s")) {
- mDeviceSerial = args[++first_arg];
- } else {
- break; // Found the atom list
- }
- }
-
- mDeviceSerial = Utils.chooseDevice(mDeviceSerial, connectedDevices, defaultDevice, LOGGER);
- if (mDeviceSerial == null) {
- return false;
- }
-
- for ( ; first_arg < args.length; ++first_arg) {
- String atom = args[first_arg];
- try {
- configuration.addAtom(Integer.valueOf(atom));
- } catch (NumberFormatException e) {
- LOGGER.severe("Bad atom id provided: " + atom);
- }
- }
-
- return configuration.hasPulledAtoms() || configuration.hasPushedAtoms();
- }
-
- private ConfigMetricsReportList testDriveAndGetReports(StatsdConfig config,
- boolean hasPulledAtoms, boolean hasPushedAtoms) {
- if (config == null) {
- LOGGER.severe("Failed to create valid config.");
- return null;
- }
-
- String remoteConfigPath = null;
- try {
- remoteConfigPath = pushConfig(config, mDeviceSerial);
- LOGGER.info("Pushed the following config to statsd on device '" + mDeviceSerial
- + "':");
- LOGGER.info(config.toString());
- if (hasPushedAtoms) {
- LOGGER.info("Now please play with the device to trigger the event.");
- }
- if (!hasPulledAtoms) {
- LOGGER.info(
- "All events should be dumped after 1 min ...");
- Thread.sleep(60_000);
- } else {
- LOGGER.info("All events should be dumped after 1.5 minutes ...");
- Thread.sleep(15_000);
- Utils.logAppBreadcrumb(0, 0, LOGGER, mDeviceSerial);
- Thread.sleep(75_000);
- }
- return Utils.getReportList(CONFIG_ID, true, false, LOGGER,
- mDeviceSerial);
- } catch (Exception e) {
- LOGGER.log(Level.SEVERE, "Failed to test drive: " + e.getMessage(), e);
- } finally {
- removeConfig(mDeviceSerial);
- if (remoteConfigPath != null) {
- try {
- Utils.runCommand(null, LOGGER,
- "adb", "-s", mDeviceSerial, "shell", "rm",
- remoteConfigPath);
- } catch (Exception e) {
- LOGGER.log(Level.WARNING,
- "Unable to remove remote config file: " + remoteConfigPath, e);
- }
- }
- }
- return null;
- }
-
- static class Configuration {
- boolean mOnePushedAtomEvent = false;
- @VisibleForTesting
- Set<Integer> mPushedAtoms = new TreeSet<>();
- @VisibleForTesting
- Set<Integer> mPulledAtoms = new TreeSet<>();
- @VisibleForTesting
- String mAdditionalAllowedPackage = null;
- private final Set<Long> mTrackedMetrics = new HashSet<>();
-
- private void dumpMetrics(ConfigMetricsReportList reportList, Dumper dumper) {
- // We may get multiple reports. Take the last one.
- ConfigMetricsReport report = reportList.getReports(reportList.getReportsCount() - 1);
- for (StatsLogReport statsLog : report.getMetricsList()) {
- if (isTrackedMetric(statsLog.getMetricId())) {
- dumper.dump(statsLog);
- }
- }
- }
-
- boolean isTrackedMetric(long metricId) {
- return mTrackedMetrics.contains(metricId);
- }
-
- static boolean isPulledAtom(int atomId) {
- return atomId >= PULL_ATOM_START && atomId <= MAX_PLATFORM_ATOM_TAG
- || atomId >= VENDOR_PULLED_ATOM_START_TAG;
- }
-
- void addAtom(Integer atom) {
- if (Atom.getDescriptor().findFieldByNumber(atom) == null) {
- LOGGER.severe("No such atom found: " + atom);
- return;
- }
- if (isPulledAtom(atom)) {
- mPulledAtoms.add(atom);
- } else {
- mPushedAtoms.add(atom);
- }
- }
-
- private boolean hasPulledAtoms() {
- return !mPulledAtoms.isEmpty();
- }
-
- private boolean hasPushedAtoms() {
- return !mPushedAtoms.isEmpty();
- }
-
- StatsdConfig createConfig() {
- long metricId = METRIC_ID_BASE;
- long atomMatcherId = ATOM_MATCHER_ID_BASE;
-
- StatsdConfig.Builder builder = baseBuilder();
-
- if (hasPulledAtoms()) {
- builder.addAtomMatcher(
- createAtomMatcher(
- Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
- APP_BREADCRUMB_MATCHER_ID));
- }
-
- for (int atomId : mPulledAtoms) {
- builder.addAtomMatcher(createAtomMatcher(atomId, atomMatcherId));
- GaugeMetric.Builder gaugeMetricBuilder = GaugeMetric.newBuilder();
- gaugeMetricBuilder
- .setId(metricId)
- .setWhat(atomMatcherId)
- .setTriggerEvent(APP_BREADCRUMB_MATCHER_ID)
- .setGaugeFieldsFilter(FieldFilter.newBuilder().setIncludeAll(true).build())
- .setBucket(TimeUnit.ONE_MINUTE)
- .setSamplingType(GaugeMetric.SamplingType.FIRST_N_SAMPLES)
- .setMaxNumGaugeAtomsPerBucket(100);
- builder.addGaugeMetric(gaugeMetricBuilder.build());
- atomMatcherId++;
- mTrackedMetrics.add(metricId++);
- }
-
- // A simple atom matcher for each pushed atom.
- List<AtomMatcher> simpleAtomMatchers = new ArrayList<>();
- for (int atomId : mPushedAtoms) {
- final AtomMatcher atomMatcher = createAtomMatcher(atomId, atomMatcherId++);
- simpleAtomMatchers.add(atomMatcher);
- builder.addAtomMatcher(atomMatcher);
- }
-
- if (mOnePushedAtomEvent) {
- // Create a union event metric, using an matcher that matches all pulled atoms.
- AtomMatcher unionAtomMatcher = createUnionMatcher(simpleAtomMatchers,
- atomMatcherId);
- builder.addAtomMatcher(unionAtomMatcher);
- EventMetric.Builder eventMetricBuilder = EventMetric.newBuilder();
- eventMetricBuilder.setId(metricId).setWhat(unionAtomMatcher.getId());
- builder.addEventMetric(eventMetricBuilder.build());
- mTrackedMetrics.add(metricId++);
- } else {
- // Create multiple event metrics, one per pulled atom.
- for (AtomMatcher atomMatcher : simpleAtomMatchers) {
- EventMetric.Builder eventMetricBuilder = EventMetric.newBuilder();
- eventMetricBuilder
- .setId(metricId)
- .setWhat(atomMatcher.getId());
- builder.addEventMetric(eventMetricBuilder.build());
- mTrackedMetrics.add(metricId++);
- }
- }
-
- return builder.build();
- }
-
- private static AtomMatcher createAtomMatcher(int atomId, long matcherId) {
- AtomMatcher.Builder atomMatcherBuilder = AtomMatcher.newBuilder();
- atomMatcherBuilder
- .setId(matcherId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder().setAtomId(atomId));
- return atomMatcherBuilder.build();
- }
-
- private AtomMatcher createUnionMatcher(List<AtomMatcher> simpleAtomMatchers,
- long atomMatcherId) {
- AtomMatcher.Combination.Builder combinationBuilder =
- AtomMatcher.Combination.newBuilder();
- combinationBuilder.setOperation(StatsdConfigProto.LogicalOperation.OR);
- for (AtomMatcher matcher : simpleAtomMatchers) {
- combinationBuilder.addMatcher(matcher.getId());
- }
- AtomMatcher.Builder atomMatcherBuilder = AtomMatcher.newBuilder();
- atomMatcherBuilder.setId(atomMatcherId).setCombination(combinationBuilder.build());
- return atomMatcherBuilder.build();
- }
-
- private StatsdConfig.Builder baseBuilder() {
- ArrayList<String> allowedSources = new ArrayList<>();
- Collections.addAll(allowedSources, ALLOWED_LOG_SOURCES);
- if (mAdditionalAllowedPackage != null) {
- allowedSources.add(mAdditionalAllowedPackage);
- }
- return StatsdConfig.newBuilder()
- .addAllAllowedLogSource(allowedSources)
- .addAllDefaultPullPackages(Arrays.asList(DEFAULT_PULL_SOURCES))
- .addPullAtomPackages(PullAtomPackages.newBuilder()
- .setAtomId(Atom.GPU_STATS_GLOBAL_INFO_FIELD_NUMBER)
- .addPackages("AID_GPU_SERVICE"))
- .addPullAtomPackages(PullAtomPackages.newBuilder()
- .setAtomId(Atom.GPU_STATS_APP_INFO_FIELD_NUMBER)
- .addPackages("AID_GPU_SERVICE"))
- .addPullAtomPackages(PullAtomPackages.newBuilder()
- .setAtomId(Atom.TRAIN_INFO_FIELD_NUMBER)
- .addPackages("AID_STATSD"))
- .addPullAtomPackages(PullAtomPackages.newBuilder()
- .setAtomId(Atom.GENERAL_EXTERNAL_STORAGE_ACCESS_STATS_FIELD_NUMBER)
- .addPackages("com.google.android.providers.media.module"))
- .setHashStringsInMetricReport(false);
- }
- }
-
- interface Dumper {
- void dump(StatsLogReport report);
- }
-
- static class BasicDumper implements Dumper {
- @Override
- public void dump(StatsLogReport report) {
- System.out.println(report.toString());
- }
- }
-
- static class TerseDumper extends BasicDumper {
- @Override
- public void dump(StatsLogReport report) {
- if (report.hasGaugeMetrics()) {
- dumpGaugeMetrics(report);
- }
- if (report.hasEventMetrics()) {
- dumpEventMetrics(report);
- }
- }
- void dumpEventMetrics(StatsLogReport report) {
- final List<StatsLog.EventMetricData> data = report.getEventMetrics().getDataList();
- if (data.isEmpty()) {
- return;
- }
- long firstTimestampNanos = data.get(0).getElapsedTimestampNanos();
- for (StatsLog.EventMetricData event : data) {
- final double deltaSec = (event.getElapsedTimestampNanos() - firstTimestampNanos)
- / 1e9;
- System.out.println(
- String.format("+%.3fs: %s", deltaSec, event.getAtom().toString()));
- }
- }
- void dumpGaugeMetrics(StatsLogReport report) {
- final List<StatsLog.GaugeMetricData> data = report.getGaugeMetrics().getDataList();
- if (data.isEmpty()) {
- return;
- }
- for (StatsLog.GaugeMetricData gauge : data) {
- System.out.println(gauge.toString());
- }
- }
- }
-
- private static String pushConfig(StatsdConfig config, String deviceSerial)
- throws IOException, InterruptedException {
- File configFile = File.createTempFile("statsdconfig", ".config");
- configFile.deleteOnExit();
- Files.write(config.toByteArray(), configFile);
- String remotePath = "/data/local/tmp/" + configFile.getName();
- Utils.runCommand(null, LOGGER, "adb", "-s", deviceSerial,
- "push", configFile.getAbsolutePath(), remotePath);
- Utils.runCommand(null, LOGGER, "adb", "-s", deviceSerial,
- "shell", "cat", remotePath, "|", Utils.CMD_UPDATE_CONFIG,
- String.valueOf(CONFIG_ID));
- return remotePath;
- }
-
- private static void removeConfig(String deviceSerial) {
- try {
- Utils.runCommand(null, LOGGER, "adb", "-s", deviceSerial,
- "shell", Utils.CMD_REMOVE_CONFIG, String.valueOf(CONFIG_ID));
- } catch (Exception e) {
- LOGGER.severe("Failed to remove config: " + e.getMessage());
- }
- }
-}
diff --git a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java b/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java
deleted file mode 100644
index b1cc60f..0000000
--- a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.statsd.shelltools.testdrive;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Tests for {@link TestDrive}
- */
-public class ConfigurationTest {
-
- private StatsdConfigProto.AtomMatcher findAndRemoveAtomMatcherById(
- List<StatsdConfigProto.AtomMatcher> atomMatchers, long id) {
- int numMatches = 0;
- StatsdConfigProto.AtomMatcher match = null;
- for (StatsdConfigProto.AtomMatcher atomMatcher : atomMatchers) {
- if (id == atomMatcher.getId()) {
- ++numMatches;
- match = atomMatcher;
- }
- }
- if (numMatches == 1) {
- atomMatchers.remove(match);
- return match;
- }
- return null; // Too many, or not found
- }
-
- private final TestDrive.Configuration mConfiguration = new TestDrive.Configuration();
-
- @Test
- public void testOnePushed() {
- final int atom = 90;
- assertFalse(TestDrive.Configuration.isPulledAtom(atom));
- mConfiguration.addAtom(atom);
- StatsdConfig config = mConfiguration.createConfig();
-
- //event_metric {
- // id: 1111
- // what: 1234567
- //}
- //atom_matcher {
- // id: 1234567
- // simple_atom_matcher {
- // atom_id: 90
- // }
- //}
-
- assertEquals(1, config.getEventMetricCount());
- assertEquals(0, config.getGaugeMetricCount());
-
- assertTrue(mConfiguration.isTrackedMetric(config.getEventMetric(0).getId()));
-
- final List<StatsdConfigProto.AtomMatcher> atomMatchers =
- new ArrayList<>(config.getAtomMatcherList());
- assertEquals(atom,
- findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(0).getWhat())
- .getSimpleAtomMatcher().getAtomId());
- assertEquals(0, atomMatchers.size());
- }
-
- @Test
- public void testOnePulled() {
- final int atom = 10022;
- assertTrue(TestDrive.Configuration.isPulledAtom(atom));
- mConfiguration.addAtom(atom);
- StatsdConfig config = mConfiguration.createConfig();
-
- //gauge_metric {
- // id: 1111
- // what: 1234567
- // gauge_fields_filter {
- // include_all: true
- // }
- // bucket: ONE_MINUTE
- // sampling_type: FIRST_N_SAMPLES
- // max_num_gauge_atoms_per_bucket: 100
- // trigger_event: 1111111
- //}
- //atom_matcher {
- // id: 1111111
- // simple_atom_matcher {
- // atom_id: 47
- // }
- //}
- //atom_matcher {
- // id: 1234567
- // simple_atom_matcher {
- // atom_id: 10022
- // }
- //}
-
- assertEquals(0, config.getEventMetricCount());
- assertEquals(1, config.getGaugeMetricCount());
-
- assertTrue(mConfiguration.isTrackedMetric(config.getGaugeMetric(0).getId()));
-
- final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0);
- assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll());
-
- final List<StatsdConfigProto.AtomMatcher> atomMatchers =
- new ArrayList<>(config.getAtomMatcherList());
- assertEquals(atom,
- findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat())
- .getSimpleAtomMatcher().getAtomId());
- assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
- findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent())
- .getSimpleAtomMatcher().getAtomId());
- assertEquals(0, atomMatchers.size());
- }
-
- @Test
- public void testOnePulledTwoPushed() {
- final int pulledAtom = 10022;
- assertTrue(TestDrive.Configuration.isPulledAtom(pulledAtom));
- mConfiguration.addAtom(pulledAtom);
-
- Integer[] pushedAtoms = new Integer[]{244, 245};
- for (int atom : pushedAtoms) {
- assertFalse(TestDrive.Configuration.isPulledAtom(atom));
- mConfiguration.addAtom(atom);
- }
- StatsdConfig config = mConfiguration.createConfig();
-
- // event_metric {
- // id: 1111
- // what: 1234567
- // }
- // event_metric {
- // id: 1112
- // what: 1234568
- // }
- // gauge_metric {
- // id: 1114
- // what: 1234570
- // gauge_fields_filter {
- // include_all: true
- // }
- // bucket: ONE_MINUTE
- // sampling_type: FIRST_N_SAMPLES
- // max_num_gauge_atoms_per_bucket: 100
- // trigger_event: 1111111
- // }
- // atom_matcher {
- // id: 1111111
- // simple_atom_matcher {
- // atom_id: 47
- // }
- // }
- // atom_matcher {
- // id: 1234567
- // simple_atom_matcher {
- // atom_id: 244
- // }
- // }
- // atom_matcher {
- // id: 1234568
- // simple_atom_matcher {
- // atom_id: 245
- // }
- // }
- // atom_matcher {
- // id: 1234570
- // simple_atom_matcher {
- // atom_id: 10022
- // }
- // }
-
- assertEquals(2, config.getEventMetricCount());
- assertEquals(1, config.getGaugeMetricCount());
-
- final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0);
- assertTrue(mConfiguration.isTrackedMetric(gaugeMetric.getId()));
- assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll());
- for (StatsdConfigProto.EventMetric eventMetric : config.getEventMetricList()) {
- assertTrue(mConfiguration.isTrackedMetric(eventMetric.getId()));
- }
-
- final List<StatsdConfigProto.AtomMatcher> atomMatchers =
- new ArrayList<>(config.getAtomMatcherList());
-
- assertEquals(pulledAtom, findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat())
- .getSimpleAtomMatcher().getAtomId());
- assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
- findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent())
- .getSimpleAtomMatcher().getAtomId());
-
- Integer[] actualAtoms = new Integer[]{
- findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(0).getWhat())
- .getSimpleAtomMatcher().getAtomId(),
- findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(1).getWhat())
- .getSimpleAtomMatcher().getAtomId()};
- Arrays.sort(actualAtoms);
- assertArrayEquals(pushedAtoms, actualAtoms);
-
- assertEquals(0, atomMatchers.size());
- }
-
- @Test
- public void testOnePulledTwoPushedTogether() {
- mConfiguration.mOnePushedAtomEvent = true; // Use one event grabbing all pushed atoms
-
- final int pulledAtom = 10022;
- assertTrue(TestDrive.Configuration.isPulledAtom(pulledAtom));
- mConfiguration.addAtom(pulledAtom);
-
- Integer[] pushedAtoms = new Integer[]{244, 245};
- for (int atom : pushedAtoms) {
- assertFalse(TestDrive.Configuration.isPulledAtom(atom));
- mConfiguration.addAtom(atom);
- }
- StatsdConfig config = mConfiguration.createConfig();
-
- // event_metric {
- // id: 1112
- // what: 1234570
- // }
- // gauge_metric {
- // id: 1111
- // what: 1234567
- // gauge_fields_filter {
- // include_all: true
- // }
- // bucket: ONE_MINUTE
- // sampling_type: FIRST_N_SAMPLES
- // max_num_gauge_atoms_per_bucket: 100
- // trigger_event: 1111111
- // }
- // atom_matcher {
- // id: 1111111
- // simple_atom_matcher {
- // atom_id: 47
- // }
- // }
- // atom_matcher {
- // id: 1234567
- // simple_atom_matcher {
- // atom_id: 10022
- // }
- // }
- // atom_matcher {
- // id: 1234568
- // simple_atom_matcher {
- // atom_id: 244
- // }
- // }
- // atom_matcher {
- // id: 1234569
- // simple_atom_matcher {
- // atom_id: 245
- // }
- // }
- // atom_matcher {
- // id: 1234570
- // combination {
- // operation: OR
- // matcher: 1234568
- // matcher: 1234569
- // }
- // }
-
- assertEquals(1, config.getEventMetricCount());
- assertEquals(1, config.getGaugeMetricCount());
-
- final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0);
- assertTrue(mConfiguration.isTrackedMetric(gaugeMetric.getId()));
- assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll());
-
- StatsdConfigProto.EventMetric eventMetric = config.getEventMetric(0);
- assertTrue(mConfiguration.isTrackedMetric(eventMetric.getId()));
-
- final List<StatsdConfigProto.AtomMatcher> atomMatchers =
- new ArrayList<>(config.getAtomMatcherList());
-
- assertEquals(pulledAtom, findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat())
- .getSimpleAtomMatcher().getAtomId());
- assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
- findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent())
- .getSimpleAtomMatcher().getAtomId());
-
- StatsdConfigProto.AtomMatcher unionMatcher = findAndRemoveAtomMatcherById(atomMatchers,
- eventMetric.getWhat());
- assertNotNull(unionMatcher.getCombination());
- assertEquals(2, unionMatcher.getCombination().getMatcherCount());
-
- Integer[] actualAtoms = new Integer[]{
- findAndRemoveAtomMatcherById(atomMatchers,
- unionMatcher.getCombination().getMatcher(0))
- .getSimpleAtomMatcher().getAtomId(),
- findAndRemoveAtomMatcherById(atomMatchers,
- unionMatcher.getCombination().getMatcher(1))
- .getSimpleAtomMatcher().getAtomId()};
- Arrays.sort(actualAtoms);
- assertArrayEquals(pushedAtoms, actualAtoms);
-
- assertEquals(0, atomMatchers.size());
- }
-}
diff --git a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java b/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java
deleted file mode 100644
index 363fac0..0000000
--- a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.statsd.shelltools.testdrive;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Tests for {@link TestDrive}
- */
-@RunWith(Parameterized.class)
-public class TestDriveTest {
- /**
- * Expected results of a single iteration of the paramerized test.
- */
- static class Expect {
- public boolean success;
- public Integer[] atoms;
- public boolean onePushedAtomEvent = false;
- public String extraPackage = null;
- public String target;
- public boolean terse = false;
-
- static Expect success(Integer... atoms) {
- return new Expect(true, atoms,
- TARGET);
- }
- Expect(boolean success, Integer[] atoms, String target) {
- this.success = success;
- this.atoms = atoms;
- this.target = target;
- }
- static final Expect FAILURE = new Expect(false, null, null);
- Expect onePushedAtomEvent() {
- this.onePushedAtomEvent = true;
- return this;
- }
- Expect extraPackage() {
- this.extraPackage = TestDriveTest.PACKAGE;
- return this;
- }
- Expect terse() {
- this.terse = true;
- return this;
- }
- }
-
- @Parameterized.Parameter(0)
- public String[] mArgs;
-
- @Parameterized.Parameter(1)
- public List<String> mConnectedDevices;
-
- @Parameterized.Parameter(2)
- public String mDefaultDevice;
-
- @Parameterized.Parameter(3)
- public Expect mExpect;
-
- private static final String TARGET = "target";
- private static final List<String> TARGET_AND_OTHER = Arrays.asList("otherDevice",
- TARGET);
- private static final List<String> TWO_OTHER_DEVICES = Arrays.asList(
- "other1", "other2");
- private static final List<String> TARGET_ONLY = Collections.singletonList(TARGET);
- private static final List<String> NOT_TARGET = Collections.singletonList("other");
- private static final List<String> NO_DEVICES = Collections.emptyList();
- private static final String PACKAGE = "extraPackage";
-
- @Parameterized.Parameters
- public static Collection<Object[]> data() {
- return Arrays.asList(
- new Object[]{new String[]{}, null, null,
- Expect.FAILURE}, // Usage explanation
- new Object[]{new String[]{"244", "245"}, null, null,
- Expect.FAILURE}, // Failure looking up connected devices
- new Object[]{new String[]{"244", "245"}, NO_DEVICES, null,
- Expect.FAILURE}, // No connected devices
- new Object[]{new String[]{"-s", TARGET, "244", "245"}, NOT_TARGET, null,
- Expect.FAILURE}, // Wrong device connected
- new Object[]{new String[]{"244", "245"}, TWO_OTHER_DEVICES, null,
- Expect.FAILURE}, // Wrong devices connected
- new Object[]{new String[]{"244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245)}, // If only one device connected, guess that one
- new Object[]{new String[]{"244", "not_an_atom"}, TARGET_ONLY, null,
- Expect.success(244)}, // Ignore non-atoms
- new Object[]{new String[]{"not_an_atom"}, TARGET_ONLY, null,
- Expect.FAILURE}, // Require at least one atom
- new Object[]{new String[]{"244", "245"}, TWO_OTHER_DEVICES, TARGET,
- Expect.FAILURE}, // ANDROID_SERIAL specifies non-connected target
- new Object[]{new String[]{"244", "245"}, TARGET_AND_OTHER, TARGET,
- Expect.success(244, 245)}, // ANDROID_SERIAL specifies a valid target
- new Object[]{new String[]{"244", "245"}, TARGET_AND_OTHER, null,
- Expect.FAILURE}, // Two connected devices, no indication of which to use
- new Object[]{new String[]{"-one", "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).onePushedAtomEvent()},
- new Object[]{new String[]{"-terse", "-one", "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).onePushedAtomEvent().terse()},
- new Object[]{new String[]{"-one", "-terse", "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).onePushedAtomEvent().terse()},
- new Object[]{new String[]{"-p", PACKAGE, "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).extraPackage()},
- new Object[]{new String[]{"-p", PACKAGE, "-one", "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
- new Object[]{new String[]{"-one", "-p", PACKAGE, "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
- new Object[]{new String[]{"-s", TARGET, "-one", "-p", PACKAGE, "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
- new Object[]{new String[]{"-one", "-s", TARGET, "-p", PACKAGE, "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
- new Object[]{new String[]{"-one", "-p", PACKAGE, "-s", TARGET, "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
- new Object[]{new String[]{"-terse", "-one", "-p", PACKAGE, "-s", TARGET,
- "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()},
- new Object[]{new String[]{"-one", "-terse", "-p", PACKAGE, "-s", TARGET,
- "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()},
- new Object[]{new String[]{"-one", "-p", PACKAGE, "-terse", "-s", TARGET,
- "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()},
- new Object[]{new String[]{"-one", "-p", PACKAGE, "-s", TARGET, "-terse",
- "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()}
- );
- }
-
- private final TestDrive.Configuration mConfiguration = new TestDrive.Configuration();
- private final TestDrive mTestDrive = new TestDrive();
-
- private static Integer[] collectAtoms(TestDrive.Configuration configuration) {
- Integer[] result = new Integer[configuration.mPulledAtoms.size()
- + configuration.mPushedAtoms.size()];
- int result_index = 0;
- for (Integer atom : configuration.mPushedAtoms) {
- result[result_index++] = atom;
- }
- for (Integer atom : configuration.mPulledAtoms) {
- result[result_index++] = atom;
- }
- Arrays.sort(result);
- return result;
- }
-
- @Test
- public void testProcessArgs() {
- boolean result = mTestDrive.processArgs(mConfiguration, mArgs, mConnectedDevices,
- mDefaultDevice);
- if (mExpect.success) {
- assertTrue(result);
- assertArrayEquals(mExpect.atoms, collectAtoms(mConfiguration));
- assertEquals(mExpect.onePushedAtomEvent, mConfiguration.mOnePushedAtomEvent);
- assertEquals(mExpect.target, mTestDrive.mDeviceSerial);
- if (mExpect.terse) {
- assertEquals(TestDrive.TerseDumper.class, mTestDrive.mDumper.getClass());
- } else {
- assertEquals(TestDrive.BasicDumper.class, mTestDrive.mDumper.getClass());
- }
- } else {
- assertFalse(result);
- }
- }
-}
diff --git a/cmds/statsd/tools/localtools/testdrive_manifest.txt b/cmds/statsd/tools/localtools/testdrive_manifest.txt
deleted file mode 100644
index 625ebfa..0000000
--- a/cmds/statsd/tools/localtools/testdrive_manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-class: com.android.statsd.shelltools.testdrive.TestDrive
diff --git a/core/java/android/annotation/SystemApi.java b/core/java/android/annotation/SystemApi.java
index 4ac0098..a468439 100644
--- a/core/java/android/annotation/SystemApi.java
+++ b/core/java/android/annotation/SystemApi.java
@@ -23,7 +23,6 @@
import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.TYPE;
-import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@@ -41,7 +40,6 @@
*/
@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE})
@Retention(RetentionPolicy.RUNTIME)
-@Repeatable(SystemApi.Container.class) // TODO(b/146727827): make this non-repeatable
public @interface SystemApi {
enum Client {
/**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 1059a6f..3c9e5a53 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -3757,7 +3757,7 @@
* running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
public @RunningAppProcessInfo.Importance int getPackageImportance(String packageName) {
try {
@@ -3777,7 +3777,7 @@
* running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
public @RunningAppProcessInfo.Importance int getUidImportance(int uid) {
try {
@@ -3794,7 +3794,7 @@
* {@link #addOnUidImportanceListener}.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public interface OnUidImportanceListener {
/**
* The importance if a given uid has changed. Will be one of the importance
@@ -3825,7 +3825,7 @@
* {@link android.Manifest.permission#PACKAGE_USAGE_STATS}.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
public void addOnUidImportanceListener(OnUidImportanceListener listener,
@RunningAppProcessInfo.Importance int importanceCutpoint) {
@@ -3854,7 +3854,7 @@
* @throws IllegalArgumentException If the listener is not registered.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
public void removeOnUidImportanceListener(OnUidImportanceListener listener) {
synchronized (this) {
@@ -3996,7 +3996,7 @@
* @see #forceStopPackageAsUser(String, int)
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.FORCE_STOP_PACKAGES)
public void forceStopPackage(String packageName) {
forceStopPackageAsUser(packageName, mContext.getUserId());
@@ -4335,7 +4335,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
public boolean switchUser(@NonNull UserHandle user) {
if (user == null) {
@@ -4768,7 +4767,7 @@
*
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.FORCE_STOP_PACKAGES)
public void killProcessesWhenImperceptible(@NonNull int[] pids, @NonNull String reason) {
try {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 0a6827c..fb87a58 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -447,7 +447,6 @@
* state the more important the UID is for the user.
* @hide
*/
- @TestApi
@SystemApi
public static final int UID_STATE_PERSISTENT = 100;
@@ -456,7 +455,6 @@
* state the more important the UID is for the user.
* @hide
*/
- @TestApi
@SystemApi
public static final int UID_STATE_TOP = 200;
@@ -468,7 +466,6 @@
* @hide
* @deprecated
*/
- @TestApi
@SystemApi
@Deprecated
public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
@@ -478,7 +475,6 @@
* state the more important the UID is for the user.
* @hide
*/
- @TestApi
@SystemApi
public static final int UID_STATE_FOREGROUND_SERVICE = 400;
@@ -487,7 +483,6 @@
* state the more important the UID is for the user.
* @hide
*/
- @TestApi
@SystemApi
public static final int UID_STATE_FOREGROUND = 500;
@@ -503,7 +498,6 @@
* state the more important the UID is for the user.
* @hide
*/
- @TestApi
@SystemApi
public static final int UID_STATE_BACKGROUND = 600;
@@ -512,7 +506,6 @@
* state the more important the UID is for the user.
* @hide
*/
- @TestApi
@SystemApi
public static final int UID_STATE_CACHED = 700;
@@ -590,7 +583,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int OP_FLAG_SELF = 0x1;
@@ -601,7 +593,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int OP_FLAG_TRUSTED_PROXY = 0x2;
@@ -612,7 +603,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4;
@@ -623,7 +613,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int OP_FLAG_TRUSTED_PROXIED = 0x8;
@@ -634,7 +623,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10;
@@ -646,7 +634,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int OP_FLAGS_ALL =
OP_FLAG_SELF
@@ -1143,7 +1130,7 @@
public static final String OPSTR_GET_USAGE_STATS
= "android:get_usage_stats";
/** Activate a VPN connection without user intervention. @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_ACTIVATE_VPN
= "android:activate_vpn";
/** Allows an application to read the user's contacts data. */
@@ -1225,7 +1212,7 @@
public static final String OPSTR_WRITE_SETTINGS
= "android:write_settings";
/** @hide Get device accounts. */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_GET_ACCOUNTS
= "android:get_accounts";
public static final String OPSTR_READ_PHONE_NUMBERS
@@ -1234,7 +1221,7 @@
public static final String OPSTR_PICTURE_IN_PICTURE
= "android:picture_in_picture";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_INSTANT_APP_START_FOREGROUND
= "android:instant_app_start_foreground";
/** Answer incoming phone calls */
@@ -1244,129 +1231,129 @@
* Accept call handover
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_ACCEPT_HANDOVER
= "android:accept_handover";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_GPS = "android:gps";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_VIBRATE = "android:vibrate";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_WRITE_SMS = "android:write_sms";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
"android:receive_emergency_broadcast";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
"android:audio_notification_volume";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
"android:audio_accessibility_volume";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
"android:bind_accessibility_service";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
/** @hide */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
/** @hide */
public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
@@ -1382,25 +1369,25 @@
"android:sms_financial_transactions";
/** @hide Read media of audio type. */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
/** @hide Write media of audio type. */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
/** @hide Read media of video type. */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
/** @hide Write media of video type. */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
/** @hide Read media of image type. */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
/** @hide Write media of image type. */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
/** @hide Has a legacy (non-isolated) view of storage. */
- @SystemApi @TestApi
+ @SystemApi
public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
/** @hide Read location metadata from media */
public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location";
@@ -1414,7 +1401,6 @@
public static final String OPSTR_QUERY_ALL_PACKAGES = "android:query_all_packages";
/** @hide Access all external storage */
@SystemApi
- @TestApi
public static final String OPSTR_MANAGE_EXTERNAL_STORAGE =
"android:manage_external_storage";
@@ -2593,7 +2579,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static int opToDefaultMode(@NonNull String appOp) {
return opToDefaultMode(strOpToOp(appOp));
@@ -2683,7 +2668,6 @@
* Class holding all of the operation information associated with an app.
* @hide
*/
- @TestApi
@SystemApi
public static final class PackageOps implements Parcelable {
private final String mPackageName;
@@ -2762,7 +2746,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
// @DataClass(genHiddenConstructor = true, genHiddenCopyConstructor = true)
// genHiddenCopyConstructor does not work for @hide @SystemApi classes
@@ -3130,7 +3113,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@Immutable
// @DataClass(genHiddenConstructor = true) codegen verifier is broken
@@ -3704,7 +3686,6 @@
*
* @hide
*/
- @TestApi
@Immutable
@SystemApi
// @DataClass(genHiddenConstructor = true) codegen verifier is broken
@@ -4382,7 +4363,6 @@
* @hide
*/
@Immutable
- @TestApi
@SystemApi
public static final class HistoricalOpsRequest {
private final int mUid;
@@ -4413,7 +4393,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final class Builder {
private int mUid = Process.INVALID_UID;
@@ -4551,7 +4530,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final class HistoricalOps implements Parcelable {
private long mBeginTimeMillis;
@@ -4988,7 +4966,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final class HistoricalUidOps implements Parcelable {
private final int mUid;
@@ -5242,7 +5219,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final class HistoricalPackageOps implements Parcelable {
private final @NonNull String mPackageName;
@@ -5573,7 +5549,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
/* codegen verifier cannot deal with nested class parameters
@DataClass(genHiddenConstructor = true,
@@ -5884,7 +5859,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final class HistoricalOp implements Parcelable {
private final int mOp;
@@ -6521,7 +6495,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
@@ -6556,7 +6529,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
@@ -6665,7 +6637,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
public void setUidMode(@NonNull String appOp, int uid, @Mode int mode) {
try {
@@ -6719,7 +6690,6 @@
* be changed.
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
public void setMode(@NonNull String op, int uid, @Nullable String packageName,
@@ -8661,7 +8631,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
public @Nullable RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage() {
try {
@@ -8676,7 +8645,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static String[] getOpStrs() {
return Arrays.copyOf(sOpToString, sOpToString.length);
}
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index cf2f769..6ce3299 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -134,7 +134,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int USER_LOCKED_SOUND = 0x00000020;
/**
@@ -391,7 +390,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void setBlockable(boolean blockable) {
mBlockableSystem = blockable;
}
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index eef9c02..c662635 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1337,7 +1337,6 @@
* @hide
*/
@SystemApi
- @TestApi
public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) {
INotificationManager service = getService();
try {
@@ -1373,7 +1372,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @NonNull @Adjustment.Keys List<String> getAllowedAssistantAdjustments() {
INotificationManager service = getService();
try {
@@ -1506,7 +1504,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void setNotificationAssistantAccessGranted(@Nullable ComponentName assistant,
boolean granted) {
INotificationManager service = getService();
@@ -1529,7 +1526,6 @@
/** @hide */
@SystemApi
- @TestApi
public @Nullable ComponentName getAllowedNotificationAssistant() {
INotificationManager service = getService();
try {
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 4cba6ea..7477899 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -1043,7 +1042,6 @@
}
}
- @TestApi
public final boolean applyConfigurationToResources(@NonNull Configuration config,
@Nullable CompatibilityInfo compat) {
synchronized(this) {
diff --git a/core/java/android/app/RuntimeAppOpAccessMessage.java b/core/java/android/app/RuntimeAppOpAccessMessage.java
index a19f815..db3ba4a 100644
--- a/core/java/android/app/RuntimeAppOpAccessMessage.java
+++ b/core/java/android/app/RuntimeAppOpAccessMessage.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,7 +31,6 @@
* @hide
*/
@Immutable
-@TestApi
@SystemApi
/*@DataClass(genConstructor = false)
@DataClass.Suppress("getOpCode")*/
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 1329fa4..1a07cc6 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -374,7 +374,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.STATUS_BAR)
public void setDisabledForSetup(boolean disabled) {
try {
@@ -422,7 +421,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.STATUS_BAR)
@NonNull
public DisableInfo getDisableInfo() {
@@ -455,7 +453,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final class DisableInfo {
private boolean mStatusBarExpansion;
@@ -488,7 +485,6 @@
* @hide
*/
@SystemApi
- @TestApi
public boolean isStatusBarExpansionDisabled() {
return mStatusBarExpansion;
}
@@ -504,7 +500,6 @@
* @hide
*/
@SystemApi
- @TestApi
public boolean isNavigateToHomeDisabled() {
return mNavigateHome;
}
@@ -520,7 +515,6 @@
* @hide
*/
@SystemApi
- @TestApi
public boolean isNotificationPeekingDisabled() {
return mNotificationPeeking;
}
@@ -536,7 +530,6 @@
* @hide
*/
@SystemApi
- @TestApi
public boolean isRecentsDisabled() {
return mRecents;
}
@@ -552,7 +545,6 @@
* @hide
*/
@SystemApi
- @TestApi
public boolean isSearchDisabled() {
return mSearch;
}
@@ -610,7 +602,6 @@
* @hide
*/
@SystemApi
- @TestApi
public boolean areAllComponentsEnabled() {
return !mStatusBarExpansion && !mNavigateHome && !mNotificationPeeking && !mRecents
&& !mSearch && !mSystemIcons && !mClock && !mNotificationIcons;
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 7c6eff1..558e222 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -314,7 +314,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED)
public void enableCarMode(@IntRange(from = 0) int priority, @EnableCarMode int flags) {
if (mService != null) {
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index c5d343d..b1c005c 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1765,7 +1765,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT)
public boolean setWallpaperComponent(ComponentName name) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 322cac8..bb837d8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1465,7 +1465,7 @@
* @see #createAdminSupportIntent(String)
* @hide
*/
- @TestApi @SystemApi
+ @SystemApi
public static final String EXTRA_RESTRICTION = "android.app.extra.RESTRICTION";
/**
@@ -2688,13 +2688,11 @@
* </ul>
*/
@SystemApi
- @TestApi
public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED =
"android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED";
/** @hide See {@link #ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED} */
@SystemApi
- @TestApi
public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED =
"android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
@@ -6682,7 +6680,6 @@
* @hide
*/
@SystemApi
- @TestApi
@SuppressLint("Doclava125")
public boolean isDeviceManaged() {
try {
@@ -10395,7 +10392,6 @@
* @hide
*/
@SystemApi
- @TestApi
@SuppressLint("Doclava125")
public @Nullable CharSequence getDeviceOwnerOrganizationName() {
try {
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 22d8c87..3e6d299 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -3,7 +3,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -36,8 +35,6 @@
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
-import com.android.internal.util.Preconditions;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -724,7 +721,6 @@
// COntent Capture.
/** @hide */
@SystemApi
- @TestApi
public ViewNode() {
}
@@ -2236,7 +2232,7 @@
ensureData();
}
Log.i(TAG, "Task id: " + mTaskId);
- Log.i(TAG, "Activity: " + (mActivityComponent != null
+ Log.i(TAG, "Activity: " + (mActivityComponent != null
? mActivityComponent.flattenToShortString()
: null));
Log.i(TAG, "Sanitize on write: " + mSanitizeOnWrite);
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 3bc043e..e199cbe 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -20,7 +20,6 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
@@ -848,7 +847,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.BACKUP)
public Intent getConfigurationIntent(String transportName) {
checkServiceBinder();
@@ -870,7 +868,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.BACKUP)
public String getDestinationString(String transportName) {
checkServiceBinder();
@@ -892,7 +889,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.BACKUP)
public Intent getDataManagementIntent(String transportName) {
checkServiceBinder();
@@ -918,7 +914,6 @@
*/
@Deprecated
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.BACKUP)
@Nullable
public String getDataManagementLabel(@NonNull String transportName) {
@@ -935,7 +930,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.BACKUP)
@Nullable
public CharSequence getDataManagementIntentLabel(@NonNull String transportName) {
diff --git a/core/java/android/app/prediction/AppPredictionContext.java b/core/java/android/app/prediction/AppPredictionContext.java
index d14238b..99fa869 100644
--- a/core/java/android/app/prediction/AppPredictionContext.java
+++ b/core/java/android/app/prediction/AppPredictionContext.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcel;
@@ -32,7 +31,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class AppPredictionContext implements Parcelable {
private final int mPredictedTargetCount;
@@ -129,7 +127,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final class Builder {
@NonNull
@@ -147,7 +144,6 @@
* @hide
*/
@SystemApi
- @TestApi
public Builder(@NonNull Context context) {
mPackageName = context.getPackageName();
}
diff --git a/core/java/android/app/prediction/AppPredictionManager.java b/core/java/android/app/prediction/AppPredictionManager.java
index ca22721..5da7aa9 100644
--- a/core/java/android/app/prediction/AppPredictionManager.java
+++ b/core/java/android/app/prediction/AppPredictionManager.java
@@ -17,7 +17,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.Context;
import java.util.Objects;
@@ -28,7 +27,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class AppPredictionManager {
private final Context mContext;
diff --git a/core/java/android/app/prediction/AppPredictionSessionId.java b/core/java/android/app/prediction/AppPredictionSessionId.java
index 876bafd..6277a7d 100644
--- a/core/java/android/app/prediction/AppPredictionSessionId.java
+++ b/core/java/android/app/prediction/AppPredictionSessionId.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,7 +29,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class AppPredictionSessionId implements Parcelable {
private final String mId;
diff --git a/core/java/android/app/prediction/AppPredictor.java b/core/java/android/app/prediction/AppPredictor.java
index 7f43640..4517c6d 100644
--- a/core/java/android/app/prediction/AppPredictor.java
+++ b/core/java/android/app/prediction/AppPredictor.java
@@ -70,7 +70,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class AppPredictor {
private static final String TAG = AppPredictor.class.getSimpleName();
diff --git a/core/java/android/app/prediction/AppTarget.java b/core/java/android/app/prediction/AppTarget.java
index 14e32b83..fef9e70 100644
--- a/core/java/android/app/prediction/AppTarget.java
+++ b/core/java/android/app/prediction/AppTarget.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.pm.ShortcutInfo;
import android.os.Parcel;
import android.os.Parcelable;
@@ -33,7 +32,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class AppTarget implements Parcelable {
private final AppTargetId mId;
@@ -190,7 +188,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final class Builder {
@NonNull
@@ -221,7 +218,6 @@
* @hide
*/
@SystemApi
- @TestApi
public Builder(@NonNull AppTargetId id, @NonNull String packageName,
@NonNull UserHandle user) {
mId = Objects.requireNonNull(id);
@@ -235,7 +231,6 @@
* @hide
*/
@SystemApi
- @TestApi
public Builder(@NonNull AppTargetId id, @NonNull ShortcutInfo info) {
mId = Objects.requireNonNull(id);
mShortcutInfo = Objects.requireNonNull(info);
diff --git a/core/java/android/app/prediction/AppTargetEvent.java b/core/java/android/app/prediction/AppTargetEvent.java
index f519145..963e750 100644
--- a/core/java/android/app/prediction/AppTargetEvent.java
+++ b/core/java/android/app/prediction/AppTargetEvent.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,7 +31,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class AppTargetEvent implements Parcelable {
/**
@@ -141,7 +139,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final class Builder {
private AppTarget mTarget;
private String mLocation;
diff --git a/core/java/android/app/prediction/AppTargetId.java b/core/java/android/app/prediction/AppTargetId.java
index 052fdc1..048e12c 100644
--- a/core/java/android/app/prediction/AppTargetId.java
+++ b/core/java/android/app/prediction/AppTargetId.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -28,7 +27,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class AppTargetId implements Parcelable {
@NonNull
@@ -40,7 +38,6 @@
* @hide
*/
@SystemApi
- @TestApi
public AppTargetId(@NonNull String id) {
mId = id;
}
diff --git a/core/java/android/app/role/OnRoleHoldersChangedListener.java b/core/java/android/app/role/OnRoleHoldersChangedListener.java
index d6f7679..5958deb 100644
--- a/core/java/android/app/role/OnRoleHoldersChangedListener.java
+++ b/core/java/android/app/role/OnRoleHoldersChangedListener.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.UserHandle;
/**
@@ -27,7 +26,6 @@
* @hide
*/
@SystemApi
-@TestApi
public interface OnRoleHoldersChangedListener {
/**
diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java
index 253c73796..fccf5ab 100644
--- a/core/java/android/app/role/RoleManager.java
+++ b/core/java/android/app/role/RoleManager.java
@@ -24,7 +24,6 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.Intent;
@@ -144,7 +143,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1;
/**
@@ -255,7 +253,6 @@
@NonNull
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
@SystemApi
- @TestApi
public List<String> getRoleHolders(@NonNull String roleName) {
return getRoleHoldersAsUser(roleName, Process.myUserHandle());
}
@@ -281,7 +278,6 @@
@NonNull
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
@SystemApi
- @TestApi
public List<String> getRoleHoldersAsUser(@NonNull String roleName, @NonNull UserHandle user) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Objects.requireNonNull(user, "user cannot be null");
@@ -315,7 +311,6 @@
*/
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
@SystemApi
- @TestApi
public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
@ManageHoldersFlags int flags, @NonNull UserHandle user,
@CallbackExecutor @NonNull Executor executor, @NonNull Consumer<Boolean> callback) {
@@ -354,7 +349,6 @@
*/
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
@SystemApi
- @TestApi
public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
@ManageHoldersFlags int flags, @NonNull UserHandle user,
@CallbackExecutor @NonNull Executor executor, @NonNull Consumer<Boolean> callback) {
@@ -392,7 +386,6 @@
*/
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
@SystemApi
- @TestApi
public void clearRoleHoldersAsUser(@NonNull String roleName, @ManageHoldersFlags int flags,
@NonNull UserHandle user, @CallbackExecutor @NonNull Executor executor,
@NonNull Consumer<Boolean> callback) {
@@ -439,7 +432,6 @@
*/
@RequiresPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS)
@SystemApi
- @TestApi
public void addOnRoleHoldersChangedListenerAsUser(@CallbackExecutor @NonNull Executor executor,
@NonNull OnRoleHoldersChangedListener listener, @NonNull UserHandle user) {
Objects.requireNonNull(executor, "executor cannot be null");
@@ -485,7 +477,6 @@
*/
@RequiresPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS)
@SystemApi
- @TestApi
public void removeOnRoleHoldersChangedListenerAsUser(
@NonNull OnRoleHoldersChangedListener listener, @NonNull UserHandle user) {
Objects.requireNonNull(listener, "listener cannot be null");
@@ -527,7 +518,6 @@
*/
@RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER)
@SystemApi
- @TestApi
public void setRoleNamesFromController(@NonNull List<String> roleNames) {
Objects.requireNonNull(roleNames, "roleNames cannot be null");
try {
@@ -558,7 +548,6 @@
*/
@RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER)
@SystemApi
- @TestApi
public boolean addRoleHolderFromController(@NonNull String roleName,
@NonNull String packageName) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
@@ -591,7 +580,6 @@
*/
@RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER)
@SystemApi
- @TestApi
public boolean removeRoleHolderFromController(@NonNull String roleName,
@NonNull String packageName) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
@@ -614,7 +602,6 @@
@NonNull
@RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER)
@SystemApi
- @TestApi
public List<String> getHeldRolesFromController(@NonNull String packageName) {
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
try {
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 85e0e08..2836325 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -19,7 +19,6 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Binder;
@@ -587,7 +586,6 @@
* @return true if connectionPolicy is set, false on error
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
@ConnectionPolicy int connectionPolicy) {
@@ -637,7 +635,6 @@
* @return connection policy of the device
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH)
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
if (VDBG) log("getConnectionPolicy(" + device + ")");
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index 19240dc..4f5c4fe 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -19,7 +19,6 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
import android.app.PendingIntent;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -276,7 +275,6 @@
* @return true if connectionPolicy is set, false on error
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
@ConnectionPolicy int connectionPolicy) {
@@ -325,7 +323,6 @@
* @return connection policy of the device
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
if (VDBG) Log.d(TAG, "getConnectionPolicy(" + device + ")");
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
index d3452ff..f356da1 100644
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -19,7 +19,6 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
@@ -276,7 +275,6 @@
* @return true if connectionPolicy is set, false on error
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
@ConnectionPolicy int connectionPolicy) {
@@ -329,7 +327,6 @@
* @return connection policy of the device
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
if (VDBG) {
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index 6e03481..48e8c1a 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -18,7 +18,6 @@
import android.Manifest;
import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Binder;
@@ -328,7 +327,6 @@
* @return true if connectionPolicy is set, false on error
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setConnectionPolicy(BluetoothDevice device,
@ConnectionPolicy int connectionPolicy) {
@@ -377,7 +375,6 @@
* @return connection policy of the device
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) {
if (VDBG) log("getConnectionPolicy(" + device + ")");
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 591a714..7059494 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -21,7 +21,6 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.app.Activity;
import android.app.Application;
import android.app.PendingIntent;
@@ -285,7 +284,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
public boolean isDeviceAssociatedForWifiConnection(
@NonNull String packageName,
diff --git a/core/java/android/content/ApexEnvironment.java b/core/java/android/content/ApexEnvironment.java
index 9f15a42..b4cc3c2 100644
--- a/core/java/android/content/ApexEnvironment.java
+++ b/core/java/android/content/ApexEnvironment.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Environment;
import android.os.UserHandle;
@@ -31,7 +30,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class ApexEnvironment {
private static final String APEX_DATA = "apexdata";
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index d0f5ec4..5af7861 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -21,7 +21,6 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.AssetFileDescriptor;
import android.database.CrossProcessCursorWrapper;
@@ -123,7 +122,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.REMOVE_TASKS)
public void setDetectNotResponding(@DurationMillisLong long timeoutMillis) {
synchronized (ContentProviderClient.class) {
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index c409613..018bcbd 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -4094,7 +4094,6 @@
* @hide
*/
@SystemApi
- @TestApi
// We can't accept an already-opened FD here, since these methods are
// rewriting actual filesystem paths
@SuppressLint("StreamFiles")
@@ -4114,7 +4113,6 @@
* @hide
*/
@SystemApi
- @TestApi
// We can't accept an already-opened FD here, since these methods are
// rewriting actual filesystem paths
@SuppressLint("StreamFiles")
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 8472144..1f8e820 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1838,7 +1838,6 @@
*/
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
@SystemApi
- @TestApi
public void startActivityAsUser(@RequiresPermission @NonNull Intent intent,
@NonNull UserHandle user) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
@@ -3953,7 +3952,6 @@
* @hide
*/
@SystemApi
- @TestApi
@SuppressLint("ServiceName")
public static final String STATUS_BAR_SERVICE = "statusbar";
@@ -4165,7 +4163,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String ETHERNET_SERVICE = "ethernet";
/**
@@ -4469,7 +4466,6 @@
* @see #getSystemService(String)
* @hide
*/
- @TestApi
@SystemApi
public static final String PERMISSION_SERVICE = "permission";
@@ -4500,7 +4496,7 @@
* @see #getSystemService(String)
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final String ROLLBACK_SERVICE = "rollback";
/**
@@ -4974,7 +4970,7 @@
* @see android.os.BugreportManager
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final String BUGREPORT_SERVICE = "bugreport";
/**
@@ -5118,7 +5114,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String APP_INTEGRITY_SERVICE = "app_integrity";
/**
@@ -5664,7 +5659,6 @@
* @hide
*/
@SystemApi
- @TestApi
@NonNull
public Context createPackageContextAsUser(
@NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user)
@@ -5683,7 +5677,6 @@
* @hide
*/
@SystemApi
- @TestApi
@NonNull
public Context createContextAsUser(@NonNull UserHandle user, @CreatePackageOptions int flags) {
if (Build.IS_ENG) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ededd0d..b457c2a 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -28,7 +28,6 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.AppGlobals;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
@@ -1747,7 +1746,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String EXTRA_ORIGINATING_UID
= "android.intent.extra.ORIGINATING_UID";
@@ -1978,7 +1976,6 @@
@RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS)
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
@SystemApi
- @TestApi
public static final String ACTION_MANAGE_DEFAULT_APP =
"android.intent.action.MANAGE_DEFAULT_APP";
@@ -1993,7 +1990,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String EXTRA_ROLE_NAME = "android.intent.extra.ROLE_NAME";
/**
@@ -2538,7 +2534,7 @@
*
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_ROLLBACK_COMMITTED =
"android.intent.action.ROLLBACK_COMMITTED";
diff --git a/core/java/android/content/integrity/AppIntegrityManager.java b/core/java/android/content/integrity/AppIntegrityManager.java
index 2869abb..0353b78 100644
--- a/core/java/android/content/integrity/AppIntegrityManager.java
+++ b/core/java/android/content/integrity/AppIntegrityManager.java
@@ -36,7 +36,6 @@
*
* @hide
*/
-@TestApi
@SystemApi
@SystemService(Context.APP_INTEGRITY_SERVICE)
public class AppIntegrityManager {
diff --git a/core/java/android/content/integrity/IntegrityFormula.java b/core/java/android/content/integrity/IntegrityFormula.java
index fc177721..d965ef5 100644
--- a/core/java/android/content/integrity/IntegrityFormula.java
+++ b/core/java/android/content/integrity/IntegrityFormula.java
@@ -19,7 +19,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.integrity.AtomicFormula.BooleanAtomicFormula;
import android.content.integrity.AtomicFormula.LongAtomicFormula;
import android.content.integrity.AtomicFormula.StringAtomicFormula;
@@ -38,7 +37,6 @@
* @hide
*/
@SystemApi
-@TestApi
@VisibleForTesting
public abstract class IntegrityFormula {
diff --git a/core/java/android/content/integrity/Rule.java b/core/java/android/content/integrity/Rule.java
index d29e6df..c421c40 100644
--- a/core/java/android/content/integrity/Rule.java
+++ b/core/java/android/content/integrity/Rule.java
@@ -21,7 +21,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -38,7 +37,6 @@
*
* @hide
*/
-@TestApi
@SystemApi
@VisibleForTesting
public final class Rule implements Parcelable {
diff --git a/core/java/android/content/integrity/RuleSet.java b/core/java/android/content/integrity/RuleSet.java
index e121ff8..b423b54 100644
--- a/core/java/android/content/integrity/RuleSet.java
+++ b/core/java/android/content/integrity/RuleSet.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import java.util.ArrayList;
import java.util.Collections;
@@ -30,7 +29,6 @@
*
* @hide
*/
-@TestApi
@SystemApi
public class RuleSet {
private final String mVersion;
diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java
index 2bdca7d..fd3d48f 100644
--- a/core/java/android/content/om/OverlayManager.java
+++ b/core/java/android/content/om/OverlayManager.java
@@ -21,7 +21,6 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
@@ -241,7 +240,6 @@
*
* @hide
*/
- @TestApi
@RequiresPermission(anyOf = {
"android.permission.INTERACT_ACROSS_USERS",
})
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index fc4ccd0..bc706b2 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1692,7 +1692,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS)
public void setGrantedRuntimePermissions(String[] permissions) {
@@ -1764,7 +1763,7 @@
* @see SessionParams#setEnableRollback(boolean, int)
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public void setEnableRollback(boolean enable) {
if (enable) {
installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
@@ -1788,7 +1787,7 @@
* @param dataPolicy the rollback data policy for this session
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public void setEnableRollback(boolean enable,
@PackageManager.RollbackDataPolicy int dataPolicy) {
if (enable) {
@@ -1811,7 +1810,7 @@
}
/** {@hide} */
- @SystemApi @TestApi
+ @SystemApi
public void setRequestDowngrade(boolean requestDowngrade) {
if (requestDowngrade) {
installFlags |= PackageManager.INSTALL_REQUEST_DOWNGRADE;
@@ -1934,7 +1933,7 @@
*
* {@hide}
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
public void setStaged() {
this.isStaged = true;
@@ -1945,7 +1944,7 @@
*
* {@hide}
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
public void setInstallAsApex() {
installFlags |= PackageManager.INSTALL_APEX;
@@ -2431,7 +2430,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public @NonNull Set<String> getWhitelistedRestrictedPermissions() {
if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0) {
@@ -2455,7 +2453,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public int getAutoRevokePermissionsMode() {
return autoRevokePermissionsMode;
@@ -2576,7 +2573,7 @@
*
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@PackageManager.RollbackDataPolicy
public int getRollbackDataPolicy() {
return rollbackDataPolicy;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 05548c7..ed77663 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -123,7 +123,6 @@
* @hide
*/
@SystemApi
- @TestApi
public interface OnPermissionsChangedListener {
/**
@@ -482,7 +481,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int MATCH_FACTORY_ONLY = 0x00200000;
/**
@@ -614,7 +612,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int MODULE_APEX_NAME = 0x00000001;
/** @hide */
@@ -3317,7 +3314,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_PERMISSION_USER_SET = 1 << 0;
/**
@@ -3328,7 +3324,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_PERMISSION_USER_FIXED = 1 << 1;
/**
@@ -3339,7 +3334,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_PERMISSION_POLICY_FIXED = 1 << 2;
/**
@@ -3356,7 +3350,6 @@
*/
@Deprecated
@SystemApi
- @TestApi
public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 1 << 3;
/**
@@ -3366,7 +3359,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_PERMISSION_SYSTEM_FIXED = 1 << 4;
/**
@@ -3387,7 +3379,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 1 << 6;
/**
@@ -3425,7 +3416,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT = 1 << 11;
@@ -3437,7 +3427,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT = 1 << 12;
@@ -3450,7 +3439,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT = 1 << 13;
@@ -3463,7 +3451,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 1 << 14;
@@ -3473,7 +3460,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_PERMISSION_GRANTED_BY_ROLE = 1 << 15;
/**
@@ -3485,7 +3471,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_PERMISSION_REVOKED_COMPAT = FLAG_PERMISSION_REVOKE_ON_UPGRADE;
/**
@@ -3495,7 +3480,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_PERMISSION_ONE_TIME = 1 << 16;
/**
@@ -4001,7 +3985,7 @@
*
* @hide
*/
- @TestApi @SystemApi
+ @SystemApi
public abstract boolean arePermissionsIndividuallyControlled();
/**
@@ -4243,7 +4227,6 @@
* @hide
*/
@NonNull
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
public abstract List<PackageInfo> getInstalledPackagesAsUser(@PackageInfoFlags int flags,
@@ -4404,7 +4387,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
public abstract void grantRuntimePermission(@NonNull String packageName,
@@ -4431,7 +4413,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
public abstract void revokeRuntimePermission(@NonNull String packageName,
@@ -4459,7 +4440,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
public void revokeRuntimePermission(@NonNull String packageName,
@@ -4478,7 +4458,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(anyOf = {
android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
@@ -4501,7 +4480,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(anyOf = {
android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
@@ -6297,7 +6275,6 @@
* @hide
*/
@Nullable
- @TestApi
@SystemApi
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
public abstract String getDefaultBrowserPackageNameAsUser(@UserIdInt int userId);
@@ -6940,7 +6917,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
public abstract void addOnPermissionsChangeListener(
@NonNull OnPermissionsChangedListener listener);
@@ -6953,7 +6929,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
public abstract void removeOnPermissionsChangeListener(
@NonNull OnPermissionsChangedListener listener);
@@ -7924,7 +7899,6 @@
* @hide
*/
@SystemApi
- @TestApi
@Nullable
public String getIncidentReportApproverPackageName() {
throw new UnsupportedOperationException(
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 70e4e6c..43632f5 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -46,7 +46,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringRes;
-import android.annotation.TestApi;
import android.apex.ApexInfo;
import android.app.ActivityTaskManager;
import android.app.ActivityThread;
@@ -2545,7 +2544,6 @@
* not compatible with this platform
* @hide Exposed for unit testing only.
*/
- @TestApi
public static int computeTargetSdkVersion(@IntRange(from = 0) int targetVers,
@Nullable String targetCode, @NonNull String[] platformSdkCodenames,
@NonNull String[] outError) {
@@ -2610,7 +2608,6 @@
* compatible with this platform
* @hide Exposed for unit testing only.
*/
- @TestApi
public static int computeMinSdkVersion(@IntRange(from = 1) int minVers,
@Nullable String minCode, @IntRange(from = 1) int platformSdkVersion,
@NonNull String[] platformSdkCodenames, @NonNull String[] outError) {
@@ -4732,7 +4729,6 @@
* AndroidManifest.xml.
* @hide Exposed for unit testing only.
*/
- @TestApi
public static int getActivityConfigChanges(int configChanges, int recreateOnConfigChanges) {
return configChanges | ((~recreateOnConfigChanges) & RECREATE_ON_CONFIG_CHANGES_MASK);
}
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 5f6befd..1903f07 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -160,7 +160,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROTECTION_FLAG_OEM = 0x4000;
/**
@@ -181,7 +180,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 0x10000;
/**
@@ -192,7 +190,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROTECTION_FLAG_WELLBEING = 0x20000;
/**
@@ -202,7 +199,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROTECTION_FLAG_DOCUMENTER = 0x40000;
/**
@@ -212,7 +208,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROTECTION_FLAG_CONFIGURATOR = 0x80000;
/**
@@ -223,7 +218,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 0x100000;
/**
@@ -234,7 +228,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROTECTION_FLAG_APP_PREDICTOR = 0x200000;
/**
@@ -245,7 +238,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROTECTION_FLAG_COMPANION = 0x800000;
/**
@@ -256,7 +248,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROTECTION_FLAG_RETAIL_DEMO = 0x1000000;
/** @hide */
@@ -340,7 +331,6 @@
* value of {@link android.R.attr#permissionFlags}.
* @hide
*/
- @TestApi
@SystemApi
public static final int FLAG_REMOVED = 1<<1;
@@ -428,7 +418,6 @@
* @hide
*/
@SystemApi
- @TestApi
public final @Nullable String backgroundPermission;
/**
diff --git a/core/java/android/content/rollback/PackageRollbackInfo.java b/core/java/android/content/rollback/PackageRollbackInfo.java
index b273cd6..278eedb 100644
--- a/core/java/android/content/rollback/PackageRollbackInfo.java
+++ b/core/java/android/content/rollback/PackageRollbackInfo.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.os.Parcel;
@@ -33,7 +32,7 @@
*
* @hide
*/
-@SystemApi @TestApi
+@SystemApi
public final class PackageRollbackInfo implements Parcelable {
private final VersionedPackage mVersionRolledBackFrom;
diff --git a/core/java/android/content/rollback/RollbackInfo.java b/core/java/android/content/rollback/RollbackInfo.java
index c09cfd5..a363718 100644
--- a/core/java/android/content/rollback/RollbackInfo.java
+++ b/core/java/android/content/rollback/RollbackInfo.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.pm.VersionedPackage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -31,7 +30,7 @@
*
* @hide
*/
-@SystemApi @TestApi
+@SystemApi
public final class RollbackInfo implements Parcelable {
/**
diff --git a/core/java/android/content/rollback/RollbackManager.java b/core/java/android/content/rollback/RollbackManager.java
index 7ebeb21..3636222 100644
--- a/core/java/android/content/rollback/RollbackManager.java
+++ b/core/java/android/content/rollback/RollbackManager.java
@@ -24,7 +24,6 @@
import android.annotation.TestApi;
import android.content.Context;
import android.content.IntentSender;
-import android.content.pm.PackageInstaller;
import android.content.pm.ParceledListSlice;
import android.content.pm.VersionedPackage;
import android.os.RemoteException;
@@ -43,7 +42,7 @@
* @see PackageInstaller.SessionParams#setEnableRollback(boolean)
* @hide
*/
-@SystemApi @TestApi
+@SystemApi
@SystemService(Context.ROLLBACK_SERVICE)
public final class RollbackManager {
private final String mCallerPackageName;
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 7dbb570..37e1280 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.hardware.camera2.params.InputConfiguration;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.SessionConfiguration;
@@ -358,7 +357,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int SESSION_OPERATION_MODE_NORMAL =
0; // ICameraDeviceUser.NORMAL_MODE;
@@ -369,7 +367,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int SESSION_OPERATION_MODE_CONSTRAINED_HIGH_SPEED =
1; // ICameraDeviceUser.CONSTRAINED_HIGH_SPEED_MODE;
@@ -380,7 +377,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int SESSION_OPERATION_MODE_VENDOR_START =
0x8000; // ICameraDeviceUser.VENDOR_MODE_START;
@@ -423,7 +419,6 @@
* @hide
*/
@SystemApi
- @TestApi
@Deprecated
public abstract void createCustomCaptureSession(
InputConfiguration inputConfig,
diff --git a/core/java/android/hardware/display/AmbientBrightnessDayStats.java b/core/java/android/hardware/display/AmbientBrightnessDayStats.java
index 26fd265..8aff911 100644
--- a/core/java/android/hardware/display/AmbientBrightnessDayStats.java
+++ b/core/java/android/hardware/display/AmbientBrightnessDayStats.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -36,7 +35,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class AmbientBrightnessDayStats implements Parcelable {
/** The localdate for which brightness stats are being tracked */
diff --git a/core/java/android/hardware/display/BrightnessChangeEvent.java b/core/java/android/hardware/display/BrightnessChangeEvent.java
index a6a44be..e2d836c 100644
--- a/core/java/android/hardware/display/BrightnessChangeEvent.java
+++ b/core/java/android/hardware/display/BrightnessChangeEvent.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,7 +31,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class BrightnessChangeEvent implements Parcelable {
/** Brightness in nits */
public final float brightness;
diff --git a/core/java/android/hardware/display/BrightnessConfiguration.java b/core/java/android/hardware/display/BrightnessConfiguration.java
index 6412a0c..d9c1063 100644
--- a/core/java/android/hardware/display/BrightnessConfiguration.java
+++ b/core/java/android/hardware/display/BrightnessConfiguration.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.pm.ApplicationInfo;
import android.os.Parcel;
import android.os.Parcelable;
@@ -44,7 +43,6 @@
/** @hide */
@SystemApi
-@TestApi
public final class BrightnessConfiguration implements Parcelable {
private static final String TAG_BRIGHTNESS_CURVE = "brightness-curve";
private static final String TAG_BRIGHTNESS_POINT = "brightness-point";
diff --git a/core/java/android/hardware/display/BrightnessCorrection.java b/core/java/android/hardware/display/BrightnessCorrection.java
index 22df778a..78cc769 100644
--- a/core/java/android/hardware/display/BrightnessCorrection.java
+++ b/core/java/android/hardware/display/BrightnessCorrection.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.MathUtils;
@@ -44,7 +43,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class BrightnessCorrection implements Parcelable {
private static final int SCALE_AND_TRANSLATE_LOG = 1;
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index c1ba209..a2400fd 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -691,7 +691,6 @@
* @hide
*/
@SystemApi
- @TestApi
public Point getStableDisplaySize() {
return mGlobal.getStableDisplaySize();
}
@@ -701,7 +700,6 @@
* @hide until we make it a system api.
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.BRIGHTNESS_SLIDER_USAGE)
public List<BrightnessChangeEvent> getBrightnessEvents() {
return mGlobal.getBrightnessEvents(mContext.getOpPackageName());
@@ -713,7 +711,6 @@
* @hide until we make it a system api
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS)
public List<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
return mGlobal.getAmbientBrightnessStats();
@@ -725,7 +722,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
public void setBrightnessConfiguration(BrightnessConfiguration c) {
setBrightnessConfigurationForUser(c, mContext.getUserId(), mContext.getPackageName());
@@ -750,7 +746,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
public BrightnessConfiguration getBrightnessConfiguration() {
return getBrightnessConfigurationForUser(mContext.getUserId());
@@ -776,7 +771,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
@Nullable
public BrightnessConfiguration getDefaultBrightnessConfiguration() {
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 1ce9b9c..4c96c54 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -29,7 +29,6 @@
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
@@ -58,7 +57,6 @@
* @hide
*/
@SystemApi
-@TestApi
@SystemService(Context.HDMI_CONTROL_SERVICE)
@RequiresFeature(PackageManager.FEATURE_HDMI_CEC)
public final class HdmiControlManager {
diff --git a/core/java/android/hardware/hdmi/HdmiPortInfo.java b/core/java/android/hardware/hdmi/HdmiPortInfo.java
index 52c3628..e97e120 100644
--- a/core/java/android/hardware/hdmi/HdmiPortInfo.java
+++ b/core/java/android/hardware/hdmi/HdmiPortInfo.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,7 +28,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class HdmiPortInfo implements Parcelable {
/** HDMI port type: Input */
public static final int PORT_INPUT = 0;
diff --git a/core/java/android/hardware/hdmi/HdmiSwitchClient.java b/core/java/android/hardware/hdmi/HdmiSwitchClient.java
index 913edfd0..04ec095 100644
--- a/core/java/android/hardware/hdmi/HdmiSwitchClient.java
+++ b/core/java/android/hardware/hdmi/HdmiSwitchClient.java
@@ -18,7 +18,6 @@
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.hardware.hdmi.HdmiControlManager.ControlCallbackResult;
import android.os.Binder;
import android.os.RemoteException;
@@ -39,7 +38,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class HdmiSwitchClient extends HdmiClient {
private static final String TAG = "HdmiSwitchClient";
diff --git a/core/java/android/hardware/lights/Light.java b/core/java/android/hardware/lights/Light.java
index e90b57cd..0400d3b 100644
--- a/core/java/android/hardware/lights/Light.java
+++ b/core/java/android/hardware/lights/Light.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -28,7 +27,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class Light implements Parcelable {
private final int mId;
private final int mOrdinal;
diff --git a/core/java/android/hardware/lights/LightState.java b/core/java/android/hardware/lights/LightState.java
index e55aa70..cd39e6d 100644
--- a/core/java/android/hardware/lights/LightState.java
+++ b/core/java/android/hardware/lights/LightState.java
@@ -19,7 +19,6 @@
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -36,7 +35,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class LightState implements Parcelable {
private final int mColor;
diff --git a/core/java/android/hardware/lights/LightsManager.java b/core/java/android/hardware/lights/LightsManager.java
index 8cd2312..33e5fca 100644
--- a/core/java/android/hardware/lights/LightsManager.java
+++ b/core/java/android/hardware/lights/LightsManager.java
@@ -45,7 +45,6 @@
* @hide
*/
@SystemApi
-@TestApi
@SystemService(Context.LIGHTS_SERVICE)
public final class LightsManager {
private static final String TAG = "LightsManager";
diff --git a/core/java/android/hardware/lights/LightsRequest.java b/core/java/android/hardware/lights/LightsRequest.java
index 5c4fc67..a318992 100644
--- a/core/java/android/hardware/lights/LightsRequest.java
+++ b/core/java/android/hardware/lights/LightsRequest.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.util.SparseArray;
import com.android.internal.util.Preconditions;
@@ -29,7 +28,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class LightsRequest {
/** Visible to {@link LightsManager.Session}. */
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index 80f35a0..1afadd4 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -59,7 +59,6 @@
*
* @hide
*/
-@TestApi
@SystemApi
public class SoundTrigger {
private static final String TAG = "SoundTrigger";
diff --git a/core/java/android/metrics/LogMaker.java b/core/java/android/metrics/LogMaker.java
index 5496e17..19848ee 100644
--- a/core/java/android/metrics/LogMaker.java
+++ b/core/java/android/metrics/LogMaker.java
@@ -16,7 +16,6 @@
package android.metrics;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.ComponentName;
import android.util.Log;
import android.util.SparseArray;
@@ -32,7 +31,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class LogMaker {
private static final String TAG = "LogBuilder";
diff --git a/core/java/android/metrics/MetricsReader.java b/core/java/android/metrics/MetricsReader.java
index 27f9a5d..5f356ca 100644
--- a/core/java/android/metrics/MetricsReader.java
+++ b/core/java/android/metrics/MetricsReader.java
@@ -16,7 +16,6 @@
package android.metrics;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.util.EventLog;
import com.android.internal.annotations.VisibleForTesting;
@@ -36,7 +35,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class MetricsReader {
private Queue<LogMaker> mPendingQueue = new LinkedList<>();
private Queue<LogMaker> mSeenQueue = new LinkedList<>();
diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java
index 8afeb30..c2586fa 100644
--- a/core/java/android/net/CaptivePortal.java
+++ b/core/java/android/net/CaptivePortal.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -42,7 +41,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int APP_RETURN_DISMISSED = 0;
/**
* Response code from the captive portal application, indicating that the user did not login and
@@ -52,7 +50,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int APP_RETURN_UNWANTED = 1;
/**
* Response code from the captive portal application, indicating that the user does not wish to
@@ -62,7 +59,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int APP_RETURN_WANTED_AS_IS = 2;
/** Event offset of request codes from captive portal application. */
private static final int APP_REQUEST_BASE = 100;
@@ -74,7 +70,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int APP_REQUEST_REEVALUATION_REQUIRED = APP_REQUEST_BASE + 0;
private final IBinder mBinder;
@@ -154,7 +149,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void useNetwork() {
try {
ICaptivePortal.Stub.asInterface(mBinder).appResponse(APP_RETURN_WANTED_AS_IS);
@@ -167,7 +161,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.NETWORK_STACK)
public void reevaluateNetwork() {
try {
@@ -183,7 +176,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void logEvent(@EventId int eventId, @NonNull String packageName) {
try {
ICaptivePortal.Stub.asInterface(mBinder).logEvent(eventId, packageName);
diff --git a/core/java/android/net/CaptivePortalData.java b/core/java/android/net/CaptivePortalData.java
index 1357803..c443c75 100644
--- a/core/java/android/net/CaptivePortalData.java
+++ b/core/java/android/net/CaptivePortalData.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,7 +29,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class CaptivePortalData implements Parcelable {
private final long mRefreshTimeMillis;
@Nullable
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a29f878..7bede46 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -269,7 +269,6 @@
* {@hide}
*/
@SystemApi
- @TestApi
public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC =
"android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
@@ -278,7 +277,6 @@
* {@hide}
*/
@SystemApi
- @TestApi
public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT =
"android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
@@ -4361,7 +4359,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
public void startCaptivePortalApp(@NonNull Network network, @NonNull Bundle appExtras) {
try {
diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java
index d975017..5860e20 100644
--- a/core/java/android/net/EthernetManager.java
+++ b/core/java/android/net/EthernetManager.java
@@ -37,7 +37,6 @@
* @hide
*/
@SystemApi
-@TestApi
@SystemService(Context.ETHERNET_SERVICE)
public class EthernetManager {
private static final String TAG = "EthernetManager";
diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java
index 8cfe6df..e7c8014 100644
--- a/core/java/android/net/IpPrefix.java
+++ b/core/java/android/net/IpPrefix.java
@@ -19,7 +19,6 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Pair;
@@ -88,7 +87,6 @@
* @hide
*/
@SystemApi
- @TestApi
public IpPrefix(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength) {
// We don't reuse the (byte[], int) constructor because it calls clone() on the byte array,
// which is unnecessary because getAddress() already returns a clone.
@@ -107,7 +105,6 @@
* @hide
*/
@SystemApi
- @TestApi
public IpPrefix(@NonNull String prefix) {
// We don't reuse the (InetAddress, int) constructor because "error: call to this must be
// first statement in constructor". We could factor out setting the member variables to an
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index a9d7f17..44d25a1 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -30,7 +30,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
@@ -158,7 +157,6 @@
* @return true if the address is IPv6.
* @hide
*/
- @TestApi
@SystemApi
public boolean isIpv6() {
return address instanceof Inet6Address;
@@ -180,7 +178,6 @@
* @return true if the address is IPv4 or is a mapped IPv4 address.
* @hide
*/
- @TestApi
@SystemApi
public boolean isIpv4() {
return address instanceof Inet4Address;
@@ -243,7 +240,6 @@
* @hide
*/
@SystemApi
- @TestApi
public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength,
int flags, int scope) {
init(address, prefixLength, flags, scope, LIFETIME_UNKNOWN, LIFETIME_UNKNOWN);
@@ -275,7 +271,6 @@
* @hide
*/
@SystemApi
- @TestApi
public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength,
int flags, int scope, long deprecationTime, long expirationTime) {
init(address, prefixLength, flags, scope, deprecationTime, expirationTime);
@@ -289,7 +284,6 @@
* @hide
*/
@SystemApi
- @TestApi
public LinkAddress(@NonNull InetAddress address,
@IntRange(from = 0, to = 128) int prefixLength) {
this(address, prefixLength, 0, 0);
@@ -314,7 +308,6 @@
* @hide
*/
@SystemApi
- @TestApi
public LinkAddress(@NonNull String address) {
this(address, 0, 0);
this.scope = scopeForUnicastAddress(this.address);
@@ -329,7 +322,6 @@
* @hide
*/
@SystemApi
- @TestApi
public LinkAddress(@NonNull String address, int flags, int scope) {
// This may throw an IllegalArgumentException; catching it is the caller's responsibility.
// TODO: consider rejecting mapped IPv4 addresses such as "::ffff:192.0.2.5/24".
@@ -389,7 +381,6 @@
* otherwise.
* @hide
*/
- @TestApi
@SystemApi
public boolean isSameAddressAs(@Nullable LinkAddress other) {
if (other == null) {
@@ -469,7 +460,6 @@
* @hide
*/
@SystemApi
- @TestApi
public long getDeprecationTime() {
return deprecationTime;
}
@@ -485,7 +475,6 @@
* @hide
*/
@SystemApi
- @TestApi
public long getExpirationTime() {
return expirationTime;
}
@@ -496,7 +485,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public boolean isGlobalPreferred() {
/**
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 651494d..9b2ef7c 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -19,15 +19,14 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.LinkPropertiesUtils;
-import android.net.util.LinkPropertiesUtils.CompareResult;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import com.android.net.module.util.LinkPropertiesUtils;
+
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -162,7 +161,6 @@
* @hide
*/
@SystemApi
- @TestApi
public LinkProperties(@Nullable LinkProperties source) {
this(source, false /* parcelSensitiveFields */);
}
@@ -178,7 +176,6 @@
* @hide
*/
@SystemApi
- @TestApi
public LinkProperties(@Nullable LinkProperties source, boolean parcelSensitiveFields) {
mParcelSensitiveFields = parcelSensitiveFields;
if (source == null) return;
@@ -293,7 +290,6 @@
* @hide
*/
@SystemApi
- @TestApi
public boolean addLinkAddress(@NonNull LinkAddress address) {
if (address == null) {
return false;
@@ -322,7 +318,6 @@
* @hide
*/
@SystemApi
- @TestApi
public boolean removeLinkAddress(@NonNull LinkAddress toRemove) {
int i = findLinkAddressIndex(toRemove);
if (i >= 0) {
@@ -376,7 +371,6 @@
* @return true if the DNS server was added, false if it was already present.
* @hide
*/
- @TestApi
@SystemApi
public boolean addDnsServer(@NonNull InetAddress dnsServer) {
if (dnsServer != null && !mDnses.contains(dnsServer)) {
@@ -393,7 +387,6 @@
* @return true if the DNS server was removed, false if it did not exist.
* @hide
*/
- @TestApi
@SystemApi
public boolean removeDnsServer(@NonNull InetAddress dnsServer) {
return mDnses.remove(dnsServer);
@@ -428,7 +421,6 @@
* @param usePrivateDns The private DNS state.
* @hide
*/
- @TestApi
@SystemApi
public void setUsePrivateDns(boolean usePrivateDns) {
mUsePrivateDns = usePrivateDns;
@@ -455,7 +447,6 @@
* @param privateDnsServerName The private DNS server name.
* @hide
*/
- @TestApi
@SystemApi
public void setPrivateDnsServerName(@Nullable String privateDnsServerName) {
mPrivateDnsServerName = privateDnsServerName;
@@ -534,7 +525,6 @@
* object.
* @hide
*/
- @TestApi
@SystemApi
public void setValidatedPrivateDnsServers(@NonNull Collection<InetAddress> dnsServers) {
mValidatedPrivateDnses.clear();
@@ -551,7 +541,6 @@
* DNS servers on this link.
* @hide
*/
- @TestApi
@SystemApi
public @NonNull List<InetAddress> getValidatedPrivateDnsServers() {
return Collections.unmodifiableList(mValidatedPrivateDnses);
@@ -592,7 +581,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void setPcscfServers(@NonNull Collection<InetAddress> pcscfServers) {
mPcscfs.clear();
for (InetAddress pcscfServer: pcscfServers) {
@@ -608,7 +596,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @NonNull List<InetAddress> getPcscfServers() {
return Collections.unmodifiableList(mPcscfs);
}
@@ -662,7 +649,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public void setTcpBufferSizes(@Nullable String tcpBufferSizes) {
mTcpBufferSizes = tcpBufferSizes;
@@ -675,7 +661,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public @Nullable String getTcpBufferSizes() {
return mTcpBufferSizes;
@@ -744,7 +729,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public boolean removeRoute(@NonNull RouteInfo route) {
return Objects.equals(mIfaceName, route.getInterface()) && mRoutes.remove(route);
@@ -1021,7 +1005,6 @@
* @return {@code true} if there is an IPv4 address, {@code false} otherwise.
* @hide
*/
- @TestApi
@SystemApi
public boolean hasIpv4Address() {
for (LinkAddress address : mLinkAddresses) {
@@ -1062,7 +1045,6 @@
* @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise.
* @hide
*/
- @TestApi
@SystemApi
public boolean hasGlobalIpv6Address() {
for (LinkAddress address : mLinkAddresses) {
@@ -1149,7 +1131,6 @@
* @return {@code true} if there is an IPv6 default route, {@code false} otherwise.
* @hide
*/
- @TestApi
@SystemApi
public boolean hasIpv6DefaultRoute() {
for (RouteInfo r : mRoutes) {
@@ -1265,7 +1246,6 @@
* @return {@code true} if the link is provisioned, {@code false} otherwise.
* @hide
*/
- @TestApi
@SystemApi
public boolean isIpv4Provisioned() {
return (hasIpv4Address()
@@ -1280,7 +1260,6 @@
* @return {@code true} if the link is provisioned, {@code false} otherwise.
* @hide
*/
- @TestApi
@SystemApi
public boolean isIpv6Provisioned() {
return (hasGlobalIpv6Address()
@@ -1308,7 +1287,6 @@
* @return {@code true} if the link is provisioned, {@code false} otherwise.
* @hide
*/
- @TestApi
@SystemApi
public boolean isProvisioned() {
return (isIpv4Provisioned() || isIpv6Provisioned());
@@ -1321,7 +1299,6 @@
* {@code false} otherwise.
* @hide
*/
- @TestApi
@SystemApi
public boolean isReachable(@NonNull InetAddress ip) {
final List<RouteInfo> allRoutes = getAllRoutes();
@@ -1578,7 +1555,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void setCaptivePortalApiUrl(@Nullable Uri url) {
mCaptivePortalApiUrl = url;
}
@@ -1593,7 +1569,6 @@
* @hide
*/
@SystemApi
- @TestApi
@Nullable
public Uri getCaptivePortalApiUrl() {
return mCaptivePortalApiUrl;
@@ -1604,7 +1579,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void setCaptivePortalData(@Nullable CaptivePortalData data) {
mCaptivePortalData = data;
}
@@ -1618,7 +1592,6 @@
* @hide
*/
@SystemApi
- @TestApi
@Nullable
public CaptivePortalData getCaptivePortalData() {
return mCaptivePortalData;
@@ -1669,78 +1642,6 @@
}
/**
- * Compares the DNS addresses in this LinkProperties with another
- * LinkProperties, examining only DNS addresses on the base link.
- *
- * @param target a LinkProperties with the new list of dns addresses
- * @return the differences between the DNS addresses.
- * @hide
- */
- public @NonNull CompareResult<InetAddress> compareDnses(@Nullable LinkProperties target) {
- /*
- * Duplicate the InetAddresses into removed, we will be removing
- * dns address which are common between mDnses and target
- * leaving the addresses that are different. And dns address which
- * are in target but not in mDnses are placed in the
- * addedAddresses.
- */
- return new CompareResult<>(mDnses, target != null ? target.getDnsServers() : null);
- }
-
- /**
- * Compares the validated private DNS addresses in this LinkProperties with another
- * LinkProperties.
- *
- * @param target a LinkProperties with the new list of validated private dns addresses
- * @return the differences between the DNS addresses.
- * @hide
- */
- public @NonNull CompareResult<InetAddress> compareValidatedPrivateDnses(
- @Nullable LinkProperties target) {
- return new CompareResult<>(mValidatedPrivateDnses,
- target != null ? target.getValidatedPrivateDnsServers() : null);
- }
-
- /**
- * Compares all routes in this LinkProperties with another LinkProperties,
- * examining both the the base link and all stacked links.
- *
- * @param target a LinkProperties with the new list of routes
- * @return the differences between the routes.
- * @hide
- */
- public @NonNull CompareResult<RouteInfo> compareAllRoutes(@Nullable LinkProperties target) {
- /*
- * Duplicate the RouteInfos into removed, we will be removing
- * routes which are common between mRoutes and target
- * leaving the routes that are different. And route address which
- * are in target but not in mRoutes are placed in added.
- */
- return new CompareResult<>(getAllRoutes(), target != null ? target.getAllRoutes() : null);
- }
-
- /**
- * Compares all interface names in this LinkProperties with another
- * LinkProperties, examining both the the base link and all stacked links.
- *
- * @param target a LinkProperties with the new list of interface names
- * @return the differences between the interface names.
- * @hide
- */
- public @NonNull CompareResult<String> compareAllInterfaceNames(
- @Nullable LinkProperties target) {
- /*
- * Duplicate the interface names into removed, we will be removing
- * interface names which are common between this and target
- * leaving the interface names that are different. And interface names which
- * are in target but not in this are placed in added.
- */
- return new CompareResult<>(getAllInterfaceNames(),
- target != null ? target.getAllInterfaceNames() : null);
- }
-
-
- /**
* Generate hashcode based on significant fields
*
* Equal objects must produce the same hash code, while unequal objects
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index 0eb3c1e..51c5a50 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -20,12 +20,12 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.MacAddressUtils;
import android.net.wifi.WifiInfo;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.Preconditions;
+import com.android.net.module.util.MacAddressUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/core/java/android/net/MatchAllNetworkSpecifier.java b/core/java/android/net/MatchAllNetworkSpecifier.java
index 68a3935..70c4a72 100644
--- a/core/java/android/net/MatchAllNetworkSpecifier.java
+++ b/core/java/android/net/MatchAllNetworkSpecifier.java
@@ -43,7 +43,8 @@
}
/** @hide */
- public boolean satisfiedBy(NetworkSpecifier other) {
+ @Override
+ public boolean canBeSatisfiedBy(NetworkSpecifier other) {
/*
* The method is called by a NetworkRequest to see if it is satisfied by a proposed
* network (e.g. as offered by a network factory). Since MatchAllNetweorkSpecifier must
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index f807a49..7bee05c 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -126,7 +125,6 @@
* @hide
*/
@SystemApi
- @TestApi
public Network(@NonNull Network that) {
this(that.netId, that.mPrivateDnsBypass);
}
@@ -163,7 +161,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public @NonNull Network getPrivateDnsBypassingCopy() {
return new Network(netId, true);
@@ -174,7 +171,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public int getNetId() {
return netId;
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 004f844..be33f4e 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -850,7 +850,6 @@
* @return an array of transport type values for this instance.
* @hide
*/
- @TestApi
@SystemApi
@NonNull public @Transport int[] getTransportTypes() {
return BitUtils.unpackBits(mTransportTypes);
@@ -1025,7 +1024,6 @@
*/
@NonNull
@SystemApi
- @TestApi
public int[] getAdministratorUids() {
return Arrays.copyOf(mAdministratorUids, mAdministratorUids.length);
}
@@ -1506,7 +1504,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @Nullable String getSsid() {
return mSSID;
}
@@ -1590,7 +1587,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public boolean satisfiedByNetworkCapabilities(@Nullable NetworkCapabilities nc) {
return satisfiedByNetworkCapabilities(nc, false);
@@ -2136,7 +2132,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final class Builder {
private final NetworkCapabilities mCaps;
diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java
index 86f3dfd..79f9e6e 100644
--- a/core/java/android/net/NetworkStack.java
+++ b/core/java/android/net/NetworkStack.java
@@ -33,7 +33,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class NetworkStack {
/**
* Permission granted only to the NetworkStack APK, defined in NetworkStackStub with signature
@@ -41,7 +40,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String PERMISSION_MAINLINE_NETWORK_STACK =
"android.permission.MAINLINE_NETWORK_STACK";
@@ -54,7 +52,6 @@
*/
@Nullable
@SystemApi
- @TestApi
public static IBinder getService() {
final IBinder mockService = sMockService;
if (mockService != null) return mockService;
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index 9876076..d53a0b1 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -20,13 +20,13 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.NetUtils;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.net.module.util.NetUtils;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.Inet4Address;
@@ -87,17 +87,14 @@
/** Unicast route. @hide */
@SystemApi
- @TestApi
public static final int RTN_UNICAST = 1;
/** Unreachable route. @hide */
@SystemApi
- @TestApi
public static final int RTN_UNREACHABLE = 7;
/** Throw route. @hide */
@SystemApi
- @TestApi
public static final int RTN_THROW = 9;
/**
@@ -135,7 +132,6 @@
* @hide
*/
@SystemApi
- @TestApi
public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
@Nullable String iface, @RouteType int type) {
this(destination, gateway, iface, type, 0);
@@ -397,7 +393,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RouteType
public int getType() {
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index a973455..f56d656 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -52,7 +51,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class StaticIpConfiguration implements Parcelable {
/** @hide */
@UnsupportedAppUsage
diff --git a/core/java/android/net/apf/ApfCapabilities.java b/core/java/android/net/apf/ApfCapabilities.java
index b1de74e..c4eba15 100644
--- a/core/java/android/net/apf/ApfCapabilities.java
+++ b/core/java/android/net/apf/ApfCapabilities.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.res.Resources;
import android.os.Parcel;
import android.os.Parcelable;
@@ -36,7 +35,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class ApfCapabilities implements Parcelable {
/**
* Version of APF instruction set supported for packet filtering. 0 indicates no support for
diff --git a/core/java/android/net/metrics/ApfProgramEvent.java b/core/java/android/net/metrics/ApfProgramEvent.java
index f93907a..c50bae9 100644
--- a/core/java/android/net/metrics/ApfProgramEvent.java
+++ b/core/java/android/net/metrics/ApfProgramEvent.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -40,7 +39,6 @@
* the APF program in place with a new APF program.
* {@hide}
*/
-@TestApi
@SystemApi
public final class ApfProgramEvent implements IpConnectivityLog.Event {
diff --git a/core/java/android/net/metrics/ApfStats.java b/core/java/android/net/metrics/ApfStats.java
index b221cb9..2a601b2 100644
--- a/core/java/android/net/metrics/ApfStats.java
+++ b/core/java/android/net/metrics/ApfStats.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,7 +28,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class ApfStats implements IpConnectivityLog.Event {
/**
@@ -126,7 +124,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final class Builder {
private long mDurationMs;
private int mReceivedRas;
diff --git a/core/java/android/net/metrics/DhcpClientEvent.java b/core/java/android/net/metrics/DhcpClientEvent.java
index 8fc1ef8..e0a93dd 100644
--- a/core/java/android/net/metrics/DhcpClientEvent.java
+++ b/core/java/android/net/metrics/DhcpClientEvent.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,7 +29,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class DhcpClientEvent implements IpConnectivityLog.Event {
// Names for recording DhcpClient pseudo-state transitions.
diff --git a/core/java/android/net/metrics/DhcpErrorEvent.java b/core/java/android/net/metrics/DhcpErrorEvent.java
index 32efb5a..de3129d 100644
--- a/core/java/android/net/metrics/DhcpErrorEvent.java
+++ b/core/java/android/net/metrics/DhcpErrorEvent.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -30,7 +29,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class DhcpErrorEvent implements IpConnectivityLog.Event {
public static final int L2_ERROR = 1;
public static final int L3_ERROR = 2;
diff --git a/core/java/android/net/metrics/IpConnectivityLog.java b/core/java/android/net/metrics/IpConnectivityLog.java
index 680c015..a008d85 100644
--- a/core/java/android/net/metrics/IpConnectivityLog.java
+++ b/core/java/android/net/metrics/IpConnectivityLog.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.net.ConnectivityMetricsEvent;
import android.net.IIpConnectivityMetrics;
import android.net.Network;
@@ -35,7 +34,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public class IpConnectivityLog {
private static final String TAG = IpConnectivityLog.class.getSimpleName();
private static final boolean DBG = false;
@@ -52,7 +50,6 @@
/** @hide */
@SystemApi
- @TestApi
public IpConnectivityLog() {
}
diff --git a/core/java/android/net/metrics/IpManagerEvent.java b/core/java/android/net/metrics/IpManagerEvent.java
index f14abb8..4f7f326 100644
--- a/core/java/android/net/metrics/IpManagerEvent.java
+++ b/core/java/android/net/metrics/IpManagerEvent.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -36,7 +35,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class IpManagerEvent implements IpConnectivityLog.Event {
public static final int PROVISIONING_OK = 1;
diff --git a/core/java/android/net/metrics/IpReachabilityEvent.java b/core/java/android/net/metrics/IpReachabilityEvent.java
index 79e01d7..d5003ba 100644
--- a/core/java/android/net/metrics/IpReachabilityEvent.java
+++ b/core/java/android/net/metrics/IpReachabilityEvent.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -32,7 +31,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class IpReachabilityEvent implements IpConnectivityLog.Event {
// Event types.
diff --git a/core/java/android/net/metrics/NetworkEvent.java b/core/java/android/net/metrics/NetworkEvent.java
index fe603cf..8c28f7a 100644
--- a/core/java/android/net/metrics/NetworkEvent.java
+++ b/core/java/android/net/metrics/NetworkEvent.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -34,7 +33,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class NetworkEvent implements IpConnectivityLog.Event {
public static final int NETWORK_CONNECTED = 1;
diff --git a/core/java/android/net/metrics/RaEvent.java b/core/java/android/net/metrics/RaEvent.java
index 661f648..b54874f 100644
--- a/core/java/android/net/metrics/RaEvent.java
+++ b/core/java/android/net/metrics/RaEvent.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -28,7 +27,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class RaEvent implements IpConnectivityLog.Event {
private static final long NO_LIFETIME = -1L;
diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java
index 8fab64a..7f4e4a7 100644
--- a/core/java/android/net/metrics/ValidationProbeEvent.java
+++ b/core/java/android/net/metrics/ValidationProbeEvent.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -35,7 +34,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class ValidationProbeEvent implements IpConnectivityLog.Event {
public static final int PROBE_DNS = 0;
diff --git a/core/java/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java
index 6967084..e64060f 100644
--- a/core/java/android/net/util/SocketUtils.java
+++ b/core/java/android/net/util/SocketUtils.java
@@ -22,7 +22,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.net.NetworkUtils;
import android.system.ErrnoException;
import android.system.NetlinkSocketAddress;
@@ -40,7 +39,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class SocketUtils {
/**
* Create a raw datagram socket that is bound to an interface.
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 12ec0a0..9a16d3f 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -20,7 +20,6 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.Intent;
@@ -392,7 +391,6 @@
*/
@RequiresPermission(permission.POWER_SAVER)
@SystemApi
- @TestApi
public boolean setChargingStateUpdateDelayMillis(int delayMillis) {
try {
return mBatteryStats.setChargingStateUpdateDelayMillis(delayMillis);
diff --git a/core/java/android/os/BugreportManager.java b/core/java/android/os/BugreportManager.java
index 9e996d1..fe4d729 100644
--- a/core/java/android/os/BugreportManager.java
+++ b/core/java/android/os/BugreportManager.java
@@ -24,13 +24,13 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
+
import com.android.internal.R;
import com.android.internal.util.Preconditions;
@@ -48,7 +48,6 @@
* @hide
*/
@SystemApi
-@TestApi
@SystemService(Context.BUGREPORT_SERVICE)
public final class BugreportManager {
diff --git a/core/java/android/os/BugreportParams.java b/core/java/android/os/BugreportParams.java
index c8347813..279ccae 100644
--- a/core/java/android/os/BugreportParams.java
+++ b/core/java/android/os/BugreportParams.java
@@ -18,7 +18,6 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -29,7 +28,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class BugreportParams {
private final int mMode;
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 9e13f05..11665fb 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -235,7 +235,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static @NonNull File getOemDirectory() {
return DIR_OEM_ROOT;
}
@@ -247,7 +246,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static @NonNull File getOdmDirectory() {
return DIR_ODM_ROOT;
}
@@ -258,7 +256,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static @NonNull File getVendorDirectory() {
return DIR_VENDOR_ROOT;
}
@@ -270,7 +267,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static @NonNull File getProductDirectory() {
return DIR_PRODUCT_ROOT;
}
@@ -297,7 +293,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static @NonNull File getSystemExtDirectory() {
return DIR_SYSTEM_EXT_ROOT;
}
diff --git a/core/java/android/os/HidlMemory.java b/core/java/android/os/HidlMemory.java
index 02d1e0c..26fc6f0 100644
--- a/core/java/android/os/HidlMemory.java
+++ b/core/java/android/os/HidlMemory.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import java.io.Closeable;
import java.io.IOException;
@@ -41,7 +40,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class HidlMemory implements Closeable {
private final @NonNull String mName;
private final long mSize;
diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java
index 7c42c36..3236816 100644
--- a/core/java/android/os/HwBinder.java
+++ b/core/java/android/os/HwBinder.java
@@ -17,7 +17,6 @@
package android.os;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import libcore.util.NativeAllocationRegistry;
@@ -26,7 +25,6 @@
/** @hide */
@SystemApi
-@TestApi
public abstract class HwBinder implements IHwBinder {
private static final String TAG = "HwBinder";
diff --git a/core/java/android/os/HwBlob.java b/core/java/android/os/HwBlob.java
index 154227b2..a43fbdb 100644
--- a/core/java/android/os/HwBlob.java
+++ b/core/java/android/os/HwBlob.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import libcore.util.NativeAllocationRegistry;
@@ -30,7 +29,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class HwBlob {
private static final String TAG = "HwBlob";
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index 228548a..9fd37d4 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import dalvik.annotation.optimization.FastNative;
@@ -34,7 +33,6 @@
/** @hide */
@SystemApi
-@TestApi
public class HwParcel {
private static final String TAG = "HwParcel";
diff --git a/core/java/android/os/IHwBinder.java b/core/java/android/os/IHwBinder.java
index 46fa6ef..249eb3a 100644
--- a/core/java/android/os/IHwBinder.java
+++ b/core/java/android/os/IHwBinder.java
@@ -17,11 +17,9 @@
package android.os;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
/** @hide */
@SystemApi
-@TestApi
public interface IHwBinder {
/**
* Process a hwbinder transaction.
diff --git a/core/java/android/os/IHwInterface.java b/core/java/android/os/IHwInterface.java
index 0a5a715..f21f6e3 100644
--- a/core/java/android/os/IHwInterface.java
+++ b/core/java/android/os/IHwInterface.java
@@ -17,11 +17,9 @@
package android.os;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
/** @hide */
@SystemApi
-@TestApi
public interface IHwInterface {
/**
* @return the binder object that corresponds to this interface.
diff --git a/core/java/android/os/IncidentManager.java b/core/java/android/os/IncidentManager.java
index 565d31a..a543a2d 100644
--- a/core/java/android/os/IncidentManager.java
+++ b/core/java/android/os/IncidentManager.java
@@ -23,7 +23,6 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.content.Context;
import android.net.Uri;
import android.util.Slog;
@@ -45,7 +44,6 @@
* @hide
*/
@SystemApi
-@TestApi
@SystemService(Context.INCIDENT_SERVICE)
public class IncidentManager {
private static final String TAG = "IncidentManager";
@@ -159,7 +157,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static class PendingReport {
/**
* Encoded data.
@@ -277,7 +274,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static class IncidentReport implements Parcelable, Closeable {
private final long mTimestampNs;
private final int mPrivacyPolicy;
diff --git a/core/java/android/os/IncidentReportArgs.java b/core/java/android/os/IncidentReportArgs.java
index 7e858e1..73e4914 100644
--- a/core/java/android/os/IncidentReportArgs.java
+++ b/core/java/android/os/IncidentReportArgs.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.IntArray;
@@ -30,7 +29,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class IncidentReportArgs implements Parcelable {
private final IntArray mSections = new IntArray();
diff --git a/core/java/android/os/NativeHandle.java b/core/java/android/os/NativeHandle.java
index 8d341b6..a26873a 100644
--- a/core/java/android/os/NativeHandle.java
+++ b/core/java/android/os/NativeHandle.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.system.ErrnoException;
import android.system.Os;
@@ -33,7 +32,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class NativeHandle implements Closeable {
// whether this object owns mFds
private boolean mOwn = false;
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index be2de0e..1af78a1 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -27,7 +27,6 @@
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.app.PropertyInvalidatedCache;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -1565,7 +1564,6 @@
* @see #isPowerSaveMode()
*/
@SystemApi
- @TestApi
@RequiresPermission(anyOf = {
android.Manifest.permission.DEVICE_POWER,
android.Manifest.permission.POWER_SAVER
@@ -1610,7 +1608,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(permission.POWER_SAVER)
public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold) {
try {
@@ -1670,7 +1667,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0;
/**
@@ -1683,7 +1679,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1;
/** @hide */
@@ -1708,7 +1703,6 @@
*/
@AutoPowerSaveModeTriggers
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.POWER_SAVER)
public int getPowerSaveModeTrigger() {
try {
diff --git a/core/java/android/os/RemoteCallback.java b/core/java/android/os/RemoteCallback.java
index 373060f..49f84adf 100644
--- a/core/java/android/os/RemoteCallback.java
+++ b/core/java/android/os/RemoteCallback.java
@@ -19,14 +19,12 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
/**
* @hide
*/
@SystemApi
-@TestApi
public final class RemoteCallback implements Parcelable {
public interface OnResultListener {
diff --git a/core/java/android/os/SystemConfigManager.java b/core/java/android/os/SystemConfigManager.java
index 12a1ffa..3f0632b 100644
--- a/core/java/android/os/SystemConfigManager.java
+++ b/core/java/android/os/SystemConfigManager.java
@@ -20,7 +20,6 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.content.Context;
import android.util.ArraySet;
import android.util.Log;
@@ -40,7 +39,6 @@
* @hide
*/
@SystemApi
-@TestApi
@SystemService(Context.SYSTEM_CONFIG_SERVICE)
public class SystemConfigManager {
private static final String TAG = SystemConfigManager.class.getSimpleName();
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index c5e5cc4..a164527 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.util.Log;
import android.util.MutableInt;
@@ -52,7 +51,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public class SystemProperties {
private static final String TAG = "SystemProperties";
private static final boolean TRACK_KEY_ACCESS = false;
@@ -146,7 +144,6 @@
*/
@NonNull
@SystemApi
- @TestApi
public static String get(@NonNull String key) {
if (TRACK_KEY_ACCESS) onKeyAccess(key);
return native_get(key);
@@ -163,7 +160,6 @@
*/
@NonNull
@SystemApi
- @TestApi
public static String get(@NonNull String key, @Nullable String def) {
if (TRACK_KEY_ACCESS) onKeyAccess(key);
return native_get(key, def);
@@ -179,7 +175,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static int getInt(@NonNull String key, int def) {
if (TRACK_KEY_ACCESS) onKeyAccess(key);
return native_get_int(key, def);
@@ -195,7 +190,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static long getLong(@NonNull String key, long def) {
if (TRACK_KEY_ACCESS) onKeyAccess(key);
return native_get_long(key, def);
@@ -216,7 +210,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static boolean getBoolean(@NonNull String key, boolean def) {
if (TRACK_KEY_ACCESS) onKeyAccess(key);
return native_get_boolean(key, def);
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index b92fb47..5357cf3 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -44,7 +44,6 @@
/** @hide A user handle to indicate all users on the device */
@SystemApi
- @TestApi
public static final @NonNull UserHandle ALL = new UserHandle(USER_ALL);
/** @hide A user id to indicate the currently active user */
@@ -53,7 +52,6 @@
/** @hide A user handle to indicate the current user of the device */
@SystemApi
- @TestApi
public static final @NonNull UserHandle CURRENT = new UserHandle(USER_CURRENT);
/** @hide A user id to indicate that we would like to send to the current
@@ -104,7 +102,6 @@
/** @hide A user handle to indicate the "system" user of the device */
@SystemApi
- @TestApi
public static final @NonNull UserHandle SYSTEM = new UserHandle(USER_SYSTEM);
/**
@@ -257,7 +254,6 @@
}
/** @hide */
- @TestApi
@SystemApi
public static UserHandle of(@UserIdInt int userId) {
if (userId == USER_SYSTEM) {
@@ -302,7 +298,6 @@
* Returns the app id (or base uid) for a given uid, stripping out the user id from it.
* @hide
*/
- @TestApi
@SystemApi
public static @AppIdInt int getAppId(int uid) {
return uid % PER_USER_RANGE;
@@ -460,7 +455,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static @UserIdInt int myUserId() {
return getUserId(Process.myUid());
}
@@ -499,7 +493,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @UserIdInt int getIdentifier() {
return mHandle;
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 2465b0e..6bd05e3 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -43,7 +43,6 @@
import android.content.IntentSender;
import android.content.pm.UserInfo;
import android.content.pm.UserInfo.UserInfoFlag;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -1408,8 +1407,7 @@
*
* @hide
*/
- @SystemApi
- @TestApi // To allow seeing it from CTS.
+ @SystemApi // To allow seeing it from CTS.
public static final String ACTION_USER_RESTRICTIONS_CHANGED =
"android.os.action.USER_RESTRICTIONS_CHANGED";
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 86d009e..097b672 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -23,7 +23,6 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -453,7 +452,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)
public boolean isVibrating() {
return false;
@@ -467,7 +465,6 @@
* @hide
*/
@SystemApi
- @TestApi
public interface OnVibratorStateChangedListener {
/**
* Called when the vibrator state has changed.
@@ -486,7 +483,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)
public void addVibratorStateListener(@NonNull OnVibratorStateChangedListener listener) {
}
@@ -500,7 +496,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)
public void addVibratorStateListener(
@NonNull @CallbackExecutor Executor executor,
@@ -515,7 +510,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)
public void removeVibratorStateListener(@NonNull OnVibratorStateChangedListener listener) {
}
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index 6adba63..b7382b9 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -98,7 +98,6 @@
* @param uid the uid performing the work
* @hide
*/
- @TestApi
@SystemApi
public WorkSource(int uid) {
mNum = 1;
@@ -152,7 +151,6 @@
* Returns the number of uids in this work source.
* @hide
*/
- @TestApi
@SystemApi
public int size() {
return mNum;
@@ -173,7 +171,6 @@
* If {@code index} < 0 or {@code index} >= {@link #size() N}, then the behavior is undefined.
* @hide
*/
- @TestApi
@SystemApi
public int getUid(int index) {
return mUids[index];
@@ -209,7 +206,6 @@
* If {@code index} < 0 or {@code index} >= {@link #size() N}, then the behavior is undefined.
* @hide
*/
- @TestApi
@SystemApi
@Nullable
public String getPackageName(int index) {
@@ -455,7 +451,6 @@
* @hide
*/
@SystemApi
- @TestApi
@NonNull
public WorkSource withoutNames() {
final WorkSource copy = new WorkSource(this);
@@ -582,7 +577,6 @@
* @hide for internal use only.
*/
@SystemApi
- @TestApi
public boolean isEmpty() {
return mNum == 0 && (mChains == null || mChains.isEmpty());
}
diff --git a/core/java/android/os/image/DynamicSystemClient.java b/core/java/android/os/image/DynamicSystemClient.java
index 50d8d80..58268e2 100644
--- a/core/java/android/os/image/DynamicSystemClient.java
+++ b/core/java/android/os/image/DynamicSystemClient.java
@@ -22,7 +22,6 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -68,7 +67,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class DynamicSystemClient {
/** @hide */
@IntDef(prefix = { "STATUS_" }, value = {
@@ -286,7 +284,6 @@
* @hide
*/
@SystemApi
- @TestApi
public DynamicSystemClient(@NonNull Context context) {
mContext = context;
mConnection = new DynSystemServiceConnection();
@@ -322,7 +319,6 @@
*/
@RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
@SystemApi
- @TestApi
public void bind() {
if (!featureFlagEnabled()) {
Slog.w(TAG, FeatureFlagUtils.DYNAMIC_SYSTEM + " not enabled; bind() aborted.");
@@ -345,7 +341,6 @@
*/
@RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
@SystemApi
- @TestApi
public void unbind() {
if (!mBound) {
return;
@@ -381,7 +376,6 @@
*/
@RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
@SystemApi
- @TestApi
public void start(@NonNull Uri systemUrl, @BytesLong long systemSize) {
start(systemUrl, systemSize, 0 /* Use the default userdata size */);
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 0abf8ae3..00848b9 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -43,7 +43,6 @@
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.annotation.WorkerThread;
import android.app.Activity;
import android.app.ActivityThread;
@@ -1707,7 +1706,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static boolean hasIsolatedStorage() {
// Prefer to use snapshot for current boot when available
return SystemProperties.getBoolean(PROP_ISOLATED_STORAGE_SNAPSHOT,
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index dea932d..e6a55f6 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -77,7 +77,6 @@
*
* @hide
*/
-@TestApi
@SystemApi
@SystemService(Context.PERMISSION_CONTROLLER_SERVICE)
public final class PermissionControllerManager {
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index bf3d46f..b827ce5 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -24,7 +24,6 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.IActivityManager;
@@ -56,7 +55,6 @@
*
* @hide
*/
-@TestApi
@SystemApi
@SystemService(Context.PERMISSION_SERVICE)
public final class PermissionManager {
@@ -114,7 +112,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(anyOf = {
Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
@@ -135,7 +132,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(anyOf = {
Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
diff --git a/core/java/android/permission/RuntimePermissionPresentationInfo.java b/core/java/android/permission/RuntimePermissionPresentationInfo.java
index d696fea..4fce14c 100644
--- a/core/java/android/permission/RuntimePermissionPresentationInfo.java
+++ b/core/java/android/permission/RuntimePermissionPresentationInfo.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -33,7 +32,6 @@
*
* @hide
*/
-@TestApi
@SystemApi
public final class RuntimePermissionPresentationInfo implements Parcelable {
private static final int FLAG_GRANTED = 1 << 0;
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index e86aa62..2840960 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -55,7 +55,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class DeviceConfig {
/**
* The content:// style URL for the config table.
@@ -107,7 +106,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String NAMESPACE_AUTOFILL = "autofill";
/**
@@ -133,7 +131,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
/**
@@ -217,7 +214,7 @@
*
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final String NAMESPACE_ROLLBACK = "rollback";
/**
@@ -225,7 +222,7 @@
*
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
/**
@@ -370,7 +367,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String NAMESPACE_PRIVACY = "privacy";
/**
@@ -379,7 +375,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String NAMESPACE_BIOMETRICS = "biometrics";
/**
@@ -388,7 +383,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String NAMESPACE_PERMISSIONS = "permissions";
/**
@@ -434,7 +428,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(READ_DEVICE_CONFIG)
public static String getProperty(@NonNull String namespace, @NonNull String name) {
// Fetch all properties for the namespace at once and cache them in the local process, so we
@@ -463,7 +456,6 @@
* @hide
*/
@SystemApi
- @TestApi
@NonNull
@RequiresPermission(READ_DEVICE_CONFIG)
public static Properties getProperties(@NonNull String namespace, @NonNull String ... names) {
@@ -483,7 +475,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(READ_DEVICE_CONFIG)
public static String getString(@NonNull String namespace, @NonNull String name,
@Nullable String defaultValue) {
@@ -502,7 +493,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(READ_DEVICE_CONFIG)
public static boolean getBoolean(@NonNull String namespace, @NonNull String name,
boolean defaultValue) {
@@ -521,7 +511,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(READ_DEVICE_CONFIG)
public static int getInt(@NonNull String namespace, @NonNull String name, int defaultValue) {
String value = getProperty(namespace, name);
@@ -547,7 +536,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(READ_DEVICE_CONFIG)
public static long getLong(@NonNull String namespace, @NonNull String name, long defaultValue) {
String value = getProperty(namespace, name);
@@ -573,7 +561,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(READ_DEVICE_CONFIG)
public static float getFloat(@NonNull String namespace, @NonNull String name,
float defaultValue) {
@@ -609,7 +596,6 @@
* @see #resetToDefaults(int, String).
*/
@SystemApi
- @TestApi
@RequiresPermission(WRITE_DEVICE_CONFIG)
public static boolean setProperty(@NonNull String namespace, @NonNull String name,
@Nullable String value, boolean makeDefault) {
@@ -633,7 +619,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(WRITE_DEVICE_CONFIG)
public static boolean setProperties(@NonNull Properties properties) throws BadConfigException {
ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
@@ -653,7 +638,6 @@
* @see #setProperty(String, String, String, boolean)
*/
@SystemApi
- @TestApi
@RequiresPermission(WRITE_DEVICE_CONFIG)
public static void resetToDefaults(@ResetMode int resetMode, @Nullable String namespace) {
ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
@@ -675,7 +659,6 @@
* @see #removeOnPropertiesChangedListener(OnPropertiesChangedListener)
*/
@SystemApi
- @TestApi
@RequiresPermission(READ_DEVICE_CONFIG)
public static void addOnPropertiesChangedListener(
@NonNull String namespace,
@@ -710,7 +693,6 @@
* @see #addOnPropertiesChangedListener(String, Executor, OnPropertiesChangedListener)
*/
@SystemApi
- @TestApi
public static void removeOnPropertiesChangedListener(
@NonNull OnPropertiesChangedListener onPropertiesChangedListener) {
Preconditions.checkNotNull(onPropertiesChangedListener);
@@ -845,7 +827,6 @@
* @hide
*/
@SystemApi
- @TestApi
public interface OnPropertiesChangedListener {
/**
* Called when one or more properties have changed, providing a Properties object with all
@@ -866,7 +847,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static class BadConfigException extends Exception {}
/**
@@ -875,7 +855,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static class Properties {
private final String mNamespace;
private final HashMap<String, String> mMap;
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 75840a5..6c9b7d8 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -22,7 +22,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentProvider;
import android.content.ContentResolver;
@@ -1303,7 +1302,6 @@
* {@hide}
*/
@SystemApi
- @TestApi
public static @NonNull Uri setManageMode(@NonNull Uri uri) {
Preconditions.checkNotNull(uri, "uri can not be null");
return uri.buildUpon().appendQueryParameter(PARAM_MANAGE, "true").build();
@@ -1315,7 +1313,6 @@
* {@hide}
*/
@SystemApi
- @TestApi
public static boolean isManageMode(@NonNull Uri uri) {
Preconditions.checkNotNull(uri, "uri can not be null");
return uri.getBooleanQueryParameter(PARAM_MANAGE, false);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 64d9c9d..1857bdca 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -225,7 +225,6 @@
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
@SystemApi
- @TestApi
public static final String ACTION_TETHER_PROVISIONING_UI =
"android.settings.TETHER_PROVISIONING_UI";
@@ -1034,7 +1033,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_MANAGE_APP_OVERLAY_PERMISSION =
@@ -1998,7 +1996,6 @@
* @hide
*/
@SystemApi
- @TestApi
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS
= "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
@@ -2081,7 +2078,6 @@
* @hide
*/
@SystemApi
- @TestApi
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE =
"android.settings.REQUEST_ENABLE_CONTENT_CAPTURE";
@@ -5553,7 +5549,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
public static void resetToDefaults(@NonNull ContentResolver resolver,
@Nullable String tag) {
@@ -6024,7 +6019,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String AUTOFILL_FEATURE_FIELD_CLASSIFICATION =
"autofill_field_classification";
@@ -6058,7 +6052,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE =
"autofill_user_data_max_user_data_size";
@@ -6069,7 +6062,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE =
"autofill_user_data_max_field_classification_size";
@@ -6080,7 +6072,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT =
"autofill_user_data_max_category_count";
@@ -6090,7 +6081,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String AUTOFILL_USER_DATA_MAX_VALUE_LENGTH =
"autofill_user_data_max_value_length";
@@ -6100,7 +6090,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String AUTOFILL_USER_DATA_MIN_VALUE_LENGTH =
"autofill_user_data_min_value_length";
@@ -6150,7 +6139,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String USER_SETUP_COMPLETE = "user_setup_complete";
/**
@@ -6515,7 +6503,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS =
"lock_screen_allow_private_notifications";
@@ -7755,7 +7742,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String DOZE_ALWAYS_ON = "doze_always_on";
/**
@@ -8150,7 +8136,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS =
"lock_screen_show_notifications";
@@ -8823,7 +8808,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS =
"location_access_check_interval_millis";
@@ -8832,7 +8816,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS =
"location_access_check_delay_millis";
@@ -10163,7 +10146,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String TETHER_OFFLOAD_DISABLED = "tether_offload_disabled";
/**
@@ -13241,7 +13223,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES =
"autofill_compat_mode_allowed_packages";
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index a2489b9..daf0bcc 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -4036,7 +4036,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final class CellBroadcasts implements BaseColumns {
/**
diff --git a/core/java/android/service/appprediction/AppPredictionService.java b/core/java/android/service/appprediction/AppPredictionService.java
index be20570..2d8aee5 100644
--- a/core/java/android/service/appprediction/AppPredictionService.java
+++ b/core/java/android/service/appprediction/AppPredictionService.java
@@ -22,7 +22,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionSessionId;
@@ -52,7 +51,6 @@
* @hide
*/
@SystemApi
-@TestApi
public abstract class AppPredictionService extends Service {
private static final String TAG = "AppPredictionService";
diff --git a/core/java/android/service/autofill/AutofillFieldClassificationService.java b/core/java/android/service/autofill/AutofillFieldClassificationService.java
index 28842a7..9d9b881 100644
--- a/core/java/android/service/autofill/AutofillFieldClassificationService.java
+++ b/core/java/android/service/autofill/AutofillFieldClassificationService.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
@@ -53,7 +52,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public abstract class AutofillFieldClassificationService extends Service {
private static final String TAG = "AutofillFieldClassificationService";
@@ -121,7 +119,6 @@
/** @hide */
@SystemApi
- @TestApi
public AutofillFieldClassificationService() {
}
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index 2d99c41..18d7992 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -21,7 +21,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.IntentSender;
import android.os.Parcel;
import android.os.Parcelable;
@@ -249,7 +248,6 @@
* @hide
*/
@SystemApi
- @TestApi
public Builder(@NonNull InlinePresentation inlinePresentation) {
Preconditions.checkNotNull(inlinePresentation, "inlinePresentation must be non-null");
mInlinePresentation = inlinePresentation;
@@ -604,7 +602,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @NonNull Builder setFieldInlinePresentation(@NonNull AutofillId id,
@Nullable AutofillValue value, @Nullable Pattern filter,
@NonNull InlinePresentation inlinePresentation) {
diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java
index 839caff..cdcd6591 100644
--- a/core/java/android/service/autofill/InlineSuggestionRenderService.java
+++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.content.Intent;
import android.content.IntentSender;
@@ -51,7 +50,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public abstract class InlineSuggestionRenderService extends Service {
private static final String TAG = "InlineSuggestionRenderService";
diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
index 95cc64a..6d09f09 100644
--- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
+++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
@@ -25,7 +25,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
@@ -70,7 +69,6 @@
* @hide
*/
@SystemApi
-@TestApi
public abstract class AugmentedAutofillService extends Service {
private static final String TAG = AugmentedAutofillService.class.getSimpleName();
diff --git a/core/java/android/service/autofill/augmented/FillCallback.java b/core/java/android/service/autofill/augmented/FillCallback.java
index fc3baf1..9fc7f34 100644
--- a/core/java/android/service/autofill/augmented/FillCallback.java
+++ b/core/java/android/service/autofill/augmented/FillCallback.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Bundle;
import android.service.autofill.Dataset;
import android.service.autofill.augmented.AugmentedAutofillService.AutofillProxy;
@@ -34,7 +33,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class FillCallback {
private static final String TAG = FillCallback.class.getSimpleName();
diff --git a/core/java/android/service/autofill/augmented/FillController.java b/core/java/android/service/autofill/augmented/FillController.java
index 7d552d6..7cd674e 100644
--- a/core/java/android/service/autofill/augmented/FillController.java
+++ b/core/java/android/service/autofill/augmented/FillController.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.RemoteException;
import android.service.autofill.augmented.AugmentedAutofillService.AutofillProxy;
import android.util.Log;
@@ -37,7 +36,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class FillController {
private static final String TAG = FillController.class.getSimpleName();
diff --git a/core/java/android/service/autofill/augmented/FillResponse.java b/core/java/android/service/autofill/augmented/FillResponse.java
index f72eb78..53484cf 100644
--- a/core/java/android/service/autofill/augmented/FillResponse.java
+++ b/core/java/android/service/autofill/augmented/FillResponse.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Bundle;
import android.service.autofill.Dataset;
@@ -33,7 +32,6 @@
* @hide
*/
@SystemApi
-@TestApi
@DataClass(
genBuilder = true,
genHiddenGetters = true)
diff --git a/core/java/android/service/autofill/augmented/FillWindow.java b/core/java/android/service/autofill/augmented/FillWindow.java
index 8e86646..d4f7e11 100644
--- a/core/java/android/service/autofill/augmented/FillWindow.java
+++ b/core/java/android/service/autofill/augmented/FillWindow.java
@@ -23,7 +23,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
@@ -64,7 +63,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class FillWindow implements AutoCloseable {
private static final String TAG = FillWindow.class.getSimpleName();
diff --git a/core/java/android/service/autofill/augmented/PresentationParams.java b/core/java/android/service/autofill/augmented/PresentationParams.java
index 8b3a001..fe78d22 100644
--- a/core/java/android/service/autofill/augmented/PresentationParams.java
+++ b/core/java/android/service/autofill/augmented/PresentationParams.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.graphics.Rect;
import android.service.autofill.augmented.AugmentedAutofillService.AutofillProxy;
import android.view.View;
@@ -36,7 +35,6 @@
* @hide
*/
@SystemApi
-@TestApi
public abstract class PresentationParams {
// /** @hide */
@@ -61,7 +59,6 @@
* @hide
*/
@SystemApi
- @TestApi
public abstract static class Area {
/** @hide */
diff --git a/core/java/android/service/contentcapture/ActivityEvent.java b/core/java/android/service/contentcapture/ActivityEvent.java
index b741cff..1188a3f 100644
--- a/core/java/android/service/contentcapture/ActivityEvent.java
+++ b/core/java/android/service/contentcapture/ActivityEvent.java
@@ -19,7 +19,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.usage.UsageEvents.Event;
import android.content.ComponentName;
import android.os.Parcel;
@@ -34,7 +33,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class ActivityEvent implements Parcelable {
/**
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index b1f147b..94e1c8e 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -26,7 +26,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
@@ -74,7 +73,6 @@
* @hide
*/
@SystemApi
-@TestApi
public abstract class ContentCaptureService extends Service {
private static final String TAG = ContentCaptureService.class.getSimpleName();
@@ -344,7 +342,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void onDataShareRequest(@NonNull DataShareRequest request,
@NonNull DataShareCallback callback) {
if (sVerbose) Log.v(TAG, "onDataShareRequest()");
diff --git a/core/java/android/service/contentcapture/DataShareCallback.java b/core/java/android/service/contentcapture/DataShareCallback.java
index 5df8a4b..e3c7bb3 100644
--- a/core/java/android/service/contentcapture/DataShareCallback.java
+++ b/core/java/android/service/contentcapture/DataShareCallback.java
@@ -19,7 +19,6 @@
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import java.util.concurrent.Executor;
@@ -33,7 +32,6 @@
* @hide
**/
@SystemApi
-@TestApi
public interface DataShareCallback {
/** Accept the data share.
diff --git a/core/java/android/service/contentcapture/DataShareReadAdapter.java b/core/java/android/service/contentcapture/DataShareReadAdapter.java
index 8cd9eea..4526aba 100644
--- a/core/java/android/service/contentcapture/DataShareReadAdapter.java
+++ b/core/java/android/service/contentcapture/DataShareReadAdapter.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.ParcelFileDescriptor;
import android.view.contentcapture.ContentCaptureManager.DataShareError;
@@ -29,7 +28,6 @@
* @hide
**/
@SystemApi
-@TestApi
public interface DataShareReadAdapter {
/**
diff --git a/core/java/android/service/contentcapture/SnapshotData.java b/core/java/android/service/contentcapture/SnapshotData.java
index 5b3930a..bf469b4 100644
--- a/core/java/android/service/contentcapture/SnapshotData.java
+++ b/core/java/android/service/contentcapture/SnapshotData.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.os.Bundle;
@@ -32,7 +31,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class SnapshotData implements Parcelable {
private final @NonNull Bundle mAssistData;
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index 8464c6d..4b25c88 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -19,7 +19,6 @@
import android.annotation.Nullable;
import android.annotation.StringDef;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Notification;
import android.os.Bundle;
import android.os.Parcel;
@@ -42,7 +41,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class Adjustment implements Parcelable {
private final String mPackage;
private final String mKey;
@@ -148,7 +146,6 @@
* @hide
*/
@SystemApi
- @TestApi
public Adjustment(String pkg, String key, Bundle signals, CharSequence explanation, int user) {
mPackage = pkg;
mKey = key;
@@ -232,7 +229,6 @@
/** @hide */
@SystemApi
- @TestApi
public int getUser() {
return mUser;
}
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index 975e75c..6320149 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -23,7 +23,6 @@
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -66,7 +65,6 @@
* @hide
*/
@SystemApi
-@TestApi
public abstract class NotificationAssistantService extends NotificationListenerService {
private static final String TAG = "NotificationAssistants";
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index c52b02b..536c9c0 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -22,7 +22,6 @@
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.ActivityManager;
import android.app.INotificationManager;
import android.app.Notification;
@@ -451,7 +450,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public void onNotificationRemoved(@NonNull StatusBarNotification sbn,
@NonNull RankingMap rankingMap, @NonNull NotificationStats stats, int reason) {
diff --git a/core/java/android/service/notification/NotificationStats.java b/core/java/android/service/notification/NotificationStats.java
index 8be114c..b369483 100644
--- a/core/java/android/service/notification/NotificationStats.java
+++ b/core/java/android/service/notification/NotificationStats.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.RemoteInput;
import android.os.Parcel;
import android.os.Parcelable;
@@ -31,7 +30,6 @@
* Information about how the user has interacted with a given notification.
* @hide
*/
-@TestApi
@SystemApi
public final class NotificationStats implements Parcelable {
diff --git a/core/java/android/service/notification/SnoozeCriterion.java b/core/java/android/service/notification/SnoozeCriterion.java
index eb624c9..d3da07a 100644
--- a/core/java/android/service/notification/SnoozeCriterion.java
+++ b/core/java/android/service/notification/SnoozeCriterion.java
@@ -17,7 +17,6 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,7 +26,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class SnoozeCriterion implements Parcelable {
private final String mId;
private final CharSequence mExplanation;
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index 93faa58..1fb18fa 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -22,7 +22,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
@@ -88,7 +87,6 @@
* @hide
*/
@SystemApi
-@TestApi
public abstract class TextClassifierService extends Service {
private static final String LOG_TAG = "TextClassifierService";
diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
index b1647fe..49e00d6 100644
--- a/core/java/android/service/watchdog/ExplicitHealthCheckService.java
+++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
@@ -66,7 +66,6 @@
* </pre>
* @hide
*/
-@TestApi
@SystemApi
public abstract class ExplicitHealthCheckService extends Service {
@@ -195,7 +194,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final class PackageConfig implements Parcelable {
private static final long DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(1);
diff --git a/core/java/android/telephony/CellBroadcastIntents.java b/core/java/android/telephony/CellBroadcastIntents.java
index e07f69a..c3ca286 100644
--- a/core/java/android/telephony/CellBroadcastIntents.java
+++ b/core/java/android/telephony/CellBroadcastIntents.java
@@ -45,7 +45,8 @@
private static final String EXTRA_MESSAGE = "message";
/**
- * Broadcast intent action for notifying area information has been updated. The information
+ * Broadcast intent action for notifying area information has been updated. broadcast is also
+ * sent when the user turns off area info alerts. The information
* can be retrieved by {@link CellBroadcastService#getCellBroadcastAreaInfo(int)}. The
* associated SIM slot index of updated area information can be retrieved through the extra
* {@link SubscriptionManager#EXTRA_SLOT_INDEX}.
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 4adcd69..04e0780 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.ChangeId;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Binder;
@@ -437,7 +436,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 0x10000000;
@@ -450,7 +448,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 0x20000000;
@@ -952,7 +949,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) {
// default implementation empty
}
@@ -964,7 +960,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) {
// default implementation empty
}
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 0854452..8ab120f 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
-import android.annotation.TestApi;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
@@ -283,7 +282,6 @@
* @param incomingNumber incoming phone number.
* @hide
*/
- @TestApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void notifyCallStateChangedForAllSubscriptions(@CallState int state,
@Nullable String incomingNumber) {
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 3742543..c0f92fd 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -1234,7 +1234,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
public void performAccessibilityShortcut() {
performAccessibilityShortcut(null);
@@ -1279,7 +1278,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
public void registerSystemAction(@NonNull RemoteAction action, int actionId) {
final IAccessibilityManager service;
@@ -1307,7 +1305,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
public void unregisterSystemAction(int actionId) {
final IAccessibilityManager service;
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index fbfeda6..f749352 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -2048,7 +2048,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void setAugmentedAutofillWhitelist(@Nullable Set<String> packages,
@Nullable Set<ComponentName> activities) {
if (!hasAutofillFeature()) {
diff --git a/core/java/android/view/contentcapture/ContentCaptureContext.java b/core/java/android/view/contentcapture/ContentCaptureContext.java
index b84cb88..9bf3626 100644
--- a/core/java/android/view/contentcapture/ContentCaptureContext.java
+++ b/core/java/android/view/contentcapture/ContentCaptureContext.java
@@ -21,7 +21,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Context;
@@ -58,7 +57,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_DISABLED_BY_APP = 0x1;
/**
@@ -69,7 +67,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_DISABLED_BY_FLAG_SECURE = 0x2;
/**
@@ -79,7 +76,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FLAG_RECONNECTED = 0x4;
/** @hide */
@@ -173,7 +169,6 @@
* @hide
*/
@SystemApi
- @TestApi
public int getTaskId() {
return mTaskId;
}
@@ -184,7 +179,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @Nullable ComponentName getActivityComponent() {
return mComponentName;
}
@@ -197,7 +191,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @Nullable ContentCaptureSessionId getParentSessionId() {
return mParentSessionId == NO_SESSION_ID ? null
: new ContentCaptureSessionId(mParentSessionId);
@@ -215,7 +208,6 @@
* @hide
*/
@SystemApi
- @TestApi
public int getDisplayId() {
return mDisplayId;
}
@@ -229,7 +221,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @ContextCreationFlags int getFlags() {
return mFlags;
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java
index f49b1be..2b12230 100644
--- a/core/java/android/view/contentcapture/ContentCaptureEvent.java
+++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java
@@ -22,7 +22,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.graphics.Insets;
import android.os.Parcel;
import android.os.Parcelable;
@@ -39,7 +38,6 @@
/** @hide */
@SystemApi
-@TestApi
public final class ContentCaptureEvent implements Parcelable {
private static final String TAG = ContentCaptureEvent.class.getSimpleName();
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 484b1c1..585bb1a 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -644,7 +644,6 @@
* @hide
*/
@SystemApi
- @TestApi
public boolean isContentCaptureFeatureEnabled() {
final SyncResultReceiver resultReceiver = syncRun(
(r) -> mService.isContentCaptureFeatureEnabled(r));
diff --git a/core/java/android/view/contentcapture/ViewNode.java b/core/java/android/view/contentcapture/ViewNode.java
index e035c62..e731d4b 100644
--- a/core/java/android/view/contentcapture/ViewNode.java
+++ b/core/java/android/view/contentcapture/ViewNode.java
@@ -42,7 +42,6 @@
// instead
/** @hide */
@SystemApi
-@TestApi
public final class ViewNode extends AssistStructure.ViewNode {
private static final String TAG = ViewNode.class.getSimpleName();
diff --git a/core/proto/Android.bp b/core/proto/Android.bp
deleted file mode 100644
index 3b891d6..0000000
--- a/core/proto/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// C++ library for Bluetooth platform wide protobuf definitions
-cc_library_static {
- name: "libbt-platform-protos-lite",
- host_supported: true,
- proto: {
- export_proto_headers: true,
- type: "lite",
- },
- srcs: [
- "android/bluetooth/a2dp/enums.proto",
- "android/bluetooth/enums.proto",
- "android/bluetooth/hci/enums.proto",
- "android/bluetooth/hfp/enums.proto",
- "android/bluetooth/smp/enums.proto",
- ],
-}
diff --git a/core/proto/android/app/enums.proto b/core/proto/android/app/enums.proto
deleted file mode 100644
index bd5cb62..0000000
--- a/core/proto/android/app/enums.proto
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app;
-
-option java_outer_classname = "AppProtoEnums";
-option java_multiple_files = true;
-
-// ActivityManagerInternal.java's APP_TRANSITION reasons.
-enum AppTransitionReasonEnum {
- APP_TRANSITION_REASON_UNKNOWN = 0;
- // The transition was started because we drew the splash screen.
- APP_TRANSITION_SPLASH_SCREEN = 1;
- // The transition was started because we all app windows were drawn.
- APP_TRANSITION_WINDOWS_DRAWN = 2;
- // The transition was started because of a timeout.
- APP_TRANSITION_TIMEOUT = 3;
- // The transition was started because of a we drew a task snapshot.
- APP_TRANSITION_SNAPSHOT = 4;
- // The transition was started because it was a recents animation and we only needed to wait on
- // the wallpaper.
- APP_TRANSITION_RECENTS_ANIM = 5;
-}
-
-// ActivityManager.java PROCESS_STATEs
-// Next tag: 1021
-enum ProcessStateEnum {
- // Unlike the ActivityManager PROCESS_STATE values, the ordering and numerical values
- // here are completely fixed and arbitrary. Order is irrelevant.
- // No attempt need be made to keep them in sync.
- // The values here must not be modified. Any new process states can be appended to the end.
-
- // Process state that is unknown to this proto file (i.e. is not mapped
- // by ActivityManager.processStateAmToProto()). Can only happen if there's a bug in the mapping.
- PROCESS_STATE_UNKNOWN_TO_PROTO = 998;
- // Not a real process state.
- PROCESS_STATE_UNKNOWN = 999;
- // Process is a persistent system process.
- PROCESS_STATE_PERSISTENT = 1000;
- // Process is a persistent system process and is doing UI.
- PROCESS_STATE_PERSISTENT_UI = 1001;
- // Process is hosting the current top activities. Note that this covers
- // all activities that are visible to the user.
- PROCESS_STATE_TOP = 1002;
- // Process is bound to a TOP app.
- PROCESS_STATE_BOUND_TOP = 1020;
- // Process is hosting a foreground service.
- PROCESS_STATE_FOREGROUND_SERVICE = 1003;
- // Process is hosting a service bound by the system or another foreground app.
- PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 1004;
- // Process is important to the user, and something they are aware of.
- PROCESS_STATE_IMPORTANT_FOREGROUND = 1005;
- // Process is important to the user, but not something they are aware of.
- PROCESS_STATE_IMPORTANT_BACKGROUND = 1006;
- // Process is in the background transient so we will try to keep running.
- PROCESS_STATE_TRANSIENT_BACKGROUND = 1007;
- // Process is in the background running a backup/restore operation.
- PROCESS_STATE_BACKUP = 1008;
- // Process is in the background running a service. Unlike oom_adj, this
- // level is used for both the normal running in background state and the
- // executing operations state.
- PROCESS_STATE_SERVICE = 1009;
- // Process is in the background running a receiver. Note that from the
- // perspective of oom_adj, receivers run at a higher foreground level, but
- // for our prioritization here that is not necessary and putting them
- // below services means many fewer changes in some process states as they
- // receive broadcasts.
- PROCESS_STATE_RECEIVER = 1010;
- // Same as PROCESS_STATE_TOP but while device is sleeping.
- PROCESS_STATE_TOP_SLEEPING = 1011;
- // Process is in the background, but it can't restore its state so we want
- // to try to avoid killing it.
- PROCESS_STATE_HEAVY_WEIGHT = 1012;
- // Process is in the background but hosts the home activity.
- PROCESS_STATE_HOME = 1013;
- // Process is in the background but hosts the last shown activity.
- PROCESS_STATE_LAST_ACTIVITY = 1014;
- // Process is being cached for later use and contains activities.
- PROCESS_STATE_CACHED_ACTIVITY = 1015;
- // Process is being cached for later use and is a client of another cached
- // process that contains activities.
- PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 1016;
- // Process is being cached for later use and has an activity that corresponds
- // to an existing recent task.
- PROCESS_STATE_CACHED_RECENT = 1017;
- // Process is being cached for later use and is empty.
- PROCESS_STATE_CACHED_EMPTY = 1018;
- // Process does not exist.
- PROCESS_STATE_NONEXISTENT = 1019;
-}
-
-// AppOpsManager.java - operation ids for logging
-enum AppOpEnum {
- APP_OP_NONE = -1;
- APP_OP_COARSE_LOCATION = 0;
- APP_OP_FINE_LOCATION = 1;
- APP_OP_GPS = 2;
- APP_OP_VIBRATE = 3;
- APP_OP_READ_CONTACTS = 4;
- APP_OP_WRITE_CONTACTS = 5;
- APP_OP_READ_CALL_LOG = 6;
- APP_OP_WRITE_CALL_LOG = 7;
- APP_OP_READ_CALENDAR = 8;
- APP_OP_WRITE_CALENDAR = 9;
- APP_OP_WIFI_SCAN = 10;
- APP_OP_POST_NOTIFICATION = 11;
- APP_OP_NEIGHBORING_CELLS = 12;
- APP_OP_CALL_PHONE = 13;
- APP_OP_READ_SMS = 14;
- APP_OP_WRITE_SMS = 15;
- APP_OP_RECEIVE_SMS = 16;
- APP_OP_RECEIVE_EMERGENCY_SMS = 17;
- APP_OP_RECEIVE_MMS = 18;
- APP_OP_RECEIVE_WAP_PUSH = 19;
- APP_OP_SEND_SMS = 20;
- APP_OP_READ_ICC_SMS = 21;
- APP_OP_WRITE_ICC_SMS = 22;
- APP_OP_WRITE_SETTINGS = 23;
- APP_OP_SYSTEM_ALERT_WINDOW = 24;
- APP_OP_ACCESS_NOTIFICATIONS = 25;
- APP_OP_CAMERA = 26;
- APP_OP_RECORD_AUDIO = 27;
- APP_OP_PLAY_AUDIO = 28;
- APP_OP_READ_CLIPBOARD = 29;
- APP_OP_WRITE_CLIPBOARD = 30;
- APP_OP_TAKE_MEDIA_BUTTONS = 31;
- APP_OP_TAKE_AUDIO_FOCUS = 32;
- APP_OP_AUDIO_MASTER_VOLUME = 33;
- APP_OP_AUDIO_VOICE_VOLUME = 34;
- APP_OP_AUDIO_RING_VOLUME = 35;
- APP_OP_AUDIO_MEDIA_VOLUME = 36;
- APP_OP_AUDIO_ALARM_VOLUME = 37;
- APP_OP_AUDIO_NOTIFICATION_VOLUME = 38;
- APP_OP_AUDIO_BLUETOOTH_VOLUME = 39;
- APP_OP_WAKE_LOCK = 40;
- APP_OP_MONITOR_LOCATION = 41;
- APP_OP_MONITOR_HIGH_POWER_LOCATION = 42;
- APP_OP_GET_USAGE_STATS = 43;
- APP_OP_MUTE_MICROPHONE = 44;
- APP_OP_TOAST_WINDOW = 45;
- APP_OP_PROJECT_MEDIA = 46;
- APP_OP_ACTIVATE_VPN = 47;
- APP_OP_WRITE_WALLPAPER = 48;
- APP_OP_ASSIST_STRUCTURE = 49;
- APP_OP_ASSIST_SCREENSHOT = 50;
- APP_OP_READ_PHONE_STATE = 51;
- APP_OP_ADD_VOICEMAIL = 52;
- APP_OP_USE_SIP = 53;
- APP_OP_PROCESS_OUTGOING_CALLS = 54;
- APP_OP_USE_FINGERPRINT = 55;
- APP_OP_BODY_SENSORS = 56;
- APP_OP_READ_CELL_BROADCASTS = 57;
- APP_OP_MOCK_LOCATION = 58;
- APP_OP_READ_EXTERNAL_STORAGE = 59;
- APP_OP_WRITE_EXTERNAL_STORAGE = 60;
- APP_OP_TURN_SCREEN_ON = 61;
- APP_OP_GET_ACCOUNTS = 62;
- APP_OP_RUN_IN_BACKGROUND = 63;
- APP_OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
- APP_OP_READ_PHONE_NUMBERS = 65;
- APP_OP_REQUEST_INSTALL_PACKAGES = 66;
- APP_OP_PICTURE_IN_PICTURE = 67;
- APP_OP_INSTANT_APP_START_FOREGROUND = 68;
- APP_OP_ANSWER_PHONE_CALLS = 69;
- APP_OP_RUN_ANY_IN_BACKGROUND = 70;
- APP_OP_CHANGE_WIFI_STATE = 71;
- APP_OP_REQUEST_DELETE_PACKAGES = 72;
- APP_OP_BIND_ACCESSIBILITY_SERVICE = 73;
- APP_OP_ACCEPT_HANDOVER = 74;
- APP_OP_MANAGE_IPSEC_TUNNELS = 75;
- APP_OP_START_FOREGROUND = 76;
- APP_OP_BLUETOOTH_SCAN = 77;
- APP_OP_USE_BIOMETRIC = 78;
- APP_OP_ACTIVITY_RECOGNITION = 79;
- APP_OP_SMS_FINANCIAL_TRANSACTIONS = 80;
- APP_OP_READ_MEDIA_AUDIO = 81;
- APP_OP_WRITE_MEDIA_AUDIO = 82;
- APP_OP_READ_MEDIA_VIDEO = 83;
- APP_OP_WRITE_MEDIA_VIDEO = 84;
- APP_OP_READ_MEDIA_IMAGES = 85;
- APP_OP_WRITE_MEDIA_IMAGES = 86;
- APP_OP_LEGACY_STORAGE = 87;
- APP_OP_ACCESS_ACCESSIBILITY = 88;
- APP_OP_READ_DEVICE_IDENTIFIERS = 89;
- APP_OP_ACCESS_MEDIA_LOCATION = 90;
- APP_OP_QUERY_ALL_PACKAGES = 91;
- APP_OP_MANAGE_EXTERNAL_STORAGE = 92;
- APP_OP_INTERACT_ACROSS_PROFILES = 93;
- APP_OP_ACTIVATE_PLATFORM_VPN = 94;
- APP_OP_LOADER_USAGE_STATS = 95;
- APP_OP_DEPRECATED_1 = 96 [deprecated = true];
- APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 97;
- APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 98;
- APP_OP_NO_ISOLATED_STORAGE = 99;
-}
diff --git a/core/proto/android/app/job/enums.proto b/core/proto/android/app/job/enums.proto
deleted file mode 100644
index 41863bb..0000000
--- a/core/proto/android/app/job/enums.proto
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.job;
-
-// This file is for JobScheduler enums inside the app directory. If you're
-// adding enums for system-server-side code, use the file in
-// frameworks/base/core/proto/android/server/job.
-option java_outer_classname = "JobProtoEnums";
-option java_multiple_files = true;
-
-// Reasons a job is stopped.
-// Primarily used in android.app.job.JobParameters.java.
-enum StopReasonEnum {
- STOP_REASON_UNKNOWN = -1;
- STOP_REASON_CANCELLED = 0;
- STOP_REASON_CONSTRAINTS_NOT_SATISFIED = 1;
- STOP_REASON_PREEMPT = 2;
- STOP_REASON_TIMEOUT = 3;
- STOP_REASON_DEVICE_IDLE = 4;
- STOP_REASON_DEVICE_THERMAL = 5;
- STOP_REASON_RESTRICTED_BUCKET = 6;
-}
diff --git a/core/proto/android/app/media_output_enum.proto b/core/proto/android/app/media_output_enum.proto
deleted file mode 100644
index 0d42fb7..0000000
--- a/core/proto/android/app/media_output_enum.proto
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.settings.mediaoutput;
-option java_multiple_files = true;
-
-/**
- * The medium type specified in an output switching operation.
- */
-enum MediumType {
- UNKNOWN_TYPE = 0;
- BUILTIN_SPEAKER = 1;
- WIRED_3POINT5_MM_AUDIO = 100;
- WIRED_3POINT5_MM_HEADSET = 101;
- WIRED_3POINT5_MM_HEADPHONES = 102;
- USB_C_AUDIO = 200;
- USB_C_DEVICE = 201;
- USB_C_HEADSET = 202;
- USB_C_ACCESSORY = 203;
- USB_C_DOCK = 204;
- USB_C_HDMI = 205;
- BLUETOOTH = 300;
- BLUETOOTH_HEARING_AID = 301;
- BLUETOOTH_A2DP = 302;
- REMOTE_SINGLE = 400;
- REMOTE_TV = 401;
- REMOTE_SPEAKER = 402;
- REMOTE_GROUP = 500;
- REMOTE_DYNAMIC_GROUP = 501;
-};
-
-/**
- * The result of an output switching operation.
- */
-enum SwitchResult {
- ERROR = 0;
- OK = 1;
-};
-
-/**
- * The sub result of an output switching operation.
- */
-enum SubResult {
- UNKNOWN_ERROR = 0;
- NO_ERROR = 1;
- REJECTED = 2;
- NETWORK_ERROR = 3;
- ROUTE_NOT_AVAILABLE = 4;
- INVALID_COMMAND = 5;
-}
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
deleted file mode 100644
index 69b32c2..0000000
--- a/core/proto/android/app/settings_enums.proto
+++ /dev/null
@@ -1,2686 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.settings;
-option java_multiple_files = true;
-
-/**
- * The action performed in this event
- */
-enum Action {
- ACTION_UNKNOWN = 0;
- PAGE_VISIBLE = 1;
- PAGE_HIDE = 2;
-
- // ACTION: Settings > Wi-Fi > [Long press network] > Connect to network
- // SUBTYPE: true if connecting to a saved network, false if not
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_CONNECT = 135;
-
- // ACTION: Settings > Wi-Fi > [Long press network] > Forget network
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_FORGET = 137;
-
- // ACTION: Settings > Wi-Fi > Toggle off
- // SUBTYPE: true if connected to network before toggle, false if not
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_OFF = 138;
-
- // ACTION: Settings > Wi-Fi > Toggle on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_ON = 139;
-
- // ACTION: Settings > Bluetooth > Overflow > Rename this device
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_BLUETOOTH_RENAME = 161;
-
- // ACTION: Settings > Bluetooth > Overflow > Show received files
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_BLUETOOTH_FILES = 162;
-
- // ACTION: DND Settings > Priority only allows > Reminder toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_REMINDERS = 167;
-
- // ACTION: DND Settings > Priority only allows > Event toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_EVENTS = 168;
-
- // ACTION: DND Settings > Priority only allows > Messages
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_MESSAGES = 169;
-
- // ACTION: DND Settings > Priority only allows > Calls
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_CALLS = 170;
-
- // ACTION: DND Settings > Priority only allows > Repeat callers toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_REPEAT_CALLS = 171;
-
- // ACTION: DND Settings > Automatic rules > [Rule] > Delete rule > Delete
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_DELETE_RULE_OK = 175;
-
- // ACTION: Settings > More > Airplane mode toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_AIRPLANE_TOGGLE = 177;
-
- // ACTION: Settings > Data usage > Cellular data toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_CELL_DATA_TOGGLE = 178;
-
- // ACTION: Settings > Display > When device is rotated
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ROTATION_LOCK = 203;
-
- // OPEN: Settings > Search > Perform search
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_SEARCH_RESULTS = 226;
-
- // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Delete
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_FINGERPRINT_DELETE = 253;
-
- // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Rename
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_FINGERPRINT_RENAME = 254;
-
- // ACTION: Settings -> Developer Options -> Take bug report -> Interactive report
- // CATEGORY: SETTINGS
- // OS: N
- // Interactive bug report initiated from Settings.
- ACTION_BUGREPORT_FROM_SETTINGS_INTERACTIVE = 294;
-
- // ACTION: Settings -> Developer Options -> Take bug report -> Full report
- // CATEGORY: SETTINGS
- // OS: N
- // Interactive bug report initiated from Settings.
- ACTION_BUGREPORT_FROM_SETTINGS_FULL = 295;
-
- // click on collapsed conditional or clicks expand button
- ACTION_SETTINGS_CONDITION_EXPAND = 373;
-
- // click main area of expanded conditional
- ACTION_SETTINGS_CONDITION_CLICK = 375;
-
- // click a direct button on expanded conditional
- ACTION_SETTINGS_CONDITION_BUTTON = 376;
-
- // Action: user enable / disabled data saver using Settings
- // OPEN: Settings -> Data Usage -> Data saver -> On/off toggle
- // VALUE: 1 for enabled, 0 for disabled
- // CATEGORY: SETTINGS
- // OS: N
- ACTION_DATA_SAVER_MODE = 394;
-
- // User whitelisted an app for Data Saver mode; action pass package name of app
- // Action: user enable / disabled data saver using Settings
- // OPEN: Settings -> Data Usage -> Data saver -> Unrestricted data access > APP toggle turned on
- // or
- // Settings -> Apps -> APP -> Data usage -> Unrestricted data usage toggle turned on
- // VALUE: package name of APP
- // CATEGORY: SETTINGS
- // OS: N
- ACTION_DATA_SAVER_WHITELIST = 395;
-
- // User blacklisted an app for Data Saver mode; action pass package name of app
- // OPEN: Settings -> Apps -> APP -> Data usage -> Background data toggle turned off
- // VALUE: package name of APP
- // CATEGORY: SETTINGS
- // OS: N
- ACTION_DATA_SAVER_BLACKLIST = 396;
-
- // ACTION: Settings -> Storage -> Manage storage -> Click Storage Manager
- // SUBTYPE: false is off, true is on
- ACTION_TOGGLE_STORAGE_MANAGER = 489;
-
- // OPEN: Settings > Display -> Ambient Display
- // CATEGORY: SETTINGS
- ACTION_AMBIENT_DISPLAY = 495;
-
- // ACTION: Allow Battery optimization for an app
- APP_SPECIAL_PERMISSION_BATTERY_ALLOW = 764;
-
- // ACTION: Deny Battery optimization for an app
- APP_SPECIAL_PERMISSION_BATTERY_DENY = 765;
-
- // ACTION: Enable Device Admin app
- APP_SPECIAL_PERMISSION_ADMIN_ALLOW = 766;
-
- // ACTION: Disable Device Admin app
- APP_SPECIAL_PERMISSION_ADMIN_DENY = 767;
-
- // ACTION: Allow "Do Not Disturb access" for an app
- APP_SPECIAL_PERMISSION_DND_ALLOW = 768;
-
- // ACTION: Deny "Do Not Disturb access" for an app
- APP_SPECIAL_PERMISSION_DND_DENY = 769;
-
- // ACTION: Allow "Draw over other apps" for an app
- APP_SPECIAL_PERMISSION_APPDRAW_ALLOW = 770;
-
- // ACTION: Deny "Display over other apps" for an app
- APP_SPECIAL_PERMISSION_APPDRAW_DENY = 771;
-
- // ACTION: Allow "VR helper services" for an app
- APP_SPECIAL_PERMISSION_VRHELPER_ALLOW = 772;
-
- // ACTION: Deny "VR helper services" for an app
- APP_SPECIAL_PERMISSION_VRHELPER_DENY = 773;
-
- // ACTION: Allow "Modify system settings" for an app
- APP_SPECIAL_PERMISSION_SETTINGS_CHANGE_ALLOW = 774;
-
- // ACTION: Deny "Modify system settings" for an app
- APP_SPECIAL_PERMISSION_SETTINGS_CHANGE_DENY = 775;
-
- // ACTION: Allow "Notification access" for an app
- APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW = 776;
-
- // ACTION: Deny "Notification access" for an app
- APP_SPECIAL_PERMISSION_NOTIVIEW_DENY = 777;
-
- // ACTION: "Premium SMS access" for an app - "ask user" option
- APP_SPECIAL_PERMISSION_PREMIUM_SMS_ASK = 778;
-
- // ACTION: "Premium SMS access" for an app - "never allow" option
- APP_SPECIAL_PERMISSION_PREMIUM_SMS_DENY = 779;
-
- // ACTION: "Premium SMS access" for an app - "always allow" option
- APP_SPECIAL_PERMISSION_PREMIUM_SMS_ALWAYS_ALLOW = 780;
-
- // ACTION: Allow "Unrestricted data access" for an app
- APP_SPECIAL_PERMISSION_UNL_DATA_ALLOW = 781;
-
- // ACTION: Deny "Unrestricted data access" for an app
- APP_SPECIAL_PERMISSION_UNL_DATA_DENY = 782;
-
- // ACTION: Allow "Usage access" for an app
- APP_SPECIAL_PERMISSION_USAGE_VIEW_ALLOW = 783;
-
- // ACTION: Deny "Usage access" for an app
- APP_SPECIAL_PERMISSION_USAGE_VIEW_DENY = 784;
-
- // ACTION: "Force stop" action on an app
- ACTION_APP_FORCE_STOP = 807;
-
- // ACTION: Allow "Enable picture-in-picture" for an app
- APP_PICTURE_IN_PICTURE_ALLOW = 813;
-
- // ACTION: Create a Settings shortcut item.
- ACTION_SETTINGS_CREATE_SHORTCUT = 829;
-
- // ACTION: A tile in Settings information architecture is clicked
- ACTION_SETTINGS_TILE_CLICK = 830;
-
- // ACTION: Settings advanced button is expanded
- ACTION_SETTINGS_ADVANCED_BUTTON_EXPAND = 834;
-
- // ACTION: Deny "Enable picture-in-picture" for an app
- APP_PICTURE_IN_PICTURE_DENY = 814;
-
- // ACTION: Settings -> Display -> Theme
- ACTION_THEME = 816;
-
- // ACTION: Settings > About device > Build number
- ACTION_SETTINGS_BUILD_NUMBER_PREF = 847;
-
- // ACTION: Settings > Battery > Menu > Optimization
- ACTION_SETTINGS_MENU_BATTERY_OPTIMIZATION = 851;
-
- // ACTION: Settings > Battery > Menu > Apps Toggle
- ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE = 852;
-
- // ACTION: Settings > Any preference is changed
- ACTION_SETTINGS_PREFERENCE_CHANGE = 853;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Available devices
- ACTION_SETTINGS_BLUETOOTH_PAIR = 866;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Paired devices
- ACTION_SETTINGS_BLUETOOTH_CONNECT = 867;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Connected device
- ACTION_SETTINGS_BLUETOOTH_DISCONNECT = 868;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Error dialog
- ACTION_SETTINGS_BLUETOOTH_CONNECT_ERROR = 869;
-
- // ACTION: Settings > Connected devices > Bluetooth master switch Toggle
- ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE = 870;
-
- // ACTION: Settings > App detail > Uninstall
- ACTION_SETTINGS_UNINSTALL_APP = 872;
-
- // ACTION: Settings > App detail > Uninstall Device admin app
- ACTION_SETTINGS_UNINSTALL_DEVICE_ADMIN = 873;
-
- // ACTION: Settings > App detail > Disable app
- ACTION_SETTINGS_DISABLE_APP = 874;
-
- // ACTION: Settings > App detail > Enable app
- ACTION_SETTINGS_ENABLE_APP = 875;
-
- // ACTION: Settings > App detail > Clear data
- ACTION_SETTINGS_CLEAR_APP_DATA = 876;
-
- // ACTION: Settings > App detail > Clear cache
- ACTION_SETTINGS_CLEAR_APP_CACHE = 877;
-
- // ACTION: Logs pressing the "Clear app" button in the app info settings page for an instant
- // app.
- // VALUE: The package name of the app
- ACTION_SETTINGS_CLEAR_INSTANT_APP = 923;
-
- // OPEN: Assist Gesture training intro in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE_TRAINING_INTRO = 991;
-
- // OPEN: Assist Gesture training enrolling in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE_TRAINING_ENROLLING = 992;
-
- // OPEN: Assist Gesture training finished in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE_TRAINING_FINISHED = 993;
-
- // ACTION: Update default app from Settings
- ACTION_SETTINGS_UPDATE_DEFAULT_APP = 1000;
-
- // ACTION: Settings > Wi-Fi > [Long press network] > Sign in to network
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_WIFI_SIGNIN = 1008;
-
- // ACTION: Settings > Notification Settings > Open application notification
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_OPEN_APP_NOTIFICATION_SETTING = 1016;
-
- // ACTION: Settings > App Info > Open app settings
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_OPEN_APP_SETTING = 1017;
-
- // ACTION: Collect PSD Signals
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_PSD_LOADER = 1019;
-
- // OPEN: Settings > Trampoline Intent > Settings page
- // CATEGORY: SETTINGS
- // OS: O DR
- TRAMPOLINE_SETTINGS_EVENT = 1033;
-
- // ACTION: Logged when user tries to pair a Bluetooth device without name from Settings app
- // CATEGORY: SETTINGS
- // OS: O MR
- ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES = 1096;
-
- // ACTION: Settings > Network & Internet > Mobile network > Network
- // CATEGORY: SETTINGS
- ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK = 1210;
-
- // ACTION: DND Settings > Priority only allows > Alarms toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ALLOW_ALARMS = 1226;
-
- // ACTION: DND Settings > Priority only allows > Media toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ALLOW_MEDIA = 1227;
-
- // ACTION: A private dns mode been selected by user
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_PRIVATE_DNS_MODE = 1249;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Select rule ("Event") > Rule name > OK
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK = 1267;
-
- // OPEN: Settings > Sound > Do Not Disturb > TURN ON NOW/TURN OFF NOW
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_TOGGLE_DND_BUTTON = 1268;
-
- // ACTION: DND Settings > What to block > full screen intents
- // SUBTYPE: false is allowed, true is blocked
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_BLOCK_FULL_SCREEN_INTENTS = 1332;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_LIGHT = 1333;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_PEEK = 1334;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_STATUS = 1335;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_BADGE = 1336;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_AMBIENT = 1337;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_NOTIFICATION_LIST = 1338;
-
- // ACTION: DND Settings > Priority only allows > System toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ALLOW_SYSTEM = 1340;
-
- // ACTION: Settings > Battery settings > Battery tip > App restriction tip
- // OS: P
- ACTION_APP_RESTRICTION_TIP = 1347;
-
- // ACTION: Settings > Battery settings > Battery tip > High usage tip
- // OS: P
- ACTION_HIGH_USAGE_TIP = 1348;
-
- // ACTION: Settings > Battery settings > Battery tip > Summary tip
- // OS: P
- ACTION_SUMMARY_TIP = 1349;
-
- // ACTION: Settings > Battery settings > Battery tip > Smart battery tip
- // OS: P
- ACTION_SMART_BATTERY_TIP = 1350;
-
- // ACTION: Settings > Battery settings > Battery tip > Early warning tip
- // OS: P
- ACTION_EARLY_WARNING_TIP = 1351;
-
- // ACTION: Settings > Battery settings > Battery tip > Low battery tip
- // OS: P
- ACTION_LOW_BATTERY_TIP = 1352;
-
- // ACTION: Settings > Battery settings > Battery tip > App restriction list shown
- // OS: P
- ACTION_APP_RESTRICTION_TIP_LIST = 1353;
-
- // ACTION: Settings > Battery settings > Battery tip > High usage list shown
- // OS: P
- ACTION_HIGH_USAGE_TIP_LIST = 1354;
-
- // ACTION: Settings > Battery settings > Battery tip > Open app restriction page
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_OPEN_APP_RESTRICTION_PAGE = 1361;
-
- // ACTION: Settings > Battery settings > Battery tip > Restrict app
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_RESTRICT_APP = 1362;
-
- // ACTION: Settings > Battery settings > Battery tip > Unrestrict app
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_UNRESTRICT_APP = 1363;
-
- // ACTION: Settings > Battery settings > Battery tip > Open smart battery page
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_OPEN_SMART_BATTERY = 1364;
-
- // ACTION: Settings > Battery settings > Battery tip > Turn on battery saver
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_TURN_ON_BATTERY_SAVER = 1365;
-
- // ACTION: Settings > Anomaly receiver > Anomaly received
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ANOMALY_TRIGGERED = 1367;
-
- // ACTION: A Settings Slice is requested
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_SETTINGS_SLICE_REQUESTED = 1371;
-
- // ACTION: A Settings Slice is updated with new value
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_SETTINGS_SLICE_CHANGED = 1372;
-
- // OPEN: DND onboarding activity > Ok button
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ONBOARDING_OK = 1378;
-
- // OPEN: DND onboarding activity > Settings link
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ONBOARDING_SETTINGS = 1379;
-
- // ACTION: Settings > Anomaly receiver > Anomaly ignored, don't show up in battery settings
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ANOMALY_IGNORED = 1387;
-
- // ACTION: Settings > Battery settings > Battery tip > Open battery saver page
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_OPEN_BATTERY_SAVER_PAGE = 1388;
-
- // ACTION: DND Settings > What to block
- // OS: P
- ACTION_ZEN_SOUND_ONLY = 1396;
-
- // ACTION: DND Settings > Notifications
- // OS: P
- ACTION_ZEN_SOUND_AND_VIS_EFFECTS = 1397;
-
- // ACTION: DND Settings > Notifications
- // OS: P
- ACTION_ZEN_SHOW_CUSTOM = 1398;
-
- // ACTION: DND Settings > Notifications
- // OS: P
- ACTION_ZEN_CUSTOM = 1399;
-
- // OPEN: DND onboarding activity > don't update button
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS = 1406;
-
- // ACTION: Storage initialization wizard initialization choice of external/portable
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_INIT_EXTERNAL = 1407;
-
- // ACTION: Storage initialization wizard initialization choice of internal/adoptable
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_INIT_INTERNAL = 1408;
-
- // ACTION: Storage initialization wizard benchmark fast choice of continue
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_BENCHMARK_FAST_CONTINUE = 1409;
-
- // ACTION: Storage initialization wizard benchmark slow choice of continue
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_BENCHMARK_SLOW_CONTINUE = 1410;
-
- // ACTION: Storage initialization wizard benchmark slow choice of abort
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_BENCHMARK_SLOW_ABORT = 1411;
-
- // ACTION: Storage initialization wizard migration choice of now
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_MIGRATE_NOW = 1412;
-
- // ACTION: Storage initialization wizard migration choice of later
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_MIGRATE_LATER = 1413;
-
- // OPEN: Settings > Sound > Switch a2dp devices dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_SWITCH_A2DP_DEVICES = 1415;
-
-
- // OPEN: Settings > Sound > Switch hfp devices dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_SWITCH_HFP_DEVICES = 1416;
-
- // OPEN: QS Sensor Privacy Mode tile shown
- // ACTION: QS Sensor Privacy Mode tile tapped
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: QUICK_SETTINGS
- // OS: Q
- QS_SENSOR_PRIVACY = 1598;
-
- // ACTION: Tap & Pay -> Default Application Setting -> Use Forground
- ACTION_NFC_PAYMENT_FOREGROUND_SETTING = 1622;
-
- // ACTION: Tap & Pay -> Default Application Setting -> Use Default
- ACTION_NFC_PAYMENT_ALWAYS_SETTING = 1623;
-
- // ACTION: Settings > Search Bar > Avatar
- // CATEGORY: SETTINGS
- // OS: Q
- CLICK_ACCOUNT_AVATAR = 1643;
-
- // ACTION: Set new password (action intent android.app.action.SET_NEW_PASSWORD)
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_SET_NEW_PASSWORD = 1645;
-
- // ACTION: Set new password (action intent android.app.action.SET_NEW_PARENT_PROFILE_PASSWORD)
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_SET_NEW_PARENT_PROFILE_PASSWORD = 1646;
-
- // ACTION: An interaction with a Slice or other component in the Panel.
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_PANEL_INTERACTION = 1658;
-
- // ACTION: Show Contextual homepage. Log total loading latency.
- ACTION_CONTEXTUAL_HOME_SHOW = 1662;
-
- // ACTION: Contextual card displays
- ACTION_CONTEXTUAL_CARD_SHOW = 1663;
-
- // ACTION: Contextual cards are eligible to be shown, but don't rank high
- ACTION_CONTEXTUAL_CARD_NOT_SHOW = 1664;
-
- // ACTION: Settings > long press a card, and click dismiss
- // Contextual card is dismissed
- ACTION_CONTEXTUAL_CARD_DISMISS = 1665;
-
- // ACTION: Settings > click a card
- // Contextual card is clicked
- ACTION_CONTEXTUAL_CARD_CLICK = 1666;
-
- // Mapping: go/at-mapping
- ACTION_ATSG = 1674;
-
- ACTION_ATPG = 1675;
-
- ACTION_ATCLPB = 1676;
-
- ACTION_ATCGIB = 1677;
-
- ACTION_ATCPAB = 1678;
-
- ACTION_ATCSAUC = 1679;
-
- ACTION_ATCSCUC = 1680;
-
- ACTION_ATCHNUC = 1681;
-
- // ACTION: Individual contextual card loading time
- ACTION_CONTEXTUAL_CARD_LOAD = 1684;
-
- //ACTION: Contextual card loading timeout
- ACTION_CONTEXTUAL_CARD_LOAD_TIMEOUT = 1685;
-
- //ACTION: Log result for each card's eligibility check
- ACTION_CONTEXTUAL_CARD_ELIGIBILITY = 1686;
-
- // ACTION: Display white balance setting enabled or disabled.
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_DISPLAY_WHITE_BALANCE_SETTING_CHANGED = 1703;
-
- // ACTION: Share a Wi-Fi network by generating a QR code
- ACTION_SETTINGS_SHARE_WIFI_QR_CODE = 1710;
-
- // ACTION: Connect to a Wi-Fi network by scanning a QR code
- ACTION_SETTINGS_ENROLL_WIFI_QR_CODE = 1711;
-
- // ACTION: Share Wi-Fi hotspot by generating a QR code
- ACTION_SETTINGS_SHARE_WIFI_HOTSPOT_QR_CODE = 1712;
-
- // ACTION: Settings > Initialize Search bar > Verify Slice > Invalid data
- ACTION_VERIFY_SLICE_ERROR_INVALID_DATA = 1725;
-
- // ACTION: Settings > Initialize Search bar > Verify Slice > Parsing error
- ACTION_VERIFY_SLICE_PARSING_ERROR = 1726;
-
- // ACTION: Settings > Initialize Search bar > Verify Slice > Other exception
- ACTION_VERIFY_SLICE_OTHER_EXCEPTION = 1727;
-
- // Custom tag to evaluate the consuming time of the Controller.updateState.
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_CONTROLLER_UPDATE_STATE = 1728;
-
- // Custom tag to evaluate the consuming time from onAttach to
- // DashboardFragment.updatePreferenceStates.
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_DASHBOARD_VISIBLE_TIME = 1729;
-
- // ACTION: Allow "Access all files" for an app
- APP_SPECIAL_PERMISSION_MANAGE_EXT_STRG_ALLOW = 1730;
-
- // ACTION: Deny "Access all files" for an app
- APP_SPECIAL_PERMISSION_MANAGE_EXT_STRG_DENY = 1731;
-
- // ACTION: Battery feature usage
- ACTION_BATTERY_OPTION_FEATURE_USAGE = 1732;
-
- // ACTION: Battery feature runtime event
- ACTION_BATTERY_OPTION_RUNTIME_EVENT = 1733;
-
- // ACTION: Settings > Developer Options > Toggle on Wireless debugging
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_ADB_WIRELESS_ON = 1734;
-
- // ACTION: Settings > Developer Options > Toggle off Wireless debugging
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_ADB_WIRELESS_OFF = 1735;
-
- // ACTION: Change Wi-Fi hotspot name
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_NAME = 1736;
-
- // ACTION: Change Wi-Fi hotspot password
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_PASSWORD = 1737;
-
- // ACTION: Settings > Security > Toggle on Confirm Sim deletion
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_CONFIRM_SIM_DELETION_ON = 1738;
-
- // ACTION: Settings > Security > Toggle off Confirm Sim deletion
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_CONFIRM_SIM_DELETION_OFF = 1739;
-}
-
-/**
- * Id for Settings pages. Each page must have its own unique Id.
- */
-enum PageId {
- // Unknown page. Should not be used in production code.
- PAGE_UNKNOWN = 0;
-
- // OPEN: Settings > Accessibility
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY = 2;
-
- // OPEN: Settings > Accessibility > Captions preference
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_CAPTION_PROPERTIES = 3;
-
- // OPEN: Settings > Accessibility > [Service]
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_SERVICE = 4;
-
- // OPEN: Settings > Accessibility > Color correction
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_TOGGLE_DALTONIZER = 5;
-
- // OPEN: Settings > Accessibility > Accessibility shortcut
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE = 6;
-
- // OPEN: Settings > Accessibility > Magnification gestures (Renamed in O)
- // OPEN: Settings > Accessibility > Magnification > Magnify with triple-tap
- // OPEN: Settings > Accessibility > Magnification > Magnify with button
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 7;
-
- // OPEN: Settings > Accounts
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCOUNT = 8;
-
- // OPEN: Settings > Accounts > [Single Account Sync Settings]
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCOUNTS_ACCOUNT_SYNC = 9;
-
- // OPEN: Settings > Accounts > Add an account
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10;
-
- // OPEN: Settings > Cellular network settings > APNs
- // CATEGORY: SETTINGS
- // OS: 6.0
- APN = 12;
-
- // OPEN: Settings > More > Cellular network settings > APNs > [Edit APN]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APN_EDITOR = 13;
-
- // OPEN: Settings > Apps > Configure apps > App links > [App]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_APP_LAUNCH = 17;
-
- // OPEN: Settings > Internal storage > Apps storage > [App]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_APP_STORAGE = 19;
-
- // OPEN: Settings > Apps > [App info]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_INSTALLED_APP_DETAILS = 20;
-
- // OPEN: Settings > Memory > App usage > [App Memory usage]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_PROCESS_STATS_DETAIL = 21;
-
- // OPEN: Settings > Memory > App usage
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_PROCESS_STATS_UI = 23;
-
- // OPEN: Choose Bluetooth device (ex: when sharing)
- // CATEGORY: SETTINGS
- // OS: 6.0
- BLUETOOTH_DEVICE_PICKER = 25;
-
- // OPEN: Settings > Security > Choose screen lock
- // CATEGORY: SETTINGS
- // OS: 6.0
- CHOOSE_LOCK_GENERIC = 27;
-
- // OPEN: Settings > Security > Choose screen lock > Choose your password
- // CATEGORY: SETTINGS
- // OS: 6.0
- CHOOSE_LOCK_PASSWORD = 28;
-
- // OPEN: Settings > Security > Choose screen lock > Choose your pattern
- // CATEGORY: SETTINGS
- // OS: 6.0
- CHOOSE_LOCK_PATTERN = 29;
-
- // OPEN: Settings > Security > Choose screen lock > Confirm your password
- // CATEGORY: SETTINGS
- // OS: 6.0
- CONFIRM_LOCK_PASSWORD = 30;
-
- // OPEN: Settings > Security > Choose screen lock > Confirm your pattern
- // CATEGORY: SETTINGS
- // OS: 6.0
- CONFIRM_LOCK_PATTERN = 31;
-
- // OPEN: Settings > Security > Encrypt phone
- // CATEGORY: SETTINGS
- // OS: 6.0
- CRYPT_KEEPER = 32;
-
- // OPEN: Settings > Security > Encrypt phone > Confirm
- // CATEGORY: SETTINGS
- // OS: 6.0
- CRYPT_KEEPER_CONFIRM = 33;
-
- // OPEN: Settings (Root page)
- // CATEGORY: SETTINGS
- // OS: 6.0
- DASHBOARD_SUMMARY = 35;
-
- // OPEN: Settings > Data usage
- // CATEGORY: SETTINGS
- // OS: 6.0
- DATA_USAGE_SUMMARY = 37;
-
- // OPEN: Settings > Date & time
- // CATEGORY: SETTINGS
- // OS: 6.0
- DATE_TIME = 38;
-
- // OPEN: Settings > Developer options
- // CATEGORY: SETTINGS
- // OS: 6.0
- DEVELOPMENT = 39;
-
- // OPEN: Settings > About phone
- // CATEGORY: SETTINGS
- // OS: 6.0
- DEVICEINFO = 40;
-
- // OPEN: Settings > Internal storage
- // CATEGORY: SETTINGS
- // OS: 6.0
- DEVICEINFO_STORAGE = 42;
-
- // OPEN: Settings > Display
- // CATEGORY: SETTINGS
- // OS: 6.0
- DISPLAY = 46;
-
- // OPEN: Settings > Display > Daydream
- // CATEGORY: SETTINGS
- // OS: 6.0
- DREAM = 47;
-
- // OPEN: Settings > Security > Screen lock > Secure start-up
- // CATEGORY: SETTINGS
- // OS: 6.0
- ENCRYPTION = 48;
-
- // OPEN: Settings > Security > Nexus Imprint
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT = 49;
-
- // OPEN: Settings > Battery > History details
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_BATTERY_HISTORY_DETAIL = 51;
-
- // OPEN: Settings > Battery > Battery saver
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_BATTERY_SAVER = 52;
-
- // OPEN: Settings > Battery > [App Use details]
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_POWER_USAGE_DETAIL = 53;
-
- // OPEN: Settings > Security > SIM card lock settings
- // CATEGORY: SETTINGS
- // OS: 6.0
- ICC_LOCK = 56;
-
- // OPEN: Settings > Language & input > Physical keyboard
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_KEYBOARD = 58;
-
- // OPEN: Settings > Language & input > Spell checker
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_SPELL_CHECKERS = 59;
-
- // OBSOLETE
- INPUTMETHOD_SUBTYPE_ENABLER = 60;
-
- // OPEN: Settings > Language & input > Personal dictionary
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_USER_DICTIONARY = 61;
-
- // OPEN: Settings > Language & input > Add word
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62;
-
- // OPEN: Settings > Location
- // CATEGORY: SETTINGS
- // OS: 6.0
- LOCATION = 63;
-
- // OPEN: Settings > Apps
- // CATEGORY: SETTINGS
- // OS: 6.0
- MANAGE_APPLICATIONS = 65;
-
- // OPEN: Settings > Backup & reset > Factory data reset
- // CATEGORY: SETTINGS
- // OS: 6.0
- MASTER_CLEAR = 66;
-
- // OPEN: Settings > Backup & reset > Factory data reset > Confirm
- // CATEGORY: SETTINGS
- // OS: 6.0
- MASTER_CLEAR_CONFIRM = 67;
-
- // OPEN: Settings > More > Android Beam
- // CATEGORY: SETTINGS
- // OS: 6.0
- NFC_BEAM = 69;
-
- // OPEN: Settings > Tap & pay
- // CATEGORY: SETTINGS
- // OS: 6.0
- NFC_PAYMENT = 70;
-
- // OPEN: Settings > Sound & notification > App notifications > [App]
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_APP_NOTIFICATION = 72;
-
- // OBSOLETE
- NOTIFICATION_REDACTION = 74;
-
- // OPEN: Settings Widget > Notification log
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_STATION = 75;
-
- // OPEN: Settings > Sound & notification > Do not disturb
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE = 76;
-
-
- // OPEN: Print job notification > Print job settings
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRINT_JOB_SETTINGS = 78;
-
- // OPEN: Settings > Printing > [Print Service]
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRINT_SERVICE_SETTINGS = 79;
-
- // OPEN: Settings > Printing
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRINT_SETTINGS = 80;
-
- // OPEN: Settings > Backup & reset
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRIVACY = 81;
-
- //OBSOLETE
- PROXY_SELECTOR = 82;
-
- // OPEN: Settings > Backup & reset > Network settings reset
- // CATEGORY: SETTINGS
- // OS: 6.0
- RESET_NETWORK = 83;
-
- // OPEN: Settings > Backup & reset > Network settings reset > Confirm
- // CATEGORY: SETTINGS
- // OS: 6.0
- RESET_NETWORK_CONFIRM = 84;
-
- // OPEN: Settings > Developer Options > Running Services
- // CATEGORY: SETTINGS
- // OS: 6.0
- RUNNING_SERVICE_DETAILS = 85;
-
- // OPEN: Settings > Security > Screen pinning
- // CATEGORY: SETTINGS
- // OS: 6.0
- SCREEN_PINNING = 86;
-
- // OPEN: Settings > Security
- // CATEGORY: SETTINGS
- // OS: 6.0
- SECURITY = 87;
-
- // OPEN: Settings > SIM cards
- // CATEGORY: SETTINGS
- // OS: 6.0
- SIM = 88;
-
- // OBSOLETE
- TESTING = 89;
-
- // OPEN: Settings > More > Tethering & portable hotspot
- // CATEGORY: SETTINGS
- // OS: 6.0
- TETHER = 90;
-
- // OPEN: Settings > Security > Trust agents
- // CATEGORY: SETTINGS
- // OS: 6.0
- TRUST_AGENT = 91;
-
- // OPEN: Settings > Security > Trusted credentials
- // CATEGORY: SETTINGS
- // OS: 6.0
- TRUSTED_CREDENTIALS = 92;
-
- // OPEN: Settings > Language & input > TTS output > [Engine] > Settings
- // CATEGORY: SETTINGS
- // OS: 6.0
- TTS_ENGINE_SETTINGS = 93;
-
- // OPEN: Settings > Language & input > Text-to-speech output
- // CATEGORY: SETTINGS
- // OS: 6.0
- TTS_TEXT_TO_SPEECH = 94;
-
- // OPEN: Settings > Security > Apps with usage access
- // CATEGORY: SETTINGS
- // OS: 6.0
- USAGE_ACCESS = 95;
-
- // OPEN: Settings > Users
- // CATEGORY: SETTINGS
- // OS: 6.0
- USER = 96;
-
- // OPEN: Settings > Users > [Restricted profile app & content access]
- // CATEGORY: SETTINGS
- // OS: 6.0
- USERS_APP_RESTRICTIONS = 97;
-
- // OPEN: Settings > Users > [User settings]
- // CATEGORY: SETTINGS
- // OS: 6.0
- USER_DETAILS = 98;
-
- // OPEN: Settings > More > VPN
- // CATEGORY: SETTINGS
- // OS: 6.0
- VPN = 100;
-
- // OPEN: Settings > Display > Choose wallpaper from
- // CATEGORY: SETTINGS
- // OS: 6.0
- WALLPAPER_TYPE = 101;
-
- // OPEN: Settings > Display > Cast
- // CATEGORY: SETTINGS
- // OS: 6.0
- WFD_WIFI_DISPLAY = 102;
-
- // OPEN: Settings > Wi-Fi
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI = 103;
-
- // OPEN: Settings > More > Wi-Fi Calling
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI_CALLING = 105;
-
- // OPEN: Settings > Wi-Fi > Saved networks
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI_SAVED_ACCESS_POINTS = 106;
-
- // OPEN: Settings > Wi-Fi > Advanced Wi-Fi > Wi-Fi Direct
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI_P2P = 109;
-
- // OPEN: Settings > Apps > Configure apps > App permissions
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_ADVANCED = 130;
-
- // OPEN: Settings > Location > Scanning
- // CATEGORY: SETTINGS
- // OS: 6.0
- LOCATION_SCANNING = 131;
-
- // OPEN: Settings > Sound & notification > App notifications
- // CATEGORY: SETTINGS
- // OS: 6.0
- MANAGE_APPLICATIONS_NOTIFICATIONS = 133;
-
- // OPEN: Settings > Sound & notification > DND > Priority only allows
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_PRIORITY = 141;
-
- // OPEN: Settings > Sound & notification > DND > Automatic rules
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_AUTOMATION = 142;
-
- // OPEN: Settings > Sound & notification > DND > [Time based rule]
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
-
- // OPEN: Settings > Apps > Configure apps > App links
- // CATEGORY: SETTINGS
- // OS: 6.0
- MANAGE_DOMAIN_URLS = 143;
-
- // OPEN: Settings > Sound & notification > DND > [Event rule]
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_EVENT_RULE = 146;
-
- // OPEN: Settings > Sound & notification > Notification access
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ACCESS = 179;
-
- // OPEN: Settings > Sound & notification > Do Not Disturb access
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_ACCESS = 180;
-
- // OPEN: Settings > Internal storage > Apps storage
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_STORAGE_APPS = 182;
-
- // OPEN: Settings > Security > Usage access
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_USAGE_ACCESS_DETAIL = 183;
-
- // OPEN: Settings > Battery > Battery optimization
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_HIGH_POWER_APPS = 184;
-
- // OPEN: Settings > Apps > Configure > Default apps > Assist & voice input
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_MANAGE_ASSIST = 201;
-
- // OPEN: Settings > Memory
- // CATEGORY: SETTINGS
- // OS: 6.0
- PROCESS_STATS_SUMMARY = 202;
-
- // OPEN: Settings > Apps > Configure Apps > Display over other apps
- // CATEGORY: SETTINGS
- // OS: 6.0
- SYSTEM_ALERT_WINDOW_APPS = 221;
-
- // OPEN: Settings > About phone > Legal information
- // CATEGORY: SETTINGS
- // OS: 6.0
- ABOUT_LEGAL_SETTINGS = 225;
-
-
- // OPEN: Settings > Developer options > Inactive apps
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_INACTIVE_APPS = 238;
-
- // OPEN: Settings > Security > Nexus Imprint > Add Fingerprint
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLLING = 240;
- // OPEN: Fingerprint Enroll > Find Sensor
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_FIND_SENSOR = 241;
-
- // OPEN: Fingerprint Enroll > Fingerprint Enrolled!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_FINISH = 242;
-
- // OPEN: Fingerprint Enroll introduction
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_INTRO = 243;
-
- // OPEN: Fingerprint Enroll > Let's Start!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_SIDECAR = 245;
-
- // OPEN: Fingerprint Enroll SUW > Let's Start!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLLING_SETUP = 246;
-
- // OPEN: Fingerprint Enroll SUW > Find Sensor
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_FIND_SENSOR_SETUP = 247;
-
- // OPEN: Fingerprint Enroll SUW > Fingerprint Enrolled!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_FINISH_SETUP = 248;
-
- // OPEN: Fingerprint Enroll SUW introduction
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_INTRO_SETUP = 249;
-
- // OPEN: Settings > Developer Options > Background Check
- // CATEGORY: SETTINGS
- // OS: N
- BACKGROUND_CHECK_SUMMARY = 258;
-
- // OPEN: Settings > Notifications > [App] > Channel Notifications
- // CATEGORY: SETTINGS
- // OS: N
- NOTIFICATION_TOPIC_NOTIFICATION = 265;
-
- // OPEN: Settings > Security > User credentials
- // CATEGORY: Settings
- // OS: N
- USER_CREDENTIALS = 285;
-
- // Logs that the user has edited the enabled VR listeners.
- // CATEGORY: SETTINGS
- // OS: N
- VR_MANAGE_LISTENERS = 334;
-
- // Settings -> Accessibility -> Click after pointer stops moving
- // CATEGORY: SETTINGS
- // OS: N
- ACCESSIBILITY_TOGGLE_AUTOCLICK = 335;
-
- // Settings -> Sound
- // CATEGORY: SETTINGS
- // OS: N
- SOUND = 336;
-
- // Settings -> Notifications -> Gear
- // CATEGORY: SETTINGS
- // OS: N
- CONFIGURE_NOTIFICATION = 337;
-
- // Settings -> Wi-Fi -> Gear
- // CATEGORY: SETTINGS
- // OS: N
- CONFIGURE_WIFI = 338;
-
- // Settings -> Display -> Display size
- // OS: N
- DISPLAY_SCREEN_ZOOM = 339;
-
- // Settings -> Display -> Font size
- // CATEGORY: SETTINGS
- // OS: N
- ACCESSIBILITY_FONT_SIZE = 340;
-
- // Settings -> Data usage -> Cellular/Wi-Fi data usage
- // CATEGORY: SETTINGS
- // OS: N
- DATA_USAGE_LIST = 341;
-
- // Settings -> Data usage -> Billing cycle or DATA_USAGE_LIST -> Gear
- // CATEGORY: SETTINGS
- // OS: N
- BILLING_CYCLE = 342;
-
- // DATA_USAGE_LIST -> Any item or App info -> Data usage
- // CATEGORY: SETTINGS
- // OS: N
- APP_DATA_USAGE = 343;
-
- // Settings -> Language & input -> Language
- // CATEGORY: SETTINGS
- // OS: N
- USER_LOCALE_LIST = 344;
-
- // Settings -> Language & input -> Virtual keyboard
- // CATEGORY: SETTINGS
- // OS: N
- VIRTUAL_KEYBOARDS = 345;
-
- // Settings -> Language & input -> Physical keyboard
- // CATEGORY: SETTINGS
- // OS: N
- PHYSICAL_KEYBOARDS = 346;
-
- // Settings -> Language & input -> Virtual keyboard -> Add a virtual keyboard
- // CATEGORY: SETTINGS
- // OS: N
- ENABLE_VIRTUAL_KEYBOARDS = 347;
-
- // Settings -> Data usage -> Data Saver
- // CATEGORY: SETTINGS
- // OS: N
- DATA_SAVER_SUMMARY = 348;
-
- // Settings -> Data usage -> Data Saver -> Unrestricted data access
- // CATEGORY: SETTINGS
- // OS: N
- DATA_USAGE_UNRESTRICTED_ACCESS = 349;
-
- // Settings -> Apps -> Gear -> Special access
- SPECIAL_ACCESS = 351;
-
- // OPEN: SUW Welcome Screen -> Vision Settings
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY = 367;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification gestures (Renamed in O)
- // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification -> Magnify with triple-tap
- // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification -> Magnify with button
- // ACTION: New magnification gesture configuration is chosen
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 368;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Font size
- // ACTION: New font size is chosen
- // SUBTYPE: 0 is small, 1 is default, 2 is large, 3 is largest
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_FONT_SIZE = 369;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Display size
- // ACTION: New display size is chosen
- // SUBTYPE: 0 is small, 1 is default, 2 is large, 3 is larger, 4 is largest
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_DISPLAY_SIZE = 370;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> TalkBack
- // ACTION: New screen reader configuration is chosen
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_TOGGLE_SCREEN_READER = 371;
-
- // Airplane mode on
- SETTINGS_CONDITION_AIRPLANE_MODE = 377;
- // AKA Data saver on
- SETTINGS_CONDITION_BACKGROUND_DATA = 378;
- // Battery saver on
- SETTINGS_CONDITION_BATTERY_SAVER = 379;
- // Cellular data off
- SETTINGS_CONDITION_CELLULAR_DATA = 380;
- // Do not disturb on
- SETTINGS_CONDITION_DND = 381;
- // Hotspot on
- SETTINGS_CONDITION_HOTSPOT = 382;
- // Work profile off
- SETTINGS_CONDITION_WORK_MODE = 383;
-
- // Settings > Apps > Gear > Special Access > Premium SMS access
- PREMIUM_SMS_ACCESS = 388;
-
- // OPEN: Settings > Accounts > Work profile settings
- // CATEGORY: SETTINGS
- ACCOUNTS_WORK_PROFILE_SETTINGS = 401;
-
- // Settings -> Dev options -> Convert to file encryption
- CONVERT_FBE = 402;
-
- // Settings -> Dev options -> Convert to file encryption -> WIPE AND CONVERT...
- CONVERT_FBE_CONFIRM = 403;
-
- // Settings -> Dev options -> Running services
- RUNNING_SERVICES = 404;
-
- // The dialog shown by 3P intent to change current webview implementation.
- WEBVIEW_IMPLEMENTATION = 405;
-
- // OPEN: Settings > Internal storage > Storage manager
- // CATEGORY: SETTINGS
- STORAGE_MANAGER_SETTINGS = 458;
-
- // OPEN: Settings -> Gestures
- // CATEGORY: SETTINGS
- SETTINGS_GESTURES = 459;
-
- // OPEN: Settings > Display > Night Light
- // CATEGORY: SETTINGS
- NIGHT_DISPLAY_SETTINGS = 488;
-
- // Night Light on
- SETTINGS_CONDITION_NIGHT_DISPLAY = 492;
-
- // OPEN: Settings > Language & input > Personal dictionary (single locale)
- USER_DICTIONARY_SETTINGS = 514;
-
- // OPEN: Settings > Date & time > Select time zone
- ZONE_PICKER = 515;
-
- // OPEN: Settings > Security > Device administrators
- DEVICE_ADMIN_SETTINGS = 516;
-
- // OPEN: Settings > Security > Factory Reset Protection dialog
- DIALOG_FRP = 528;
-
- // OPEN: Settings > Custom list preference with confirmation message
- DIALOG_CUSTOM_LIST_CONFIRMATION = 529;
-
- // OPEN: Settings > APN Editor > Error dialog
- DIALOG_APN_EDITOR_ERROR = 530;
-
- // OPEN: Settings > Users > Edit owner info dialog
- DIALOG_OWNER_INFO_SETTINGS = 531;
-
- // OPEN: Settings > Security > Use one lock dialog
- DIALOG_UNIFICATION_CONFIRMATION = 532;
-
- // OPEN: Settings > Security > User Credential
- DIALOG_USER_CREDENTIAL = 533;
-
- // OPEN: Settings > Accounts > Remove account
- DIALOG_REMOVE_USER = 534;
-
- // OPEN: Settings > Accounts > Confirm auto sync dialog
- DIALOG_CONFIRM_AUTO_SYNC_CHANGE = 535;
-
- // OPEN: Settings > Apps > Dialog for running service details
- DIALOG_RUNNIGN_SERVICE = 536;
-
- // OPEN: Settings > Bluetooth > Rename this device
- DIALOG_BLUETOOTH_RENAME = 538;
-
- // OPEN: Settings > Battery optimization > details for app
- DIALOG_HIGH_POWER_DETAILS = 540;
-
- // OPEN: Settings > Keyboard > Show keyboard layout dialog
- DIALOG_KEYBOARD_LAYOUT = 541;
-
- // OPEN: Settings > WIFI Scan permission dialog
- DIALOG_WIFI_SCAN_MODE = 543;
-
- // OPEN: Settings > Wireless > VPN > Config dialog
- DIALOG_LEGACY_VPN_CONFIG = 545;
-
- // OPEN: Settings > Wireless > VPN > Config dialog for app
- DIALOG_VPN_APP_CONFIG = 546;
-
- // OPEN: Settings > Wireless > VPN > Cannot connect dialog
- DIALOG_VPN_CANNOT_CONNECT = 547;
-
- // OPEN: Settings > Wireless > VPN > Replace existing VPN dialog
- DIALOG_VPN_REPLACE_EXISTING = 548;
-
- // OPEN: Settings > Billing cycle > Edit billing cycle dates dialog
- DIALOG_BILLING_CYCLE = 549;
-
- // OPEN: Settings > Billing cycle > Edit data limit/warning dialog
- DIALOG_BILLING_BYTE_LIMIT = 550;
-
- // OPEN: Settings > Billing cycle > turn on data limit dialog
- DIALOG_BILLING_CONFIRM_LIMIT = 551;
-
- // OPEN: Settings > Service > Turn off notification access dialog
- DIALOG_DISABLE_NOTIFICATION_ACCESS = 552;
-
- // OPEN: Settings > Sound > Use personal sound for work profile dialog
- DIALOG_UNIFY_SOUND_SETTINGS = 553;
-
- // OPEN: Settings > Zen mode > Dialog warning about the zen access privileges being granted.
- DIALOG_ZEN_ACCESS_GRANT = 554;
-
- // OPEN: Settings > Zen mode > Dialog warning about the zen access privileges being revoked.
- DIALOG_ZEN_ACCESS_REVOKE = 555;
-
- // OPEN: Settings > Zen mode > Dialog that picks time for zen mode.
- DIALOG_ZEN_TIMEPICKER = 556;
-
- // OPEN: Settings > Apps > Dialog that informs user to allow service access for app.
- DIALOG_SERVICE_ACCESS_WARNING = 557;
-
- // OPEN: Settings > Apps > Dialog for app actions (such as force stop/clear data)
- DIALOG_APP_INFO_ACTION = 558;
-
- // OPEN: Settings > Storage > Dialog for forgetting a storage device
- DIALOG_VOLUME_FORGET = 559;
-
- // OPEN: Settings > Storage > Dialog for initializing a volume
- DIALOG_VOLUME_INIT = 561;
-
- // OPEN: Settings > Storage > Dialog for unmounting a volume
- DIALOG_VOLUME_UNMOUNT = 562;
-
- // OPEN: Settings > Storage > Dialog for renaming a volume
- DIALOG_VOLUME_RENAME = 563;
-
- // OPEN: Settings > Storage > Dialog for clear cache
- DIALOG_STORAGE_CLEAR_CACHE = 564;
-
- // OPEN: Settings > Storage > Dialog for system info
- DIALOG_STORAGE_SYSTEM_INFO = 565;
-
- // OPEN: Settings > Storage > Dialog for other info
- DIALOG_STORAGE_OTHER_INFO = 566;
-
- // OPEN: Settings > Storage > Dialog for user info
- DIALOG_STORAGE_USER_INFO = 567;
- // OPEN: Settings > Add fingerprint > Dialog when user touches fingerprint icon.
- DIALOG_FINGERPRINT_ICON_TOUCH = 568;
-
- // OPEN: Settings > Add fingerprint > Error dialog
- DIALOG_FINGERPINT_ERROR = 569;
-
- // OPEN: Settings > Fingerprint > Rename or delete dialog
- DIALOG_FINGERPINT_EDIT = 570;
-
- // OPEN: Settings > Fingerprint > Dialog for deleting last fingerprint
- DIALOG_FINGERPINT_DELETE_LAST = 571;
-
- // OPEN: SUW > Fingerprint > Dialog to confirm skip fingerprint setup entirely.
- DIALOG_FINGERPRINT_SKIP_SETUP = 573;
-
- // OPEN: Settings > Proxy Selector error dialog
- DIALOG_PROXY_SELECTOR_ERROR = 574;
-
- // OPEN: Settings > Wifi > P2P Settings > Disconnect dialog
- DIALOG_WIFI_P2P_DISCONNECT = 575;
-
- // OPEN: Settings > Wifi > P2P Settings > Cancel connection dialog
- DIALOG_WIFI_P2P_CANCEL_CONNECT = 576;
-
- // OPEN: Settings > Wifi > P2P Settings > Rename dialog
- DIALOG_WIFI_P2P_RENAME = 577;
-
- // OPEN: Settings > Wifi > P2P Settings > Forget group dialog
- DIALOG_WIFI_P2P_DELETE_GROUP = 578;
-
- // OPEN: Settings > APN > Restore default dialog
- DIALOG_APN_RESTORE_DEFAULT = 579;
-
- // OPEN: Settings > Encryption interstitial accessibility warning dialog
- DIALOG_ENCRYPTION_INTERSTITIAL_ACCESSIBILITY = 581;
-
- // OPEN: Settings > Acessibility > Enable accessiblity service dialog
- DIALOG_ACCESSIBILITY_SERVICE_ENABLE = 583;
-
- // OPEN: Settings > Acessibility > Disable accessiblity service dialog
- DIALOG_ACCESSIBILITY_SERVICE_DISABLE = 584;
-
- // OPEN: Settings > Account > Remove account dialog
- DIALOG_ACCOUNT_SYNC_REMOVE = 585;
-
- // OPEN: Settings > Account > Remove account failed dialog
- DIALOG_ACCOUNT_SYNC_FAILED_REMOVAL = 586;
-
- // OPEN: Settings > Account > Cannot do onetime sync dialog
- DIALOG_ACCOUNT_SYNC_CANNOT_ONETIME_SYNC = 587;
-
- // OPEN: Settings > Display > Night light > Set start time dialog
- DIALOG_NIGHT_DISPLAY_SET_START_TIME = 588;
-
- // OPEN: Settings > Display > Night light > Set end time dialog
- DIALOG_NIGHT_DISPLAY_SET_END_TIME = 589;
-
-
-
- // OPEN: Settings > User > Edit info dialog
- DIALOG_USER_EDIT = 590;
-
- // OPEN: Settings > User > Confirm remove dialog
- DIALOG_USER_REMOVE = 591;
-
- // OPEN: Settings > User > Enable calling dialog
- DIALOG_USER_ENABLE_CALLING = 592;
-
- // OPEN: Settings > User > Enable calling and sms dialog
- DIALOG_USER_ENABLE_CALLING_AND_SMS = 593;
-
- // OPEN: Settings > User > Cannot manage device message dialog
- DIALOG_USER_CANNOT_MANAGE = 594;
-
- // OPEN: Settings > User > Add user dialog
- DIALOG_USER_ADD = 595;
-
- // OPEN: Settings > User > Setup user dialog
- DIALOG_USER_SETUP = 596;
-
- // OPEN: Settings > User > Setup profile dialog
- DIALOG_USER_SETUP_PROFILE = 597;
-
- // OPEN: Settings > User > Choose user type dialog
- DIALOG_USER_CHOOSE_TYPE = 598;
-
- // OPEN: Settings > User > Need lockscreen dialog
- DIALOG_USER_NEED_LOCKSCREEN = 599;
-
- // OPEN: Settings > User > Confirm exit guest mode dialog
- DIALOG_USER_CONFIRM_EXIT_GUEST = 600;
-
- // OPEN: Settings > User > Edit user profile dialog
- DIALOG_USER_EDIT_PROFILE = 601;
-
-
- // OPEN: Settings > Wifi > Saved AP > Edit dialog
- DIALOG_WIFI_SAVED_AP_EDIT = 602;
-
- // OPEN: Settings > Wifi > Edit AP dialog
- DIALOG_WIFI_AP_EDIT = 603;
-
- // OPEN: Settings > Wifi > Write config to NFC dialog
- DIALOG_WIFI_WRITE_NFC = 606;
-
- // OPEN: Settings > Date > Date picker dialog
- DIALOG_DATE_PICKER = 607;
-
- // OPEN: Settings > Date > Time picker dialog
- DIALOG_TIME_PICKER = 608;
-
- // OPEN: Settings > Wireless > Manage wireless plan dialog
- DIALOG_MANAGE_MOBILE_PLAN = 609;
-
- // OPEN Settings > Bluetooth > Attempt to connect to device that shows dialog
- BLUETOOTH_DIALOG_FRAGMENT = 613;
-
- // OPEN: Settings > Security
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_SETTINGS = 628;
-
- // OPEN: Settings > System
- SETTINGS_SYSTEM_CATEGORY = 744;
-
- // OPEN: Settings > Storage
- SETTINGS_STORAGE_CATEGORY = 745;
-
- // OPEN: Settings > Network & Internet
- SETTINGS_NETWORK_CATEGORY = 746;
-
- // OPEN: Settings > Connected Device
- SETTINGS_CONNECTED_DEVICE_CATEGORY = 747;
-
- // OPEN: Settings > App & Notification
- SETTINGS_APP_NOTIF_CATEGORY = 748;
-
- // OPEN: Settings > System > Language & Region
- SETTINGS_LANGUAGE_CATEGORY = 750;
-
- // OPEN: Settings > System > Input & Gesture > Swipe to notification gesture
- SETTINGS_GESTURE_SWIPE_TO_NOTIFICATION = 751;
-
- // OPEN: Settings > System > Input & Gesture > Double tap power button gesture
- SETTINGS_GESTURE_DOUBLE_TAP_POWER = 752;
-
- // OPEN: Settings > System > Input & Gesture > Pick up gesture
- SETTINGS_GESTURE_PICKUP = 753;
-
- // OPEN: Settings > System > Input & Gesture > Double tap screen gesture
- SETTINGS_GESTURE_DOUBLE_TAP_SCREEN = 754;
-
- // OPEN: Settings > System > Input & Gesture > Double twist gesture
- SETTINGS_GESTURE_DOUBLE_TWIST = 755;
-
- // OPEN: Settings > Apps > Default Apps > Default browser
- DEFAULT_BROWSER_PICKER = 785;
- // OPEN: Settings > Apps > Default Apps > Default emergency app
- DEFAULT_EMERGENCY_APP_PICKER = 786;
-
- // OPEN: Settings > Apps > Default Apps > Default home
- DEFAULT_HOME_PICKER = 787;
-
- // OPEN: Settings > Apps > Default Apps > Default phone
- DEFAULT_PHONE_PICKER = 788;
-
- // OPEN: Settings > Apps > Default Apps > Default sms
- DEFAULT_SMS_PICKER = 789;
-
- // OPEN: Settings > Apps > Notification > Notification Assistant
- DEFAULT_NOTIFICATION_ASSISTANT = 790;
-
-
- // OPEN: Settings > Apps > Default Apps > Warning dialog to confirm selection
- DEFAULT_APP_PICKER_CONFIRMATION_DIALOG = 791;
-
- // OPEN: Settings > Apps > Default Apps > Default autofill app
- DEFAULT_AUTOFILL_PICKER = 792;
-
- // OPEN: Settings > Apps > Gear > Special Access > Install other apps
- // CATEGORY: SETTINGS
- // OS: 8.0
- MANAGE_EXTERNAL_SOURCES = 808;
-
- // Logs that the user has edited the picture-in-picture settings.
- // CATEGORY: SETTINGS
- SETTINGS_MANAGE_PICTURE_IN_PICTURE = 812;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Select to Speak
- // ACTION: Select to Speak configuration is chosen
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK = 817;
-
- // OPEN: Settings > System > Backup
- // CATEGORY: SETTINGS
- // OS: O
- BACKUP_SETTINGS = 818;
-
- // OPEN: Settings > Storage > Games
- // CATEGORY: SETTINGS
- // OS: O
- APPLICATIONS_STORAGE_GAMES = 838;
-
- // OPEN: Settings > Storage > Audio and Music
- // CATEGORY: SETTINGS
- // OS: O
- APPLICATIONS_STORAGE_MUSIC = 839;
-
- // ACTION: Settings > Storage > Free Up Space to launch Deletion Helper
- // CATEGORY: SETTINGS
- // OS: O
- STORAGE_FREE_UP_SPACE_NOW = 840;
-
- // ACTION: Settings > Storage > Files to open the File Manager
- // CATEGORY: SETTINGS
- // OS: O
- STORAGE_FILES = 841;
-
- // OPEN: Settings > Apps > Default Apps > Assist > Default assist
- DEFAULT_ASSIST_PICKER = 843;
-
- // OPEN: Settings > Apps > Default Apps > Assist > Default voice input
- DEFAULT_VOICE_INPUT_PICKER = 844;
-
- // OPEN: Settings > Storage > [Profile]
- SETTINGS_STORAGE_PROFILE = 845;
-
- // OPEN: Settings > Security & screen lock -> Encryption & crendentials
- // CATEGORY: SETTINGS
- // OS: O
- ENCRYPTION_AND_CREDENTIAL = 846;
-
- // OPEN: Settings > Wi-Fi > Network Details (click on Access Point)
- // CATEGORY: SETTINGS
- // OS: O
- WIFI_NETWORK_DETAILS = 849;
-
- // OPEN: Settings > Wi-Fi > Wifi Preferences -> Advanced -> Network Scorer
- // CATEGORY: SETTINGS
- // OS: O
- SETTINGS_NETWORK_SCORER = 861;
-
- // OPEN: Settings > About device > Model > Hardware info dialog
- DIALOG_SETTINGS_HARDWARE_INFO = 862;
-
- // OPEN: Settings > Security & screen lock -> Lock screen preferences
- // CATEGORY: SETTINGS
- SETTINGS_LOCK_SCREEN_PREFERENCES = 882;
-
-
- // OPEN: Settings -> Display -> When in VR Mode
- VR_DISPLAY_PREFERENCE = 921;
-
- // OPEN: Settings > Accessibility > Magnification
- // CATEGORY: SETTINGS
- // OS: O
- ACCESSIBILITY_SCREEN_MAGNIFICATION_SETTINGS = 922;
-
- // OPEN: Settings -> System -> Reset options
- RESET_DASHBOARD = 924;
-
- // OPEN: Settings > Security > Nexus Imprint > [Fingerprint] > Delete
- // CATEGORY: SETTINGS
- // OS: O
- FINGERPRINT_REMOVE_SIDECAR = 934;
-
- // OPEN: Settings > Storage > Movies & TV
- // CATEGORY: SETTINGS
- // OS: O
- APPLICATIONS_STORAGE_MOVIES = 935;
-
- // OPEN: Settings > Security > Managed Device Info > Apps installed
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_INSTALLED_APPS = 938;
-
- // OPEN: Settings > Security > Managed Device Info > nnn permissions
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_PERMISSIONS = 939;
-
-
- // OPEN: Settings > Security > Managed Device Info > Default apps
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_DEFAULT_APPS = 940;
-
- // OPEN: Choose screen lock dialog in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_CHOOSE_LOCK_DIALOG = 990;
-
- // OPEN: Settings > System > Languages & input > Assist gesture
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE = 996;
-
- // OPEN: Settings > Connected Devices > Bluetooth > (click on details link for a paired device)
- BLUETOOTH_DEVICE_DETAILS = 1009;
-
- // OPEN: Settings > credential pages - prompt for key guard configuration confirmation
- CONFIGURE_KEYGUARD_DIALOG = 1010;
-
- // OPEN: Settings > Network > Tether > Wi-Fi hotspot
- WIFI_TETHER_SETTINGS = 1014;
-
- // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
- // -> Edit name button.
- // CATEGORY: SETTINGS
- // OS: O DR
- DIALOG_BLUETOOTH_PAIRED_DEVICE_RENAME = 1015;
-
- // OPEN: Settings > Connected devices > Bluetooth > Pair new device
- // CATEGORY: SETTINGS
- // OS: O DR
- BLUETOOTH_PAIRING = 1018;
-
- // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
- // -> Forget button.
- // CATEGORY: SETTINGS
- // OS: O DR
- DIALOG_BLUETOOTH_PAIRED_DEVICE_FORGET = 1031;
-
- // OPEN: Settings > Storage > Photos & Videos
- // CATEGORY: SETTINGS
- // OS: O MR
- APPLICATIONS_STORAGE_PHOTOS = 1092;
-
- // OPEN: Settings > Display > Colors
- // CATEGORY: SETTINGS
- // OS: O MR
- COLOR_MODE_SETTINGS = 1143;
-
- // OPEN: Settings > Developer Options > Experiment dashboard
- // CATEGORY: SETTINGS
- SETTINGS_FEATURE_FLAGS_DASHBOARD = 1217;
-
- // OPEN: Settings > Notifications > [App] > Topic Notifications
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_CHANNEL_GROUP = 1218;
-
- // OPEN: Settings > Developer options > Enable > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_ENABLE_DEVELOPMENT_OPTIONS = 1219;
-
- // OPEN: Settings > Developer options > OEM unlocking > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_ENABLE_OEM_UNLOCKING = 1220;
-
- // OPEN: Settings > Developer options > USB debugging > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_ENABLE_ADB = 1222;
-
- // OPEN: Settings > Security > Nexus Imprint > [Fingerprint]
- // CATEGORY: SETTINGS
- // OS: P
- FINGERPRINT_AUTHENTICATE_SIDECAR = 1221;
-
- // OPEN: Settings > Developer options > Revoke USB debugging authorizations > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_CLEAR_ADB_KEYS = 1223;
-
- // Open: Settings > Developer options > Quick setting tile config
- // CATEGORY: SETTINGS
- // OS: P
- DEVELOPMENT_QS_TILE_CONFIG = 1224;
-
- // OPEN: Settings > Developer options > Store logger data persistently on device > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_LOG_PERSIST = 1225;
-
- // OPEN: Settings > Network & Internet > Mobile network > Wi-Fi calling
- // CATEGORY: SETTINGS
- // OS: P
- WIFI_CALLING_FOR_SUB = 1230;
-
- // Open: Settings > Dev options > Oem unlock > lock it > warning dialog.
- // OS: P
- DIALOG_OEM_LOCK_INFO = 1238;
-
- // Open: Settings > System > About phone > IMEI
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_IMEI_INFO = 1240;
-
- // OPEN: Settings > System > About Phone > Sim status
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_SIM_STATUS = 1246;
-
- // OPEN: Settings > System > About Phone > Android Version
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_FIRMWARE_VERSION = 1247;
-
- // OPEN: Settings > Battery(version 2)
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_POWER_USAGE_SUMMARY_V2 = 1263;
-
- // OPEN: Settings > Connected devices > Connection preferences
- // CATEGORY: SETTINGS
- // OS: P
- CONNECTION_DEVICE_ADVANCED = 1264;
-
- // OPEN: Settings > Security > Screen lock gear icon
- // CATEGORY: SETTINGS
- // OS: P
- SCREEN_LOCK_SETTINGS = 1265;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Delete rule (trash can icon)
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_DELETE_RULE_DIALOG = 1266;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Add rule > Event/Time
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Select rule ("Event") > Rule name
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_RULE_NAME_DIALOG = 1269;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Add rule
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_RULE_SELECTION_DIALOG = 1270;
-
- // OPEN: Settings > Battery > Smart Battery
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_SMART_BATTERY = 1281;
-
- // OPEN: Settings > Battery > Smart Battery > Restricted apps
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_RESTRICTED_APP_DETAILS = 1285;
-
- // OPEN: Settings > Sound & notification > Do Not Disturb > Turn on now
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_ENABLE_DIALOG = 1286;
-
- // OPEN: Settings->Connected Devices->USB->(click on details link)
- // CATEGORY: SETTINGS
- // OS: P
- USB_DEVICE_DETAILS = 1291;
-
- // OPEN: Settings > Accessibility > Vibration
- // CATEGORY: SETTINGS
- // OS: P
- ACCESSIBILITY_VIBRATION = 1292;
-
- // OPEN: Settings > Accessibility > Vibration > Notification vibration
- // CATEGORY: SETTINGS
- // OS: P
- ACCESSIBILITY_VIBRATION_NOTIFICATION = 1293;
-
- // OPEN: Settings > Accessibility > Vibration > Touch vibration
- // CATEGORY: SETTINGS
- // OS: P
- ACCESSIBILITY_VIBRATION_TOUCH = 1294;
-
- // OPEN: Settings->Developer Options->Default USB
- // CATEGORY: SETTINGS
- // OS: P
- USB_DEFAULT = 1312;
-
- // OPEN: Settings > Battery > Battery tip > Battery tip Dialog
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_BATTERY_TIP_DIALOG = 1323;
-
- // OPEN: DND Settings > What to block
- // OS: P
- ZEN_WHAT_TO_BLOCK = 1339;
-
- // OPEN: Settings > Sounds > Do Not Disturb > Duration
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_DURATION_DIALOG = 1341;
-
- // OPEN: Settings > Date & time > Select time zone -> Region
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZONE_PICKER_REGION = 1355;
-
- // OPEN: Settings > Date & time > Select time zone -> Time Zone
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZONE_PICKER_TIME_ZONE = 1356;
- // OPEN: Settings > Date & time > Select time zone -> Select UTC Offset
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZONE_PICKER_FIXED_OFFSET = 1357;
-
- // OPEN: Settings > Gestures > Prevent Ringing
- // OS: P
- SETTINGS_PREVENT_RINGING = 1360;
-
- // Settings > Condition > Device muted
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_CONDITION_DEVICE_MUTED = 1368;
-
- // Settings > Condition > Device vibrate
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_CONDITION_DEVICE_VIBRATE = 1369;
-
- // OPEN: Settings > Connected devices > previously connected devices
- // CATEGORY: SETTINGS
- // OS: P
- PREVIOUSLY_CONNECTED_DEVICES = 1370;
-
- // OPEN: Settings > Network & Internet > Wi-Fi > Wi-Fi Preferences > Turn on Wi-Fi automatically
- // note: Wifi Scanning must be off for this dialog to show
- // CATEGORY: SETTINGS
- // OS: P
- WIFI_SCANNING_NEEDED_DIALOG = 1373;
-
- // OPEN: Settings > System > Gestures > System navigation
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_GESTURE_SWIPE_UP = 1374;
-
- // OPEN: Settings > Storage > Dialog to format a storage volume
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_VOLUME_FORMAT = 1375;
-
- // OPEN: DND onboarding activity
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZEN_ONBOARDING = 1380;
-
- // OPEN: Settings > Display > Auto brightness
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_AUTO_BRIGHTNESS = 1381;
-
- // OPEN: Settings > Connected Devices > Bluetooth
- // CATEGORY: SETTINGS
- // OS: P
- BLUETOOTH_FRAGMENT = 1390;
-
- // Screen: DND Settings > Notifications
- // OS: P
- SETTINGS_ZEN_NOTIFICATIONS = 1400;
-
- // An event category for slices.
- // OPEN: Slice became visible.
- // CLOSE: Slice became invisible.
- // ACTION: Slice was tapped.
- SLICE = 1401;
-
- // OPEN: Settings -> Developer Options -> Disable Bluetooth A2DP hardware
- // offload
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_BLUETOOTH_DISABLE_A2DP_HW_OFFLOAD = 1441;
-
- // OPEN: Settings homepage
- SETTINGS_HOMEPAGE = 1502;
-
- // OPEN: Settings > Create shortcut(widget)
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_CREATE_SHORTCUT = 1503;
-
- // OPEN: Face Enroll introduction
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_INTRO = 1506;
-
- // OPEN: Face Enroll introduction
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_ENROLLING = 1507;
-
- // OPEN: Face Enroll introduction
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_FINISHED = 1508;
-
- // OPEN: Face Enroll sidecar
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_SIDECAR = 1509;
-
- // OPEN: Settings > Add face > Error dialog
- // OS: Q
- DIALOG_FACE_ERROR = 1510;
-
- // OPEN: Settings > Security > Face
- // CATEGORY: SETTINGS
- // OS: Q
- FACE = 1511;
-
- // OPEN: Settings > Acessibility > HearingAid pairing instructions dialog
- // CATEGORY: SETTINGS
- // OS: Q
- DIALOG_ACCESSIBILITY_HEARINGAID = 1512;
-
- // OPEN: Settings > Add face
- // OS: Q
- FACE_ENROLL_PREVIEW = 1554;
-
- // OPEN: Settings > Network & Internet > Wi-Fi > Add network
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_WIFI_ADD_NETWORK = 1556;
-
- // OPEN: Settings > System > Input & Gesture > Reach up gesture
- // OS: Q
- SETTINGS_GESTURE_WAKE_LOCK_SCREEN = 1557;
-
- // OPEN: Settings > System > Input & Gesture > Wake screen
- SETTINGS_GESTURE_WAKE_SCREEN = 1570;
-
- // OPEN: Settings > Network & internet > Mobile network
- MOBILE_NETWORK = 1571;
-
- // OPEN: Settings > Network & internet > Mobile network > Choose network
- MOBILE_NETWORK_SELECT = 1581;
-
- // OPEN: Settings > Network & internet > Mobile network > Mobile Data > Dialog
- MOBILE_DATA_DIALOG = 1582;
-
- // OPEN: Settings > Network & internet > Mobile network > Data roaming > Dialog
- MOBILE_ROAMING_DIALOG = 1583;
-
- // Settings > Display > Lock screen display > On lock screen
- LOCK_SCREEN_NOTIFICATION_CONTENT = 1584;
-
- // ConfirmDeviceCredentials > BiometricPrompt
- BIOMETRIC_FRAGMENT = 1585;
-
- // OPEN: Biometric Enrollment (android.settings.BIOMETRIC_ENROLL action intent)
- BIOMETRIC_ENROLL_ACTIVITY = 1586;
-
- // OPEN: Settings > Privacy
- TOP_LEVEL_PRIVACY = 1587;
-
- // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions >
- // Allow apps to override
- // CATEGORY: SETTINGS
- // OS: Q
- NOTIFICATION_ZEN_MODE_OVERRIDING_APPS = 1588;
-
-
- // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions >
- // Allow apps to override > Choose app
- // CATEGORY: SETTINGS
- // OS: Q
- NOTIFICATION_ZEN_MODE_OVERRIDING_APP = 1589;
-
- // OPEN: Settings > Developer options > Disable > Info dialog
- DIALOG_DISABLE_DEVELOPMENT_OPTIONS = 1591;
-
- // OPEN: WifiDppConfiguratorActivity (android.settings.WIFI_DPP_CONFIGURATOR_XXX action intents)
- SETTINGS_WIFI_DPP_CONFIGURATOR = 1595;
-
- // OPEN: WifiDppEnrolleeActivity (android.settings.WIFI_DPP_ENROLLEE_XXX action intents)
- SETTINGS_WIFI_DPP_ENROLLEE = 1596;
-
- // OPEN: Settings > Apps & Notifications -> Special app access -> Financial Apps Sms Access
- SETTINGS_FINANCIAL_APPS_SMS_ACCESS = 1597;
-
-
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_SETTINGS = 1604;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Custom
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_SOUND_SETTINGS = 1605;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_DEFAULT_SETTINGS = 1606;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_NOTIFICATION_RESTRICTIONS = 1608;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction > Custom
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_VIS_EFFECTS = 1609;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction > Custom > Allow messages
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_MESSAGES = 1610;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction > Custom > Allow calls
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_CALLS = 1611;
-
- // OPEN: Settings > Sound > Do Not Disturb > Click footer link if custom settings applied
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_SETTINGS_DIALOG = 1612;
-
- // OPEN: Settings > Developer Options > Game Driver Preferences
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_GAME_DRIVER_DASHBOARD = 1613;
-
- // OPEN: Settings > Accessibility > Vibration > Ring vibration
- // CATEGORY: SETTINGS
- // OS: Q
- ACCESSIBILITY_VIBRATION_RING = 1620;
-
- // OPEN: Settings > System > Input & Gesture > Skip songs
- SETTINGS_GESTURE_SKIP = 1624;
-
- // OPEN: Settings > System > Input & Gesture > Silence alerts
- SETTINGS_GESTURE_SILENCE = 1625;
-
- // OPEN: Settings > System > Input & Gesture > Tap to check
- SETTINGS_GESTURE_TAP_SCREEN = 1626;
-
- // OPEN: Settings > Network & internet > Click Mobile network to land on a page with a list of
- // SIM/eSIM subscriptions.
- MOBILE_NETWORK_LIST = 1627;
-
- // OPEN: Settings > Display > Adaptive sleep
- // OS: Q
- SETTINGS_ADAPTIVE_SLEEP = 1628;
-
- // OPEN: Settings > System > Aware
- SETTINGS_AWARE = 1632;
-
- // OPEN: Settings > System > Aware > Disable > Dialog
- DIALOG_AWARE_DISABLE = 1633;
-
- // OPEN: Settings > Settings > Network & internet > Click Mobile network to land on page with
- // details for a SIM/eSIM mobile network > Click edit icon to bring up a rename dialog.
- // OS: Q
- MOBILE_NETWORK_RENAME_DIALOG = 1642;
-
- // OPEN: Set new password (android.app.action.SET_NEW_PASSWORD action intent)
- // CATEGORY: SETTINGS
- // OS: Q
- SET_NEW_PASSWORD_ACTIVITY = 1644;
-
- // Panel for Internet Connectivity
- PANEL_INTERNET_CONNECTIVITY = 1654;
-
- // Panel for Volume
- PANEL_VOLUME = 1655;
-
- // Panel for NFC
- PANEL_NFC = 1656;
-
- // Panel for Media Output
- PANEL_MEDIA_OUTPUT = 1657;
-
- // Mapping: go/at-mapping
- PAGE_ATSSI = 1667;
-
- PAGE_ATSII = 1668;
-
- PAGE_ATUS = 1669;
-
- PAGE_ATSSP = 1670;
-
- PAGE_ATSAP = 1671;
-
- PAGE_ATSCP = 1672;
-
- PAGE_ATHNP = 1673;
-
- // OPEN: Accessibility detail settings (android.settings.ACCESSIBILITY_DETAILS_SETTINGS intent)
- ACCESSIBILITY_DETAILS_SETTINGS = 1682;
-
- // Open: Settings will show the conditional when Grayscale mode is on
- SETTINGS_CONDITION_GRAYSCALE_MODE = 1683;
-
- // Panel for Wifi
- PANEL_WIFI = 1687;
-
- // Open: Settings > Special App Access > Do not disturb control for app
- ZEN_ACCESS_DETAIL = 1692;
-
- // OPEN: Settings > Face > Remove face
- // OS: Q
- DIALOG_FACE_REMOVE = 1693;
-
- // Settings > Display > Theme
- DARK_UI_SETTINGS = 1698;
-
- // Settings > global bubble settings
- BUBBLE_SETTINGS = 1699;
-
- // Settings > app > bubble settings
- APP_BUBBLE_SETTINGS = 1700;
-
- // OPEN: Settings > System > Aware > Info dialog
- DIALOG_AWARE_STATUS = 1701;
-
- // Open: Settings > app > bubble settings > confirmation dialog
- DIALOG_APP_BUBBLE_SETTINGS = 1702;
-
- // OPEN: Settings > Pick SIM dialog
- DIALOG_SIM_LIST = 1707;
-
- // OPEN: Settings > Pick SIM (that supports calling) dialog
- DIALOG_CALL_SIM_LIST = 1708;
-
- // OPEN: Settings > Pick preferred SIM dialog
- DIALOG_PREFERRED_SIM_PICKER = 1709;
-
- // OPEN: Settings > Network & internet > Mobile network > Delete sim
- DIALOG_DELETE_SIM_CONFIRMATION = 1713;
-
- // OPEN: Settings > Network & internet > Mobile network > Delete sim > (answer yes to
- // confirmation)
- DIALOG_DELETE_SIM_PROGRESS = 1714;
-
- // Settings > Apps and notifications > Notifications > Gentle notifications
- GENTLE_NOTIFICATIONS_SCREEN = 1715;
-
- // OPEN: Settings > System > Gestures > Global Actions Panel
- // CATEGORY: SETTINGS
- // OS: Q
- GLOBAL_ACTIONS_PANEL_SETTINGS = 1728;
-
- // OPEN: Settings > Display > Dark Theme
- // CATEGORY: SETTINGS
- // OS: Q
- // Note: Only shows up on first time toggle
- DIALOG_DARK_UI_INFO = 1740;
-
- // OPEN: Settings > About phone > Legal information > Google Play system update licenses
- // CATEGORY: SETTINGS
- // OS: Q
- MODULE_LICENSES_DASHBOARD = 1746;
-
- // OPEN: Settings > System > Gestures > System navigation > Info icon
- // CATEGORY: SETTINGS
- // OS: Q
- // Note: Info icon is visible only when gesture navigation is not available and disabled
- SETTINGS_GESTURE_NAV_NOT_AVAILABLE_DLG = 1747;
-
- // OPEN: Settings > System > Gestures > System navigation > Gear icon
- // CATEGORY: SETTINGS
- // OS: Q
- // Note: Gear icon is shown next to gesture navigation preference and opens sensitivity dialog
- SETTINGS_GESTURE_NAV_BACK_SENSITIVITY_DLG = 1748;
-
- // OPEN: Settings > System > Aware > Aware Display
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_AWARE_DISPLAY = 1750;
-
- // OPEN: Settings > System > Input & Gesture > tap gesture
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_GESTURE_TAP = 1751;
- // ---- End Q Constants, all Q constants go above this line ----
- // OPEN: Settings > Network & Internet > Wi-Fi > Click new network
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_WIFI_CONFIGURE_NETWORK = 1800;
-
- // OPEN: Settings > Accessibility > Magnification
- // CATEGORY: SETTINGS
- // OS: R
- // Note: Shows up only when Magnify with shortcut is enabled
- // and under accessibility button mode.
- DIALOG_TOGGLE_SCREEN_MAGNIFICATION_ACCESSIBILITY_BUTTON = 1801;
-
- // OPEN: Settings > Accessibility > Magnification
- // CATEGORY: SETTINGS
- // OS: R
- // Note: Shows up only when Magnify with shortcut is enabled.
- // and under gesture navigation mode.
- DIALOG_TOGGLE_SCREEN_MAGNIFICATION_GESTURE_NAVIGATION = 1802;
-
- // OPEN: Settings > Security & screen lock -> Encryption & credentials > Install a certificate
- // CATEGORY: SETTINGS
- // OS: R
- INSTALL_CERTIFICATE_FROM_STORAGE = 1803;
-
- // OPEN: Settings > Apps and notifications > Special app access > notification access >
- // an app
- // CATEGORY: SETTINGS
- // OS: R
- NOTIFICATION_ACCESS_DETAIL = 1804;
-
- // OPEN: Settings > Developer Options > Platform Compat
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_PLATFORM_COMPAT_DASHBOARD = 1805;
-
- // OPEN: Settings > Location -> Work profile tab
- // CATEGORY: SETTINGS
- // OS: R
- LOCATION_WORK = 1806;
-
- // OPEN: Settings > Account -> Work profile tab
- // CATEGORY: SETTINGS
- // OS: R
- ACCOUNT_WORK = 1807;
-
- // OPEN: Settings > Developer Options > Bug report handler
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_BUGREPORT_HANDLER = 1808;
-
- // Panel for adding Wi-Fi networks
- // CATEGORY: SETTINGS
- // OS: R
- PANEL_ADD_WIFI_NETWORKS = 1809;
-
- // OPEN: Settings > Accessibility > Enable the feature or shortcut > Show tutorial dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_ACCESSIBILITY_TUTORIAL = 1810;
-
- // OPEN: Settings > Accessibility > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_ACCESSIBILITY_SERVICE_EDIT_SHORTCUT = 1812;
-
- // OPEN: Settings > Accessibility > Magnification > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_MAGNIFICATION_EDIT_SHORTCUT = 1813;
-
- // OPEN: Settings > Accessibility > Color correction > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_DALTONIZER_EDIT_SHORTCUT = 1814;
-
- // OPEN: Settings > Accessibility > Magnification > Settings
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_MAGNIFICATION_SETTINGS = 1815;
-
- // OPEN: Settings > Accessibility > Magnification > Settings > Magnification area dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_MAGNIFICATION_CAPABILITY = 1816;
-
- // OPEN: Settings > Accessibility > Color inversion
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_COLOR_INVERSION_SETTINGS = 1817;
-
- // OPEN: Settings > Accessibility > Color inversion > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_COLOR_INVERSION_EDIT_SHORTCUT = 1818;
-
- // OPEN: Settings > Accessibility > Captions preference > Captions appearance
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_CAPTION_APPEARANCE = 1819;
-
- // OPEN: Settings > Accessibility > Captions preference > More options
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_CAPTION_MORE_OPTIONS = 1820;
-
- // OPEN: Settings > Battery > Battery share
- // CATEGORY: SETTINGS
- // OS: R
- FUELGAUGE_BATTERY_SHARE = 1821;
-
- // OPEN: Settings -> Apps & Notifications -> Special App Access
- // CATEGORY: SETTINGS
- // OS: R
- MANAGE_EXTERNAL_STORAGE = 1822;
-
- // Open: Settings > DND > People
- // OS: R
- DND_PEOPLE = 1823;
-
- // OPEN: Settings > Apps and notifications > App info > one of any app > Open by default
- // > Open supported links
- // CATEGORY: SETTINGS
- // OS: R
- OPEN_SUPPORTED_LINKS = 1824;
-
- // OPEN: Settings > Display > Dark theme > Set start time dialog
- DIALOG_DARK_THEME_SET_START_TIME = 1825;
-
- // OPEN: Settings > Display > Dark theme > Set end time dialog
- DIALOG_DARK_THEME_SET_END_TIME = 1826;
-
- // OPEN: Settings -> Sound -> Vibrate for calls
- // CATEGORY: SETTINGS
- // OS: R
- VIBRATE_FOR_CALLS = 1827;
-
- // OPEN: Settings > Connected devices > Connection preferences > NFC
- // CATEGORY: SETTINGS
- // OS: R
- CONNECTION_DEVICE_ADVANCED_NFC = 1828;
-
- // OPEN: Settings -> Apps & Notifications -> Special App Access
- INTERACT_ACROSS_PROFILES = 1829;
-
- // OPEN: Settings > Notifications > (app or conversations) > conversation
- NOTIFICATION_CONVERSATION_SETTINGS = 1830;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_ADB_WIRELESS = 1831;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // > Pair device with pairing code > Pairing code dialog
- // CATEGORY: SETTINGS
- // OS: R
- ADB_WIRELESS_DEVICE_PAIRING_DIALOG = 1832;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // > Pair device with QR code > Scan QR code > Pairing device dialog
- // CATEGORY: SETTINGS
- // OS: R
- ADB_WIRELESS_DEVICE_QR_PAIRING_DIALOG = 1833;
-
- // OPEN: Settings > apps & notifications > notifications > conversations
- // CATEGORY: SETTINGS
- // OS: R
- NOTIFICATION_CONVERSATION_LIST_SETTINGS = 1834;
-
- // Panel for Media Output Group operation
- // CATEGORY: SETTINGS
- // OS: R
- PANEL_MEDIA_OUTPUT_GROUP = 1835;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // > Click on paired device
- // CATEGORY: SETTINGS
- // OS: R
- ADB_WIRELESS_DEVICE_DETAILS = 1836;
-
- // Open: Settings > Sound > Do Not Disturb > People > Conversations
- // OS: R
- DND_CONVERSATIONS = 1837;
-
- // Open: Settings > Sound > Do Not Disturb > People > Calls
- // OS: R
- DND_CALLS = 1838;
-
- // Open: Settings > Sound > Do Not Disturb > People > Messages
- // OS: R
- DND_MESSAGES = 1839;
-
- // Open: Settings > Sound > Do Not Disturb > Apps > <Choose App>
- // OS: R
- DND_APPS_BYPASSING = 1840;
-
- // OPEN: Settings > Battery > Advanced battery option
- // CATEGORY: SETTINGS
- // OS: R
- FUELGAUGE_ADVANCED_BATTERY_OPTION = 1842;
-
- // OPEN: Settings > System > Gestures > Power menu
- // CATEGORY: SETTINGS
- // OS: R
- POWER_MENU_SETTINGS = 1843;
-
- // OPEN: Settings > System > Gestures > Power menu > Device controls
- // CATEGORY: SETTINGS
- // OS: R
- DEVICE_CONTROLS_SETTINGS = 1844;
-
- // OPEN: Settings > Sound > Media
- // CATEGORY: SETTINGS
- // OS: R
- MEDIA_CONTROLS_SETTINGS = 1845;
-}
diff --git a/core/proto/android/app/tvsettings_enums.proto b/core/proto/android/app/tvsettings_enums.proto
deleted file mode 100644
index 31c5dd6..0000000
--- a/core/proto/android/app/tvsettings_enums.proto
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.tvsettings;
-option java_multiple_files = true;
-option java_outer_classname = "TvSettingsEnums";
-
-/** The performed action types */
-enum Action {
-
- /**
- * Denotes an unknown action. It is a filler that should generally be
- * avoided.
- */
- ACTION_UNKNOWN = 0;
-
- /**
- * Denotes that a TvSettings page is being focused. (Previewing a page in
- * two panel settings should NOT be considered as focusing on the page.)
- */
- PAGE_FOCUSED = 1;
-
- /**
- * Denotes that an entry (typically a leaf node of settings tree) is
- * selected by a user.
- */
- ENTRY_SELECTED = 2;
-
- /** Denotes that a toggle is clicked by a user. */
- TOGGLE_INTERACTED = 3;
-
- /**
- * Denotes that a TvSettings page is being focused in the forward direction
- * into the settings tree.
- */
- PAGE_FOCUSED_FORWARD = 4;
-
- /**
- * Denotes that a TvSettings page is being focused in the backward direction
- * up the settings tree.
- */
- PAGE_FOCUSED_BACKWARD = 5;
-
- /** Denotes that a toggle is turned on by a user. */
- TOGGLED_ON = 6;
-
- /** Denotes that a toggle is turned off by a user. */
- TOGGLED_OFF = 7;
-
-}
-
-/**
- * Ids for TvSettings focusable pages or actionable entries
- *
- * For details of the scheme, please refer to the "Definition of item_id" and
- * "Evolve of item_id" sections in go/atv-settings-ww-logging-design.
- */
-enum ItemId {
-
- option allow_alias = true;
-
- // Filler that should be avoided
- UNKNOWN = 0x00000000;
-
- // TvSettings
- TV_SETTINGS_ROOT = 0x00000001;
-
- // TvSettings unknown/default classic page
- PAGE_CLASSIC_DEFAULT = 0x00000002;
-
- // TvSettings unknown/default slice page
- PAGE_SLICE_DEFAULT = 0x00000003;
-
- // TvSettings unknown/default entry
- ENTRY_DEFAULT = 0x00000004;
-
- // TvSettings > Suggested settings entry
- SUGGESTED_SETTINGS = 0x00000010;
-
- // TvSettings > Quick Settings
- QUICK_SETTINGS = 0x00000011;
-
- // VERSION 1: Starting with Q
- // These are ordered in depth-first search manner.
-
- // TvSettings > Network & Internet
- NETWORK = 0x11000000;
-
- // TvSettings > Network & Internet > Wi-Fi (toggle)
- NETWORK_WIFI_ON_OFF = 0x11100000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list]
- NETWORK_AP_INFO = 0x11200000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list] > Proxy settings
- NETWORK_AP_INFO_PROXY_SETTINGS = 0x11210000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list] > IP settings
- NETWORK_AP_INFO_IP_SETTINGS = 0x11220000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list] > Forget network
- NETWORK_AP_INFO_FORGET_NETWORK = 0x11230000;
-
- // TvSettings > Network & Internet >
- // [A not connected network entry in available networks list]
- NETWORK_NOT_CONNECTED_AP = 0x11300000;
-
- // TvSettings > Network & Internet > See all
- NETWORK_SEE_ALL = 0x11400000;
-
- // TvSettings > Network & Internet > See fewer
- NETWORK_SEE_FEWER = 0x11500000;
-
- // TvSettings > Network & Internet > Add new network
- NETWORK_ADD_NEW_NETWORK = 0x11600000;
-
- // TvSettings > Network & Internet > Scanning always available (toggle)
- NETWORK_ALWAYS_SCANNING_NETWORKS = 0x11700000;
-
- // TvSettings > Network & Internet > Proxy settings (in Ethernet category)
- NETWORK_ETHERNET_PROXY_SETTINGS = 0x11800000;
-
- // TvSettings > Network & Internet > IP settings (in Ethernet category)
- NETWORK_ETHERNET_IP_SETTINGS = 0x11900000;
-
- // TvSettings > Account & Sign In (Slice)
- ACCOUNT_SLICE = 0x12000000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account]
- ACCOUNT_SLICE_REG_ACCOUNT = 0x12100000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT = 0x12130000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > SafeSearch filter (toggle)
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SAFE_SEARCH = 0x12131000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > Block offensive words (toggle)
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_BLOCK_OFFENSIVE = 0x12132000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > Searchable apps
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SEARCHABLE_APPS = 0x12133000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > Personal results (toggle)
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_PERSONAL_RESULTS = 0x12134000;
-
- // Reserving [0x12140000, 0x12190000] for possible future settings
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] > Remove
- ACCOUNT_SLICE_REG_ACCOUNT_REMOVE = 0x121A0000;
-
- // Reserving [0x12200000, 0x12900000] for possible future settings
-
- // TvSettings > Account & Sign In (Slice) > Add account...
- ACCOUNT_SLICE_ADD_ACCOUNT = 0x12A00000;
-
- // TvSettings > Account & Sign In (Classic)
- ACCOUNT_CLASSIC = 0x13000000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account]
- ACCOUNT_CLASSIC_REG_ACCOUNT = 0x13100000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] > Sync now
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_NOW = 0x13110000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // Remove account
- ACCOUNT_CLASSIC_REG_ACCOUNT_REMOVE_ACCOUNT = 0x13120000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Calendar (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_CALENDAR = 0x13130000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Contacts (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_CONTACTS = 0x13140000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Google Play Movies & TV (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_GPMT = 0x13150000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Google Play Music (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_GPM = 0x13160000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] People details (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_PEOPLE = 0x13170000;
-
- // Reserving [0x13200000, 0x13900000] for possible future settings
-
- // TvSettings > Account & Sign In (Classic) > Add account
- ACCOUNT_CLASSIC_ADD_ACCOUNT = 0x13A00000;
-
- // TvSettings > Display & Sound
- DISPLAY_SOUND = 0x15000000;
-
- // TvSettings > Display & Sound > Advanced display settings
- DISPLAY_SOUND_ADVANCED_DISPLAY = 0x15100000;
-
- // TvSettings > Display & Sound > Advanced display settings >
- // Allow game mode (toggle)
- DISPLAY_SOUND_ADVANCED_DISPLAY_GAME_MODE = 0x15110000;
-
- // TvSettings > Display & Sound > System sounds (toggle)
- DISPLAY_SOUND_SYSTEM_SOUNDS = 0x15200000;
-
- // TvSettings > Display & Sound > Advanced sound settings
- DISPLAY_SOUND_ADVANCED_SOUNDS = 0x15300000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS = 0x15310000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats >
- // Auto...
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_AUTO = 0x15311000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats >
- // None...
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_NONE = 0x15312000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats >
- // Manual...
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_MANUAL = 0x15313000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby AC-4 (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DAC4 = 0x15320000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby Atmos in Dolby Digital Plus (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DADDP = 0x15330000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby Digital (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DD = 0x15340000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby Digital Plus (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DDP = 0x15350000;
-
- // TvSettings > Display & Sound > Advanced sound settings > DTS (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DTS = 0x15360000;
-
- // TvSettings > Display & Sound > Advanced sound settings > DTS-HD (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DTSHD = 0x15370000;
-
- // TvSettings > Display & Sound > Advanced sound settings > AAC (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_AAC = 0x15380000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby TrueHD (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DTHD = 0x15390000;
-
- // TvSettings > Apps
- APPS = 0x16000000;
-
- // TvSettings > Apps > See all apps
- APPS_ALL_APPS = 0x16100000;
-
- // TvSettings > Apps > See all apps > [An app entry]
- APPS_ALL_APPS_APP_ENTRY = 0x16110000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Open
- APPS_ALL_APPS_APP_ENTRY_OPEN = 0x16111000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Force stop
- APPS_ALL_APPS_APP_ENTRY_FORCE_STOP = 0x16112000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Uninstall
- APPS_ALL_APPS_APP_ENTRY_UNINSTALL = 0x16113000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Uninstall updates
- APPS_ALL_APPS_APP_ENTRY_UNINSTALL_UPDATES = 0x16114000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Disable
- APPS_ALL_APPS_APP_ENTRY_DISABLE = 0x16115000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Clear data
- APPS_ALL_APPS_APP_ENTRY_CLEAR_DATA = 0x16116000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Clear cache
- APPS_ALL_APPS_APP_ENTRY_CLEAR_CACHE = 0x16117000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Clear defaults
- APPS_ALL_APPS_APP_ENTRY_CLEAR_DEFAULTS = 0x16118000;
-
- // TvSettings > Apps > See all apps > [An app entry] >
- // Notifications (toggle)
- APPS_ALL_APPS_APP_ENTRY_NOTIFICATIONS = 0x16119000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Permissions
- APPS_ALL_APPS_APP_ENTRY_PERMISSIONS = 0x1611A000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Enable
- APPS_ALL_APPS_APP_ENTRY_ENABLE = 0x1611B000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Open source licenses
- APPS_ALL_APPS_APP_ENTRY_LICENSES = 0x1611C000;
-
- // TvSettings > Apps > See all apps > Show system apps
- APPS_ALL_APPS_SHOW_SYSTEM_APPS = 0x16120000;
-
- // TvSettings > Apps > App permissions
- APPS_APP_PERMISSIONS = 0x16200000;
-
- // TvSettings > Apps > App permission > Body sensors
- APPS_APP_PERMISSIONS_BODY_SENSORS = 0x16210000;
-
- // TvSettings > Apps > App permission > Calendar
- APPS_APP_PERMISSIONS_CALENDAR = 0x16220000;
-
- // TvSettings > Apps > App permission > Call logs
- APPS_APP_PERMISSIONS_CALL_LOGS = 0x16230000;
-
- // TvSettings > Apps > App permission > Camera
- APPS_APP_PERMISSIONS_CAMERA = 0x16240000;
-
- // TvSettings > Apps > App permission > Contacts
- APPS_APP_PERMISSIONS_CONTACTS = 0x16250000;
-
- // TvSettings > Apps > App permission > Location
- APPS_APP_PERMISSIONS_LOCATION = 0x16260000;
-
- // TvSettings > Apps > App permission > Microphone
- APPS_APP_PERMISSIONS_MICROPHONE = 0x16270000;
-
- // TvSettings > Apps > App permission > Phone
- APPS_APP_PERMISSIONS_PHONE = 0x16280000;
-
- // TvSettings > Apps > App permission > Physical activity
- APPS_APP_PERMISSIONS_PHYSICAL_ACTIVITY = 0x16290000;
-
- // TvSettings > Apps > App permission > SMS
- APPS_APP_PERMISSIONS_SMS = 0x162A0000;
-
- // TvSettings > Apps > App permission > Storage
- APPS_APP_PERMISSIONS_STORAGE = 0x162B0000;
-
- // TvSettings > Apps > App permission > Additional permissions
- APPS_APP_PERMISSIONS_ADDITIONAL = 0x162C0000;
-
- // TvSettings > Apps > App permission > Additional permissions >
- // real all TV listings
- APPS_APP_PERMISSIONS_ADDITIONAL_READ_TV_LISTINGS = 0x162C1000;
-
- // TvSettings > Apps > App permission > Additional permissions >
- // real instant messages
- APPS_APP_PERMISSIONS_ADDITIONAL_READ_INSTANT_MESSAGES = 0x162C2000;
-
- // TvSettings > Apps > App permission > Additional permissions >
- // write instant messages
- APPS_APP_PERMISSIONS_ADDITIONAL_WRITE_INSTANT_MESSAGES = 0x162C3000;
-
- // TvSettings > Apps > Special app access
- APPS_SPECIAL_APP_ACCESS = 0x16300000;
-
- // TvSettings > Apps > Special app access > Energy optimization
- APPS_SPECIAL_APP_ACCESS_ENERGY_OPTIMIZATION = 0x16310000;
-
- // TvSettings > Apps > Special app access > Usage access
- APPS_SPECIAL_APP_ACCESS_USAGE_ACCESS = 0x16320000;
-
- // TvSettings > Apps > Special app access > Notification access
- APPS_SPECIAL_APP_ACCESS_NOTIFICATION_ACCESS = 0x16330000;
-
- // TvSettings > Apps > Special app access > Display over other apps
- APPS_SPECIAL_APP_ACCESS_DISPLAY_OVER_OTHERS = 0x16340000;
-
- // TvSettings > Apps > Special app access > Modify system settings
- APPS_SPECIAL_APP_ACCESS_MODIFY_SYSTEM_SETTINGS = 0x16350000;
-
- // TvSettings > Apps > Special app access > Picture-in-picture
- APPS_SPECIAL_APP_ACCESS_PICTURE_IN_PICTURE = 0x16360000;
-
- // TvSettings > Apps > Security & restrictions
- APPS_SECURITY_RESTRICTIONS = 0x16400000;
-
- // TvSettings > Apps > Security & restrictions > Unknown sources
- APPS_SECURITY_RESTRICTIONS_UNKNOWN_SOURCES = 0x16410000;
-
- // TvSettings > Apps > Security & restrictions > Verify apps (toggle)
- APPS_SECURITY_RESTRICTIONS_VERIFY_APPS = 0x16420000;
-
- // TvSettings > Apps > Security & restrictions > Create restricted profile
- APPS_SECURITY_RESTRICTIONS_CREATE_PROFILE = 0x16430000;
-
- // TvSettings > Apps > Security & restrictions > Enter restricted profile
- APPS_SECURITY_RESTRICTIONS_ENTER_PROFILE = 0x16440000;
-
- // TvSettings > Apps > Security & restrictions >
- // Allowed apps (Restricted Profile)
- APPS_SECURITY_RESTRICTIONS_PROFILE_ALLOWED_APPS = 0x16450000;
-
- // TvSettings > Apps > Security & restrictions >
- // Change pin (Restricted Profile)
- APPS_SECURITY_RESTRICTIONS_PROFILE_CHANGE_PIN = 0x16460000;
-
- // TvSettings > Apps > Security & restrictions >
- // Delete restricted profile
- APPS_SECURITY_RESTRICTIONS_DELETE_PROFILE = 0x16470000;
-
- // TvSettings > Apps > Security & restrictions >
- // Exit restricted profile
- APPS_SECURITY_RESTRICTIONS_EXIT_PROFILE = 0x16480000;
-
- // TvSettings > System (same as TvSettings > Device Preferences)
- SYSTEM = 0x17000000;
-
- // TvSettings > System > About
- SYSTEM_ABOUT = 0x17100000;
-
- // TvSettings > System > System update
- SYSTEM_ABOUT_SYSTEM_UPDATE = 0x17110000;
-
- // TvSettings > System > Device name
- SYSTEM_ABOUT_DEVICE_NAME = 0x17120000;
-
- // TvSettings > System > Factory reset
- SYSTEM_ABOUT_FACTORY_RESET = 0x17130000;
-
- // TvSettings > System > Status
- SYSTEM_ABOUT_STATUS = 0x17140000;
-
- // TvSettings > System > Legal information
- SYSTEM_ABOUT_LEGAL_INFO = 0x17150000;
-
- // TvSettings > System > Legal information > Open source licenses
- SYSTEM_ABOUT_LEGAL_INFO_OPEN_SOURCE = 0x17151000;
-
- // TvSettings > System > Legal information > Google legal
- SYSTEM_ABOUT_LEGAL_INFO_GOOGLE_LEGAL = 0x17152000;
-
- // TvSettings > System > Legal information > System WebView licenses
- SYSTEM_ABOUT_LEGAL_INFO_SYSTEM_WEBVIEW = 0x17153000;
-
- // TvSettings > System > Build
- SYSTEM_ABOUT_BUILD = 0x17160000;
-
- // TvSettings > System > Date & time
- SYSTEM_DATE_TIME = 0x17200000;
-
- // TvSettings > System > Date & time > Automatic data & time
- SYSTEM_DATE_TIME_AUTOMATIC = 0x17210000;
-
- // TvSettings > System > Date & time > Automatic data & time >
- // Use network-provided time
- SYSTEM_DATE_TIME_AUTOMATIC_USE_NETWORK_TIME = 0x17211000;
-
- // TvSettings > System > Date & time > Automatic data & time > Off
- SYSTEM_DATE_TIME_AUTOMATIC_OFF = 0x17212000;
-
- // TvSettings > System > Date & time > Set date
- SYSTEM_DATE_TIME_SET_DATE = 0x17220000;
-
- // TvSettings > System > Date & time > Set time
- SYSTEM_DATE_TIME_SET_TIME = 0x17230000;
-
- // TvSettings > System > Date & time > Set time zone
- SYSTEM_DATE_TIME_SET_TIME_ZONE = 0x17240000;
-
- // TvSettings > System > Date & time > Set time zone > [A time zone button]
- SYSTEM_DATE_TIME_SET_TIME_ZONE_BUTTON = 0x17241000;
-
- // TvSettings > System > Date & time > Use 24-hour format (toggle)
- SYSTEM_DATE_TIME_USE_24_HOUR_FORMAT = 0x17250000;
-
- // TvSettings > System > Language
- SYSTEM_LANGUAGE = 0x17300000;
-
- // TvSettings > System > Language > [A language button]
- SYSTEM_LANGUAGE_BUTTON = 0x17310000;
-
- // TvSettings > System > Keyboard
- SYSTEM_KEYBOARD = 0x17400000;
-
- // TvSettings > System > Keyboard > Current keyboard
- SYSTEM_KEYBOARD_CURRENT_KEYBOARD = 0x17410000;
-
- // TvSettings > System > Keyboard > Gboard Settings
- SYSTEM_KEYBOARD_GBOARD_SETTINGS = 0x17420000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Languages
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_LANGUAGES = 0x17421000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Terms of services
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_TOS = 0x17422000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Privacy policy
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_PRIVACY_POLICY = 0x17423000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Open source licenses
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_OPEN_SOURCE = 0x17424000;
-
- // TvSettings > System > Keyboard > Gboard Settings >
- // Share usage statistics (toggle)
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_SHARE_USAGE_STATS = 0x17425000;
-
- // TvSettings > System > Keyboard > Manage keyboards
- SYSTEM_KEYBOARD_MANAGE_KEYBOARDS = 0x17430000;
-
- // TvSettings > System > Storage
- SYSTEM_STORAGE = 0x17500000;
-
- // TvSettings > System > Internal shared storage
- SYSTEM_STORAGE_INTERNAL_STORAGE = 0x17510000;
-
- // TvSettings > System > Internal shared storage > Apps
- SYSTEM_STORAGE_INTERNAL_STORAGE_APPS = 0x17511000;
-
- // TvSettings > System > Internal shared storage >
- // Cached data (brings up "Clear cached data?" dialog upon click)
- SYSTEM_STORAGE_INTERNAL_STORAGE_CACHED = 0x17512000;
-
- // TvSettings > System > Energy saver
- SYSTEM_ENERGYSAVER = 0x17700000;
-
- // TvSettings > System > Energy saver > Turn off display after
- SYSTEM_ENERGYSAVER_START_DELAY = 0x17710000;
-
- // TvSettings > System > Energy saver > Turn off display after > 15 minutes
- SYSTEM_ENERGYSAVER_START_DELAY_15M = 0x17711000;
-
- // TvSettings > System > Energy saver > Turn off display after > 30 minutes
- SYSTEM_ENERGYSAVER_START_DELAY_30M = 0x17712000;
-
- // TvSettings > System > Energy saver > Turn off display after > 1 hour
- SYSTEM_ENERGYSAVER_START_DELAY_1H = 0x17713000;
-
- // TvSettings > System > Energy saver > Turn off display after > 3 hours
- SYSTEM_ENERGYSAVER_START_DELAY_3H = 0x17714000;
-
- // TvSettings > System > Energy saver > Turn off display after > 6 hours
- SYSTEM_ENERGYSAVER_START_DELAY_6H = 0x17715000;
-
- // TvSettings > System > Energy saver > Turn off display after > 12 hours
- SYSTEM_ENERGYSAVER_START_DELAY_12H = 0x17716000;
-
- // TvSettings > System > Energy saver > Turn off display after > Never
- SYSTEM_ENERGYSAVER_START_DELAY_NEVER = 0x17717000;
-
- // TvSettings > System > Accessibility
- SYSTEM_A11Y = 0x17800000;
-
- // TvSettings > System > Accessibility > Captions
- SYSTEM_A11Y_CAPTIONS = 0x17810000;
-
- // TvSettings > System > Accessibility > Captions > Display (toggle)
- SYSTEM_A11Y_CAPTIONS_DISPLAY_ON_OFF = 0x17811000;
-
- // TvSettings > System > Accessibility > Captions > Language
- SYSTEM_A11Y_CAPTIONS_LANGUAGE = 0x17812000;
-
- // TvSettings > System > Accessibility > Captions > Language > [A language]
- SYSTEM_A11Y_CAPTIONS_LANGUAGE_BUTTON = 0x17812100;
-
- // TvSettings > System > Accessibility > Captions > Text size
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE = 0x17813000;
-
- // TvSettings > System > Accessibility > Captions > Text size > Very small
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_VERY_SMALL = 0x17813100;
-
- // TvSettings > System > Accessibility > Captions > Text size > Small
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_SMALL = 0x17813200;
-
- // TvSettings > System > Accessibility > Captions > Text size > Normal
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_NORMAL = 0x17813300;
-
- // TvSettings > System > Accessibility > Captions > Text size > Large
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_LARGE = 0x17813400;
-
- // TvSettings > System > Accessibility > Captions > Text size > Very large
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_VERY_LARGE = 0x17813500;
-
- // TvSettings > System > Accessibility > Captions >
- // White on black (radio button)
- SYSTEM_A11Y_CAPTIONS_WHITE_ON_BLACK = 0x17814000;
-
- // TvSettings > System > Accessibility > Captions >
- // Black on white (radio button)
- SYSTEM_A11Y_CAPTIONS_BLACK_ON_WHITE = 0x17815000;
-
- // TvSettings > System > Accessibility > Captions >
- // Yellow on black (radio button)
- SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLACK = 0x17816000;
-
- // TvSettings > System > Accessibility > Captions >
- // Yellow on blue (radio button)
- SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLUE = 0x17817000;
-
- // TvSettings > System > Accessibility > Captions > Custom
- SYSTEM_A11Y_CAPTIONS_CUSTOM = 0x17818000;
-
- // TvSettings > System > Accessibility > Captions > Custom > Font family
- SYSTEM_A11Y_CAPTIONS_CUSTOM_FONT = 0x17818100;
-
- // TvSettings > System > Accessibility > Captions > Custom > Text color
- SYSTEM_A11Y_CAPTIONS_CUSTOM_TEXT_COLOR = 0x17818200;
-
- // TvSettings > System > Accessibility > Captions > Custom > Text opacity
- SYSTEM_A11Y_CAPTIONS_CUSTOM_TEXT_OPACITY = 0x17818300;
-
- // TvSettings > System > Accessibility > Captions > Custom > Edge type
- SYSTEM_A11Y_CAPTIONS_CUSTOM_EDGE_TYPE = 0x17818400;
-
- // TvSettings > System > Accessibility > Captions > Custom > Edge color
- SYSTEM_A11Y_CAPTIONS_CUSTOM_EDGE_COLOR = 0x17818500;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Show background (toggle)
- SYSTEM_A11Y_CAPTIONS_SHOW_BACKGROUND = 0x17818600;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Background color
- SYSTEM_A11Y_CAPTIONS_BACKGROUND_COLOR = 0x17818700;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Background opacity
- SYSTEM_A11Y_CAPTIONS_BACKGROUND_OPACITY = 0x17818800;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Show window (toggle)
- SYSTEM_A11Y_CAPTIONS_SHOW_WINDOW = 0x17818900;
-
- // TvSettings > System > Accessibility > Captions > Custom > Window color
- SYSTEM_A11Y_CAPTIONS_WINDOW_COLOR = 0x17818A00;
-
- // TvSettings > System > Accessibility > Captions > Custom > Window opacity
- SYSTEM_A11Y_CAPTIONS_WINDOW_OPACITY = 0x17818B00;
-
- // TvSettings > System > Accessibility > High contrast text (toggle)
- SYSTEM_A11Y_HIGH_CONTRAST_TEXT = 0x17820000;
-
- // TvSettings > System > Accessibility > Text to speech
- SYSTEM_A11Y_TTS = 0x17830000;
-
- // TvSettings > System > Accessibility > Text to speech > [Select an engine]
- SYSTEM_A11Y_TTS_ENGINE_SELECT = 0x17831000;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration
- SYSTEM_A11Y_TTS_ENGINE_CONFIG = 0x17832000;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Language
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_LANGUAGE = 0x17832100;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Language > Button
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_LANGUAGE_CHOOSE_LANGUAGE = 0x17832110;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Settings for Google Text-to-speech Engine
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_SETTINGS_GTTS_ENGINE = 0x17832200;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Install voice data
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_INSTALL_VOICE_DATA = 0x17832300;
-
- // TvSettings > System > Accessibility > Text to speech > Speech rate
- SYSTEM_A11Y_TTS_SPEECH_RATE = 0x17833000;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Listen to an example
- SYSTEM_A11Y_TTS_LISTEN_EXAMPLE = 0x17834000;
-
- // TvSettings > System > Accessibility > Accessibility shortcut
- SYSTEM_A11Y_SHORTCUT = 0x17840000;
-
- // TvSettings > System > Accessibility > Accessibility shortcut >
- // Enable (toggle)
- SYSTEM_A11Y_SHORTCUT_ON_OFF = 0x17841000;
-
- // TvSettings > System > Accessibility > Accessibility shortcut >
- // Shortcut services
- SYSTEM_A11Y_SHORTCUT_SERVICE = 0x17842000;
-
- // TvSettings > System > Accessibility > TalkBack
- SYSTEM_A11Y_TALKBACK = 0x17850000;
-
- // TvSettings > System > Accessibility > TalkBack > Enable (toggle)
- SYSTEM_A11Y_TALKBACK_ON_OFF = 0x17851000;
-
- // TvSettings > System > Accessibility > TalkBack > Configuration
- SYSTEM_A11Y_TALKBACK_CONFIG = 0x17852000;
-
- // TvSettings > System > Accessibility > Accessibility Menu
- SYSTEM_A11Y_A11Y_MENU = 0x17860000;
-
- // TvSettings > System > Accessibility > Accessibility Menu >
- // Enable (toggle)
- SYSTEM_A11Y_A11Y_MENU_ON_OFF = 0x17861000;
-
- // TvSettings > System > Accessibility > Accessibility Menu > Configuration
- SYSTEM_A11Y_A11Y_MENU_CONFIG = 0x17862000;
-
- // TvSettings > System > Accessibility > Select to Speak
- SYSTEM_A11Y_STS = 0x17870000;
-
- // TvSettings > System > Accessibility > Select to Speak > Enable (toggle)
- SYSTEM_A11Y_STS_ON_OFF = 0x17871000;
-
- // TvSettings > System > Accessibility > Select to Speak > Configuration
- SYSTEM_A11Y_STS_CONFIG = 0x17872000;
-
- // TvSettings > System > Accessibility > Switch Access
- SYSTEM_A11Y_SWITCH_ACCESS = 0x17880000;
-
- // TvSettings > System > Accessibility > Switch Access > Enable (Toggle)
- SYSTEM_A11Y_SWITCH_ACCESS_ON_OFF = 0x17881000;
-
- // TvSettings > System > Accessibility > Switch Access > Configuration
- SYSTEM_A11Y_SWITCH_ACCESS_CONFIG = 0x17882000;
-
- // TvSettings > System > Reboot
- SYSTEM_REBOOT = 0x17900000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings)
- PREFERENCES_HOME_SCREEN = 0x17A00000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS = 0x17A10000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN = 0x17A11000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > On (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_ON_OFF = 0x17A11100;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > Google Play Movies & TV (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_GPMT = 0x17A11200;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > Google Play Music (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_GPM = 0x17A11300;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > Promotional channels (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_PROMOTIONAL = 0x17A11400;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Home screen channels
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_HOME_SCREEN = 0x17A12000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Promotional channels
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PROMOTIONAL = 0x17A13000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Enable video previews (toggle)
- PREFERENCES_HOME_SCREEN_VIDEO_PREVIEWS = 0x17A20000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Enable audio previews (toggle)
- PREFERENCES_HOME_SCREEN_AUDIO_PREVIEWS = 0x17A30000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Reorder apps
- PREFERENCES_HOME_SCREEN_REORDER_APPS = 0x17A40000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Reorder games
- PREFERENCES_HOME_SCREEN_REORDER_GAMES = 0x17A50000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Android TV Home open source licenses
- PREFERENCES_HOME_SCREEN_ATVH_OPEN_SOURCE = 0x17A60000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Android TV Core Services open source licenses
- PREFERENCES_HOME_SCREEN_ATVCS_OPEN_SOURCE = 0x17A70000;
-
- // TvSettings > Device Preferences > Google Assistant
- PREFERENCES_ASSISTANT = 0x17B00000;
-
- // TvSettings > Device Preferences > Google Assistant > Accounts
- PREFERENCES_ASSISTANT_ACCOUNTS = 0x17B10000;
-
- // TvSettings > Device Preferences > Google Assistant > Accept permissions
- PREFERENCES_ASSISTANT_ACCEPT_PERMISSIONS = 0x17B20000;
-
- // TvSettings > Device Preferences > Google Assistant > View permissions
- PREFERENCES_ASSISTANT_VIEW_PERMISSIONS = 0x17B30000;
-
- // TvSettings > Device Preferences > Google Assistant > Searchable apps
- // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SEARCHABLE_APPS)
- PREFERENCES_ASSISTANT_SEARCHABLE_APPS = 0x12133000;
-
- // TvSettings > Device Preferences > Google Assistant > SafeSearch filter
- // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SAFE_SEARCH)
- PREFERENCES_ASSISTANT_SAFESEARCH_FILTER = 0x12131000;
-
- // TvSettings > Device Preferences > Google Assistant >
- // Block offensive words
- // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_BLOCK_OFFENSIVE)
- PREFERENCES_ASSISTANT_BLOCK_OFFENSIVE = 0x12132000;
-
- // TvSettings > Device Preferences > Google Assistant > Open source licenses
- PREFERENCES_ASSISTANT_OPEN_SOURCE = 0x17B40000;
-
- // TvSettings > Device Preferences > Chromecast Android Shell
- PREFERENCES_CHROMECAST_SHELL = 0x17C00000;
-
- // TvSettings > Device Preferences > Chromecast Android Shell >
- // Open source licenses
- PREFERENCES_CHROMECAST_SHELL_OPEN_SOURCE = 0x17C10000;
-
- // TvSettings > Device Preferences > Screen saver
- PREFERENCES_SCREENSAVER = 0x17D00000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser)
- PREFERENCES_SCREENSAVER_CHOOSER = 0x17D10000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) >
- // Turn screen off
- PREFERENCES_SCREENSAVER_CHOOSER_SCREEN_OFF = 0x17D11000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) >
- // Backdrop
- PREFERENCES_SCREENSAVER_CHOOSER_BACKDROP = 0x17D12000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) >
- // Colors
- PREFERENCES_SCREENSAVER_CHOOSER_COLORS = 0x17D13000;
-
- // TvSettings > Device Preferences > Screen saver > When to start
- PREFERENCES_SCREENSAVER_START_DELAY = 0x17D20000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 5 minutes
- PREFERENCES_SCREENSAVER_START_DELAY_5M = 0x17D21000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 15 minutes
- PREFERENCES_SCREENSAVER_START_DELAY_15M = 0x17D22000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 30 minutes
- PREFERENCES_SCREENSAVER_START_DELAY_30M = 0x17D23000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 1 hour
- PREFERENCES_SCREENSAVER_START_DELAY_1H = 0x17D24000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 2 hours
- PREFERENCES_SCREENSAVER_START_DELAY_2H = 0x17D25000;
-
- // TvSettings > Device Preferences > Screen saver > Start now
- PREFERENCES_SCREENSAVER_START_NOW = 0x17D30000;
-
- // TvSettings > Connected Devices (Slice)
- CONNECTED_SLICE = 0x18000000;
-
- // TvSettings > Connected Devices (Slice) > Connect remote or headphones
- CONNECTED_SLICE_CONNECT_NEW_DEVICES = 0x18100000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device]
- CONNECTED_SLICE_DEVICE_ENTRY = 0x18200000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device] >
- // Remote update
- CONNECTED_SLICE_DEVICE_ENTRY_UPDATE = 0x18210000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device] > Rename
- CONNECTED_SLICE_DEVICE_ENTRY_RENAME = 0x18220000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device] > Forget
- CONNECTED_SLICE_DEVICE_ENTRY_FORGET = 0x18230000;
-
- // TvSettings > Connected Devices (Slice) > HDMI-CEC
- CONNECTED_SLICE_HDMICEC = 0x18300000;
-
- // TvSettings > Connected Devices (Slice) > HDMI-CEC > Enable (toggle)
- CONNECTED_SLICE_HDMICEC_ON_OFF = 0x18310000;
-
- // TvSettings > Connected Devices (aliasing CONNECTED_SLICE)
- CONNECTED_CLASSIC = 0x18000000;
-
- // TvSettings > Connected Devices > Connect remote
- // (aliasing CONNECTED_SLICE_CONNECT_NEW_DEVICES)
- CONNECTED_CLASSIC_CONNECT_REMOTE = 0x18100000;
-
- // TvSettings > Connected Devices > [A connected device]
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY)
- CONNECTED_CLASSIC_DEVICE_ENTRY = 0x18200000;
-
- // TvSettings > Connected Devices > [A connected device] > Update
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_UPDATE)
- CONNECTED_CLASSIC_DEVICE_ENTRY_UPDATE = 0x18210000;
-
- // TvSettings > Connected Devices > [A connected device] > Rename
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_RENAME)
- CONNECTED_CLASSIC_DEVICE_ENTRY_RENAME = 0x18220000;
-
- // TvSettings > Connected Devices > [A connected device] > Forget
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_FORGET)
- CONNECTED_CLASSIC_DEVICE_ENTRY_FORGET = 0x18230000;
-
- // TvSettings > Connected Devices > HDMI-CEC
- // (aliasing CONNECTED_SLICE_HDMICEC)
- CONNECTED_CLASSIC_HDMICEC = 0x18300000;
-
- // TvSettings > Connected Devices > HDMI-CEC > Enable (toggle)
- // (aliasing CONNECTED_SLICE_HDMICEC_ON_OFF)
- CONNECTED_CLASSIC_HDMICEC_ON_OFF = 0x18310000;
-
- // TvSettings > Help & Feedback
- FEEDBACK = 0x19000000;
-
- // TvSettings > Help & Feedback > Send feedback
- FEEDBACK_SEND = 0x19100000;
-}
diff --git a/core/proto/android/bluetooth/a2dp/enums.proto b/core/proto/android/bluetooth/a2dp/enums.proto
deleted file mode 100644
index 5a025bd..0000000
--- a/core/proto/android/bluetooth/a2dp/enums.proto
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth.a2dp;
-
-option java_outer_classname = "BluetoothA2dpProtoEnums";
-option java_multiple_files = true;
-
-// A2dp playback state enum, defined from:
-// frameworks/base/core/java/android/bluetooth/BluetoothA2dp.java
-enum PlaybackStateEnum {
- PLAYBACK_STATE_UNKNOWN = 0;
- PLAYBACK_STATE_PLAYING = 10;
- PLAYBACK_STATE_NOT_PLAYING = 11;
-}
-
-enum AudioCodingModeEnum {
- AUDIO_CODING_MODE_UNKNOWN = 0;
- AUDIO_CODING_MODE_HARDWARE = 1;
- AUDIO_CODING_MODE_SOFTWARE = 2;
-}
diff --git a/core/proto/android/bluetooth/enums.proto b/core/proto/android/bluetooth/enums.proto
deleted file mode 100644
index 22f2498..0000000
--- a/core/proto/android/bluetooth/enums.proto
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth;
-
-option java_outer_classname = "BluetoothProtoEnums";
-option java_multiple_files = true;
-
-// Bluetooth connection states.
-enum ConnectionStateEnum {
- CONNECTION_STATE_DISCONNECTED = 0;
- CONNECTION_STATE_CONNECTING = 1;
- CONNECTION_STATE_CONNECTED = 2;
- CONNECTION_STATE_DISCONNECTING = 3;
-}
-
-// Bluetooth Adapter Enable and Disable Reasons
-enum EnableDisableReasonEnum {
- ENABLE_DISABLE_REASON_UNSPECIFIED = 0;
- ENABLE_DISABLE_REASON_APPLICATION_REQUEST = 1;
- ENABLE_DISABLE_REASON_AIRPLANE_MODE = 2;
- ENABLE_DISABLE_REASON_DISALLOWED = 3;
- ENABLE_DISABLE_REASON_RESTARTED = 4;
- ENABLE_DISABLE_REASON_START_ERROR = 5;
- ENABLE_DISABLE_REASON_SYSTEM_BOOT = 6;
- ENABLE_DISABLE_REASON_CRASH = 7;
- ENABLE_DISABLE_REASON_USER_SWITCH = 8;
- ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9;
- ENABLE_DISABLE_REASON_FACTORY_RESET = 10;
-}
-
-enum DirectionEnum {
- DIRECTION_UNKNOWN = 0;
- DIRECTION_OUTGOING = 1;
- DIRECTION_INCOMING = 2;
-}
-
-// First item is the default value, other values follow Bluetooth spec definition
-enum LinkTypeEnum {
- // Link type is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- LINK_TYPE_UNKNOWN = 0xFFF;
- LINK_TYPE_SCO = 0x00;
- LINK_TYPE_ACL = 0x01;
- LINK_TYPE_ESCO = 0x02;
-}
-
-enum DeviceInfoSrcEnum {
- DEVICE_INFO_SRC_UNKNOWN = 0;
- // Within Android Bluetooth stack
- DEVICE_INFO_INTERNAL = 1;
- // Outside Android Bluetooth stack
- DEVICE_INFO_EXTERNAL = 2;
-}
-
-enum DeviceTypeEnum {
- DEVICE_TYPE_UNKNOWN = 0;
- DEVICE_TYPE_CLASSIC = 1;
- DEVICE_TYPE_LE = 2;
- DEVICE_TYPE_DUAL = 3;
-}
-
-// Defined in frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
-enum TransportTypeEnum {
- TRANSPORT_TYPE_AUTO = 0;
- TRANSPORT_TYPE_BREDR = 1;
- TRANSPORT_TYPE_LE = 2;
-}
-
-// Bond state enum
-// Defined in frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
-enum BondStateEnum {
- BOND_STATE_UNKNOWN = 0;
- BOND_STATE_NONE = 10;
- BOND_STATE_BONDING = 11;
- BOND_STATE_BONDED = 12;
-}
-
-// Sub states within the bonding general state
-enum BondSubStateEnum {
- BOND_SUB_STATE_UNKNOWN = 0;
- BOND_SUB_STATE_LOCAL_OOB_DATA_PROVIDED = 1;
- BOND_SUB_STATE_LOCAL_PIN_REQUESTED = 2;
- BOND_SUB_STATE_LOCAL_PIN_REPLIED = 3;
- BOND_SUB_STATE_LOCAL_SSP_REQUESTED = 4;
- BOND_SUB_STATE_LOCAL_SSP_REPLIED = 5;
-}
-
-enum UnbondReasonEnum {
- UNBOND_REASON_UNKNOWN = 0;
- UNBOND_REASON_AUTH_FAILED = 1;
- UNBOND_REASON_AUTH_REJECTED = 2;
- UNBOND_REASON_AUTH_CANCELED = 3;
- UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
- UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
- UNBOND_REASON_AUTH_TIMEOUT = 6;
- UNBOND_REASON_REPEATED_ATTEMPTS = 7;
- UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
- UNBOND_REASON_REMOVED = 9;
-}
-
-enum SocketTypeEnum {
- SOCKET_TYPE_UNKNOWN = 0;
- SOCKET_TYPE_RFCOMM = 1;
- SOCKET_TYPE_SCO = 2;
- SOCKET_TYPE_L2CAP_BREDR = 3;
- SOCKET_TYPE_L2CAP_LE = 4;
-}
-
-enum SocketConnectionstateEnum {
- SOCKET_CONNECTION_STATE_UNKNOWN = 0;
- // Socket acts as a server waiting for connection
- SOCKET_CONNECTION_STATE_LISTENING = 1;
- // Socket acts as a client trying to connect
- SOCKET_CONNECTION_STATE_CONNECTING = 2;
- // Socket is connected
- SOCKET_CONNECTION_STATE_CONNECTED = 3;
- // Socket tries to disconnect from remote
- SOCKET_CONNECTION_STATE_DISCONNECTING = 4;
- // This socket is closed
- SOCKET_CONNECTION_STATE_DISCONNECTED = 5;
-}
-
-enum SocketRoleEnum {
- SOCKET_ROLE_UNKNOWN = 0;
- SOCKET_ROLE_LISTEN = 1;
- SOCKET_ROLE_CONNECTION = 2;
-}
diff --git a/core/proto/android/bluetooth/hci/enums.proto b/core/proto/android/bluetooth/hci/enums.proto
deleted file mode 100644
index ef894e5..0000000
--- a/core/proto/android/bluetooth/hci/enums.proto
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth.hci;
-
-option java_outer_classname = "BluetoothHciProtoEnums";
-option java_multiple_files = true;
-
-// HCI command opcodes (OCF+OGF) from Bluetooth 5.0 specification Vol 2, Part E, Section 7
-// Original definition: system/bt/stack/include/hcidefs.h
-enum CommandEnum {
- // Opcode is at most 2 bytes (0xFFFF), thus 0xFFFFF must not be a valid value
- CMD_UNKNOWN = 0xFFFFF;
- // Link control commands 0x0400
- CMD_INQUIRY = 0x0401;
- CMD_INQUIRY_CANCEL = 0x0402;
- CMD_PERIODIC_INQUIRY_MODE = 0x0403;
- CMD_EXIT_PERIODIC_INQUIRY_MODE = 0x0404;
- CMD_CREATE_CONNECTION = 0x0405;
- CMD_DISCONNECT = 0x0406;
- CMD_ADD_SCO_CONNECTION = 0x0407; // Deprecated since Bluetooth 1.2
- CMD_CREATE_CONNECTION_CANCEL = 0x0408;
- CMD_ACCEPT_CONNECTION_REQUEST = 0x0409;
- CMD_REJECT_CONNECTION_REQUEST = 0x040A;
- CMD_LINK_KEY_REQUEST_REPLY = 0x040B;
- CMD_LINK_KEY_REQUEST_NEG_REPLY = 0x040C;
- CMD_PIN_CODE_REQUEST_REPLY = 0x040D;
- CMD_PIN_CODE_REQUEST_NEG_REPLY = 0x040E;
- CMD_CHANGE_CONN_PACKET_TYPE = 0x040F;
- CMD_AUTHENTICATION_REQUESTED = 0x0411;
- CMD_SET_CONN_ENCRYPTION = 0x0413;
- CMD_CHANGE_CONN_LINK_KEY = 0x0415;
- CMD_MASTER_LINK_KEY = 0x0417;
- CMD_RMT_NAME_REQUEST = 0x0419;
- CMD_RMT_NAME_REQUEST_CANCEL = 0x041A;
- CMD_READ_RMT_FEATURES = 0x041B;
- CMD_READ_RMT_EXT_FEATURES = 0x041C;
- CMD_READ_RMT_VERSION_INFO = 0x041D;
- CMD_READ_RMT_CLOCK_OFFSET = 0x041F;
- CMD_READ_LMP_HANDLE = 0x0420;
- CMD_SETUP_ESCO_CONNECTION = 0x0428;
- CMD_ACCEPT_ESCO_CONNECTION = 0x0429;
- CMD_REJECT_ESCO_CONNECTION = 0x042A;
- CMD_IO_CAPABILITY_REQUEST_REPLY = 0x042B;
- CMD_USER_CONF_REQUEST_REPLY = 0x042C;
- CMD_USER_CONF_VALUE_NEG_REPLY = 0x042D;
- CMD_USER_PASSKEY_REQ_REPLY = 0x042E;
- CMD_USER_PASSKEY_REQ_NEG_REPLY = 0x042F;
- CMD_REM_OOB_DATA_REQ_REPLY = 0x0430;
- CMD_REM_OOB_DATA_REQ_NEG_REPLY = 0x0433;
- CMD_IO_CAP_REQ_NEG_REPLY = 0x0434;
- // BEGIN: AMP commands (not used in system/bt)
- CMD_CREATE_PHYSICAL_LINK = 0x0435;
- CMD_ACCEPT_PHYSICAL_LINK = 0x0436;
- CMD_DISCONNECT_PHYSICAL_LINK = 0x0437;
- CMD_CREATE_LOGICAL_LINK = 0x0438;
- CMD_ACCEPT_LOGICAL_LINK = 0x0439;
- CMD_DISCONNECT_LOGICAL_LINK = 0x043A;
- CMD_LOGICAL_LINK_CANCEL = 0x043B;
- CMD_FLOW_SPEC_MODIFY = 0x043C;
- // END: AMP commands
- CMD_ENH_SETUP_ESCO_CONNECTION = 0x043D;
- CMD_ENH_ACCEPT_ESCO_CONNECTION = 0x043E;
- CMD_TRUNCATED_PAGE = 0x043F;
- CMD_TRUNCATED_PAGE_CANCEL = 0x0440;
- CMD_SET_CLB = 0x0441;
- CMD_RECEIVE_CLB = 0x0442;
- CMD_START_SYNC_TRAIN = 0x0443;
- CMD_RECEIVE_SYNC_TRAIN = 0x0444;
- CMD_REM_OOB_EXTENDED_DATA_REQ_REPLY = 0x0445; // Not currently used in system/bt
- // Link policy commands 0x0800
- CMD_HOLD_MODE = 0x0801;
- CMD_SNIFF_MODE = 0x0803;
- CMD_EXIT_SNIFF_MODE = 0x0804;
- CMD_PARK_MODE = 0x0805;
- CMD_EXIT_PARK_MODE = 0x0806;
- CMD_QOS_SETUP = 0x0807;
- CMD_ROLE_DISCOVERY = 0x0809;
- CMD_SWITCH_ROLE = 0x080B;
- CMD_READ_POLICY_SETTINGS = 0x080C;
- CMD_WRITE_POLICY_SETTINGS = 0x080D;
- CMD_READ_DEF_POLICY_SETTINGS = 0x080E;
- CMD_WRITE_DEF_POLICY_SETTINGS = 0x080F;
- CMD_FLOW_SPECIFICATION = 0x0810;
- CMD_SNIFF_SUB_RATE = 0x0811;
- // Host controller baseband commands 0x0C00
- CMD_SET_EVENT_MASK = 0x0C01;
- CMD_RESET = 0x0C03;
- CMD_SET_EVENT_FILTER = 0x0C05;
- CMD_FLUSH = 0x0C08;
- CMD_READ_PIN_TYPE = 0x0C09;
- CMD_WRITE_PIN_TYPE = 0x0C0A;
- CMD_CREATE_NEW_UNIT_KEY = 0x0C0B;
- CMD_GET_MWS_TRANS_LAYER_CFG = 0x0C0C; // Deprecated (not used in spec)
- CMD_READ_STORED_LINK_KEY = 0x0C0D;
- CMD_WRITE_STORED_LINK_KEY = 0x0C11;
- CMD_DELETE_STORED_LINK_KEY = 0x0C12;
- CMD_CHANGE_LOCAL_NAME = 0x0C13;
- CMD_READ_LOCAL_NAME = 0x0C14;
- CMD_READ_CONN_ACCEPT_TOUT = 0x0C15;
- CMD_WRITE_CONN_ACCEPT_TOUT = 0x0C16;
- CMD_READ_PAGE_TOUT = 0x0C17;
- CMD_WRITE_PAGE_TOUT = 0x0C18;
- CMD_READ_SCAN_ENABLE = 0x0C19;
- CMD_WRITE_SCAN_ENABLE = 0x0C1A;
- CMD_READ_PAGESCAN_CFG = 0x0C1B;
- CMD_WRITE_PAGESCAN_CFG = 0x0C1C;
- CMD_READ_INQUIRYSCAN_CFG = 0x0C1D;
- CMD_WRITE_INQUIRYSCAN_CFG = 0x0C1E;
- CMD_READ_AUTHENTICATION_ENABLE = 0x0C1F;
- CMD_WRITE_AUTHENTICATION_ENABLE = 0x0C20;
- CMD_READ_ENCRYPTION_MODE = 0x0C21; // Deprecated
- CMD_WRITE_ENCRYPTION_MODE = 0x0C22; // Deprecated
- CMD_READ_CLASS_OF_DEVICE = 0x0C23;
- CMD_WRITE_CLASS_OF_DEVICE = 0x0C24;
- CMD_READ_VOICE_SETTINGS = 0x0C25;
- CMD_WRITE_VOICE_SETTINGS = 0x0C26;
- CMD_READ_AUTOMATIC_FLUSH_TIMEOUT = 0x0C27;
- CMD_WRITE_AUTOMATIC_FLUSH_TIMEOUT = 0x0C28;
- CMD_READ_NUM_BCAST_REXMITS = 0x0C29;
- CMD_WRITE_NUM_BCAST_REXMITS = 0x0C2A;
- CMD_READ_HOLD_MODE_ACTIVITY = 0x0C2B;
- CMD_WRITE_HOLD_MODE_ACTIVITY = 0x0C2C;
- CMD_READ_TRANSMIT_POWER_LEVEL = 0x0C2D;
- CMD_READ_SCO_FLOW_CTRL_ENABLE = 0x0C2E;
- CMD_WRITE_SCO_FLOW_CTRL_ENABLE = 0x0C2F;
- CMD_SET_HC_TO_HOST_FLOW_CTRL = 0x0C31;
- CMD_HOST_BUFFER_SIZE = 0x0C33;
- CMD_HOST_NUM_PACKETS_DONE = 0x0C35;
- CMD_READ_LINK_SUPER_TOUT = 0x0C36;
- CMD_WRITE_LINK_SUPER_TOUT = 0x0C37;
- CMD_READ_NUM_SUPPORTED_IAC = 0x0C38;
- CMD_READ_CURRENT_IAC_LAP = 0x0C39;
- CMD_WRITE_CURRENT_IAC_LAP = 0x0C3A;
- CMD_READ_PAGESCAN_PERIOD_MODE = 0x0C3B; // Deprecated
- CMD_WRITE_PAGESCAN_PERIOD_MODE = 0x0C3C; // Deprecated
- CMD_READ_PAGESCAN_MODE = 0x0C3D; // Deprecated
- CMD_WRITE_PAGESCAN_MODE = 0x0C3E; // Deprecated
- CMD_SET_AFH_CHANNELS = 0x0C3F;
- CMD_READ_INQSCAN_TYPE = 0x0C42;
- CMD_WRITE_INQSCAN_TYPE = 0x0C43;
- CMD_READ_INQUIRY_MODE = 0x0C44;
- CMD_WRITE_INQUIRY_MODE = 0x0C45;
- CMD_READ_PAGESCAN_TYPE = 0x0C46;
- CMD_WRITE_PAGESCAN_TYPE = 0x0C47;
- CMD_READ_AFH_ASSESSMENT_MODE = 0x0C48;
- CMD_WRITE_AFH_ASSESSMENT_MODE = 0x0C49;
- CMD_READ_EXT_INQ_RESPONSE = 0x0C51;
- CMD_WRITE_EXT_INQ_RESPONSE = 0x0C52;
- CMD_REFRESH_ENCRYPTION_KEY = 0x0C53;
- CMD_READ_SIMPLE_PAIRING_MODE = 0x0C55;
- CMD_WRITE_SIMPLE_PAIRING_MODE = 0x0C56;
- CMD_READ_LOCAL_OOB_DATA = 0x0C57;
- CMD_READ_INQ_TX_POWER_LEVEL = 0x0C58;
- CMD_WRITE_INQ_TX_POWER_LEVEL = 0x0C59;
- CMD_READ_ERRONEOUS_DATA_RPT = 0x0C5A;
- CMD_WRITE_ERRONEOUS_DATA_RPT = 0x0C5B;
- CMD_ENHANCED_FLUSH = 0x0C5F;
- CMD_SEND_KEYPRESS_NOTIF = 0x0C60;
- CMD_READ_LOGICAL_LINK_ACCEPT_TIMEOUT = 0x0C61;
- CMD_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT = 0x0C62;
- CMD_SET_EVENT_MASK_PAGE_2 = 0x0C63;
- CMD_READ_LOCATION_DATA = 0x0C64;
- CMD_WRITE_LOCATION_DATA = 0x0C65;
- CMD_READ_FLOW_CONTROL_MODE = 0x0C66;
- CMD_WRITE_FLOW_CONTROL_MODE = 0x0C67;
- CMD_READ_ENHANCED_TX_PWR_LEVEL = 0x0C68; // Not currently used in system/bt
- CMD_READ_BE_FLUSH_TOUT = 0x0C69;
- CMD_WRITE_BE_FLUSH_TOUT = 0x0C6A;
- CMD_SHORT_RANGE_MODE = 0x0C6B;
- CMD_READ_BLE_HOST_SUPPORT = 0x0C6C;
- CMD_WRITE_BLE_HOST_SUPPORT = 0x0C6D;
- CMD_SET_MWS_CHANNEL_PARAMETERS = 0x0C6E;
- CMD_SET_EXTERNAL_FRAME_CONFIGURATION = 0x0C6F;
- CMD_SET_MWS_SIGNALING = 0x0C70;
- CMD_SET_MWS_TRANSPORT_LAYER = 0x0C71;
- CMD_SET_MWS_SCAN_FREQUENCY_TABLE = 0x0C72;
- CMD_SET_MWS_PATTERN_CONFIGURATION = 0x0C73;
- CMD_SET_RESERVED_LT_ADDR = 0x0C74;
- CMD_DELETE_RESERVED_LT_ADDR = 0x0C75;
- CMD_WRITE_CLB_DATA = 0x0C76;
- CMD_READ_SYNC_TRAIN_PARAM = 0x0C77;
- CMD_WRITE_SYNC_TRAIN_PARAM = 0x0C78;
- CMD_READ_SECURE_CONNS_SUPPORT = 0x0C79;
- CMD_WRITE_SECURE_CONNS_SUPPORT = 0x0C7A;
- CMD_READ_AUTHED_PAYLOAD_TIMEOUT = 0x0C7B; // Not currently used in system/bt
- CMD_WRITE_AUTHED_PAYLOAD_TIMEOUT = 0x0C7C; // Not currently used in system/bt
- CMD_READ_LOCAL_OOB_EXTENDED_DATA = 0x0C7D; // Not currently used in system/bt
- CMD_READ_EXTENDED_PAGE_TIMEOUT = 0x0C7E; // Not currently used in system/bt
- CMD_WRITE_EXTENDED_PAGE_TIMEOUT = 0x0C7F; // Not currently used in system/bt
- CMD_READ_EXTENDED_INQUIRY_LENGTH = 0x0C80; // Not currently used in system/bt
- CMD_WRITE_EXTENDED_INQUIRY_LENGTH = 0x0C81; // Not currently used in system/bt
- // Informational parameter commands 0x1000
- CMD_READ_LOCAL_VERSION_INFO = 0x1001;
- CMD_READ_LOCAL_SUPPORTED_CMDS = 0x1002;
- CMD_READ_LOCAL_FEATURES = 0x1003;
- CMD_READ_LOCAL_EXT_FEATURES = 0x1004;
- CMD_READ_BUFFER_SIZE = 0x1005;
- CMD_READ_COUNTRY_CODE = 0x1007; // Deprecated
- CMD_READ_BD_ADDR = 0x1009;
- CMD_READ_DATA_BLOCK_SIZE = 0x100A;
- CMD_READ_LOCAL_SUPPORTED_CODECS = 0x100B;
- // Status parameter commands 0x1400
- CMD_READ_FAILED_CONTACT_COUNTER = 0x1401;
- CMD_RESET_FAILED_CONTACT_COUNTER = 0x1402;
- CMD_GET_LINK_QUALITY = 0x1403;
- CMD_READ_RSSI = 0x1405;
- CMD_READ_AFH_CH_MAP = 0x1406;
- CMD_READ_CLOCK = 0x1407;
- CMD_READ_ENCR_KEY_SIZE = 0x1408;
- CMD_READ_LOCAL_AMP_INFO = 0x1409;
- CMD_READ_LOCAL_AMP_ASSOC = 0x140A;
- CMD_WRITE_REMOTE_AMP_ASSOC = 0x140B;
- CMD_GET_MWS_TRANSPORT_CFG = 0x140C; // Not currently used in system/bt
- CMD_SET_TRIGGERED_CLK_CAPTURE = 0x140D; // Not currently used in system/bt
- // Testing commands 0x1800
- CMD_READ_LOOPBACK_MODE = 0x1801;
- CMD_WRITE_LOOPBACK_MODE = 0x1802;
- CMD_ENABLE_DEV_UNDER_TEST_MODE = 0x1803;
- CMD_WRITE_SIMP_PAIR_DEBUG_MODE = 0x1804;
- CMD_ENABLE_AMP_RCVR_REPORTS = 0x1807;
- CMD_AMP_TEST_END = 0x1808;
- CMD_AMP_TEST = 0x1809;
- CMD_WRITE_SECURE_CONN_TEST_MODE = 0x180A; // Not currently used in system/bt
- // BLE commands 0x2000
- CMD_BLE_SET_EVENT_MASK = 0x2001;
- CMD_BLE_READ_BUFFER_SIZE = 0x2002;
- CMD_BLE_READ_LOCAL_SPT_FEAT = 0x2003;
- CMD_BLE_WRITE_LOCAL_SPT_FEAT = 0x2004;
- CMD_BLE_WRITE_RANDOM_ADDR = 0x2005;
- CMD_BLE_WRITE_ADV_PARAMS = 0x2006;
- CMD_BLE_READ_ADV_CHNL_TX_POWER = 0x2007;
- CMD_BLE_WRITE_ADV_DATA = 0x2008;
- CMD_BLE_WRITE_SCAN_RSP_DATA = 0x2009;
- CMD_BLE_WRITE_ADV_ENABLE = 0x200A;
- CMD_BLE_WRITE_SCAN_PARAMS = 0x200B;
- CMD_BLE_WRITE_SCAN_ENABLE = 0x200C;
- CMD_BLE_CREATE_LL_CONN = 0x200D;
- CMD_BLE_CREATE_CONN_CANCEL = 0x200E;
- CMD_BLE_READ_WHITE_LIST_SIZE = 0x200F;
- CMD_BLE_CLEAR_WHITE_LIST = 0x2010;
- CMD_BLE_ADD_WHITE_LIST = 0x2011;
- CMD_BLE_REMOVE_WHITE_LIST = 0x2012;
- CMD_BLE_UPD_LL_CONN_PARAMS = 0x2013;
- CMD_BLE_SET_HOST_CHNL_CLASS = 0x2014;
- CMD_BLE_READ_CHNL_MAP = 0x2015;
- CMD_BLE_READ_REMOTE_FEAT = 0x2016;
- CMD_BLE_ENCRYPT = 0x2017;
- CMD_BLE_RAND = 0x2018;
- CMD_BLE_START_ENC = 0x2019;
- CMD_BLE_LTK_REQ_REPLY = 0x201A;
- CMD_BLE_LTK_REQ_NEG_REPLY = 0x201B;
- CMD_BLE_READ_SUPPORTED_STATES = 0x201C;
- CMD_BLE_RECEIVER_TEST = 0x201D;
- CMD_BLE_TRANSMITTER_TEST = 0x201E;
- CMD_BLE_TEST_END = 0x201F;
- CMD_BLE_RC_PARAM_REQ_REPLY = 0x2020;
- CMD_BLE_RC_PARAM_REQ_NEG_REPLY = 0x2021;
- CMD_BLE_SET_DATA_LENGTH = 0x2022;
- CMD_BLE_READ_DEFAULT_DATA_LENGTH = 0x2023;
- CMD_BLE_WRITE_DEFAULT_DATA_LENGTH = 0x2024;
- CMD_BLE_GENERATE_DHKEY = 0x2026; // Not currently used in system/bt
- CMD_BLE_ADD_DEV_RESOLVING_LIST = 0x2027;
- CMD_BLE_RM_DEV_RESOLVING_LIST = 0x2028;
- CMD_BLE_CLEAR_RESOLVING_LIST = 0x2029;
- CMD_BLE_READ_RESOLVING_LIST_SIZE = 0x202A;
- CMD_BLE_READ_RESOLVABLE_ADDR_PEER = 0x202B;
- CMD_BLE_READ_RESOLVABLE_ADDR_LOCAL = 0x202C;
- CMD_BLE_SET_ADDR_RESOLUTION_ENABLE = 0x202D;
- CMD_BLE_SET_RAND_PRIV_ADDR_TIMOUT = 0x202E;
- CMD_BLE_READ_MAXIMUM_DATA_LENGTH = 0x202F;
- CMD_BLE_READ_PHY = 0x2030;
- CMD_BLE_SET_DEFAULT_PHY = 0x2031;
- CMD_BLE_SET_PHY = 0x2032;
- CMD_BLE_ENH_RECEIVER_TEST = 0x2033;
- CMD_BLE_ENH_TRANSMITTER_TEST = 0x2034;
- CMD_BLE_SET_EXT_ADVERTISING_RANDOM_ADDRESS = 0x2035;
- CMD_BLE_SET_EXT_ADVERTISING_PARAM = 0x2036;
- CMD_BLE_SET_EXT_ADVERTISING_DATA = 0x2037;
- CMD_BLE_SET_EXT_ADVERTISING_SCAN_RESP = 0x2038;
- CMD_BLE_SET_EXT_ADVERTISING_ENABLE = 0x2039;
- CMD_BLE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = 0x203A;
- CMD_BLE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = 0x203B;
- CMD_BLE_REMOVE_ADVERTISING_SET = 0x203C;
- CMD_BLE_CLEAR_ADVERTISING_SETS = 0x203D;
- CMD_BLE_SET_PERIODIC_ADVERTISING_PARAM = 0x203E;
- CMD_BLE_SET_PERIODIC_ADVERTISING_DATA = 0x203F;
- CMD_BLE_SET_PERIODIC_ADVERTISING_ENABLE = 0x2040;
- CMD_BLE_SET_EXTENDED_SCAN_PARAMETERS = 0x2041;
- CMD_BLE_SET_EXTENDED_SCAN_ENABLE = 0x2042;
- CMD_BLE_EXTENDED_CREATE_CONNECTION = 0x2043;
- CMD_BLE_PERIODIC_ADVERTISING_CREATE_SYNC = 0x2044;
- CMD_BLE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = 0x2045;
- CMD_BLE_PERIODIC_ADVERTISING_TERMINATE_SYNC = 0x2046;
- CMD_BLE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST = 0x2047;
- CMD_BLE_RM_DEVICE_FROM_PERIODIC_ADVERTISING_LIST = 0x2048;
- CMD_BLE_CLEAR_PERIODIC_ADVERTISING_LIST = 0x2049;
- CMD_BLE_READ_PERIODIC_ADVERTISING_LIST_SIZE = 0x204A;
- CMD_BLE_READ_TRANSMIT_POWER = 0x204B;
- CMD_BLE_READ_RF_COMPENS_POWER = 0x204C;
- CMD_BLE_WRITE_RF_COMPENS_POWER = 0x204D;
- CMD_BLE_SET_PRIVACY_MODE = 0x204E;
- // Vendor specific commands 0xFC00 and above
- // Android vendor specific commands defined in
- // https://source.android.com/devices/bluetooth/hci_requirements#vendor-specific-capabilities
- CMD_BLE_VENDOR_CAP = 0xFD53;
- CMD_BLE_MULTI_ADV = 0xFD54;
- CMD_BLE_BATCH_SCAN = 0xFD56;
- CMD_BLE_ADV_FILTER = 0xFD57;
- CMD_BLE_TRACK_ADV = 0xFD58;
- CMD_BLE_ENERGY_INFO = 0xFD59;
- CMD_BLE_EXTENDED_SCAN_PARAMS = 0xFD5A;
- CMD_CONTROLLER_DEBUG_INFO = 0xFD5B;
- CMD_CONTROLLER_A2DP_OPCODE = 0xFD5D;
- CMD_BRCM_SET_ACL_PRIORITY = 0xFC57;
- // Other vendor specific commands below here
-}
-
-// HCI event codes from the Bluetooth 5.0 specification Vol 2, Part 7, Section 7
-// Original definition: system/bt/stack/include/hcidefs.h
-enum EventEnum {
- // Event is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- EVT_UNKNOWN = 0xFFF;
- EVT_INQUIRY_COMP = 0x01;
- EVT_INQUIRY_RESULT = 0x02;
- EVT_CONNECTION_COMP = 0x03;
- EVT_CONNECTION_REQUEST = 0x04;
- EVT_DISCONNECTION_COMP = 0x05;
- EVT_AUTHENTICATION_COMP = 0x06;
- EVT_RMT_NAME_REQUEST_COMP = 0x07;
- EVT_ENCRYPTION_CHANGE = 0x08;
- EVT_CHANGE_CONN_LINK_KEY = 0x09;
- EVT_MASTER_LINK_KEY_COMP = 0x0A;
- EVT_READ_RMT_FEATURES_COMP = 0x0B;
- EVT_READ_RMT_VERSION_COMP = 0x0C;
- EVT_QOS_SETUP_COMP = 0x0D;
- EVT_COMMAND_COMPLETE = 0x0E;
- EVT_COMMAND_STATUS = 0x0F;
- EVT_HARDWARE_ERROR = 0x10;
- EVT_FLUSH_OCCURRED = 0x11;
- EVT_ROLE_CHANGE = 0x12;
- EVT_NUM_COMPL_DATA_PKTS = 0x13;
- EVT_MODE_CHANGE = 0x14;
- EVT_RETURN_LINK_KEYS = 0x15;
- EVT_PIN_CODE_REQUEST = 0x16;
- EVT_LINK_KEY_REQUEST = 0x17;
- EVT_LINK_KEY_NOTIFICATION = 0x18;
- EVT_LOOPBACK_COMMAND = 0x19;
- EVT_DATA_BUF_OVERFLOW = 0x1A;
- EVT_MAX_SLOTS_CHANGED = 0x1B;
- EVT_READ_CLOCK_OFF_COMP = 0x1C;
- EVT_CONN_PKT_TYPE_CHANGE = 0x1D;
- EVT_QOS_VIOLATION = 0x1E;
- EVT_PAGE_SCAN_MODE_CHANGE = 0x1F; // Deprecated
- EVT_PAGE_SCAN_REP_MODE_CHNG = 0x20;
- EVT_FLOW_SPECIFICATION_COMP = 0x21;
- EVT_INQUIRY_RSSI_RESULT = 0x22;
- EVT_READ_RMT_EXT_FEATURES_COMP = 0x23;
- EVT_ESCO_CONNECTION_COMP = 0x2C;
- EVT_ESCO_CONNECTION_CHANGED = 0x2D;
- EVT_SNIFF_SUB_RATE = 0x2E;
- EVT_EXTENDED_INQUIRY_RESULT = 0x2F;
- EVT_ENCRYPTION_KEY_REFRESH_COMP = 0x30;
- EVT_IO_CAPABILITY_REQUEST = 0x31;
- EVT_IO_CAPABILITY_RESPONSE = 0x32;
- EVT_USER_CONFIRMATION_REQUEST = 0x33;
- EVT_USER_PASSKEY_REQUEST = 0x34;
- EVT_REMOTE_OOB_DATA_REQUEST = 0x35;
- EVT_SIMPLE_PAIRING_COMPLETE = 0x36;
- EVT_LINK_SUPER_TOUT_CHANGED = 0x38;
- EVT_ENHANCED_FLUSH_COMPLETE = 0x39;
- EVT_USER_PASSKEY_NOTIFY = 0x3B;
- EVT_KEYPRESS_NOTIFY = 0x3C;
- EVT_RMT_HOST_SUP_FEAT_NOTIFY = 0x3D;
- EVT_BLE_META = 0x3E;
- EVT_PHYSICAL_LINK_COMP = 0x40;
- EVT_CHANNEL_SELECTED = 0x41;
- EVT_DISC_PHYSICAL_LINK_COMP = 0x42;
- EVT_PHY_LINK_LOSS_EARLY_WARNING = 0x43;
- EVT_PHY_LINK_RECOVERY = 0x44;
- EVT_LOGICAL_LINK_COMP = 0x45;
- EVT_DISC_LOGICAL_LINK_COMP = 0x46;
- EVT_FLOW_SPEC_MODIFY_COMP = 0x47;
- EVT_NUM_COMPL_DATA_BLOCKS = 0x48;
- EVT_AMP_TEST_START = 0x49; // Not currently used in system/bt
- EVT_AMP_TEST_END = 0x4A; // Not currently used in system/bt
- EVT_AMP_RECEIVER_RPT = 0x4B; // Not currently used in system/bt
- EVT_SHORT_RANGE_MODE_COMPLETE = 0x4C;
- EVT_AMP_STATUS_CHANGE = 0x4D;
- EVT_SET_TRIGGERED_CLOCK_CAPTURE = 0x4E;
- EVT_SYNC_TRAIN_CMPL = 0x4F; // Not currently used in system/bt
- EVT_SYNC_TRAIN_RCVD = 0x50; // Not currently used in system/bt
- EVT_CONNLESS_SLAVE_BROADCAST_RCVD = 0x51; // Not currently used in system/bt
- EVT_CONNLESS_SLAVE_BROADCAST_TIMEOUT = 0x52; // Not currently used in system/bt
- EVT_TRUNCATED_PAGE_CMPL = 0x53; // Not currently used in system/bt
- EVT_SLAVE_PAGE_RES_TIMEOUT = 0x54; // Not currently used in system/bt
- EVT_CONNLESS_SLAVE_BROADCAST_CHNL_MAP_CHANGE = 0x55; // Not currently used in system/bt
- EVT_INQUIRY_RES_NOTIFICATION = 0x56; // Not currently used in system/bt
- EVT_AUTHED_PAYLOAD_TIMEOUT = 0x57; // Not currently used in system/bt
- EVT_SAM_STATUS_CHANGE = 0x58; // Not currently used in system/bt
-}
-
-// Bluetooth low energy related meta event codes
-// from the Bluetooth 5.0 specification Vol 2, Part E, Section 7.7.65
-// Original definition: system/bt/stack/include/hcidefs.h
-enum BleMetaEventEnum {
- // BLE meta event code is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- BLE_EVT_UNKNOWN = 0xFFF;
- BLE_EVT_CONN_COMPLETE_EVT = 0x01;
- BLE_EVT_ADV_PKT_RPT_EVT = 0x02;
- BLE_EVT_LL_CONN_PARAM_UPD_EVT = 0x03;
- BLE_EVT_READ_REMOTE_FEAT_CMPL_EVT = 0x04;
- BLE_EVT_LTK_REQ_EVT = 0x05;
- BLE_EVT_RC_PARAM_REQ_EVT = 0x06;
- BLE_EVT_DATA_LENGTH_CHANGE_EVT = 0x07;
- BLE_EVT_READ_LOCAL_P256_PUB_KEY = 0x08; // Not currently used in system/bt
- BLE_EVT_GEN_DHKEY_CMPL = 0x09; // Not currently used in system/bt
- BLE_EVT_ENHANCED_CONN_COMPLETE_EVT = 0x0a;
- BLE_EVT_DIRECT_ADV_EVT = 0x0b;
- BLE_EVT_PHY_UPDATE_COMPLETE_EVT = 0x0c;
- BLE_EVT_EXTENDED_ADVERTISING_REPORT_EVT = 0x0D;
- BLE_EVT_PERIODIC_ADV_SYNC_EST_EVT = 0x0E;
- BLE_EVT_PERIODIC_ADV_REPORT_EVT = 0x0F;
- BLE_EVT_PERIODIC_ADV_SYNC_LOST_EVT = 0x10;
- BLE_EVT_SCAN_TIMEOUT_EVT = 0x11;
- BLE_EVT_ADVERTISING_SET_TERMINATED_EVT = 0x12;
- BLE_EVT_SCAN_REQ_RX_EVT = 0x13;
- BLE_EVT_CHNL_SELECTION_ALGORITHM = 0x14; // Not currently used in system/bt
-}
-
-// HCI status code from the Bluetooth 5.0 specification Vol 2, Part D.
-// Original definition: system/bt/stack/include/hcidefs.h
-enum StatusEnum {
- // Status is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- STATUS_UNKNOWN = 0xFFF;
- STATUS_SUCCESS = 0x00;
- STATUS_ILLEGAL_COMMAND = 0x01;
- STATUS_NO_CONNECTION = 0x02;
- STATUS_HW_FAILURE = 0x03;
- STATUS_PAGE_TIMEOUT = 0x04;
- STATUS_AUTH_FAILURE = 0x05;
- STATUS_KEY_MISSING = 0x06;
- STATUS_MEMORY_FULL = 0x07;
- STATUS_CONNECTION_TOUT = 0x08;
- STATUS_MAX_NUM_OF_CONNECTIONS = 0x09;
- STATUS_MAX_NUM_OF_SCOS = 0x0A;
- STATUS_CONNECTION_EXISTS = 0x0B;
- STATUS_COMMAND_DISALLOWED = 0x0C;
- STATUS_HOST_REJECT_RESOURCES = 0x0D;
- STATUS_HOST_REJECT_SECURITY = 0x0E;
- STATUS_HOST_REJECT_DEVICE = 0x0F;
- STATUS_HOST_TIMEOUT = 0x10;
- STATUS_UNSUPPORTED_VALUE = 0x11;
- STATUS_ILLEGAL_PARAMETER_FMT = 0x12;
- STATUS_PEER_USER = 0x13;
- STATUS_PEER_LOW_RESOURCES = 0x14;
- STATUS_PEER_POWER_OFF = 0x15;
- STATUS_CONN_CAUSE_LOCAL_HOST = 0x16;
- STATUS_REPEATED_ATTEMPTS = 0x17;
- STATUS_PAIRING_NOT_ALLOWED = 0x18;
- STATUS_UNKNOWN_LMP_PDU = 0x19;
- STATUS_UNSUPPORTED_REM_FEATURE = 0x1A;
- STATUS_SCO_OFFSET_REJECTED = 0x1B;
- STATUS_SCO_INTERVAL_REJECTED = 0x1C;
- STATUS_SCO_AIR_MODE = 0x1D;
- STATUS_INVALID_LMP_PARAM = 0x1E;
- STATUS_UNSPECIFIED = 0x1F;
- STATUS_UNSUPPORTED_LMP_FEATURE = 0x20;
- STATUS_ROLE_CHANGE_NOT_ALLOWED = 0x21;
- STATUS_LMP_RESPONSE_TIMEOUT = 0x22;
- STATUS_LMP_STATUS_TRANS_COLLISION = 0x23;
- STATUS_LMP_PDU_NOT_ALLOWED = 0x24;
- STATUS_ENCRY_MODE_NOT_ACCEPTABLE = 0x25;
- STATUS_UNIT_KEY_USED = 0x26;
- STATUS_QOS_NOT_SUPPORTED = 0x27;
- STATUS_INSTANT_PASSED = 0x28;
- STATUS_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29;
- STATUS_DIFF_TRANSACTION_COLLISION = 0x2A;
- STATUS_UNDEFINED_0x2B = 0x2B; // Not used
- STATUS_QOS_UNACCEPTABLE_PARAM = 0x2C;
- STATUS_QOS_REJECTED = 0x2D;
- STATUS_CHAN_CLASSIF_NOT_SUPPORTED = 0x2E;
- STATUS_INSUFFCIENT_SECURITY = 0x2F;
- STATUS_PARAM_OUT_OF_RANGE = 0x30;
- STATUS_UNDEFINED_0x31 = 0x31; // Not used
- STATUS_ROLE_SWITCH_PENDING = 0x32;
- STATUS_UNDEFINED_0x33 = 0x33;
- STATUS_RESERVED_SLOT_VIOLATION = 0x34;
- STATUS_ROLE_SWITCH_FAILED = 0x35;
- STATUS_INQ_RSP_DATA_TOO_LARGE = 0x36;
- STATUS_SIMPLE_PAIRING_NOT_SUPPORTED = 0x37;
- STATUS_HOST_BUSY_PAIRING = 0x38;
- STATUS_REJ_NO_SUITABLE_CHANNEL = 0x39;
- STATUS_CONTROLLER_BUSY = 0x3A;
- STATUS_UNACCEPT_CONN_INTERVAL = 0x3B;
- STATUS_ADVERTISING_TIMEOUT = 0x3C;
- STATUS_CONN_TOUT_DUE_TO_MIC_FAILURE = 0x3D;
- STATUS_CONN_FAILED_ESTABLISHMENT = 0x3E;
- STATUS_MAC_CONNECTION_FAILED = 0x3F;
- STATUS_LT_ADDR_ALREADY_IN_USE = 0x40;
- STATUS_LT_ADDR_NOT_ALLOCATED = 0x41;
- STATUS_CLB_NOT_ENABLED = 0x42;
- STATUS_CLB_DATA_TOO_BIG = 0x43;
- STATUS_OPERATION_CANCELED_BY_HOST = 0x44; // Not currently used in system/bt
-}
-
-enum BqrIdEnum {
- BQR_ID_UNKNOWN = 0x00;
- BQR_ID_MONITOR_MODE = 0x01;
- BQR_ID_APPROACH_LSTO = 0x02;
- BQR_ID_A2DP_AUDIO_CHOPPY = 0x03;
- BQR_ID_SCO_VOICE_CHOPPY = 0x04;
-}
-
-enum BqrPacketTypeEnum {
- BQR_PACKET_TYPE_UNKNOWN = 0x00;
- BQR_PACKET_TYPE_ID = 0x01;
- BQR_PACKET_TYPE_NULL = 0x02;
- BQR_PACKET_TYPE_POLL = 0x03;
- BQR_PACKET_TYPE_FHS = 0x04;
- BQR_PACKET_TYPE_HV1 = 0x05;
- BQR_PACKET_TYPE_HV2 = 0x06;
- BQR_PACKET_TYPE_HV3 = 0x07;
- BQR_PACKET_TYPE_DV = 0x08;
- BQR_PACKET_TYPE_EV3 = 0x09;
- BQR_PACKET_TYPE_EV4 = 0x0A;
- BQR_PACKET_TYPE_EV5 = 0x0B;
- BQR_PACKET_TYPE_2EV3 = 0x0C;
- BQR_PACKET_TYPE_2EV5 = 0x0D;
- BQR_PACKET_TYPE_3EV3 = 0x0E;
- BQR_PACKET_TYPE_3EV5 = 0x0F;
- BQR_PACKET_TYPE_DM1 = 0x10;
- BQR_PACKET_TYPE_DH1 = 0x11;
- BQR_PACKET_TYPE_DM3 = 0x12;
- BQR_PACKET_TYPE_DH3 = 0x13;
- BQR_PACKET_TYPE_DM5 = 0x14;
- BQR_PACKET_TYPE_DH5 = 0x15;
- BQR_PACKET_TYPE_AUX1 = 0x16;
- BQR_PACKET_TYPE_2DH1 = 0x17;
- BQR_PACKET_TYPE_2DH3 = 0x18;
- BQR_PACKET_TYPE_2DH5 = 0x19;
- BQR_PACKET_TYPE_3DH1 = 0x1A;
- BQR_PACKET_TYPE_3DH3 = 0x1B;
- BQR_PACKET_TYPE_3DH5 = 0x1C;
-}
diff --git a/core/proto/android/bluetooth/hfp/enums.proto b/core/proto/android/bluetooth/hfp/enums.proto
deleted file mode 100644
index d286e4b..0000000
--- a/core/proto/android/bluetooth/hfp/enums.proto
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth.hfp;
-
-option java_outer_classname = "BluetoothHfpProtoEnums";
-option java_multiple_files = true;
-
-enum ScoCodec {
- SCO_CODEC_UNKNOWN = 0;
- SCO_CODEC_CVSD = 1;
- // Default codec behind Wide Band Speech
- SCO_CODEC_MSBC = 2;
-}
\ No newline at end of file
diff --git a/core/proto/android/bluetooth/smp/enums.proto b/core/proto/android/bluetooth/smp/enums.proto
deleted file mode 100644
index c6747b7..0000000
--- a/core/proto/android/bluetooth/smp/enums.proto
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth.smp;
-
-option java_outer_classname = "BluetoothSmpProtoEnums";
-option java_multiple_files = true;
-
-// SMP Pairing command codes
-enum CommandEnum {
- CMD_UNKNOWN = 0x00;
- CMD_PAIRING_REQUEST = 0x01;
- CMD_PAIRING_RESPONSE = 0x02;
- CMD_PAIRING_CONFIRM = 0x03;
- CMD_PAIRING_RANDOM = 0x04;
- CMD_PAIRING_FAILED = 0x05;
- CMD_ENCRYPTION_INFON = 0x06;
- CMD_MASTER_IDENTIFICATION = 0x07;
- CMD_IDENTITY_INFO = 0x08;
- CMD_IDENTITY_ADDR_INFO = 0x09;
- CMD_SIGNING_INFO = 0x0A;
- CMD_SECURITY_REQUEST = 0x0B;
- CMD_PAIRING_PUBLIC_KEY = 0x0C;
- CMD_PAIRING_DHKEY_CHECK = 0x0D;
- CMD_PAIRING_KEYPRESS_INFO = 0x0E;
-}
-
-enum PairingFailReasonEnum {
- PAIRING_FAIL_REASON_RESERVED = 0x00;
- PAIRING_FAIL_REASON_PASSKEY_ENTRY = 0x01;
- PAIRING_FAIL_REASON_OOB = 0x02;
- PAIRING_FAIL_REASON_AUTH_REQ = 0x03;
- PAIRING_FAIL_REASON_CONFIRM_VALUE = 0x04;
- PAIRING_FAIL_REASON_PAIR_NOT_SUPPORT = 0x05;
- PAIRING_FAIL_REASON_ENC_KEY_SIZE = 0x06;
- PAIRING_FAIL_REASON_INVALID_CMD = 0x07;
- PAIRING_FAIL_REASON_UNSPECIFIED = 0x08;
- PAIRING_FAIL_REASON_REPEATED_ATTEMPTS = 0x09;
- PAIRING_FAIL_REASON_INVALID_PARAMETERS = 0x0A;
- PAIRING_FAIL_REASON_DHKEY_CHK = 0x0B;
- PAIRING_FAIL_REASON_NUMERIC_COMPARISON = 0x0C;
- PAIRING_FAIL_REASON_CLASSIC_PAIRING_IN_PROGR = 0x0D;
- PAIRING_FAIL_REASON_XTRANS_DERIVE_NOT_ALLOW = 0x0E;
-}
\ No newline at end of file
diff --git a/core/proto/android/debug/enums.proto b/core/proto/android/debug/enums.proto
deleted file mode 100644
index 6747bb7..0000000
--- a/core/proto/android/debug/enums.proto
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.debug;
-
-option java_outer_classname = "AdbProtoEnums";
-option java_multiple_files = true;
-
-/**
- * adb connection state used to track adb connection changes in AdbDebuggingManager.java.
- */
-enum AdbConnectionStateEnum {
- UNKNOWN = 0;
-
- /**
- * The adb connection is waiting for approval from the user.
- */
- AWAITING_USER_APPROVAL = 1;
-
- /**
- * The user allowed the adb connection from the system.
- */
- USER_ALLOWED = 2;
-
- /**
- * The user denied the adb connection from the system.
- */
- USER_DENIED = 3;
-
- /**
- * The adb connection was automatically allowed without user interaction due to the system
- * being previously allowed by the user with the 'always allow' option selected, and the adb
- * grant has not yet expired.
- */
- AUTOMATICALLY_ALLOWED = 4;
-
- /**
- * An empty or invalid base64 encoded key was provided to the framework; the connection was
- * automatically denied.
- */
- DENIED_INVALID_KEY = 5;
-
- /**
- * vold decrypt has not yet occurred; the connection was automatically denied.
- */
- DENIED_VOLD_DECRYPT = 6;
-
- /**
- * The adb session has been disconnected.
- */
- DISCONNECTED = 7;
-}
-
diff --git a/core/proto/android/hardware/biometrics/enums.proto b/core/proto/android/hardware/biometrics/enums.proto
deleted file mode 100644
index f2e0638..0000000
--- a/core/proto/android/hardware/biometrics/enums.proto
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.hardware.biometrics;
-
-option java_outer_classname = "BiometricsProtoEnums";
-option java_multiple_files = true;
-
-// Logging constants for <Biometric>Service and BiometricService
-
-enum ModalityEnum {
- MODALITY_UNKNOWN = 0;
- MODALITY_FINGERPRINT = 1; // 1 << 0
- MODALITY_IRIS = 2; // 1 << 1
- MODALITY_FACE = 4; // 1 << 2
-}
-
-enum ClientEnum {
- CLIENT_UNKNOWN = 0;
- CLIENT_KEYGUARD = 1;
- CLIENT_BIOMETRIC_PROMPT = 2;
- CLIENT_FINGERPRINT_MANAGER = 3; // Deprecated API before BiometricPrompt was introduced
-}
-
-enum ActionEnum {
- ACTION_UNKNOWN = 0;
- ACTION_ENROLL = 1;
- ACTION_AUTHENTICATE = 2;
- ACTION_ENUMERATE = 3;
- ACTION_REMOVE = 4;
-}
-
-enum IssueEnum {
- ISSUE_UNKNOWN = 0;
- // When a biometric HAL has crashed.
- ISSUE_HAL_DEATH = 1;
- // When Android Framework has a template that doesn't exist in the HAL. The framework
- // is expected to remove its template to stay in sync with the HAL.
- ISSUE_UNKNOWN_TEMPLATE_ENROLLED_FRAMEWORK = 2;
- // When the HAL has a template that doesn't exist in Android Framework. The framework
- // is expected to notify the HAL to remove this template to stay in sync with the framework.
- ISSUE_UNKNOWN_TEMPLATE_ENROLLED_HAL = 3;
- // When the HAL has not sent ERROR_CANCELED within the specified timeout.
- ISSUE_CANCEL_TIMED_OUT = 4;
-}
\ No newline at end of file
diff --git a/core/proto/android/hardware/sensor/assist/enums.proto b/core/proto/android/hardware/sensor/assist/enums.proto
deleted file mode 100644
index 012dcb2..0000000
--- a/core/proto/android/hardware/sensor/assist/enums.proto
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.hardware.sensor.assist;
-
-option java_outer_classname = "AssistGestureProtoEnums";
-option java_multiple_files = true;
-
-enum AssistGestureStageEnum {
- ASSIST_GESTURE_STAGE_UNKNOWN = 0;
- ASSIST_GESTURE_STAGE_PROGRESS = 1;
- ASSIST_GESTURE_STAGE_PRIMED = 2;
- ASSIST_GESTURE_STAGE_DETECTED = 3;
-}
-
-enum AssistGestureFeedbackEnum {
- ASSIST_GESTURE_FEEDBACK_UNKNOWN = 0;
- ASSIST_GESTURE_FEEDBACK_NOT_USED = 1;
- ASSIST_GESTURE_FEEDBACK_USED = 2;
-}
\ No newline at end of file
diff --git a/core/proto/android/net/networkcapabilities.proto b/core/proto/android/net/networkcapabilities.proto
deleted file mode 100644
index be0cad1..0000000
--- a/core/proto/android/net/networkcapabilities.proto
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.net;
-
-option java_multiple_files = true;
-
-import "frameworks/base/core/proto/android/privacy.proto";
-
-/**
- * An android.net.NetworkCapabilities object.
- */
-message NetworkCapabilitiesProto {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- enum Transport {
- // Indicates this network uses a Cellular transport.
- TRANSPORT_CELLULAR = 0;
- // Indicates this network uses a Wi-Fi transport.
- TRANSPORT_WIFI = 1;
- // Indicates this network uses a Bluetooth transport.
- TRANSPORT_BLUETOOTH = 2;
- // Indicates this network uses an Ethernet transport.
- TRANSPORT_ETHERNET = 3;
- // Indicates this network uses a VPN transport.
- TRANSPORT_VPN = 4;
- // Indicates this network uses a Wi-Fi Aware transport.
- TRANSPORT_WIFI_AWARE = 5;
- // Indicates this network uses a LoWPAN transport.
- TRANSPORT_LOWPAN = 6;
- }
- repeated Transport transports = 1;
-
- enum NetCapability {
- // Indicates this is a network that has the ability to reach the
- // carrier's MMSC for sending and receiving MMS messages.
- NET_CAPABILITY_MMS = 0;
- // Indicates this is a network that has the ability to reach the
- // carrier's SUPL server, used to retrieve GPS information.
- NET_CAPABILITY_SUPL = 1;
- // Indicates this is a network that has the ability to reach the
- // carrier's DUN or tethering gateway.
- NET_CAPABILITY_DUN = 2;
- // Indicates this is a network that has the ability to reach the
- // carrier's FOTA portal, used for over the air updates.
- NET_CAPABILITY_FOTA = 3;
- // Indicates this is a network that has the ability to reach the
- // carrier's IMS servers, used for network registration and signaling.
- NET_CAPABILITY_IMS = 4;
- // Indicates this is a network that has the ability to reach the
- // carrier's CBS servers, used for carrier specific services.
- NET_CAPABILITY_CBS = 5;
- // Indicates this is a network that has the ability to reach a Wi-Fi
- // direct peer.
- NET_CAPABILITY_WIFI_P2P = 6;
- // Indicates this is a network that has the ability to reach a carrier's
- // Initial Attach servers.
- NET_CAPABILITY_IA = 7;
- // Indicates this is a network that has the ability to reach a carrier's
- // RCS servers, used for Rich Communication Services.
- NET_CAPABILITY_RCS = 8;
- // Indicates this is a network that has the ability to reach a carrier's
- // XCAP servers, used for configuration and control.
- NET_CAPABILITY_XCAP = 9;
- // Indicates this is a network that has the ability to reach a carrier's
- // Emergency IMS servers or other services, used for network signaling
- // during emergency calls.
- NET_CAPABILITY_EIMS = 10;
- // Indicates that this network is unmetered.
- NET_CAPABILITY_NOT_METERED = 11;
- // Indicates that this network should be able to reach the internet.
- NET_CAPABILITY_INTERNET = 12;
- // Indicates that this network is available for general use. If this is
- // not set applications should not attempt to communicate on this
- // network. Note that this is simply informative and not enforcement -
- // enforcement is handled via other means. Set by default.
- NET_CAPABILITY_NOT_RESTRICTED = 13;
- // Indicates that the user has indicated implicit trust of this network.
- // This generally means it's a sim-selected carrier, a plugged in
- // ethernet, a paired BT device or a wifi the user asked to connect to.
- // Untrusted networks are probably limited to unknown wifi AP. Set by
- // default.
- NET_CAPABILITY_TRUSTED = 14;
- // Indicates that this network is not a VPN. This capability is set by
- // default and should be explicitly cleared for VPN networks.
- NET_CAPABILITY_NOT_VPN = 15;
- // Indicates that connectivity on this network was successfully
- // validated. For example, for a network with NET_CAPABILITY_INTERNET,
- // it means that Internet connectivity was successfully detected.
- NET_CAPABILITY_VALIDATED = 16;
- // Indicates that this network was found to have a captive portal in
- // place last time it was probed.
- NET_CAPABILITY_CAPTIVE_PORTAL = 17;
- // Indicates that this network is not roaming.
- NET_CAPABILITY_NOT_ROAMING = 18;
- // Indicates that this network is available for use by apps, and not a
- // network that is being kept up in the background to facilitate fast
- // network switching.
- NET_CAPABILITY_FOREGROUND = 19;
- }
- repeated NetCapability capabilities = 2;
-
- // Passive link bandwidth. This is a rough guide of the expected peak
- // bandwidth for the first hop on the given transport. It is not measured,
- // but may take into account link parameters (Radio technology, allocated
- // channels, etc).
- optional int32 link_up_bandwidth_kbps = 3;
- optional int32 link_down_bandwidth_kbps = 4;
-
- optional string network_specifier = 5 [ (.android.privacy).dest = DEST_EXPLICIT ];
-
- // True if this object specifies a signal strength.
- optional bool can_report_signal_strength = 6;
- // This is a signed integer, and higher values indicate better signal. The
- // exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
- // Only valid if can_report_signal_strength is true.
- optional sint32 signal_strength = 7;
-}
diff --git a/core/proto/android/net/networkrequest.proto b/core/proto/android/net/networkrequest.proto
index b35a020..6794c8c 100644
--- a/core/proto/android/net/networkrequest.proto
+++ b/core/proto/android/net/networkrequest.proto
@@ -20,8 +20,8 @@
option java_multiple_files = true;
-import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/net/networkcapabilities.proto";
/**
* An android.net.NetworkRequest object.
diff --git a/core/proto/android/os/batterystats.proto b/core/proto/android/os/batterystats.proto
index 892ebf7..7d68a0d 100644
--- a/core/proto/android/os/batterystats.proto
+++ b/core/proto/android/os/batterystats.proto
@@ -19,10 +19,10 @@
package android.os;
-import "frameworks/base/core/proto/android/app/job/enums.proto";
import "frameworks/base/core/proto/android/os/powermanager.proto";
-import "frameworks/base/core/proto/android/telephony/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/app/job/enums.proto";
+import "frameworks/proto_logging/stats/enums/telephony/enums.proto";
message BatteryStatsProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/os/enums.proto b/core/proto/android/os/enums.proto
deleted file mode 100644
index 566861b..0000000
--- a/core/proto/android/os/enums.proto
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.os;
-
-option java_outer_classname = "OsProtoEnums";
-option java_multiple_files = true;
-
-// These constants are defined in hardware/interfaces/health/1.0/types.hal
-// They are primarily used by android/os/BatteryManager.java.
-enum BatteryHealthEnum {
- BATTERY_HEALTH_INVALID = 0;
- BATTERY_HEALTH_UNKNOWN = 1;
- BATTERY_HEALTH_GOOD = 2;
- BATTERY_HEALTH_OVERHEAT = 3;
- BATTERY_HEALTH_DEAD = 4;
- BATTERY_HEALTH_OVER_VOLTAGE = 5;
- BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6;
- BATTERY_HEALTH_COLD = 7;
-}
-
-// Plug states, primarily used by android/os/BatteryManager.java.
-enum BatteryPluggedStateEnum {
- // Note that NONE is not in BatteryManager.java's constants.
- BATTERY_PLUGGED_NONE = 0;
- // Power source is an AC charger.
- BATTERY_PLUGGED_AC = 1;
- // Power source is a USB port.
- BATTERY_PLUGGED_USB = 2;
- // Power source is wireless.
- BATTERY_PLUGGED_WIRELESS = 4;
-}
-
-// These constants are defined in hardware/interfaces/health/1.0/types.hal
-// They are primarily used by android/os/BatteryManager.java.
-enum BatteryStatusEnum {
- BATTERY_STATUS_INVALID = 0;
- BATTERY_STATUS_UNKNOWN = 1;
- BATTERY_STATUS_CHARGING = 2;
- BATTERY_STATUS_DISCHARGING = 3;
- BATTERY_STATUS_NOT_CHARGING = 4;
- BATTERY_STATUS_FULL = 5;
-}
-
-// These constants are defined in hardware/interfaces/thermal/1.0/types.hal
-// and in hardware/interfaces/thermal/2.0/types.hal
-// They are primarily used by android/os/HardwarePropertiesManager.java.
-// Any change to the types in the thermal hal should be made here as well.
-enum TemperatureTypeEnum {
- TEMPERATURE_TYPE_UNKNOWN = -1;
- TEMPERATURE_TYPE_CPU = 0;
- TEMPERATURE_TYPE_GPU = 1;
- TEMPERATURE_TYPE_BATTERY = 2;
- TEMPERATURE_TYPE_SKIN = 3;
- TEMPERATURE_TYPE_USB_PORT = 4;
- TEMPERATURE_TYPE_POWER_AMPLIFIER = 5;
-
- // Battery Charge Limit - virtual thermal sensors.
- TEMPERATURE_TYPE_BCL_VOLTAGE = 6;
- TEMPERATURE_TYPE_BCL_CURRENT = 7;
- TEMPERATURE_TYPE_BCL_PERCENTAGE = 8;
-
- // Neural Processing Unit.
- TEMPERATURE_TYPE_NPU = 9;
-}
-
-// Device throttling severity
-// These constants are defined in hardware/interfaces/thermal/2.0/types.hal.
-// Any change to the types in the thermal hal should be made here as well.
-enum ThrottlingSeverityEnum {
- // Not under throttling.
- NONE = 0;
- // Light throttling where UX is not impacted.
- LIGHT = 1;
- // Moderate throttling where UX is not largely impacted.
- MODERATE = 2;
- // Severe throttling where UX is largely impacted.
- // Similar to 1.0 throttlingThreshold.
- SEVERE = 3;
- // Platform has done everything to reduce power.
- CRITICAL = 4;
- // Key components in platform are shutting down due to thermal condition.
- // Device functionalities will be limited.
- EMERGENCY = 5;
- // Need shutdown immediately.
- SHUTDOWN = 6;
-};
-
-// Device cooling device types.
-// These constants are defined in hardware/interfaces/thermal/2.0/types.hal.
-// Any change to the types in the thermal hal should be made here as well.
-enum CoolingTypeEnum {
- FAN = 0;
- BATTERY = 1;
- CPU = 2;
- GPU = 3;
- MODEM = 4;
- NPU = 5;
- COMPONENT = 6;
-};
-
-// Wakelock types, primarily used by android/os/PowerManager.java.
-enum WakeLockLevelEnum {
- // NOTE: Wake lock levels were previously defined as a bit field, except
- // that only a few combinations were actually supported so the bit field
- // was removed. This explains why the numbering scheme is so odd. If
- // adding a new wake lock level, any unused value can be used.
-
- // Ensures that the CPU is running; the screen and keyboard backlight
- // will be allowed to go off.
- PARTIAL_WAKE_LOCK = 1;
-
- // Ensures that the screen is on (but may be dimmed); the keyboard
- // backlight will be allowed to go off. If the user presses the power
- // button, then the SCREEN_DIM_WAKE_LOCK will be implicitly released by
- // the system, causing both the screen and the CPU to be turned off.
- SCREEN_DIM_WAKE_LOCK = 6 [deprecated = true];
-
- // Ensures that the screen is on at full brightness; the keyboard
- // backlight will be allowed to go off. If the user presses the power
- // button, then the SCREEN_BRIGHT_WAKE_LOCK will be implicitly released
- // by the system, causing both the screen and the CPU to be turned off.
- SCREEN_BRIGHT_WAKE_LOCK = 10 [deprecated = true];
-
- // Ensures that the screen and keyboard backlight are on at full
- // brightness. If the user presses the power button, then the
- // FULL_WAKE_LOCK will be implicitly released by the system, causing
- // both the screen and the CPU to be turned off.
- FULL_WAKE_LOCK = 26 [deprecated = true];
-
- // Turns the screen off when the proximity sensor activates. If the
- // proximity sensor detects that an object is nearby, the screen turns
- // off immediately. Shortly after the object moves away, the screen
- // turns on again.
- // A proximity wake lock does not prevent the device from falling asleep
- // unlike FULL_WAKE_LOCK, SCREEN_BRIGHT_WAKE_LOCK and
- // SCREEN_DIM_WAKE_LOCK. If there is no user activity and no other wake
- // locks are held, then the device will fall asleep (and lock) as usual.
- // However, the device will not fall asleep while the screen has been
- // turned off by the proximity sensor because it effectively counts as
- // ongoing user activity.
- PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32;
-
- // Put the screen in a low power state and allow the CPU to suspend if
- // no other wake locks are held. This is used by the dream manager to
- // implement doze mode. It currently has no effect unless the power
- // manager is in the dozing state.
- DOZE_WAKE_LOCK = 64;
-
- // Keep the device awake enough to allow drawing to occur. This is used
- // by the window manager to allow applications to draw while the system
- // is dozing. It currently has no effect unless the power manager is in
- // the dozing state.
- DRAW_WAKE_LOCK = 128;
-}
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 64cf75d..e97b1a8 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -55,13 +55,13 @@
import "frameworks/base/core/proto/android/service/procstats.proto";
import "frameworks/base/core/proto/android/service/restricted_image.proto";
import "frameworks/base/core/proto/android/service/sensor_service.proto";
-import "frameworks/base/core/proto/android/service/usb.proto";
import "frameworks/base/core/proto/android/util/event_log_tags.proto";
import "frameworks/base/core/proto/android/util/log.proto";
import "frameworks/base/core/proto/android/util/textdump.proto";
import "frameworks/base/core/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/section.proto";
import "frameworks/base/proto/src/ipconnectivity.proto";
+import "frameworks/proto_logging/stats/enums/service/usb.proto";
package android.os;
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 2d2ead4..fa046c6 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -20,7 +20,6 @@
import "frameworks/base/core/proto/android/app/activitymanager.proto";
import "frameworks/base/core/proto/android/app/appexitinfo.proto";
-import "frameworks/base/core/proto/android/app/enums.proto";
import "frameworks/base/core/proto/android/app/notification.proto";
import "frameworks/base/core/proto/android/app/profilerinfo.proto";
import "frameworks/base/core/proto/android/content/component_name.proto";
@@ -35,6 +34,7 @@
import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
import "frameworks/base/core/proto/android/util/common.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/app/enums.proto";
option java_multiple_files = true;
diff --git a/core/proto/android/server/bluetooth_manager_service.proto b/core/proto/android/server/bluetooth_manager_service.proto
index 998413f..c33f66a 100644
--- a/core/proto/android/server/bluetooth_manager_service.proto
+++ b/core/proto/android/server/bluetooth_manager_service.proto
@@ -17,8 +17,8 @@
syntax = "proto2";
package com.android.server;
-import "frameworks/base/core/proto/android/bluetooth/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/bluetooth/enums.proto";
option java_multiple_files = true;
diff --git a/core/proto/android/server/connectivity/Android.bp b/core/proto/android/server/connectivity/Android.bp
deleted file mode 100644
index 4136239..0000000
--- a/core/proto/android/server/connectivity/Android.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "datastallprotosnano",
- proto: {
- type: "nano",
- },
- srcs: [
- "data_stall_event.proto",
- ],
- sdk_version: "system_current",
-}
diff --git a/core/proto/android/server/connectivity/data_stall_event.proto b/core/proto/android/server/connectivity/data_stall_event.proto
deleted file mode 100644
index 787074b..0000000
--- a/core/proto/android/server/connectivity/data_stall_event.proto
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package com.android.server.connectivity;
-option java_multiple_files = true;
-option java_outer_classname = "DataStallEventProto";
-
-enum ProbeResult {
- UNKNOWN = 0;
- VALID = 1;
- INVALID = 2;
- PORTAL = 3;
- PARTIAL = 4;
-}
-
-enum ApBand {
- AP_BAND_UNKNOWN = 0;
- AP_BAND_2GHZ = 1;
- AP_BAND_5GHZ = 2;
- AP_BAND_6GHZ = 3;
-}
-
-// Refer to definition in TelephonyManager.java.
-enum RadioTech {
- RADIO_TECHNOLOGY_UNKNOWN = 0;
- RADIO_TECHNOLOGY_GPRS = 1;
- RADIO_TECHNOLOGY_EDGE = 2;
- RADIO_TECHNOLOGY_UMTS = 3;
- RADIO_TECHNOLOGY_IS95A = 4;
- RADIO_TECHNOLOGY_IS95B = 5;
- RADIO_TECHNOLOGY_1XRTT = 6;
- RADIO_TECHNOLOGY_EVDO_0 = 7;
- RADIO_TECHNOLOGY_EVDO_A = 8;
- RADIO_TECHNOLOGY_HSDPA = 9;
- RADIO_TECHNOLOGY_HSUPA = 10;
- RADIO_TECHNOLOGY_HSPA = 11;
- RADIO_TECHNOLOGY_EVDO_B = 12;
- RADIO_TECHNOLOGY_LTE = 13;
- RADIO_TECHNOLOGY_EHRPD = 14;
- RADIO_TECHNOLOGY_HSPAP = 15;
- RADIO_TECHNOLOGY_GSM = 16;
- RADIO_TECHNOLOGY_TD_SCDMA = 17;
- RADIO_TECHNOLOGY_IWLAN = 18;
- RADIO_TECHNOLOGY_LTE_CA = 19;
- RADIO_TECHNOLOGY_NR = 20;
-}
-
-// Cellular specific information.
-message CellularData {
- // Indicate the radio technology at the time of data stall suspected.
- optional RadioTech rat_type = 1;
- // True if device is in roaming network at the time of data stall suspected.
- optional bool is_roaming = 2;
- // Registered network MccMnc when data stall happen
- optional string network_mccmnc = 3;
- // Indicate the SIM card carrier.
- optional string sim_mccmnc = 4;
- // Signal strength level at the time of data stall suspected.
- optional int32 signal_strength = 5;
-}
-
-// Wifi specific information.
-message WifiData {
- // Signal strength at the time of data stall suspected.
- // RSSI range is between -55 to -110.
- optional int32 signal_strength = 1;
- // AP band.
- optional ApBand wifi_band = 2;
-}
-
-message DnsEvent {
- // The dns return code.
- repeated int32 dns_return_code = 1;
- // Indicate the timestamp of the dns event.
- repeated int64 dns_time = 2;
-}
diff --git a/core/proto/android/server/enums.proto b/core/proto/android/server/enums.proto
deleted file mode 100644
index 89f7010..0000000
--- a/core/proto/android/server/enums.proto
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.server;
-
-option java_outer_classname = "ServerProtoEnums";
-option java_multiple_files = true;
-
-enum DeviceIdleModeEnum {
- // Device idle mode - not active.
- DEVICE_IDLE_MODE_OFF = 0;
- // Device idle mode - active in lightweight mode.
- DEVICE_IDLE_MODE_LIGHT = 1;
- // Device idle mode - active in full mode.
- DEVICE_IDLE_MODE_DEEP = 2;
-}
-
-enum ErrorSource {
- ERROR_SOURCE_UNKNOWN = 0;
- // Data app
- DATA_APP = 1;
- // System app
- SYSTEM_APP = 2;
- // System server.
- SYSTEM_SERVER = 3;
-}
diff --git a/core/proto/android/server/job/enums.proto b/core/proto/android/server/job/enums.proto
deleted file mode 100644
index 50fc031..0000000
--- a/core/proto/android/server/job/enums.proto
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package com.android.server.job;
-
-// This file is for JobScheduler enums inside the server directory. If you're
-// adding enums for app-side code, use the file in
-// frameworks/base/core/proto/android/app/job.
-option java_outer_classname = "JobServerProtoEnums";
-option java_multiple_files = true;
-
-// Set of constraints that a job potentially needs satisfied before it can run.
-// Defined in
-// frameworks/base/services/core/java/com/android/server/job/controllers/JobStatus.java
-enum ConstraintEnum {
- CONSTRAINT_UNKNOWN = 0;
- CONSTRAINT_CHARGING = 1;
- CONSTRAINT_BATTERY_NOT_LOW = 2;
- CONSTRAINT_STORAGE_NOT_LOW = 3;
- CONSTRAINT_TIMING_DELAY = 4;
- CONSTRAINT_DEADLINE = 5;
- CONSTRAINT_IDLE = 6;
- CONSTRAINT_CONNECTIVITY = 7;
- CONSTRAINT_CONTENT_TRIGGER = 8;
- CONSTRAINT_DEVICE_NOT_DOZING = 9;
- CONSTRAINT_WITHIN_QUOTA = 10;
- CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 11;
-}
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index f2f20e3a..d16ba28 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -20,7 +20,6 @@
option java_multiple_files = true;
-import "frameworks/base/core/proto/android/app/job/enums.proto";
import "frameworks/base/core/proto/android/content/clipdata.proto";
import "frameworks/base/core/proto/android/content/component_name.proto";
import "frameworks/base/core/proto/android/content/intent.proto";
@@ -29,10 +28,11 @@
import "frameworks/base/core/proto/android/os/bundle.proto";
import "frameworks/base/core/proto/android/os/persistablebundle.proto";
import "frameworks/base/core/proto/android/server/appstatetracker.proto";
-import "frameworks/base/core/proto/android/server/job/enums.proto";
import "frameworks/base/core/proto/android/server/statlogger.proto";
import "frameworks/base/core/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/util/quotatracker.proto";
+import "frameworks/proto_logging/stats/enums/app/job/enums.proto";
+import "frameworks/proto_logging/stats/enums/server/job/enums.proto";
message JobSchedulerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/location/enums.proto b/core/proto/android/server/location/enums.proto
deleted file mode 100644
index 943ff18..0000000
--- a/core/proto/android/server/location/enums.proto
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.server.location;
-
-option java_outer_classname = "ServerLocationProtoEnums";
-option java_multiple_files = true;
-
-// GPS Signal Quality levels,
-// primarily used by location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
-enum GpsSignalQualityEnum {
- GPS_SIGNAL_QUALITY_UNKNOWN = -1;
- GPS_SIGNAL_QUALITY_POOR = 0;
- GPS_SIGNAL_QUALITY_GOOD = 1;
-}
-
-// A type which distinguishes different categories of NI request, such as VOICE, UMTS_SUPL etc.
-enum GnssNiType {
- VOICE = 1;
- UMTS_SUPL = 2;
- UMTS_CTRL_PLANE = 3;
- EMERGENCY_SUPL = 4;
-};
-
-// GNSS NI responses, used to define the response in NI structures.
-enum GnssUserResponseType {
- RESPONSE_ACCEPT = 1;
- RESPONSE_DENY = 2;
- RESPONSE_NORESP = 3;
-};
-
-// GNSS NI data encoding scheme.
-enum GnssNiEncodingType {
- ENC_NONE = 0;
- ENC_SUPL_GSM_DEFAULT = 1;
- ENC_SUPL_UTF8 = 2;
- ENC_SUPL_UCS2 = 3;
- ENC_UNKNOWN = -1;
-};
-
-// Protocol stack that initiated the non-framework location request.
-enum NfwProtocolStack {
- // Cellular control plane requests.
- CTRL_PLANE = 0;
- // All types of SUPL requests.
- SUPL = 1;
- // All types of requests from IMS.
- IMS = 10;
- // All types of requests from SIM.
- SIM = 11;
- // Requests from other protocol stacks.
- OTHER_PROTOCOL_STACK = 100;
-};
-
-// Source initiating/receiving the location information.
-enum NfwRequestor {
- // Wireless service provider.
- CARRIER = 0;
- // Device manufacturer.
- OEM = 10;
- // Modem chipset vendor.
- MODEM_CHIPSET_VENDOR = 11;
- // GNSS chipset vendor.
- GNSS_CHIPSET_VENDOR = 12;
- // Other chipset vendor.
- OTHER_CHIPSET_VENDOR = 13;
- // Automobile client.
- AUTOMOBILE_CLIENT = 20;
- // Other sources.
- OTHER_REQUESTOR = 100;
-};
-
-// Indicates whether location information was provided for this request.
-enum NfwResponseType {
- // Request rejected because framework has not given permission for this use case.
- REJECTED = 0;
- // Request accepted but could not provide location because of a failure.
- ACCEPTED_NO_LOCATION_PROVIDED = 1;
- // Request accepted and location provided.
- ACCEPTED_LOCATION_PROVIDED = 2;
-};
-
-// The SUPL mode.
-enum SuplMode {
- // Mobile Station Based.
- MSB = 0x01;
- // Mobile Station Assisted.
- MSA = 0x02;
-};
-
-// Enum that hold the bit masks for various LTE Positioning Profile settings (LPP_PROFILE
-// configuration parameter). If none of the bits in the enum are set, the default setting is
-// Radio Resource Location Protocol(RRLP).
-enum LppProfile {
- // Enable LTE Positioning Protocol user plane.
- USER_PLANE = 0x01;
- // Enable LTE Positioning Protocol Control plane.
- CONTROL_PLANE = 0x02;
-};
-
-// Positioning protocol on A-Glonass system.
-enum GlonassPosProtocol {
- // Radio Resource Control(RRC) control-plane.
- RRC_CPLANE = 0x01;
- // Radio Resource Location user-plane.
- RRLP_CPLANE = 0x02;
- // LTE Positioning Protocol User plane.
- LPP_UPLANE = 0x04;
-};
-
-// Configurations of how GPS functionalities should be locked when user turns off GPS On setting.
-enum GpsLock {
- // Lock Mobile Originated GPS functionalitues.
- MO = 0x01;
- // Lock Network Initiated GPS functionalities.
- NI = 0x02;
-};
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index 0455d58..c5c4d7c 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -19,16 +19,16 @@
option java_multiple_files = true;
-import "frameworks/base/core/proto/android/app/enums.proto";
import "frameworks/base/core/proto/android/content/intent.proto";
-import "frameworks/base/core/proto/android/os/enums.proto";
import "frameworks/base/core/proto/android/os/looper.proto";
import "frameworks/base/core/proto/android/os/powermanager.proto";
import "frameworks/base/core/proto/android/os/worksource.proto";
import "frameworks/base/core/proto/android/providers/settings.proto";
import "frameworks/base/core/proto/android/server/wirelesschargerdetector.proto";
-import "frameworks/base/core/proto/android/view/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/app/enums.proto";
+import "frameworks/proto_logging/stats/enums/os/enums.proto";
+import "frameworks/proto_logging/stats/enums/view/enums.proto";
message PowerManagerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 0f5616f..420fc7d 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -24,11 +24,12 @@
import "frameworks/base/core/proto/android/server/surfaceanimator.proto";
import "frameworks/base/core/proto/android/view/displaycutout.proto";
import "frameworks/base/core/proto/android/view/displayinfo.proto";
-import "frameworks/base/core/proto/android/view/enums.proto";
import "frameworks/base/core/proto/android/view/surface.proto";
import "frameworks/base/core/proto/android/view/windowlayoutparams.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/view/enums.proto";
+
package com.android.server.wm;
option java_multiple_files = true;
diff --git a/core/proto/android/service/battery.proto b/core/proto/android/service/battery.proto
index 586411f..3a112e7 100644
--- a/core/proto/android/service/battery.proto
+++ b/core/proto/android/service/battery.proto
@@ -20,8 +20,8 @@
option java_multiple_files = true;
option java_outer_classname = "BatteryServiceProto";
-import "frameworks/base/core/proto/android/os/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/os/enums.proto";
message BatteryServiceDumpProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto
index 7a4c070..57051f0 100644
--- a/core/proto/android/service/procstats.proto
+++ b/core/proto/android/service/procstats.proto
@@ -21,8 +21,8 @@
option java_outer_classname = "ProcessStatsServiceProto";
import "frameworks/base/core/proto/android/util/common.proto";
-import "frameworks/base/core/proto/android/service/procstats_enum.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/service/procstats_enum.proto";
/**
* Data from ProcStatsService Dumpsys
diff --git a/core/proto/android/service/procstats_enum.proto b/core/proto/android/service/procstats_enum.proto
deleted file mode 100644
index 2abf373..0000000
--- a/core/proto/android/service/procstats_enum.proto
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.service.procstats;
-
-option java_multiple_files = true;
-option java_outer_classname = "ProcessStatsEnums";
-
-enum ScreenState {
- SCREEN_STATE_UNKNOWN = 0;
- SCREEN_STATE_OFF = 1;
- SCREEN_STATE_ON = 2;
-}
-
-enum MemoryState {
- MEMORY_STATE_UNKNOWN = 0;
- MEMORY_STATE_NORMAL = 1; // normal.
- MEMORY_STATE_MODERATE = 2; // moderate memory pressure.
- MEMORY_STATE_LOW = 3; // low memory.
- MEMORY_STATE_CRITICAL = 4; // critical memory.
-}
-
-// this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
-// and not frameworks/base/core/java/android/app/ActivityManager.java
-enum ProcessState {
- PROCESS_STATE_UNKNOWN = 0;
- // Persistent system process.
- PROCESS_STATE_PERSISTENT = 1;
- // Top activity; actually any visible activity.
- PROCESS_STATE_TOP = 2;
- // Important foreground process (ime, wallpaper, etc).
- PROCESS_STATE_IMPORTANT_FOREGROUND = 3;
- // Important background process.
- PROCESS_STATE_IMPORTANT_BACKGROUND = 4;
- // Performing backup operation.
- PROCESS_STATE_BACKUP = 5;
- // Background process running a service.
- PROCESS_STATE_SERVICE = 6;
- // Process not running, but would be if there was enough RAM.
- PROCESS_STATE_SERVICE_RESTARTING = 7;
- // Process running a receiver.
- PROCESS_STATE_RECEIVER = 8;
- // Heavy-weight process (currently not used).
- PROCESS_STATE_HEAVY_WEIGHT = 9;
- // Process hosting home/launcher app when not on top.
- PROCESS_STATE_HOME = 10;
- // Process hosting the last app the user was in.
- PROCESS_STATE_LAST_ACTIVITY = 11;
- // Cached process hosting a previous activity.
- PROCESS_STATE_CACHED_ACTIVITY = 12;
- // Cached process hosting a client activity.
- PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 13;
- // Cached process that is empty.
- PROCESS_STATE_CACHED_EMPTY = 14;
-}
-
-enum ServiceOperationState {
- SERVICE_OPERATION_STATE_UNKNOWN = 0;
- SERVICE_OPERATION_STATE_RUNNING = 1;
- SERVICE_OPERATION_STATE_STARTED = 2;
- SERVICE_OPERATION_STATE_FOREGROUND = 3;
- SERVICE_OPERATION_STATE_BOUND = 4;
- SERVICE_OPERATION_STATE_EXECUTING = 5;
-}
-
-// this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
-// and not frameworks/base/core/java/android/app/ActivityManager.java
-enum AggregatedProcessState {
- AGGREGATED_PROCESS_STATE_UNKNOWN = 0;
- // Persistent system process; PERSISTENT or PERSISTENT_UI in ActivityManager
- AGGREGATED_PROCESS_STATE_PERSISTENT = 1;
- // Top activity; actually any visible activity; TOP or TOP_SLEEPING in ActivityManager
- AGGREGATED_PROCESS_STATE_TOP = 2;
- // Bound top foreground process; BOUND_TOP or BOUND_FOREGROUND_SERVICE in ActivityManager
- AGGREGATED_PROCESS_STATE_BOUND_TOP_OR_FGS = 3;
- // Important foreground process; FOREGROUND_SERVICE in ActivityManager
- AGGREGATED_PROCESS_STATE_FGS = 4;
- // Important foreground process ; IMPORTANT_FOREGROUND in ActivityManager
- AGGREGATED_PROCESS_STATE_IMPORTANT_FOREGROUND = 5;
- // Various background processes; IMPORTANT_BACKGROUND, TRANSIENT_BACKGROUND, BACKUP, SERVICE,
- // HEAVY_WEIGHT in ActivityManager
- AGGREGATED_PROCESS_STATE_BACKGROUND = 6;
- // Process running a receiver; RECEIVER in ActivityManager
- AGGREGATED_PROCESS_STATE_RECEIVER = 7;
- // Various cached processes; HOME, LAST_ACTIVITY, CACHED_ACTIVITY, CACHED_RECENT,
- // CACHED_ACTIVITY_CLIENT, CACHED_EMPTY in ActivityManager
- AGGREGATED_PROCESS_STATE_CACHED = 8;
-}
\ No newline at end of file
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
deleted file mode 100644
index 40c5a85..0000000
--- a/core/proto/android/service/usb.proto
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.service.usb;
-
-option java_multiple_files = true;
-option java_outer_classname = "UsbServiceProto";
-
-import "frameworks/base/core/proto/android/content/component_name.proto";
-import "frameworks/base/core/proto/android/service/enums.proto";
-import "frameworks/base/core/proto/android/privacy.proto";
-
-message UsbServiceDumpProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbDeviceManagerProto device_manager = 1;
- optional UsbHostManagerProto host_manager = 2;
- optional UsbPortManagerProto port_manager = 3;
- optional UsbAlsaManagerProto alsa_manager = 4;
- optional UsbSettingsManagerProto settings_manager = 5;
- optional UsbPermissionsManagerProto permissions_manager = 6;
-}
-
-message UsbDeviceManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbHandlerProto handler = 1;
- optional UsbDebuggingManagerProto debugging_manager = 2;
-}
-
-message UsbHandlerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- /* Same as android.hardware.usb.gadget.V1_0.GadgetFunction.* */
- enum Function {
- FUNCTION_ADB = 1;
- FUNCTION_ACCESSORY = 2;
- FUNCTION_MTP = 4;
- FUNCTION_MIDI = 8;
- FUNCTION_PTP = 16;
- FUNCTION_RNDIS = 32;
- FUNCTION_AUDIO_SOURCE = 64;
- }
-
- repeated Function current_functions = 1;
- optional bool current_functions_applied = 2;
- repeated Function screen_unlocked_functions = 3;
- optional bool screen_locked = 4;
- optional bool connected = 5;
- optional bool configured = 6;
- optional UsbAccessoryProto current_accessory = 7;
- optional bool host_connected = 8;
- optional bool source_power = 9;
- optional bool sink_power = 10;
- optional bool usb_charging = 11;
- optional bool hide_usb_notification = 12;
- optional bool audio_accessory_connected = 13;
- optional bool adb_enabled = 14;
- optional string kernel_state = 15;
- optional string kernel_function_list = 16;
-}
-
-message UsbAccessoryProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional string manufacturer = 1;
- optional string model = 2;
- // For "classical" USB-accessories the manufacturer bakes this into the
- // firmware of the device. If an Android phone is configured as accessory, the
- // app that sets up the accessory side of the connection set this. Either way,
- // these are part of the detection protocol, and so they cannot be user set or
- // unique.
- optional string description = 3;
- optional string version = 4;
- optional string uri = 5 [ (android.privacy).dest = DEST_EXPLICIT ];
- // Non-resettable hardware ID.
- optional string serial = 6 [ (android.privacy).dest = DEST_LOCAL ];
-}
-
-message UsbDebuggingManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional bool connected_to_adb = 1;
- // A workstation that connects to the phone for debugging is identified by
- // this key.
- optional string last_key_received = 2 [ (android.privacy).dest = DEST_EXPLICIT ];
- optional string user_keys = 3 [ (android.privacy).dest = DEST_LOCAL ];
- optional string system_keys = 4 [ (android.privacy).dest = DEST_LOCAL ];
-}
-
-message UsbHostManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional android.content.ComponentNameProto default_usb_host_connection_handler = 1;
- repeated UsbDeviceProto devices = 2;
- optional int32 num_connects = 3;
- repeated UsbConnectionRecordProto connections = 4;
-}
-
-message UsbDeviceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Generic USB name, not user-provided.
- optional string name = 1;
- // ID specific to the vendor, not the device.
- optional int32 vendor_id = 2;
- // ID of this product type: Each vendor gives each product a unique ID. E.g.
- // all mice of the same model would have the same ID.
- optional int32 product_id = 3;
- optional int32 class = 4;
- optional int32 subclass = 5;
- optional int32 protocol = 6;
- optional string manufacturer_name = 7;
- optional string product_name = 8;
- optional string version = 9;
- // Non-resettable hardware ID.
- optional string serial_number = 10 [ (android.privacy).dest = DEST_LOCAL ];
- repeated UsbConfigurationProto configurations = 11;
-}
-
-message UsbConfigurationProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // A single USB device can have several configurations and the app accessing
- // the USB device can switch between them. At any time only one can be active.
- // Each configuration can present completely different interfaces end
- // endpoints, i.e. a completely different behavior.
- optional int32 id = 1;
- // Hardware-defined name, not set by the user.
- optional string name = 2;
- optional uint32 attributes = 3;
- optional int32 max_power = 4;
- repeated UsbInterfaceProto interfaces = 5;
-}
-
-message UsbInterfaceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Hardware defined. This is the id used by the app to identify the interface.
- optional int32 id = 1;
- optional int32 alternate_settings = 2;
- optional string name = 3;
- optional int32 class = 4;
- optional int32 subclass = 5;
- optional int32 protocol = 6;
- repeated UsbEndPointProto endpoints = 7;
-}
-
-message UsbEndPointProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 endpoint_number = 1;
- optional android.service.UsbEndPointDirection direction = 2;
- // The address of the endpoint. Needed to read and write to the endpoint.
- optional int32 address = 3;
- optional android.service.UsbEndPointType type = 4;
- optional uint32 attributes = 5;
- optional int32 max_packet_size = 6;
- optional int32 interval = 7;
-}
-
-message UsbConnectionRecordProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // usb device's address, e.g. 001/002, nothing about the phone
- optional string device_address = 1;
- optional android.service.UsbConnectionRecordMode mode = 2;
- optional int64 timestamp = 3;
- optional int32 manufacturer = 4;
- optional int32 product = 5;
- optional UsbIsHeadsetProto is_headset = 6;
-}
-
-message UsbIsHeadsetProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional bool in = 1;
- optional bool out = 2;
-}
-
-message UsbPortManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional bool is_simulation_active = 1;
- repeated UsbPortInfoProto usb_ports = 2;
-}
-
-message UsbPortInfoProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbPortProto port = 1;
- optional UsbPortStatusProto status = 2;
- optional bool can_change_mode = 3;
- optional bool can_change_power_role = 4;
- optional bool can_change_data_role = 5;
- optional int64 connected_at_millis = 6;
- optional int64 last_connect_duration_millis = 7;
-}
-
-message UsbPortProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- /* Same as android.hardware.usb.V1_1.Constants.PortMode_1_1 */
- enum Mode {
- MODE_NONE = 0;
- MODE_UFP = 1;
- MODE_DFP = 2;
- MODE_DRP = 3;
- MODE_AUDIO_ACCESSORY = 4;
- MODE_DEBUG_ACCESSORY = 8;
- }
-
- // ID of the port. A device (eg: Chromebooks) might have multiple ports.
- optional string id = 1;
- repeated Mode supported_modes = 2;
-}
-
-/* Same as android.hardware.usb.V1_2.Constants.ContaminantPresenceStatus */
-enum ContaminantPresenceStatus {
- CONTAMINANT_STATUS_UNKNOWN = 0;
- CONTAMINANT_STATUS_NOT_SUPPORTED = 1;
- CONTAMINANT_STATUS_DISABLED = 2;
- CONTAMINANT_STATUS_NOT_DETECTED = 3;
- CONTAMINANT_STATUS_DETECTED = 4;
-}
-
-message UsbPortStatusProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- /* Same as android.hardware.usb.V1_0.Constants.PortPowerRole */
- enum PowerRole {
- POWER_ROLE_NONE = 0;
- POWER_ROLE_SOURCE = 1;
- POWER_ROLE_SINK = 2;
- }
-
- /* Same as android.hardware.usb.V1_0.Constants.PortDataRole */
- enum DataRole {
- DATA_ROLE_NONE = 0;
- DATA_ROLE_HOST = 1;
- DATA_ROLE_DEVICE = 2;
- }
-
- optional bool connected = 1;
- optional UsbPortProto.Mode current_mode = 2;
- optional PowerRole power_role = 3;
- optional DataRole data_role = 4;
- repeated UsbPortStatusRoleCombinationProto role_combinations = 5;
- optional ContaminantPresenceStatus contaminant_presence_status = 6;
-}
-
-message UsbPortStatusRoleCombinationProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbPortStatusProto.PowerRole power_role = 1;
- optional UsbPortStatusProto.DataRole data_role = 2;
-}
-
-message UsbAlsaManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 cards_parser = 1;
- repeated UsbAlsaDeviceProto alsa_devices = 2;
- repeated UsbMidiDeviceProto midi_devices = 3;
-}
-
-message UsbAlsaDeviceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 card = 1;
- optional int32 device = 2;
- optional string name = 3;
- optional bool has_playback = 4;
- optional bool has_capture = 5;
- // usb device's address, e.g. 001/002, nothing about the phone
- optional string address = 6;
-}
-
-message UsbMidiDeviceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 card = 1;
- optional int32 device = 2;
- // usb device's address, e.g. 001/002, nothing about the phone
- optional string device_address = 3;
-}
-
-message UsbSettingsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- repeated UsbUserSettingsManagerProto user_settings = 1;
- repeated UsbProfileGroupSettingsManagerProto profile_group_settings = 2;
-}
-
-message UsbUserSettingsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 user_id = 1;
- reserved 2; // previously device_permissions, now unused
- reserved 3; // previously accessory_permissions, now unused
- repeated UsbDeviceAttachedActivities device_attached_activities = 4;
- repeated UsbAccessoryAttachedActivities accessory_attached_activities = 5;
-}
-
-message UsbProfileGroupSettingsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // The user id of the personal profile if the device has a work profile.
- optional int32 parent_user_id = 1;
- repeated UsbSettingsDevicePreferenceProto device_preferences = 2;
- repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3;
-}
-
-message UsbSettingsDevicePreferenceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbDeviceFilterProto filter = 1;
- optional UserPackageProto user_package = 2;
-}
-
-message UsbPermissionsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- repeated UsbUserPermissionsManagerProto user_permissions = 1;
-}
-
-message UsbUserPermissionsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 user_id = 1;
-
- repeated UsbDevicePermissionProto device_permissions = 2;
- repeated UsbAccessoryPermissionProto accessory_permissions = 3;
-
- repeated UsbDevicePersistentPermissionProto device_persistent_permissions = 4;
- repeated UsbAccessoryPersistentPermissionProto accessory_persistent_permissions = 5;
-}
-
-message UsbDevicePermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Name of device set by manufacturer
- // All devices of the same model have the same name
- optional string device_name = 1;
- repeated int32 uids = 2;
-}
-
-message UsbAccessoryPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Description of accessory set by manufacturer
- // All accessories of the same model have the same description
- optional string accessory_description = 1;
- repeated int32 uids = 2;
-}
-
-message UsbDevicePersistentPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbDeviceFilterProto device_filter = 1;
- repeated UsbUidPermissionProto permission_values = 2;
-}
-
-message UsbAccessoryPersistentPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbAccessoryFilterProto accessory_filter = 1;
- repeated UsbUidPermissionProto permission_values = 2;
-}
-
-message UsbUidPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 uid = 1;
- optional bool is_granted = 2;
-}
-
-message UsbDeviceFilterProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Mirrors the vendor_id of UsbDeviceProto.
- optional int32 vendor_id = 1;
- optional int32 product_id = 2;
- optional int32 class = 3;
- optional int32 subclass = 4;
- optional int32 protocol = 5;
- optional string manufacturer_name = 6;
- optional string product_name = 7;
- optional string serial_number = 8 [ (android.privacy).dest = DEST_EXPLICIT ];
-}
-
-message UserPackageProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 user_id = 1;
- optional string package_name =2;
-}
-
-message UsbSettingsAccessoryPreferenceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbAccessoryFilterProto filter = 1;
- optional UserPackageProto user_package = 2;
-}
-
-message UsbAccessoryFilterProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional string manufacturer = 1;
- optional string model = 2;
- optional string version = 3;
-}
-
-message UsbDeviceAttachedActivities {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional android.content.ComponentNameProto activity = 1;
- repeated UsbDeviceFilterProto filters = 2;
-}
-
-message UsbAccessoryAttachedActivities {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional android.content.ComponentNameProto activity = 1;
- repeated UsbAccessoryFilterProto filters = 2;
-}
diff --git a/core/proto/android/stats/accessibility/accessibility_enums.proto b/core/proto/android/stats/accessibility/accessibility_enums.proto
deleted file mode 100644
index 5118ad5..0000000
--- a/core/proto/android/stats/accessibility/accessibility_enums.proto
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.accessibility;
-option java_multiple_files = true;
-
-// The entry point of the accessibility shortcut.
-enum ShortcutType {
- UNKNOWN_TYPE = 0;
- A11Y_BUTTON = 1;
- VOLUME_KEY = 2;
- TRIPLE_TAP = 3;
- A11Y_BUTTON_LONG_PRESS = 4;
-}
-
-// The service status code.
-enum ServiceStatus {
- UNKNOWN = 0;
- ENABLED = 1;
- DISABLED = 2;
-}
\ No newline at end of file
diff --git a/core/proto/android/stats/connectivity/Android.bp b/core/proto/android/stats/connectivity/Android.bp
deleted file mode 100644
index 5e6ac3c..0000000
--- a/core/proto/android/stats/connectivity/Android.bp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "networkstackprotos",
- proto: {
- type: "lite",
- },
- srcs: [
- "network_stack.proto",
- ],
- sdk_version: "system_29",
-}
-
-java_library_static {
- name: "tetheringprotos",
- proto: {
- type: "lite",
- },
- srcs: [
- "tethering.proto",
- ],
- apex_available: [
- "com.android.tethering",
- ],
- sdk_version: "system_current",
-}
diff --git a/core/proto/android/stats/connectivity/network_stack.proto b/core/proto/android/stats/connectivity/network_stack.proto
deleted file mode 100644
index e9726d7..0000000
--- a/core/proto/android/stats/connectivity/network_stack.proto
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.connectivity;
-option java_multiple_files = true;
-option java_outer_classname = "NetworkStackProto";
-
-enum DhcpRenewResult {
- RR_UNKNOWN = 0;
- RR_SUCCESS = 1;
- RR_ERROR_NAK = 2;
- RR_ERROR_IP_MISMATCH = 3;
- RR_ERROR_IP_EXPIRE = 4;
-}
-
-enum DisconnectCode {
- DC_NONE = 0;
- DC_NORMAL_TERMINATION = 1;
- DC_PROVISIONING_FAIL = 2;
- DC_ERROR_STARTING_IPV4 = 4;
- DC_ERROR_STARTING_IPV6 = 5;
- DC_ERROR_STARTING_IPREACHABILITYMONITOR = 6;
- DC_INVALID_PROVISIONING = 7;
- DC_INTERFACE_NOT_FOUND = 8;
- DC_PROVISIONING_TIMEOUT = 9;
-}
-
-enum TransportType {
- TT_UNKNOWN = 0;
- // Indicates this network uses a Cellular transport
- TT_CELLULAR = 1;
- // Indicates this network uses a Wi-Fi transport
- TT_WIFI = 2;
- // Indicates this network uses a Bluetooth transport
- TT_BLUETOOTH = 3;
- // Indicates this network uses an Ethernet transport
- TT_ETHERNET = 4;
- // Indicates this network uses a Wi-Fi Aware transport
- TT_WIFI_AWARE = 5;
- // Indicates this network uses a LoWPAN transport
- TT_LOWPAN = 6;
- // Indicates this network uses a Cellular+VPN transport
- TT_CELLULAR_VPN = 7;
- // Indicates this network uses a Wi-Fi+VPN transport
- TT_WIFI_VPN = 8;
- // Indicates this network uses a Bluetooth+VPN transport
- TT_BLUETOOTH_VPN = 9;
- // Indicates this network uses an Ethernet+VPN transport
- TT_ETHERNET_VPN = 10;
- // Indicates this network uses a Wi-Fi+Cellular+VPN transport
- TT_WIFI_CELLULAR_VPN = 11;
- // Indicates this network uses for test only
- TT_TEST = 12;
-}
-
-enum DhcpFeature {
- DF_UNKNOWN = 0;
- // DHCP INIT-REBOOT state
- DF_INITREBOOT = 1;
- // DHCP rapid commit option
- DF_RAPIDCOMMIT = 2;
- // Duplicate address detection
- DF_DAD = 3;
- // Fast initial Link setup
- DF_FILS = 4;
-}
-
-enum HostnameTransResult {
- HTR_UNKNOWN = 0;
- HTR_SUCCESS = 1;
- HTR_FAILURE = 2;
- HTR_DISABLE = 3;
-}
-
-enum ProbeResult {
- PR_UNKNOWN = 0;
- PR_SUCCESS = 1;
- PR_FAILURE = 2;
- PR_PORTAL = 3;
- // DNS query for the probe host returned a private IP address
- PR_PRIVATE_IP_DNS = 4;
-}
-
-enum ValidationResult {
- VR_UNKNOWN = 0;
- VR_SUCCESS = 1;
- VR_FAILURE = 2;
- VR_PORTAL = 3;
- VR_PARTIAL = 4;
-}
-
-enum ProbeType {
- PT_UNKNOWN = 0;
- PT_DNS = 1;
- PT_HTTP = 2;
- PT_HTTPS = 3;
- PT_PAC = 4;
- PT_FALLBACK = 5;
- PT_PRIVDNS = 6;
- PT_CAPPORT_API = 7;
-}
-
-// The Dhcp error code is defined in android.net.metrics.DhcpErrorEvent
-enum DhcpErrorCode {
- ET_UNKNOWN = 0;
- ET_L2_ERROR = 1;
- ET_L3_ERROR = 2;
- ET_L4_ERROR = 3;
- ET_DHCP_ERROR = 4;
- ET_MISC_ERROR = 5;
- /* Reserve for error type
- // ET_L2_ERROR_TYPE = ET_L2_ERROR << 8;
- ET_L2_ERROR_TYPE = 256;
- // ET_L3_ERROR_TYPE = ET_L3_ERROR << 8;
- ET_L3_ERROR_TYPE = 512;
- // ET_L4_ERROR_TYPE = ET_L4_ERROR << 8;
- ET_L4_ERROR_TYPE = 768;
- // ET_DHCP_ERROR_TYPE = ET_DHCP_ERROR << 8;
- ET_DHCP_ERROR_TYPE = 1024;
- // ET_MISC_ERROR_TYPE = ET_MISC_ERROR << 8;
- ET_MISC_ERROR_TYPE = 1280;
- */
- // ET_L2_TOO_SHORT = (ET_L2_ERROR_TYPE | 0x1) << 16;
- ET_L2_TOO_SHORT = 16842752;
- // ET_L2_WRONG_ETH_TYPE = (ET_L2_ERROR_TYPE | 0x2) << 16;
- ET_L2_WRONG_ETH_TYPE = 16908288;
- // ET_L3_TOO_SHORT = (ET_L3_ERROR_TYPE | 0x1) << 16;
- ET_L3_TOO_SHORT = 33619968;
- // ET_L3_NOT_IPV4 = (ET_L3_ERROR_TYPE | 0x2) << 16;
- ET_L3_NOT_IPV4 = 33685504;
- // ET_L3_INVALID_IP = (ET_L3_ERROR_TYPE | 0x3) << 16;
- ET_L3_INVALID_IP = 33751040;
- // ET_L4_NOT_UDP = (ET_L4_ERROR_TYPE | 0x1) << 16;
- ET_L4_NOT_UDP = 50397184;
- // ET_L4_WRONG_PORT = (ET_L4_ERROR_TYPE | 0x2) << 16;
- ET_L4_WRONG_PORT = 50462720;
- // ET_BOOTP_TOO_SHORT = (ET_DHCP_ERROR_TYPE | 0x1) << 16;
- ET_BOOTP_TOO_SHORT = 67174400;
- // ET_DHCP_BAD_MAGIC_COOKIE = (ET_DHCP_ERROR_TYPE | 0x2) << 16;
- ET_DHCP_BAD_MAGIC_COOKIE = 67239936;
- // ET_DHCP_INVALID_OPTION_LENGTH = (ET_DHCP_ERROR_TYPE | 0x3) << 16;
- ET_DHCP_INVALID_OPTION_LENGTH = 67305472;
- // ET_DHCP_NO_MSG_TYPE = (ET_DHCP_ERROR_TYPE | 0x4) << 16;
- ET_DHCP_NO_MSG_TYPE = 67371008;
- // ET_DHCP_UNKNOWN_MSG_TYPE = (ET_DHCP_ERROR_TYPE | 0x5) << 16;
- ET_DHCP_UNKNOWN_MSG_TYPE = 67436544;
- // ET_DHCP_NO_COOKIE = (ET_DHCP_ERROR_TYPE | 0x6) << 16;
- ET_DHCP_NO_COOKIE = 67502080;
- // ET_BUFFER_UNDERFLOW = (ET_MISC_ERROR_TYPE | 0x1) << 16;
- ET_BUFFER_UNDERFLOW = 83951616;
- // ET_RECEIVE_ERROR = (ET_MISC_ERROR_TYPE | 0x2) << 16;
- ET_RECEIVE_ERROR = 84017152;
- // ET_PARSING_ERROR = (ET_MISC_ERROR_TYPE | 0x3) << 16;
- ET_PARSING_ERROR = 84082688;
-}
-
-enum NetworkQuirkEvent {
- QE_UNKNOWN = 0;
- QE_IPV6_PROVISIONING_ROUTER_LOST = 1;
-}
-
-message NetworkStackEventData {
-
-}
-
diff --git a/core/proto/android/stats/connectivity/tethering.proto b/core/proto/android/stats/connectivity/tethering.proto
deleted file mode 100644
index 13f0b8c..0000000
--- a/core/proto/android/stats/connectivity/tethering.proto
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-syntax = "proto2";
-package android.stats.connectivity;
-option java_multiple_files = true;
-option java_outer_classname = "TetheringProto";
-
-enum ErrorCode {
- EC_NO_ERROR = 0;
- EC_UNKNOWN_IFACE = 1;
- EC_SERVICE_UNAVAIL = 2;
- EC_UNSUPPORTED = 3;
- EC_UNAVAIL_IFACE = 4;
- EC_INTERNAL_ERROR = 5;
- EC_TETHER_IFACE_ERROR = 6;
- EC_UNTETHER_IFACE_ERROR = 7;
- EC_ENABLE_FORWARDING_ERROR = 8;
- EC_DISABLE_FORWARDING_ERROR = 9;
- EC_IFACE_CFG_ERROR = 10;
- EC_PROVISIONING_FAILED = 11;
- EC_DHCPSERVER_ERROR = 12;
- EC_ENTITLEMENT_UNKNOWN = 13;
- EC_NO_CHANGE_TETHERING_PERMISSION = 14;
- EC_NO_ACCESS_TETHERING_PERMISSION = 15;
- EC_UNKNOWN_TYPE = 16;
-}
-
-enum DownstreamType {
- // Unspecific tethering type.
- DS_UNSPECIFIED = 0;
- // Wifi tethering type.
- DS_TETHERING_WIFI = 1;
- // USB tethering type.
- DS_TETHERING_USB = 2;
- // Bluetooth tethering type.
- DS_TETHERING_BLUETOOTH = 3;
- // Wifi P2p tethering type.
- DS_TETHERING_WIFI_P2P = 4;
- // NCM (Network Control Model) local tethering type.
- DS_TETHERING_NCM = 5;
- // Ethernet tethering type.
- DS_TETHERING_ETHERNET = 6;
-}
-
-enum UpstreamType {
- UT_UNKNOWN = 0;
- // Indicates upstream using a Cellular transport.
- UT_CELLULAR = 1;
- // Indicates upstream using a Wi-Fi transport.
- UT_WIFI = 2;
- // Indicates upstream using a Bluetooth transport.
- UT_BLUETOOTH = 3;
- // Indicates upstream using an Ethernet transport.
- UT_ETHERNET = 4;
- // Indicates upstream using a Wi-Fi Aware transport.
- UT_WIFI_AWARE = 5;
- // Indicates upstream using a LoWPAN transport.
- UT_LOWPAN = 6;
- // Indicates upstream using a Cellular+VPN transport.
- UT_CELLULAR_VPN = 7;
- // Indicates upstream using a Wi-Fi+VPN transport.
- UT_WIFI_VPN = 8;
- // Indicates upstream using a Bluetooth+VPN transport.
- UT_BLUETOOTH_VPN = 9;
- // Indicates upstream using an Ethernet+VPN transport.
- UT_ETHERNET_VPN = 10;
- // Indicates upstream using a Wi-Fi+Cellular+VPN transport.
- UT_WIFI_CELLULAR_VPN = 11;
- // Indicates upstream using for test only.
- UT_TEST = 12;
- // Indicates upstream using DUN capability + Cellular transport.
- UT_DUN_CELLULAR = 13;
-}
-
-enum UserType {
- // Unknown.
- USER_UNKNOWN = 0;
- // Settings.
- USER_SETTINGS = 1;
- // System UI.
- USER_SYSTEMUI = 2;
- // Google mobile service.
- USER_GMS = 3;
-}
diff --git a/core/proto/android/stats/devicepolicy/Android.bp b/core/proto/android/stats/devicepolicy/Android.bp
deleted file mode 100644
index 5fb278a..0000000
--- a/core/proto/android/stats/devicepolicy/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "devicepolicyprotosnano",
- proto: {
- type: "nano",
- },
- srcs: [
- "*.proto",
- ],
- java_version: "1.8",
- target: {
- android: {
- jarjar_rules: "jarjar-rules.txt",
- },
- host: {
- static_libs: ["libprotobuf-java-nano"],
- }
- },
- sdk_version: "core_platform",
-}
diff --git a/core/proto/android/stats/devicepolicy/device_policy.proto b/core/proto/android/stats/devicepolicy/device_policy.proto
deleted file mode 100644
index af30cf3..0000000
--- a/core/proto/android/stats/devicepolicy/device_policy.proto
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.devicepolicy;
-option java_multiple_files = true;
-
-message StringList {
- repeated string string_value = 1;
-}
diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
deleted file mode 100644
index 7c1a049..0000000
--- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.devicepolicy;
-option java_multiple_files = true;
-
-/**
- * Id for device policy features.
- */
-enum EventId {
- SET_PASSWORD_QUALITY = 1;
- SET_PASSWORD_MINIMUM_LENGTH = 2;
- SET_PASSWORD_MINIMUM_NUMERIC = 3;
- SET_PASSWORD_MINIMUM_NON_LETTER = 4;
- SET_PASSWORD_MINIMUM_LETTERS = 5;
- SET_PASSWORD_MINIMUM_LOWER_CASE = 6;
- SET_PASSWORD_MINIMUM_UPPER_CASE = 7;
- SET_PASSWORD_MINIMUM_SYMBOLS = 8;
- SET_KEYGUARD_DISABLED_FEATURES = 9;
- LOCK_NOW = 10;
- WIPE_DATA_WITH_REASON = 11;
- ADD_USER_RESTRICTION = 12;
- REMOVE_USER_RESTRICTION = 13;
- SET_SECURE_SETTING = 14;
- SET_SECURITY_LOGGING_ENABLED = 15;
- RETRIEVE_SECURITY_LOGS = 16;
- RETRIEVE_PRE_REBOOT_SECURITY_LOGS = 17;
- SET_PERMISSION_POLICY = 18;
- SET_PERMISSION_GRANT_STATE = 19;
- INSTALL_KEY_PAIR = 20;
- INSTALL_CA_CERT = 21;
- CHOOSE_PRIVATE_KEY_ALIAS = 22;
- REMOVE_KEY_PAIR = 23;
- UNINSTALL_CA_CERTS = 24;
- SET_CERT_INSTALLER_PACKAGE = 25;
- SET_ALWAYS_ON_VPN_PACKAGE = 26;
- SET_PERMITTED_INPUT_METHODS = 27;
- SET_PERMITTED_ACCESSIBILITY_SERVICES = 28;
- SET_SCREEN_CAPTURE_DISABLED = 29;
- SET_CAMERA_DISABLED = 30;
- QUERY_SUMMARY_FOR_USER = 31;
- QUERY_SUMMARY = 32;
- QUERY_DETAILS = 33;
- REBOOT = 34;
- SET_MASTER_VOLUME_MUTED = 35;
- SET_AUTO_TIME_REQUIRED = 36;
- SET_KEYGUARD_DISABLED = 37;
- SET_STATUS_BAR_DISABLED = 38;
- SET_ORGANIZATION_COLOR = 39;
- SET_PROFILE_NAME = 40;
- SET_USER_ICON = 41;
- SET_DEVICE_OWNER_LOCK_SCREEN_INFO = 42;
- SET_SHORT_SUPPORT_MESSAGE = 43;
- SET_LONG_SUPPORT_MESSAGE = 44;
- SET_CROSS_PROFILE_CONTACTS_SEARCH_DISABLED = 45;
- SET_CROSS_PROFILE_CALLER_ID_DISABLED = 46;
- SET_BLUETOOTH_CONTACT_SHARING_DISABLED = 47;
- ADD_CROSS_PROFILE_INTENT_FILTER = 48;
- ADD_CROSS_PROFILE_WIDGET_PROVIDER = 49;
- SET_SYSTEM_UPDATE_POLICY = 50;
- SET_LOCKTASK_MODE_ENABLED = 51;
- ADD_PERSISTENT_PREFERRED_ACTIVITY = 52;
- REQUEST_BUGREPORT = 53;
- GET_WIFI_MAC_ADDRESS = 54;
- REQUEST_QUIET_MODE_ENABLED = 55;
- WORK_PROFILE_LOCATION_CHANGED = 56;
- DO_USER_INFO_CLICKED = 57;
- TRANSFER_OWNERSHIP = 58;
- GENERATE_KEY_PAIR = 59;
- SET_KEY_PAIR_CERTIFICATE = 60;
- SET_KEEP_UNINSTALLED_PACKAGES = 61;
- SET_APPLICATION_RESTRICTIONS = 62;
- SET_APPLICATION_HIDDEN = 63;
- ENABLE_SYSTEM_APP = 64;
- ENABLE_SYSTEM_APP_WITH_INTENT = 65;
- INSTALL_EXISTING_PACKAGE = 66;
- SET_UNINSTALL_BLOCKED = 67;
- SET_PACKAGES_SUSPENDED = 68;
- ON_LOCK_TASK_MODE_ENTERING = 69;
- SET_CROSS_PROFILE_CALENDAR_PACKAGES = 70;
- GET_USER_PASSWORD_COMPLEXITY_LEVEL = 72;
- INSTALL_SYSTEM_UPDATE = 73;
- INSTALL_SYSTEM_UPDATE_ERROR = 74;
- IS_MANAGED_KIOSK = 75;
- IS_UNATTENDED_MANAGED_KIOSK = 76;
- PROVISIONING_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE = 77;
- PROVISIONING_PERSISTENT_DEVICE_OWNER = 78;
-
- // existing Tron logs to be migrated to statsd
- PROVISIONING_ENTRY_POINT_NFC = 79;
- PROVISIONING_ENTRY_POINT_QR_CODE = 80;
- PROVISIONING_ENTRY_POINT_CLOUD_ENROLLMENT = 81;
- PROVISIONING_ENTRY_POINT_ADB = 82;
- PROVISIONING_ENTRY_POINT_TRUSTED_SOURCE = 83;
- PROVISIONING_DPC_PACKAGE_NAME = 84;
- PROVISIONING_DPC_INSTALLED_BY_PACKAGE = 85;
- PROVISIONING_PROVISIONING_ACTIVITY_TIME_MS = 86;
- PROVISIONING_PREPROVISIONING_ACTIVITY_TIME_MS = 87;
- PROVISIONING_ENCRYPT_DEVICE_ACTIVITY_TIME_MS = 88;
- PROVISIONING_WEB_ACTIVITY_TIME_MS = 89;
- PROVISIONING_TRAMPOLINE_ACTIVITY_TIME_MS = 90 [deprecated=true];
- PROVISIONING_POST_ENCRYPTION_ACTIVITY_TIME_MS = 91 [deprecated=true];
- PROVISIONING_FINALIZATION_ACTIVITY_TIME_MS = 92 [deprecated=true];
- PROVISIONING_NETWORK_TYPE = 93;
- PROVISIONING_ACTION = 94;
- PROVISIONING_EXTRAS = 95;
- PROVISIONING_COPY_ACCOUNT_TASK_MS = 96;
- PROVISIONING_CREATE_PROFILE_TASK_MS = 97;
- PROVISIONING_START_PROFILE_TASK_MS = 98;
- PROVISIONING_DOWNLOAD_PACKAGE_TASK_MS = 99;
- PROVISIONING_INSTALL_PACKAGE_TASK_MS = 100;
- PROVISIONING_CANCELLED = 101;
- PROVISIONING_ERROR = 102;
- PROVISIONING_COPY_ACCOUNT_STATUS = 103;
- PROVISIONING_TOTAL_TASK_TIME_MS = 104;
- PROVISIONING_SESSION_STARTED = 105;
- PROVISIONING_SESSION_COMPLETED = 106;
- PROVISIONING_TERMS_ACTIVITY_TIME_MS = 107;
- PROVISIONING_TERMS_COUNT = 108;
- PROVISIONING_TERMS_READ = 109;
-
- SEPARATE_PROFILE_CHALLENGE_CHANGED = 110;
- SET_GLOBAL_SETTING = 111;
- INSTALL_PACKAGE = 112;
- UNINSTALL_PACKAGE = 113;
- WIFI_SERVICE_ADD_NETWORK_SUGGESTIONS = 114;
- WIFI_SERVICE_ADD_OR_UPDATE_NETWORK = 115;
- QUERY_SUMMARY_FOR_DEVICE = 116;
- REMOVE_CROSS_PROFILE_WIDGET_PROVIDER = 117;
- ESTABLISH_VPN = 118;
- SET_NETWORK_LOGGING_ENABLED = 119;
- RETRIEVE_NETWORK_LOGS = 120;
- PROVISIONING_PREPARE_TOTAL_TIME_MS = 121;
- PROVISIONING_PREPARE_STARTED = 122;
- PROVISIONING_PREPARE_COMPLETED = 123;
- PROVISIONING_FLOW_TYPE = 124;
- CROSS_PROFILE_APPS_GET_TARGET_USER_PROFILES = 125;
- CROSS_PROFILE_APPS_START_ACTIVITY_AS_USER = 126;
- SET_AUTO_TIME = 127;
- SET_AUTO_TIME_ZONE = 128;
- SET_USER_CONTROL_DISABLED_PACKAGES = 129;
- SET_FACTORY_RESET_PROTECTION = 130;
- SET_COMMON_CRITERIA_MODE = 131;
- ALLOW_MODIFICATION_OF_ADMIN_CONFIGURED_NETWORKS = 132;
- SET_TIME = 133;
- SET_TIME_ZONE = 134;
- SET_PERSONAL_APPS_SUSPENDED = 135;
- SET_MANAGED_PROFILE_MAXIMUM_TIME_OFF = 136;
- COMP_TO_ORG_OWNED_PO_MIGRATED = 137;
- SET_CROSS_PROFILE_PACKAGES = 138;
- SET_INTERACT_ACROSS_PROFILES_APP_OP = 139;
- GET_CROSS_PROFILE_PACKAGES = 140;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_TRUE = 141;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_NO_PROFILES = 142;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_WHITELIST = 143;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_PERMISSION = 144;
- CAN_INTERACT_ACROSS_PROFILES_TRUE = 145;
- CAN_INTERACT_ACROSS_PROFILES_FALSE_PERMISSION = 146;
- CAN_INTERACT_ACROSS_PROFILES_FALSE_NO_PROFILES = 147;
- CREATE_CROSS_PROFILE_INTENT = 148;
- IS_MANAGED_PROFILE = 149;
- START_ACTIVITY_BY_INTENT = 150;
- BIND_CROSS_PROFILE_SERVICE = 151;
- PROVISIONING_DPC_SETUP_STARTED = 152;
- PROVISIONING_DPC_SETUP_COMPLETED = 153;
- PROVISIONING_ORGANIZATION_OWNED_MANAGED_PROFILE = 154;
- RESOLVER_CROSS_PROFILE_TARGET_OPENED = 155;
- RESOLVER_SWITCH_TABS = 156;
- RESOLVER_EMPTY_STATE_WORK_APPS_DISABLED = 157;
- RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL= 158;
- RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK= 159;
- RESOLVER_EMPTY_STATE_NO_APPS_RESOLVED= 160;
- RESOLVER_AUTOLAUNCH_CROSS_PROFILE_TARGET = 161;
- CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_APP = 162;
- CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_SETTINGS = 163;
- CROSS_PROFILE_SETTINGS_PAGE_ADMIN_RESTRICTED = 164;
- CROSS_PROFILE_SETTINGS_PAGE_MISSING_WORK_APP = 165;
- CROSS_PROFILE_SETTINGS_PAGE_MISSING_PERSONAL_APP = 166;
- CROSS_PROFILE_SETTINGS_PAGE_MISSING_INSTALL_BANNER_INTENT = 167;
- CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_CLICKED = 168;
- CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_NO_INTENT_CLICKED = 169;
- CROSS_PROFILE_SETTINGS_PAGE_USER_CONSENTED = 170;
- CROSS_PROFILE_SETTINGS_PAGE_USER_DECLINED_CONSENT = 171;
- CROSS_PROFILE_SETTINGS_PAGE_PERMISSION_REVOKED = 172;
- DOCSUI_EMPTY_STATE_NO_PERMISSION = 173;
- DOCSUI_EMPTY_STATE_QUIET_MODE = 174;
- DOCSUI_LAUNCH_OTHER_APP = 175;
- DOCSUI_PICK_RESULT = 176;
-}
diff --git a/core/proto/android/stats/devicepolicy/jarjar-rules.txt b/core/proto/android/stats/devicepolicy/jarjar-rules.txt
deleted file mode 100644
index 40043a86..0000000
--- a/core/proto/android/stats/devicepolicy/jarjar-rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1
diff --git a/core/proto/android/stats/dnsresolver/Android.bp b/core/proto/android/stats/dnsresolver/Android.bp
deleted file mode 100644
index 1e8c763..0000000
--- a/core/proto/android/stats/dnsresolver/Android.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "dnsresolverprotosnano",
- proto: {
- type: "nano",
- },
- srcs: [
- "dns_resolver.proto",
- ],
- sdk_version: "system_current",
-}
diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto
deleted file mode 100644
index b17d12c..0000000
--- a/core/proto/android/stats/dnsresolver/dns_resolver.proto
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-syntax = "proto2";
-package android.stats.dnsresolver;
-
-enum EventType {
- EVENT_UNKNOWN = 0;
- EVENT_GETADDRINFO = 1;
- EVENT_GETHOSTBYNAME = 2;
- EVENT_GETHOSTBYADDR = 3;
- EVENT_RES_NSEND = 4;
-}
-
-// The return value of the DNS resolver for each DNS lookups.
-// bionic/libc/include/netdb.h
-// system/netd/resolv/include/netd_resolv/resolv.h
-enum ReturnCode {
- RC_EAI_NO_ERROR = 0;
- RC_EAI_ADDRFAMILY = 1;
- RC_EAI_AGAIN = 2;
- RC_EAI_BADFLAGS = 3;
- RC_EAI_FAIL = 4;
- RC_EAI_FAMILY = 5;
- RC_EAI_MEMORY = 6;
- RC_EAI_NODATA = 7;
- RC_EAI_NONAME = 8;
- RC_EAI_SERVICE = 9;
- RC_EAI_SOCKTYPE = 10;
- RC_EAI_SYSTEM = 11;
- RC_EAI_BADHINTS = 12;
- RC_EAI_PROTOCOL = 13;
- RC_EAI_OVERFLOW = 14;
- RC_RESOLV_INTERNAL_ERROR = 254;
- RC_RESOLV_TIMEOUT = 255;
- RC_EAI_MAX = 256;
-}
-
-enum NsRcode {
- NS_R_NO_ERROR = 0; // No error occurred.
- NS_R_FORMERR = 1; // Format error.
- NS_R_SERVFAIL = 2; // Server failure.
- NS_R_NXDOMAIN = 3; // Name error.
- NS_R_NOTIMPL = 4; // Unimplemented.
- NS_R_REFUSED = 5; // Operation refused.
- // these are for BIND_UPDATE
- NS_R_YXDOMAIN = 6; // Name exists
- NS_R_YXRRSET = 7; // RRset exists
- NS_R_NXRRSET = 8; // RRset does not exist
- NS_R_NOTAUTH = 9; // Not authoritative for zone
- NS_R_NOTZONE = 10; // Zone of record different from zone section
- NS_R_MAX = 11;
- // Define rcode=12~15(UNASSIGNED) in rcode enum type.
- // Some DNS Servers might return undefined code to devices.
- // Without the enum definition, that would be noise for our dashboard.
- NS_R_UNASSIGNED12 = 12; // Unassigned
- NS_R_UNASSIGNED13 = 13; // Unassigned
- NS_R_UNASSIGNED14 = 14; // Unassigned
- NS_R_UNASSIGNED15 = 15; // Unassigned
- // The following are EDNS extended rcodes
- NS_R_BADVERS = 16;
- // The following are TSIG errors
- // NS_R_BADSIG = 16,
- NS_R_BADKEY = 17;
- NS_R_BADTIME = 18;
- NS_R_INTERNAL_ERROR = 254;
- NS_R_TIMEOUT = 255;
-}
-
-// Currently defined type values for resources and queries.
-enum NsType {
- NS_T_INVALID = 0; // Cookie.
- NS_T_A = 1; // Host address.
- NS_T_NS = 2; // Authoritative server.
- NS_T_MD = 3; // Mail destination.
- NS_T_MF = 4; // Mail forwarder.
- NS_T_CNAME = 5; // Canonical name.
- NS_T_SOA = 6; // Start of authority zone.
- NS_T_MB = 7; // Mailbox domain name.
- NS_T_MG = 8; // Mail group member.
- NS_T_MR = 9; // Mail rename name.
- NS_T_NULL = 10; // Null resource record.
- NS_T_WKS = 11; // Well known service.
- NS_T_PTR = 12; // Domain name pointer.
- NS_T_HINFO = 13; // Host information.
- NS_T_MINFO = 14; // Mailbox information.
- NS_T_MX = 15; // Mail routing information.
- NS_T_TXT = 16; // Text strings.
- NS_T_RP = 17; // Responsible person.
- NS_T_AFSDB = 18; // AFS cell database.
- NS_T_X25 = 19; // X_25 calling address.
- NS_T_ISDN = 20; // ISDN calling address.
- NS_T_RT = 21; // Router.
- NS_T_NSAP = 22; // NSAP address.
- NS_T_NSAP_PTR = 23; // Reverse NSAP lookup (deprecated).
- NS_T_SIG = 24; // Security signature.
- NS_T_KEY = 25; // Security key.
- NS_T_PX = 26; // X.400 mail mapping.
- NS_T_GPOS = 27; // Geographical position (withdrawn).
- NS_T_AAAA = 28; // IPv6 Address.
- NS_T_LOC = 29; // Location Information.
- NS_T_NXT = 30; // Next domain (security).
- NS_T_EID = 31; // Endpoint identifier.
- NS_T_NIMLOC = 32; // Nimrod Locator.
- NS_T_SRV = 33; // Server Selection.
- NS_T_ATMA = 34; // ATM Address
- NS_T_NAPTR = 35; // Naming Authority PoinTeR
- NS_T_KX = 36; // Key Exchange
- NS_T_CERT = 37; // Certification record
- NS_T_A6 = 38; // IPv6 address (experimental)
- NS_T_DNAME = 39; // Non-terminal DNAME
- NS_T_SINK = 40; // Kitchen sink (experimentatl)
- NS_T_OPT = 41; // EDNS0 option (meta-RR)
- NS_T_APL = 42; // Address prefix list (RFC 3123)
- NS_T_DS = 43; // Delegation Signer
- NS_T_SSHFP = 44; // SSH Fingerprint
- NS_T_IPSECKEY = 45; // IPSEC Key
- NS_T_RRSIG = 46; // RRset Signature
- NS_T_NSEC = 47; // Negative security
- NS_T_DNSKEY = 48; // DNS Key
- NS_T_DHCID = 49; // Dynamic host configuratin identifier
- NS_T_NSEC3 = 50; // Negative security type 3
- NS_T_NSEC3PARAM = 51; // Negative security type 3 parameters
- NS_T_HIP = 55; // Host Identity Protocol
- NS_T_SPF = 99; // Sender Policy Framework
- NS_T_TKEY = 249; // Transaction key
- NS_T_TSIG = 250; // Transaction signature.
- NS_T_IXFR = 251; // Incremental zone transfer.
- NS_T_AXFR = 252; // Transfer zone of authority.
- NS_T_MAILB = 253; // Transfer mailbox records.
- NS_T_MAILA = 254; // Transfer mail agent records.
- NS_T_ANY = 255; // Wildcard match.
- NS_T_ZXFR = 256; // BIND-specific, nonstandard.
- NS_T_DLV = 32769; // DNSSEC look-aside validatation.
- NS_T_MAX = 65536;
-}
-
-enum IpVersion {
- IV_UNKNOWN = 0;
- IV_IPV4 = 1;
- IV_IPV6 = 2;
-}
-
-enum Protocol {
- PROTO_UNKNOWN = 0;
- PROTO_UDP = 1;
- PROTO_TCP = 2;
- PROTO_DOT = 3;
-}
-
-enum PrivateDnsModes {
- PDM_UNKNOWN = 0;
- PDM_OFF = 1;
- PDM_OPPORTUNISTIC = 2;
- PDM_STRICT = 3;
-}
-
-enum NetworkType {
- NT_UNKNOWN = 0;
- // Indicates this network uses a Cellular transport.
- NT_CELLULAR = 1;
- // Indicates this network uses a Wi-Fi transport.
- NT_WIFI = 2;
- // Indicates this network uses a Bluetooth transport.
- NT_BLUETOOTH = 3;
- // Indicates this network uses an Ethernet transport.
- NT_ETHERNET = 4;
- // Indicates this network uses a VPN transport, now deprecated.
- NT_VPN = 5 [deprecated=true];
- // Indicates this network uses a Wi-Fi Aware transport.
- NT_WIFI_AWARE = 6;
- // Indicates this network uses a LoWPAN transport.
- NT_LOWPAN = 7;
- // Indicates this network uses a Cellular+VPN transport.
- NT_CELLULAR_VPN = 8;
- // Indicates this network uses a Wi-Fi+VPN transport.
- NT_WIFI_VPN = 9;
- // Indicates this network uses a Bluetooth+VPN transport.
- NT_BLUETOOTH_VPN = 10;
- // Indicates this network uses an Ethernet+VPN transport.
- NT_ETHERNET_VPN = 11;
- // Indicates this network uses a Wi-Fi+Cellular+VPN transport.
- NT_WIFI_CELLULAR_VPN = 12;
-}
-
-enum CacheStatus{
- // the cache can't handle that kind of queries.
- // or the answer buffer is too small.
- CS_UNSUPPORTED = 0;
- // the cache doesn't know about this query.
- CS_NOTFOUND = 1;
- // the cache found the answer.
- CS_FOUND = 2;
- // Don't do anything on cache.
- CS_SKIP = 3;
-}
-
-// The enum LinuxErrno is defined in the following 2 files.
-// 1. bionic/libc/kernel/uapi/asm-generic/errno-base.h
-// 2. bionic/libc/kernel/uapi/asm-generic/errno.h
-enum LinuxErrno {
- SYS_NO_ERROR = 0;
- SYS_EPERM = 1; // Not super-user
- SYS_ENOENT = 2; // No such file or directory
- SYS_ESRCH = 3; // No such process
- SYS_EINTR = 4; // Interrupted system call
- SYS_EIO = 5; // I/O error
- SYS_ENXIO = 6; // No such device or address
- SYS_E2BIG = 7; // Arg list too long
- SYS_ENOEXEC = 8; // Exec format error
- SYS_EBADF = 9; // Bad file number
- SYS_ECHILD = 10; // No children
- SYS_EAGAIN = 11; // No more processes
- SYS_ENOMEM = 12; // Not enough core
- SYS_EACCES = 13; // Permission denied
- SYS_EFAULT = 14; // Bad address
- SYS_ENOTBLK = 15; // Block device required
- SYS_EBUSY = 16; // Mount device busy
- SYS_EEXIST = 17; // File exists
- SYS_EXDEV = 18; // Cross-device link
- SYS_ENODEV = 19; // No such device
- SYS_ENOTDIR = 20; // Not a directory
- SYS_EISDIR = 21; // Is a directory
- SYS_EINVAL = 22; // Invalid argument
- SYS_ENFILE = 23; // Too many open files in system
- SYS_EMFILE = 24; // Too many open files
- SYS_ENOTTY = 25; // Not a typewriter
- SYS_ETXTBSY = 26; // Text file busy
- SYS_EFBIG = 27; // File too large
- SYS_ENOSPC = 28; // No space left on device
- SYS_ESPIPE = 29; // Illegal seek
- SYS_EROFS = 30; // Read only file system
- SYS_EMLINK = 31; // Too many links
- SYS_EPIPE = 32; // Broken pipe
- SYS_EDOM = 33; // Math arg out of domain of func
- SYS_ERANGE = 34; // Math result not representable
- SYS_EDEADLOCK = 35; // File locking deadlock error
- SYS_ENAMETOOLONG = 36; // File or path name too long
- SYS_ENOLCK = 37; // No record locks available
- SYS_ENOSYS = 38; // Function not implemented
- SYS_ENOTEMPTY = 39; // Directory not empty
- SYS_ELOOP = 40; // Too many symbolic links
- SYS_ENOMSG = 42; // No message of desired type
- SYS_EIDRM = 43; // Identifier removed
- SYS_ECHRNG = 44; // Channel number out of range
- SYS_EL2NSYNC = 45; // Level 2 not synchronized
- SYS_EL3HLT = 46; // Level 3 halted
- SYS_EL3RST = 47; // Level 3 reset
- SYS_ELNRNG = 48; // Link number out of range
- SYS_EUNATCH = 49; // rotocol driver not attached
- SYS_ENOCSI = 50; // No CSI structure available
- SYS_EL2HLT = 51; // Level 2 halted
- SYS_EBADE = 52; // Invalid exchange
- SYS_EBADR = 53; // Invalid request descriptor
- SYS_EXFULL = 54; // Exchange full
- SYS_ENOANO = 55; // No anode
- SYS_EBADRQC = 56; // Invalid request code
- SYS_EBADSLT = 57; // Invalid slot
- SYS_EBFONT = 59; // Bad font file fmt
- SYS_ENOSTR = 60; // Device not a stream
- SYS_ENODATA = 61; // No data (for no delay io)
- SYS_ETIME = 62; // Timer expired
- SYS_ENOSR = 63; // Out of streams resources
- SYS_ENONET = 64; // Machine is not on the network
- SYS_ENOPKG = 65; // Package not installed
- SYS_EREMOTE = 66; // The object is remote
- SYS_ENOLINK = 67; // The link has been severed
- SYS_EADV = 68; // Advertise error
- SYS_ESRMNT = 69; // Srmount error
- SYS_ECOMM = 70; // Communication error on send
- SYS_EPROTO = 71; // Protocol error
- SYS_EMULTIHOP = 72; // Multihop attempted
- SYS_EDOTDOT = 73; // Cross mount point (not really error)
- SYS_EBADMSG = 74; // Trying to read unreadable message
- SYS_EOVERFLOW = 75; // Value too large for defined data type
- SYS_ENOTUNIQ = 76; // Given log. name not unique
- SYS_EBADFD = 77; // f.d. invalid for this operation
- SYS_EREMCHG = 78; // Remote address changed
- SYS_ELIBACC = 79; // Can't access a needed shared lib
- SYS_ELIBBAD = 80; // Accessing a corrupted shared lib
- SYS_ELIBSCN = 81; // .lib section in a.out corrupted
- SYS_ELIBMAX = 82; // Attempting to link in too many libs
- SYS_ELIBEXEC = 83; // Attempting to exec a shared library
- SYS_EILSEQ = 84;
- SYS_ERESTART = 85;
- SYS_ESTRPIPE = 86;
- SYS_EUSERS = 87;
- SYS_ENOTSOCK = 88; // Socket operation on non-socket
- SYS_EDESTADDRREQ = 89; // Destination address required
- SYS_EMSGSIZE = 90; // Message too long
- SYS_EPROTOTYPE = 91; // Protocol wrong type for socket
- SYS_ENOPROTOOPT = 92; // Protocol not available
- SYS_EPROTONOSUPPORT = 93; // Unknown protocol
- SYS_ESOCKTNOSUPPORT = 94; // Socket type not supported
- SYS_EOPNOTSUPP = 95; // Operation not supported on transport endpoint
- SYS_EPFNOSUPPORT = 96; // Protocol family not supported
- SYS_EAFNOSUPPORT = 97; // Address family not supported by protocol family
- SYS_EADDRINUSE = 98; // Address already in use
- SYS_EADDRNOTAVAIL = 99; // Address not available
- SYS_ENETDOWN = 100; // Network interface is not configured
- SYS_ENETUNREACH = 101; // Network is unreachable
- SYS_ENETRESET = 102;
- SYS_ECONNABORTED = 103; // Connection aborted
- SYS_ECONNRESET = 104; // Connection reset by peer
- SYS_ENOBUFS = 105; // No buffer space available
- SYS_EISCONN = 106; // Socket is already connected
- SYS_ENOTCONN = 107; // Socket is not connected
- SYS_ESHUTDOWN = 108; // Can't send after socket shutdown
- SYS_ETOOMANYREFS = 109;
- SYS_ETIMEDOUT = 110; // Connection timed out
- SYS_ECONNREFUSED = 111; // Connection refused
- SYS_EHOSTDOWN = 112; // Host is down
- SYS_EHOSTUNREACH = 113; // Host is unreachable
- SYS_EALREADY = 114; // Socket already connected
- SYS_EINPROGRESS = 115; // Connection already in progress
- SYS_ESTALE = 116;
- SYS_EUCLEAN = 117;
- SYS_ENOTNAM = 118;
- SYS_ENAVAIL = 119;
- SYS_EISNAM = 120;
- SYS_EREMOTEIO = 121;
- SYS_EDQUOT = 122;
- SYS_ENOMEDIUM = 123; // No medium (in tape drive)
- SYS_EMEDIUMTYPE = 124;
- SYS_ECANCELED = 125;
- SYS_ENOKEY = 126;
- SYS_EKEYEXPIRED = 127;
- SYS_EKEYREVOKED = 128;
- SYS_EKEYREJECTED = 129;
- SYS_EOWNERDEAD = 130;
- SYS_ENOTRECOVERABLE = 131;
- SYS_ERFKILL = 132;
- SYS_EHWPOISON = 133;
-}
-
-message DnsQueryEvent {
- optional android.stats.dnsresolver.NsRcode rcode = 1;
-
- optional android.stats.dnsresolver.NsType type = 2;
-
- optional android.stats.dnsresolver.CacheStatus cache_hit = 3;
-
- optional android.stats.dnsresolver.IpVersion ip_version = 4;
-
- optional android.stats.dnsresolver.Protocol protocol = 5;
-
- // Number of DNS query retry times
- optional int32 retry_times = 6;
-
- // Ordinal number of name server.
- optional int32 dns_server_index = 7;
-
- // Used only by TCP and DOT. True for new connections.
- optional bool connected = 8;
-
- optional int32 latency_micros = 9;
-
- optional android.stats.dnsresolver.LinuxErrno linux_errno = 10;
-}
-
-message DnsQueryEvents {
- repeated DnsQueryEvent dns_query_event = 1;
-}
diff --git a/core/proto/android/stats/docsui/docsui_enums.proto b/core/proto/android/stats/docsui/docsui_enums.proto
deleted file mode 100644
index 5963f6a..0000000
--- a/core/proto/android/stats/docsui/docsui_enums.proto
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.docsui;
-option java_multiple_files = true;
-
-enum LaunchAction {
- UNKNOWN = 0;
- OPEN = 1;
- CREATE = 2;
- GET_CONTENT = 3;
- OPEN_TREE = 4;
- PICK_COPY_DEST = 5;
- BROWSE = 6;
- OTHER = 7;
-}
-
-enum MimeType {
- MIME_UNKNOWN = 0;
- MIME_NONE = 1;
- MIME_ANY = 2;
- MIME_APPLICATION = 3;
- MIME_AUDIO = 4;
- MIME_IMAGE = 5;
- MIME_MESSAGE = 6;
- MIME_MULTIPART = 7;
- MIME_TEXT = 8;
- MIME_VIDEO = 9;
- MIME_OTHER = 10;
-}
-
-enum Root {
- ROOT_UNKNOWN = 0;
- ROOT_NONE = 1;
- ROOT_OTHER_DOCS_PROVIDER = 2;
- ROOT_AUDIO = 3;
- ROOT_DEVICE_STORAGE = 4;
- ROOT_DOWNLOADS = 5;
- ROOT_HOME = 6;
- ROOT_IMAGES = 7;
- ROOT_RECENTS = 8;
- ROOT_VIDEOS = 9;
- ROOT_MTP = 10;
- ROOT_THIRD_PARTY_APP = 11;
- ROOT_DOCUMENTS = 12;
-}
-
-enum ContextScope {
- SCOPE_UNKNOWN = 0;
- SCOPE_FILES = 1;
- SCOPE_PICKER = 2;
-}
-
-enum Provider {
- PROVIDER_UNKNOWN = 0;
- PROVIDER_SYSTEM = 1;
- PROVIDER_EXTERNAL = 2;
-}
-
-enum FileOperation {
- OP_UNKNOWN = 0;
- OP_OTHER = 1;
- OP_COPY = 2;
- OP_COPY_INTRA_PROVIDER = 3;
- OP_COPY_SYSTEM_PROVIDER = 4;
- OP_COPY_EXTERNAL_PROVIDER = 5;
- OP_MOVE = 6;
- OP_MOVE_INTRA_PROVIDER = 7;
- OP_MOVE_SYSTEM_PROVIDER = 8;
- OP_MOVE_EXTERNAL_PROVIDER = 9;
- OP_DELETE = 10;
- OP_RENAME = 11;
- OP_CREATE_DIR = 12;
- OP_OTHER_ERROR = 13;
- OP_DELETE_ERROR = 14;
- OP_MOVE_ERROR = 15;
- OP_COPY_ERROR = 16;
- OP_RENAME_ERROR = 17;
- OP_CREATE_DIR_ERROR = 18;
- OP_COMPRESS_INTRA_PROVIDER = 19;
- OP_COMPRESS_SYSTEM_PROVIDER = 20;
- OP_COMPRESS_EXTERNAL_PROVIDER = 21;
- OP_EXTRACT_INTRA_PROVIDER = 22;
- OP_EXTRACT_SYSTEM_PROVIDER = 23;
- OP_EXTRACT_EXTERNAL_PROVIDER = 24;
- OP_COMPRESS_ERROR = 25;
- OP_EXTRACT_ERROR = 26;
-}
-
-enum SubFileOperation {
- SUB_OP_UNKNOWN = 0;
- SUB_OP_QUERY_DOC = 1;
- SUB_OP_QUERY_CHILD = 2;
- SUB_OP_OPEN_FILE = 3;
- SUB_OP_READ_FILE = 4;
- SUB_OP_CREATE_DOC = 5;
- SUB_OP_WRITE_FILE = 6;
- SUB_OP_DELETE_DOC = 7;
- SUB_OP_OBTAIN_STREAM_TYPE = 8;
- SUB_OP_QUICK_MOVE = 9;
- SUB_OP_QUICK_COPY = 10;
-}
-
-enum CopyMoveOpMode {
- MODE_UNKNOWN = 0;
- MODE_PROVIDER = 1;
- MODE_CONVERTED = 2;
- MODE_CONVENTIONAL = 3;
-}
-
-enum Authority {
- AUTH_UNKNOWN = 0;
- AUTH_OTHER = 1;
- AUTH_MEDIA = 2;
- AUTH_STORAGE_INTERNAL = 3;
- AUTH_STORAGE_EXTERNAL = 4;
- AUTH_DOWNLOADS = 5;
- AUTH_MTP = 6;
-}
-
-enum UserAction {
- ACTION_UNKNOWN = 0;
- ACTION_OTHER = 1;
- ACTION_GRID = 2;
- ACTION_LIST = 3;
- ACTION_SORT_NAME = 4;
- ACTION_SORT_DATE = 5;
- ACTION_SORT_SIZE = 6;
- ACTION_SORT_TYPE = 7;
- ACTION_SEARCH = 8;
- ACTION_SHOW_SIZE = 9;
- ACTION_HIDE_SIZE = 10;
- ACTION_SETTINGS = 11;
- ACTION_COPY_TO = 12;
- ACTION_MOVE_TO = 13;
- ACTION_DELETE = 14;
- ACTION_RENAME = 15;
- ACTION_CREATE_DIR = 16;
- ACTION_SELECT_ALL = 17;
- ACTION_SHARE = 18;
- ACTION_OPEN = 19;
- ACTION_SHOW_ADVANCED = 20;
- ACTION_HIDE_ADVANCED = 21;
- ACTION_NEW_WINDOW = 22;
- ACTION_PASTE_CLIPBOARD = 23;
- ACTION_COPY_CLIPBOARD = 24;
- ACTION_DRAG_N_DROP = 25;
- ACTION_DRAG_N_DROP_MULTI_WINDOW = 26;
- ACTION_CUT_CLIPBOARD = 27;
- ACTION_COMPRESS = 28;
- ACTION_EXTRACT_TO = 29;
- ACTION_VIEW_IN_APPLICATION = 30;
- ACTION_INSPECTOR = 31;
- ACTION_SEARCH_CHIP = 32;
- ACTION_SEARCH_HISTORY = 33;
-}
-
-enum InvalidScopedAccess {
- SCOPED_DIR_ACCESS_UNKNOWN = 0;
- SCOPED_DIR_ACCESS_INVALID_ARGUMENTS = 1;
- SCOPED_DIR_ACCESS_INVALID_DIRECTORY = 2;
- SCOPED_DIR_ACCESS_ERROR = 3;
- SCOPED_DIR_ACCESS_DEPRECATED = 4;
-}
-
-enum SearchType {
- TYPE_UNKNOWN = 0;
- TYPE_CHIP_IMAGES = 1;
- TYPE_CHIP_AUDIOS = 2;
- TYPE_CHIP_VIDEOS = 3;
- TYPE_CHIP_DOCS = 4;
- TYPE_SEARCH_HISTORY = 5;
- TYPE_SEARCH_STRING = 6;
- TYPE_CHIP_LARGE_FILES = 7;
- TYPE_CHIP_FROM_THIS_WEEK = 8;
-}
-
-enum SearchMode {
- SEARCH_UNKNOWN = 0;
- SEARCH_KEYWORD = 1;
- SEARCH_CHIPS = 2;
- SEARCH_KEYWORD_N_CHIPS = 3;
-}
diff --git a/core/proto/android/stats/enums.proto b/core/proto/android/stats/enums.proto
deleted file mode 100644
index 8f8055e..0000000
--- a/core/proto/android/stats/enums.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats;
-option java_outer_classname = "StatsEnums";
-
-enum EventType {
- // Unknown.
- TYPE_UNKNOWN = 0;
- CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL_SUCCEEDED = 1;
- CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL_FAILED = 2;
- CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL_SUCCEEDED = 3;
- CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL_FAILED = 4;
-}
diff --git a/core/proto/android/stats/intelligence/enums.proto b/core/proto/android/stats/intelligence/enums.proto
deleted file mode 100644
index 0c210e3..0000000
--- a/core/proto/android/stats/intelligence/enums.proto
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.intelligence;
-option java_outer_classname = "IntelligenceStatsEnums";
-
-enum Status {
- // The value wasn't set.
- // protoc requires enum values to be unique by package rather than enum type.
- // This forces us to prefix the enum values.
- STATUS_UNKNOWN = 0;
- // The event succeeded.
- STATUS_SUCCEEDED = 1;
- // The event had an error.
- STATUS_FAILED = 2;
-}
-
-enum EventType {
- // The value wasn't set.
- EVENT_UNKNOWN = 0;
- // ContentSuggestionsService classifyContentSelections call.
- EVENT_CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL = 1;
- // ContentSuggestionsService suggestContentSelections call.
- EVENT_CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL = 2;
-}
diff --git a/core/proto/android/stats/launcher/Android.bp b/core/proto/android/stats/launcher/Android.bp
deleted file mode 100644
index 976a0b8..0000000
--- a/core/proto/android/stats/launcher/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library {
- name: "launcherprotosnano",
- proto: {
- type: "nano",
- output_params: ["store_unknown_fields=true"],
- include_dirs: ["external/protobuf/src"],
- },
-
- sdk_version: "current",
- srcs: [
- "*.proto",
- ],
-}
-
-java_library {
- name: "launcherprotoslite",
- proto: {
- type: "lite",
- include_dirs: ["external/protobuf/src"],
- },
-
- sdk_version: "current",
- srcs: [
- "*.proto",
- ],
-}
diff --git a/core/proto/android/stats/launcher/launcher.proto b/core/proto/android/stats/launcher/launcher.proto
deleted file mode 100644
index fc177d5..0000000
--- a/core/proto/android/stats/launcher/launcher.proto
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.launcher;
-option java_multiple_files = true;
-
-enum LauncherAction {
- DEFAULT_ACTION = 0;
- LAUNCH_APP = 1;
- LAUNCH_TASK = 2;
- DISMISS_TASK = 3;
- LONGPRESS = 4;
- DRAGDROP = 5;
- SWIPE_UP = 6;
- SWIPE_DOWN = 7;
- SWIPE_LEFT = 8;
- SWIPE_RIGHT = 9;
-}
-
-enum LauncherState {
- LAUNCHER_STATE_UNSPECIFIED = 0;
- BACKGROUND = 1;
- HOME = 2;
- OVERVIEW = 3;
- ALLAPPS = 4;
- UNCHANGED = 5;
-}
-
-message LauncherTarget {
- enum Type {
- NONE = 0;
- ITEM_TYPE = 1;
- CONTROL_TYPE = 2;
- CONTAINER_TYPE = 3;
- }
- enum Item {
- DEFAULT_ITEM = 0;
- APP_ICON = 1;
- SHORTCUT = 2;
- WIDGET = 3;
- FOLDER_ICON = 4;
- DEEPSHORTCUT = 5;
- SEARCHBOX = 6;
- EDITTEXT = 7;
- NOTIFICATION = 8;
- TASK = 9;
- }
- enum Container {
- DEFAULT_CONTAINER = 0;
- HOTSEAT = 1;
- FOLDER = 2;
- PREDICTION = 3;
- SEARCHRESULT = 4;
- }
- enum Control {
- DEFAULT_CONTROL = 0;
- MENU = 1;
- UNINSTALL = 2;
- REMOVE = 3;
- }
- optional Type type = 1;
- optional Item item = 2;
- optional Container container = 3;
- optional Control control = 4;
- optional string launch_component = 5;
- optional int32 page_id = 6;
- optional int32 grid_x = 7;
- optional int32 grid_y = 8;
-}
-
-message LauncherExtension {
- repeated LauncherTarget src_target = 1;
- repeated LauncherTarget dst_target = 2;
-}
diff --git a/core/proto/android/stats/location/location_enums.proto b/core/proto/android/stats/location/location_enums.proto
deleted file mode 100644
index 553c01c..0000000
--- a/core/proto/android/stats/location/location_enums.proto
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.location;
-option java_outer_classname = "LocationStatsEnums";
-
-
-// APIs from LocationManagerService
-enum LocationManagerServiceApi {
- API_UNKNOWN = 0;
- API_REQUEST_LOCATION_UPDATES = 1;
- API_ADD_GNSS_MEASUREMENTS_LISTENER = 2;
- API_REGISTER_GNSS_STATUS_CALLBACK = 3;
- API_REQUEST_GEOFENCE = 4;
- API_SEND_EXTRA_COMMAND = 5;
-}
-
-enum UsageState {
- USAGE_STARTED = 0;
- USAGE_ENDED = 1;
-}
-
-// Type of location providers
-enum ProviderType {
- PROVIDER_UNKNOWN = 0;
- PROVIDER_NETWORK = 1;
- PROVIDER_GPS = 2;
- PROVIDER_PASSIVE = 3;
- PROVIDER_FUSED = 4;
-}
-
-// Type of Callback passed in for this API
-enum CallbackType {
- CALLBACK_UNKNOWN = 0;
- // Current API does not need a callback, e.g. sendExtraCommand
- CALLBACK_NOT_APPLICABLE = 1;
- CALLBACK_LISTENER = 2;
- CALLBACK_PENDING_INTENT = 3;
-}
-
-// Possible values for mQuality field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-enum LocationRequestQuality {
- QUALITY_UNKNOWN = 0;
- ACCURACY_FINE = 100;
- ACCURACY_BLOCK = 102;
- ACCURACY_CITY = 104;
- POWER_NONE = 200;
- POWER_LOW = 201;
- POWER_HIGH = 203;
-}
-
-// Bucketized values for interval field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-enum LocationRequestIntervalBucket {
- INTERVAL_UNKNOWN = 0;
- INTERVAL_BETWEEN_0_SEC_AND_1_SEC = 1;
- INTERVAL_BETWEEN_1_SEC_AND_5_SEC = 2;
- INTERVAL_BETWEEN_5_SEC_AND_1_MIN = 3;
- INTERVAL_BETWEEN_1_MIN_AND_10_MIN = 4;
- INTERVAL_BETWEEN_10_MIN_AND_1_HOUR = 5;
- INTERVAL_LARGER_THAN_1_HOUR = 6;
-}
-
-// Bucketized values for small displacement field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-// Value in meters.
-enum SmallestDisplacementBucket {
- DISTANCE_UNKNOWN = 0;
- DISTANCE_ZERO = 1;
- DISTANCE_BETWEEN_0_AND_100 = 2;
- DISTANCE_LARGER_THAN_100 = 3;
-}
-
-// Bucketized values for expire_in field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-enum ExpirationBucket {
- EXPIRATION_UNKNOWN = 0;
- EXPIRATION_BETWEEN_0_AND_20_SEC = 1;
- EXPIRATION_BETWEEN_20_SEC_AND_1_MIN = 2;
- EXPIRATION_BETWEEN_1_MIN_AND_10_MIN = 3;
- EXPIRATION_BETWEEN_10_MIN_AND_1_HOUR = 4;
- EXPIRATION_LARGER_THAN_1_HOUR = 5;
- EXPIRATION_NO_EXPIRY = 6;
-}
-
-// Bucketized values for radius field in
-// frameworks/base/location/java/android/location/Geofence.java
-// Value in meters.
-enum GeofenceRadiusBucket {
- RADIUS_UNKNOWN = 0;
- RADIUS_BETWEEN_0_AND_100 = 1;
- RADIUS_BETWEEN_100_AND_200 = 2;
- RADIUS_BETWEEN_200_AND_300 = 3;
- RADIUS_BETWEEN_300_AND_1000 = 4;
- RADIUS_BETWEEN_1000_AND_10000 = 5;
- RADIUS_LARGER_THAN_100000 = 6;
- RADIUS_NEGATIVE = 7;
-}
-
-// Caller Activity Importance.
-enum ActivityImportance {
- IMPORTANCE_UNKNOWN = 0;
- IMPORTANCE_TOP = 1;
- IMPORTANCE_FORGROUND_SERVICE = 2;
- IMPORTANCE_BACKGROUND = 3;
-}
diff --git a/core/proto/android/stats/mediametrics/mediametrics.proto b/core/proto/android/stats/mediametrics/mediametrics.proto
deleted file mode 100644
index 9f0ff59..0000000
--- a/core/proto/android/stats/mediametrics/mediametrics.proto
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.mediametrics;
-
-/**
- * Track how we arbitrate between microphone/input requests.
- * Logged from
- * frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiopolicy.cpp
- * Next Tag: 10
- */
-message AudioPolicyData {
- optional int32 status = 1;
- optional string request_source = 2;
- optional string request_package = 3;
- optional int32 request_session = 4;
- optional string request_device = 5;
- optional string active_source = 6;
- optional string active_package = 7;
- optional int32 active_session = 8;
- optional string active_device = 9;
-}
-
-/**
- * Track properties of audio recording
- * Logged from
- * frameworks/av/media/libaudioclient/AudioRecord.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiorecord.cpp
- * Next Tag: 16
- */
-message AudioRecordData {
- optional string encoding = 1;
- optional string source = 2;
- optional int32 latency = 3;
- optional int32 samplerate = 4;
- optional int32 channels = 5;
- optional int64 created_millis = 6;
- optional int64 duration_millis = 7;
- optional int32 count = 8;
- optional int32 error_code = 9;
- optional string error_function = 10;
- optional int32 port_id = 11;
- optional int32 frame_count = 12;
- optional string attributes = 13;
- optional int64 channel_mask = 14;
- optional int64 start_count = 15;
-
-}
-
-/**
- * Track audio thread performance data
- * Logged from
- * frameworks/av/media/libnblog/ReportPerformance.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiothread.cpp
- * Next Tag: 28
- */
-message AudioThreadData {
- optional string type = 1;
- optional int32 framecount = 2;
- optional int32 samplerate = 3;
- optional string work_millis_hist = 4;
- optional string latency_millis_hist = 5;
- optional string warmup_millis_hist = 6;
- optional int64 underruns = 7;
- optional int64 overruns = 8;
- optional int64 active_millis = 9;
- optional int64 duration_millis = 10;
-
- optional int32 id = 11;
- optional int32 port_id = 12;
- optional int32 sample_rate = 13;
- optional int64 channel_mask = 14;
- optional string encoding = 15;
- optional int32 frame_count = 16;
- optional string output_device = 17;
- optional string input_device = 18;
- optional double io_jitter_mean_millis = 19;
- optional double io_jitter_stddev_millis = 20;
- optional double process_time_mean_millis = 21;
- optional double process_time_stddev_millis = 22;
- optional double timestamp_jitter_mean_millis = 23;
- optional double timestamp_jitter_stddev_millis = 24;
- optional double latency_mean_millis = 25;
- optional double latency_stddev_millis = 26;
-
-}
-
-/**
- * Track audio track playback data
- * Logged from
- * frameworks/av/media/libaudioclient/AudioTrack.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiotrack.cpp
- * Next Tag: 12
- */
-message AudioTrackData {
- optional string stream_type = 1;
- optional string content_type = 2;
- optional string track_usage = 3;
- optional int32 sample_rate = 4;
- optional int64 channel_mask = 5;
-
- optional int32 underrun_frames = 6;
- optional int32 startup_glitch = 7;
-
- optional int32 port_id = 8;
- optional string encoding = 9;
- optional int32 frame_count = 10;
- optional string attributes = 11;
-
-
-}
-
-/**
- * Track Media Codec usage
- * Logged from:
- * frameworks/av/media/libstagefright/MediaCodec.cpp
- * frameworks/av/services/mediaanalytics/statsd_codec.cpp
- * Next Tag: 26
- */
-message CodecData {
- optional string codec = 1;
- optional string mime = 2;
- optional string mode = 3;
- optional int32 encoder = 4;
- optional int32 secure = 5;
- optional int32 width = 6;
- optional int32 height = 7;
- optional int32 rotation = 8;
- optional int32 crypto = 9;
- optional int32 profile = 10;
- optional int32 level = 11;
- optional int32 max_width = 12;
- optional int32 max_height = 13;
- optional int32 error_code = 14;
- optional string error_state = 15;
- optional int64 latency_max = 16;
- optional int64 latency_min = 17;
- optional int64 latency_avg = 18;
- optional int64 latency_count = 19;
- optional int64 latency_unknown = 20;
- optional int32 queue_input_buffer_error = 21;
- optional int32 queue_secure_input_buffer_error = 22;
- optional string bitrate_mode = 23;
- optional int32 bitrate = 24;
- optional int64 lifetime_millis = 25;
-}
-
-/**
- * Track Media Extractor (pulling video/audio streams out of containers) usage
- * Logged from:
- * frameworks/av/media/libstagefright/RemoteMediaExtractor.cpp
- * frameworks/av/services/mediaanalytics/statsd_extractor.cpp
- * Next Tag: 4
- */
-message ExtractorData {
- optional string format = 1;
- optional string mime = 2;
- optional int32 tracks = 3;
-}
-
-/**
- * Track Media Player usage
- * this handles both nuplayer and nuplayer2
- * Logged from:
- * frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
- * frameworks/av/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
- * frameworks/av/services/mediaanalytics/statsd_nuplayer.cpp
- * Next Tag: 21
- */
-message NuPlayerData {
- optional string whichPlayer = 1;
-
- optional string video_mime = 2;
- optional string video_codec = 3;
- optional int32 width = 4;
- optional int32 height = 5;
- optional int64 frames = 6;
- optional int64 frames_dropped = 7;
- optional double framerate = 8;
- optional string audio_mime = 9;
- optional string audio_codec = 10;
- optional int64 duration_millis = 11;
- optional int64 playing_millis = 12;
- optional int32 error = 13;
- optional int32 error_code = 14;
- optional string error_state = 15;
- optional string data_source_type = 16;
- optional int64 rebuffering_millis = 17;
- optional int32 rebuffers = 18;
- optional int32 rebuffer_at_exit = 19;
- optional int64 frames_dropped_startup = 20;
-}
-
-/**
- * Track information about recordings (e.g. camcorder)
- * Logged from
- * frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp
- * frameworks/av/services/mediaanalytics/if_statsd.cpp
- * Next Tag: 22
- */
-message RecorderData {
- optional string audio_mime = 1;
- optional string video_mime = 2;
- optional int32 video_profile = 3;
- optional int32 video_level = 4;
- optional int32 width = 5;
- optional int32 height = 6;
- optional int32 rotation = 7;
- optional int32 framerate = 8;
- optional int32 capture_fps = 9;
- optional double capture_fps_enable = 10;
- optional int64 duration_millis = 11;
- optional int64 paused_millis = 12;
- optional int32 paused_count = 13;
- optional int32 audio_bitrate = 14;
- optional int32 audio_channels = 15;
- optional int32 audio_samplerate = 16;
- optional int32 movie_timescale = 17;
- optional int32 audio_timescale = 18;
- optional int32 video_timescale = 19;
- optional int32 video_bitrate = 20;
- optional int32 iframe_interval = 21;
-}
diff --git a/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto b/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto
deleted file mode 100644
index 138782b..0000000
--- a/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.mediaprovider;
-option java_multiple_files = true;
-
-enum VolumeType {
- // Volume is unknown
- UNKNOWN = 0;
- // Volume is MediaStore.VOLUME_INTERNAL
- INTERNAL = 1;
- // Volume is MediaStore.VOLUME_EXTERNAL_PRIMARY
- EXTERNAL_PRIMARY = 2;
- // Volume is non-primary external storage
- EXTERNAL_OTHER = 3;
-}
diff --git a/core/proto/android/stats/otaupdate/updateengine_enums.proto b/core/proto/android/stats/otaupdate/updateengine_enums.proto
deleted file mode 100644
index a6e9919..0000000
--- a/core/proto/android/stats/otaupdate/updateengine_enums.proto
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.otaupdate;
-
-// The payload type of an OTA update attempt on A/B devices.
-enum PayloadType {
- FULL = 10000;
- DELTA = 10001;
-}
-
-// The attempt result reported by the update engine for an OTA update.
-enum AttemptResult {
- UPDATE_SUCCEEDED = 10000;
- INTERNAL_ERROR = 10001;
- PAYLOAD_DOWNLOAD_ERROR = 10002;
- METADATA_MALFORMED = 10003;
- OPERATION_MALFORMED = 10004;
- OPERATION_EXECUTION_ERROR = 10005;
- METADATA_VERIFICATION_FAILED = 10006;
- PAYLOAD_VERIFICATION_FAILED = 10007;
- VERIFICATION_FAILED = 10008;
- POSTINSTALL_FAILED = 10009;
- ABNORMAL_TERMINATION = 10010;
- UPDATE_CANCELED = 10011;
- UPDATE_SUCCEEDED_NOT_ACTIVE = 10012;
-}
-
-// The error code reported by the update engine after an OTA update attempt
-// on A/B devices. More details in system/update_engine/common/error_code.h
-enum ErrorCode {
- SUCCESS = 10000;
- ERROR = 10001;
- FILESYSTEM_COPIER_ERROR = 10004;
- POST_INSTALL_RUNNER_ERROR = 10005;
- PAYLOAD_MISMATCHED_TYPE_ERROR = 10006;
- INSTALL_DEVICE_OPEN_ERROR = 10007;
- KERNEL_DEVICE_OPEN_ERROR = 10008;
- DOWNLOAD_TRANSFER_ERROR = 10009;
- PAYLOAD_HASH_MISMATCH_ERROR = 10010;
- PAYLOAD_SIZE_MISMATCH_ERROR = 10011;
- DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 10012;
- DOWNLOAD_NEW_PARTITION_INFO_ERROR = 10013;
- DOWNLOAD_WRITE_ERROR = 10014;
- NEW_ROOTFS_VERIFICATION_ERROR = 10015;
- SIGNED_DELTA_PAYLOAD_EXPECTED_ERROR = 10017;
- DOWNLOAD_PAYLOAD_PUB_KEY_VERIFICATION_ERROR = 10018;
- DOWNLOAD_STATE_INITIALIZATION_ERROR = 10020;
- DOWNLOAD_INVALID_METADATA_MAGIC_STRING = 10021;
- DOWNLOAD_SIGNATURE_MISSING_IN_MANIFEST = 10022;
- DOWNLOAD_MANIFEST_PARSE_ERROR = 10023;
- DOWNLOAD_METADATA_SIGNATURE_ERROR = 10024;
- DOWNLOAD_METADATA_SIGNATURE_VERIFICATION_ERROR = 10025;
- DOWNLOAD_METADATA_SIGNATURE_MISMATCH = 10026;
- DOWNLOAD_OPERATION_HASH_VERIFICATION_ERROR = 10027;
- DOWNLOAD_OPERATION_EXECUTION_ERROR = 10028;
- DOWNLOAD_OPERATION_HASH_MISMATCH = 10029;
- DOWNLOAD_INVALID_METADATA_SIZE = 10032;
- DOWNLOAD_INVALID_METADATA_SIGNATURE = 10033;
- DOWNLOAD_OPERATION_HASH_MISSING_ERROR = 10038;
- DOWNLOAD_METADATA_SIGNATURE_MISSING_ERROR = 10039;
- UNSUPPORTED_MAJOR_PAYLOAD_VERSION = 10044;
- UNSUPPORTED_MINOR_PAYLOAD_VERSION = 10045;
- FILESYSTEM_VERIFIER_ERROR = 10047;
- USER_CANCELED = 10048;
- PAYLOAD_TIMESTAMP_ERROR = 10051;
- UPDATED_BUT_NOT_ACTIVE = 10052;
-}
diff --git a/core/proto/android/stats/storage/storage_enums.proto b/core/proto/android/stats/storage/storage_enums.proto
deleted file mode 100644
index 6892e287..0000000
--- a/core/proto/android/stats/storage/storage_enums.proto
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.storage;
-
-enum ExternalStorageType {
- UNKNOWN = 0;
- SD_CARD = 1;
- USB = 2;
- OTHER = 3;
-}
diff --git a/core/proto/android/stats/style/Android.bp b/core/proto/android/stats/style/Android.bp
deleted file mode 100644
index f085a52..0000000
--- a/core/proto/android/stats/style/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library {
- name: "styleprotosnano",
- proto: {
- type: "nano",
- output_params: ["store_unknown_fields=true"],
- include_dirs: ["external/protobuf/src"],
- },
-
- sdk_version: "current",
- srcs: [
- "*.proto",
- ],
-}
diff --git a/core/proto/android/stats/style/style_enums.proto b/core/proto/android/stats/style/style_enums.proto
deleted file mode 100644
index f3f491f..0000000
--- a/core/proto/android/stats/style/style_enums.proto
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.style;
-option java_multiple_files = true;
-
-enum Action {
- DEFAULT_ACTION = 0;
- ONRESUME = 1;
- ONSTOP = 2;
- PICKER_SELECT = 3;
- PICKER_APPLIED = 4;
- WALLPAPER_OPEN_CATEGORY = 5;
- WALLPAPER_SELECT = 6;
- WALLPAPER_APPLIED = 7;
- WALLPAPER_EXPLORE = 8;
- WALLPAPER_DOWNLOAD = 9;
- WALLPAPER_REMOVE = 10;
- LIVE_WALLPAPER_DOWNLOAD_SUCCESS = 11;
- LIVE_WALLPAPER_DOWNLOAD_FAILED = 12;
- LIVE_WALLPAPER_DOWNLOAD_CANCELLED = 13;
- LIVE_WALLPAPER_DELETE_SUCCESS = 14;
- LIVE_WALLPAPER_DELETE_FAILED = 15;
- LIVE_WALLPAPER_APPLIED = 16;
- LIVE_WALLPAPER_INFO_SELECT = 17;
- LIVE_WALLPAPER_CUSTOMIZE_SELECT = 18;
-}
-
-enum LocationPreference {
- LOCATION_PREFERENCE_UNSPECIFIED = 0;
- LOCATION_UNAVAILABLE = 1;
- LOCATION_CURRENT = 2;
- LOCATION_MANUAL = 3;
-}
diff --git a/core/proto/android/stats/sysui/notification_enums.proto b/core/proto/android/stats/sysui/notification_enums.proto
deleted file mode 100644
index 30bdeca..0000000
--- a/core/proto/android/stats/sysui/notification_enums.proto
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.sysui;
-
-// Enum used in NotificationReported and NotificationChannelModified atoms
-enum NotificationImportance { // Constants from NotificationManager.java
- IMPORTANCE_UNSPECIFIED = -1000; // Should not occur for real notifications.
- IMPORTANCE_NONE = 0; // No importance: does not show in the shade.
- IMPORTANCE_MIN = 1; // Minimum to show in the shade.
- IMPORTANCE_LOW = 2; // Shows in shade, maybe status bar, no buzz/beep.
- IMPORTANCE_DEFAULT = 3; // Shows everywhere, makes noise, no heads-up.
- IMPORTANCE_HIGH = 4; // Shows everywhere, makes noise, heads-up, may full-screen.
- IMPORTANCE_IMPORTANT_CONVERSATION = 5; // High + isImportantConversation().
-}
diff --git a/core/proto/android/stats/textclassifier/Android.bp b/core/proto/android/stats/textclassifier/Android.bp
deleted file mode 100644
index bf90227..0000000
--- a/core/proto/android/stats/textclassifier/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "textclassifierprotoslite",
- proto: {
- type: "lite",
- },
- srcs: [
- "*.proto",
- ],
-}
\ No newline at end of file
diff --git a/core/proto/android/stats/textclassifier/textclassifier_enums.proto b/core/proto/android/stats/textclassifier/textclassifier_enums.proto
deleted file mode 100644
index 4be7b7c..0000000
--- a/core/proto/android/stats/textclassifier/textclassifier_enums.proto
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.textclassifier;
-option java_multiple_files = true;
-
-enum EventType {
- TYPE_UNKNOWN = 0;
- // User started a new selection.
- SELECTION_STARTED = 1;
- // User modified an existing selection.
- SELECTION_MODIFIED = 2;
- // Smart selection triggered for a single token (word).
- SMART_SELECTION_SINGLE = 3;
- // Smart selection triggered spanning multiple tokens (words).
- SMART_SELECTION_MULTI = 4;
- // Something else other than user or the default TextClassifier triggered a selection.
- AUTO_SELECTION = 5;
- // Smart actions shown to the user.
- ACTIONS_SHOWN = 6;
- // User clicked a link.
- LINK_CLICKED = 7;
- // User typed over the selection.
- OVERTYPE = 8;
- // User clicked on Copy action.
- COPY_ACTION = 9;
- // User clicked on Paste action.
- PASTE_ACTION = 10;
- // User clicked on Cut action.
- CUT_ACTION = 11;
- // User clicked on Share action.
- SHARE_ACTION = 12;
- // User clicked on a Smart action.
- SMART_ACTION = 13;
- // User dragged+dropped the selection.
- SELECTION_DRAG = 14;
- // Selection is destroyed.
- SELECTION_DESTROYED = 15;
- // User clicked on a custom action.
- OTHER_ACTION = 16;
- // User clicked on Select All action
- SELECT_ALL = 17;
- // User reset the smart selection.
- SELECTION_RESET = 18;
- // User composed a reply.
- MANUAL_REPLY = 19;
- // TextClassifier generated some actions
- ACTIONS_GENERATED = 20;
- // Some text links were generated
- LINKS_GENERATED = 21;
-}
-
-enum WidgetType {
- WIDGET_TYPE_UNKNOWN = 0;
- // Standard TextView
- WIDGET_TYPE_TEXTVIEW = 1;
- // EditText
- WIDGET_TYPE_EDITTEXT = 2;
- // Not selectable textview
- WIDGET_TYPE_UNSELECTABLE_TEXTVIEW = 3;
- // Standard Webview
- WIDGET_TYPE_WEBVIEW = 4;
- // Editable TextView
- WIDGET_TYPE_EDIT_WEBVIEW = 5;
- // Custom text widget
- WIDGET_TYPE_CUSTOM_TEXTVIEW = 6;
- // Custom editable text widget.
- WIDGET_TYPE_CUSTOM_EDITTEXT = 7;
- // Non-selectable text widget.
- WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW = 8;
- // Notification
- WIDGET_TYPE_NOTIFICATION = 9;
-}
diff --git a/core/proto/android/telecomm/enums.proto b/core/proto/android/telecomm/enums.proto
deleted file mode 100644
index 5ca4a85..0000000
--- a/core/proto/android/telecomm/enums.proto
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.telecom;
-
-option java_outer_classname = "TelecomProtoEnums";
-option java_multiple_files = true;
-
-/**
- * Call states, primarily used in CallState.java,
- * Call.java, and CallsManager.java in packages/services.
- */
-enum CallStateEnum {
- /**
- * Indicates that a call is new and not connected. This is used as the default state internally
- * within Telecom and should not be used between Telecom and call services. Call services are
- * not expected to ever interact with NEW calls, but {@link android.telecom.InCallService}s will
- * see calls in this state.
- */
- NEW = 0;
-
- /**
- * The initial state of an outgoing {@code Call}.
- * Common transitions are to {@link #DIALING} state for a successful call or
- * {@link #DISCONNECTED} if it failed.
- */
- CONNECTING = 1;
-
- /**
- * The state of an outgoing {@code Call} when waiting on user to select a
- * {@link android.telecom.PhoneAccount} through which to place the call.
- */
- SELECT_PHONE_ACCOUNT = 2;
-
- /**
- * Indicates that a call is outgoing and in the dialing state. A call transitions to this state
- * once an outgoing call has begun (e.g., user presses the dial button in Dialer). Calls in this
- * state usually transition to {@link #ACTIVE} if the call was answered or {@link #DISCONNECTED}
- * if the call was disconnected somehow (e.g., failure or cancellation of the call by the user).
- */
- DIALING = 3;
-
- /**
- * Indicates that a call is incoming and the user still has the option of answering, rejecting,
- * or doing nothing with the call. This state is usually associated with some type of audible
- * ringtone. Normal transitions are to {@link #ACTIVE} if answered or {@link #DISCONNECTED}
- * otherwise.
- */
- RINGING = 4;
-
- /**
- * Indicates that a call is currently connected to another party and a communication channel is
- * open between them. The normal transition to this state is by the user answering a
- * {@link #DIALING} call or a {@link #RINGING} call being answered by the other party.
- */
- ACTIVE = 5;
-
- /**
- * Indicates that the call is currently on hold. In this state, the call is not terminated
- * but no communication is allowed until the call is no longer on hold. The typical transition
- * to this state is by the user putting an {@link #ACTIVE} call on hold by explicitly performing
- * an action, such as clicking the hold button.
- */
- ON_HOLD = 6;
-
- /**
- * Indicates that a call is currently disconnected. All states can transition to this state
- * by the call service giving notice that the connection has been severed. When the user
- * explicitly ends a call, it will not transition to this state until the call service confirms
- * the disconnection or communication was lost to the call service currently responsible for
- * this call (e.g., call service crashes).
- */
- DISCONNECTED = 7;
-
- /**
- * Indicates that the call was attempted (mostly in the context of outgoing, at least at the
- * time of writing) but cancelled before it was successfully connected.
- */
- ABORTED = 8;
-
- /**
- * Indicates that the call is in the process of being disconnected and will transition next
- * to a {@link #DISCONNECTED} state.
- * <p>
- * This state is not expected to be communicated from the Telephony layer, but will be reported
- * to the InCall UI for calls where disconnection has been initiated by the user but the
- * ConnectionService has confirmed the call as disconnected.
- */
- DISCONNECTING = 9;
-
- /**
- * Indicates that the call is in the process of being pulled to the local device.
- * <p>
- * This state should only be set on a call with
- * {@link android.telecom.Connection#PROPERTY_IS_EXTERNAL_CALL} and
- * {@link android.telecom.Connection#CAPABILITY_CAN_PULL_CALL}.
- */
- PULLING = 10;
-
- /**
- * Indicates that an incoming call has been answered by the in-call UI, but Telephony hasn't yet
- * set the call to active.
- */
- ANSWERED = 11;
-
- /**
- * Indicates that the call is undergoing audio processing by a different app in the background.
- * @see android.telecom.Call#STATE_AUDIO_PROCESSING
- */
- AUDIO_PROCESSING = 12;
-
- /**
- * Indicates that the call is in a fake ringing state.
- * @see android.telecom.Call#STATE_SIMULATED_RINGING
- */
- SIMULATED_RINGING = 13;
-}
-
-// Disconnect causes for a call. Primarily used by android/telecom/DisconnectCause.java
-enum DisconnectCauseEnum {
- /**
- * Disconnected because of an unknown or unspecified reason.
- */
- UNKNOWN = 0;
-
- /**
- * Disconnected because there was an error, such as a problem with the network.
- */
- ERROR = 1;
-
- /**
- * Disconnected because of a local user-initiated action, such as hanging up.
- */
- LOCAL = 2;
-
- /**
- * Disconnected because of a remote user-initiated action, such as the other party hanging up
- * up.
- */
- REMOTE = 3;
-
- /**
- * Disconnected because it has been canceled.
- */
- CANCELED = 4;
-
- /**
- * Disconnected because there was no response to an incoming call.
- */
- MISSED = 5;
-
- /**
- * Disconnected because the user rejected an incoming call.
- */
- REJECTED = 6;
-
- /**
- * Disconnected because the other party was busy.
- */
- BUSY = 7;
-
- /**
- * Disconnected because of a restriction on placing the call, such as dialing in airplane
- * mode.
- */
- RESTRICTED = 8;
-
- /**
- * Disconnected for reason not described by other disconnect codes.
- */
- OTHER = 9;
-
- /**
- * Disconnected because the connection manager did not support the call. The call will be tried
- * again without a connection manager. See {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
- */
- CONNECTION_MANAGER_NOT_SUPPORTED = 10;
-
- /**
- * Disconnected because the user did not locally answer the incoming call, but it was answered
- * on another device where the call was ringing.
- */
- ANSWERED_ELSEWHERE = 11;
-
- /**
- * Disconnected because the call was pulled from the current device to another device.
- */
- CALL_PULLED = 12;
-}
diff --git a/core/proto/android/telephony/enums.proto b/core/proto/android/telephony/enums.proto
deleted file mode 100644
index f14e3ed..0000000
--- a/core/proto/android/telephony/enums.proto
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.telephony;
-
-option java_outer_classname = "TelephonyProtoEnums";
-option java_multiple_files = true;
-
-enum CallBearerEnum {
- /** Call bearer is unknown or invalid */
- CALL_BEARER_UNKNOWN = 0;
-
- /** Call bearer is legacy CS */
- CALL_BEARER_CS = 1;
-
- /** Call bearer is IMS */
- CALL_BEARER_IMS = 2;
-}
-
-enum CallDirectionEnum {
- /** Call direction: unknown or invalid */
- CALL_DIRECTION_UNKNOWN = 0;
-
- /** Call direction: mobile originated (outgoing for this device) */
- CALL_DIRECTION_MO = 1;
-
- /** Call direction: mobile terminated (incoming for this device) */
- CALL_DIRECTION_MT = 2;
-}
-
-// Call setup duration buckets.
-// See com.android.internal.telephony.metrics.VoiceCallSessionStats for definition.
-enum CallSetupDurationEnum {
- CALL_SETUP_DURATION_UNKNOWN = 0;
- CALL_SETUP_DURATION_EXTREMELY_FAST = 1;
- CALL_SETUP_DURATION_ULTRA_FAST = 2;
- CALL_SETUP_DURATION_VERY_FAST = 3;
- CALL_SETUP_DURATION_FAST = 4;
- CALL_SETUP_DURATION_NORMAL = 5;
- CALL_SETUP_DURATION_SLOW = 6;
- CALL_SETUP_DURATION_VERY_SLOW = 7;
- CALL_SETUP_DURATION_ULTRA_SLOW = 8;
- CALL_SETUP_DURATION_EXTREMELY_SLOW = 9;
-}
-
-// Data conn. power states, primarily used by android/telephony/DataConnectionRealTimeInfo.java.
-enum DataConnectionPowerStateEnum {
- DATA_CONNECTION_POWER_STATE_LOW = 1;
- DATA_CONNECTION_POWER_STATE_MEDIUM = 2;
- DATA_CONNECTION_POWER_STATE_HIGH = 3;
- DATA_CONNECTION_POWER_STATE_UNKNOWN = 2147483647; // Java Integer.MAX_VALUE;
-}
-
-// Network type enums, primarily used by android/telephony/TelephonyManager.java.
-// Do not add negative types.
-enum NetworkTypeEnum {
- NETWORK_TYPE_UNKNOWN = 0;
- NETWORK_TYPE_GPRS = 1;
- NETWORK_TYPE_EDGE = 2;
- NETWORK_TYPE_UMTS = 3;
- NETWORK_TYPE_CDMA = 4;
- NETWORK_TYPE_EVDO_0 = 5;
- NETWORK_TYPE_EVDO_A = 6;
- NETWORK_TYPE_1XRTT = 7;
- NETWORK_TYPE_HSDPA = 8;
- NETWORK_TYPE_HSUPA = 9;
- NETWORK_TYPE_HSPA = 10;
- NETWORK_TYPE_IDEN = 11;
- NETWORK_TYPE_EVDO_B = 12;
- NETWORK_TYPE_LTE = 13;
- NETWORK_TYPE_EHRPD = 14;
- NETWORK_TYPE_HSPAP = 15;
- NETWORK_TYPE_GSM = 16;
- NETWORK_TYPE_TD_SCDMA = 17;
- NETWORK_TYPE_IWLAN = 18;
- NETWORK_TYPE_LTE_CA = 19;
- NETWORK_TYPE_NR = 20;
-}
-
-// Signal strength levels, primarily used by android/telephony/SignalStrength.java.
-enum SignalStrengthEnum {
- SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
- SIGNAL_STRENGTH_POOR = 1;
- SIGNAL_STRENGTH_MODERATE = 2;
- SIGNAL_STRENGTH_GOOD = 3;
- SIGNAL_STRENGTH_GREAT = 4;
-}
-
-enum ServiceStateEnum {
- /**
- * Normal operation condition, the phone is registered
- * with an operator either in home network or in roaming.
- */
- SERVICE_STATE_IN_SERVICE = 0;
-
- /**
- * Phone is not registered with any operator, the phone
- * can be currently searching a new operator to register to, or not
- * searching to registration at all, or registration is denied, or radio
- * signal is not available.
- */
- SERVICE_STATE_OUT_OF_SERVICE = 1;
-
- /**
- * The phone is registered and locked. Only emergency numbers are allowed. {@more}
- */
- SERVICE_STATE_EMERGENCY_ONLY = 2;
-
- /**
- * Radio of telephony is explicitly powered off.
- */
- SERVICE_STATE_POWER_OFF = 3;
-}
-
-enum SimStateEnum {
- SIM_STATE_UNKNOWN = 0;
- /** SIM card state: no SIM card is available in the device */
- SIM_STATE_ABSENT = 1;
- /** SIM card state: Locked: requires the user's SIM PIN to unlock */
- SIM_STATE_PIN_REQUIRED = 2;
- /** SIM card state: Locked: requires the user's SIM PUK to unlock */
- SIM_STATE_PUK_REQUIRED = 3;
- /** SIM card state: Locked: requires a network PIN to unlock */
- SIM_STATE_NETWORK_LOCKED = 4;
- /** SIM card state: Ready */
- SIM_STATE_READY = 5;
- /** SIM card state: SIM Card is NOT READY */
- SIM_STATE_NOT_READY = 6;
- /** SIM card state: SIM Card Error, permanently disabled */
- SIM_STATE_PERM_DISABLED = 7;
- /** SIM card state: SIM Card Error, present but faulty */
- SIM_STATE_CARD_IO_ERROR = 8;
- /** SIM card state: SIM Card restricted, present but not usable due to
- * carrier restrictions.
- */
- SIM_STATE_CARD_RESTRICTED = 9;
- /**
- * SIM card state: Loaded: SIM card applications have been loaded
- * @hide
- */
- SIM_STATE_LOADED = 10;
- /**
- * SIM card state: SIM Card is present
- * @hide
- */
- SIM_STATE_PRESENT = 11;
-}
diff --git a/core/proto/android/view/enums.proto b/core/proto/android/view/enums.proto
deleted file mode 100644
index 0172e78..0000000
--- a/core/proto/android/view/enums.proto
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.view;
-
-option java_outer_classname = "ViewProtoEnums";
-option java_multiple_files = true;
-
-// Screen states, primarily used by android/view/Display.java.
-enum DisplayStateEnum {
- // The display state is unknown.
- DISPLAY_STATE_UNKNOWN = 0;
- // The display state is off.
- DISPLAY_STATE_OFF = 1;
- // The display state is on.
- DISPLAY_STATE_ON = 2;
- // The display is dozing in a low power state; it is still on but is
- // optimized for showing system-provided content while the device is
- // non-interactive.
- DISPLAY_STATE_DOZE = 3;
- // The display is dozing in a suspended low power state; it is still on
- // but is optimized for showing static system-provided content while the
- // device is non-interactive.
- DISPLAY_STATE_DOZE_SUSPEND = 4;
- // The display is on and optimized for VR mode.
- DISPLAY_STATE_VR = 5;
- // The display is in a suspended full power state; it is still on but the
- // CPU is not updating it.
- DISPLAY_STATE_ON_SUSPEND = 6;
-}
-
-// Constants found in android.view.WindowManager.
-enum TransitionTypeEnum {
- TRANSIT_NONE = 0;
- TRANSIT_UNSET = -1;
- TRANSIT_ACTIVITY_OPEN = 6;
- TRANSIT_ACTIVITY_CLOSE = 7;
- TRANSIT_TASK_OPEN = 8;
- TRANSIT_TASK_CLOSE = 9;
- TRANSIT_TASK_TO_FRONT = 10;
- TRANSIT_TASK_TO_BACK = 11;
- TRANSIT_WALLPAPER_CLOSE = 12;
- TRANSIT_WALLPAPER_OPEN = 13;
- TRANSIT_WALLPAPER_INTRA_OPEN = 14;
- TRANSIT_WALLPAPER_INTRA_CLOSE = 15;
- TRANSIT_TASK_OPEN_BEHIND = 16;
- TRANSIT_TASK_IN_PLACE = 17;
- TRANSIT_ACTIVITY_RELAUNCH = 18;
- TRANSIT_DOCK_TASK_FROM_RECENTS = 19;
- TRANSIT_KEYGUARD_GOING_AWAY = 20;
- TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21;
- TRANSIT_KEYGUARD_OCCLUDE = 22;
- TRANSIT_KEYGUARD_UNOCCLUDE = 23;
- TRANSIT_TRANSLUCENT_ACTIVITY_OPEN = 24;
- TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE = 25;
- TRANSIT_CRASHING_ACTIVITY_CLOSE = 26;
-}
diff --git a/core/proto/android/wifi/enums.proto b/core/proto/android/wifi/enums.proto
deleted file mode 100644
index 315c579..0000000
--- a/core/proto/android/wifi/enums.proto
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.net.wifi;
-
-option java_outer_classname = "WifiProtoEnums";
-option java_multiple_files = true;
-
-/**
- * Wifi Lock modes, primarily used in
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiLockManager.java.
- */
-enum WifiModeEnum {
- /**
- * Deprecated.
- * Wi-Fi will be kept active, and will behave normally.
- */
- WIFI_MODE_FULL = 1 [deprecated=true];
-
- /**
- * Deprecated.
- * Wi-Fi will be kept active, but the only operation that will be supported is initiation of
- * scans, and the subsequent reporting of scan results.
- */
- WIFI_MODE_SCAN_ONLY = 2 [deprecated=true];
-
- /**
- * Wi-Fi will not go to power save.
- */
- WIFI_MODE_FULL_HIGH_PERF = 3;
-
- /**
- * Wi-Fi will operate with a priority to achieve low latency.
- */
- WIFI_MODE_FULL_LOW_LATENCY = 4;
-}
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 944f058..0012671 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -123,28 +123,28 @@
<string name="roamingText11" msgid="5245687407203281407">"Baner rominga je uključen"</string>
<string name="roamingText12" msgid="673537506362152640">"Baner rominga je isključen"</string>
<string name="roamingTextSearching" msgid="5323235489657753486">"Pretraživanje usluge"</string>
- <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Podešavanje pozivanja preko WiFi-ja nije uspelo"</string>
+ <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Podešavanje pozivanja preko WiFi-a nije uspelo"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="468830943567116703">"Da biste upućivali pozive i slali poruke preko WiFi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko WiFi-ja. (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ <item msgid="468830943567116703">"Da biste upućivali pozive i slali poruke preko WiFi-a, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko WiFi-a. (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
<item msgid="4795145070505729156">"Problem u vezi sa registrovanjem pozivanja preko Wi‑Fi-ja kod mobilnog operatera: <xliff:g id="CODE">%1$s</xliff:g>"</item>
</string-array>
<!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
<skip />
- <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> pozivanje preko WiFi-ja"</string>
- <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – pozivanje preko WiFi-ja"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> pozivanje preko WiFi-a"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – pozivanje preko WiFi-a"</string>
<string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN poziv"</string>
<string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN poziv"</string>
<string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> WiFi"</string>
- <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Pozivanje preko WiFi-ja | <xliff:g id="SPN">%s</xliff:g>"</string>
+ <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Pozivanje preko WiFi-a | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
- <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Pozivanje preko WiFi-ja"</string>
+ <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Pozivanje preko WiFi-a"</string>
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WiFi"</string>
- <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Pozivanje preko WiFi-ja"</string>
+ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Pozivanje preko WiFi-a"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Isključeno"</string>
- <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Pozivanje preko WiFi-ja"</string>
+ <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Pozivanje preko WiFi-a"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Poziv preko mobilne mreže"</string>
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Samo WiFi"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 1b143c8..b95cab1 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -795,7 +795,7 @@
<string name="orgTypeOther" msgid="5450675258408005553">"অন্যান্য"</string>
<string name="orgTypeCustom" msgid="1126322047677329218">"কাস্টম"</string>
<string name="relationTypeCustom" msgid="282938315217441351">"কাস্টম"</string>
- <string name="relationTypeAssistant" msgid="4057605157116589315">"Assistant"</string>
+ <string name="relationTypeAssistant" msgid="4057605157116589315">"অ্যাসিস্ট্যান্ট"</string>
<string name="relationTypeBrother" msgid="7141662427379247820">"ভাই"</string>
<string name="relationTypeChild" msgid="9076258911292693601">"সন্তান"</string>
<string name="relationTypeDomesticPartner" msgid="7825306887697559238">"জীবনসাথি"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 0bd6353..6fefb23 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -947,7 +947,7 @@
<string name="autofill_district" msgid="6428712062213557327">"Districte"</string>
<string name="autofill_department" msgid="9047276226873531529">"Departament"</string>
<string name="autofill_prefecture" msgid="7267397763720241872">"Prefectura"</string>
- <string name="autofill_parish" msgid="6847960518334530198">"Districte"</string>
+ <string name="autofill_parish" msgid="6847960518334530198">"Parròquia"</string>
<string name="autofill_area" msgid="8289022370678448983">"Àrea"</string>
<string name="autofill_emirate" msgid="2544082046790551168">"Emirat"</string>
<string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"lectura dels marcadors i l\'historial web"</string>
@@ -1219,8 +1219,8 @@
<string name="volume_music" msgid="7727274216734955095">"Volum de multimèdia"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"S\'està reproduint per Bluetooth"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"S\'ha establert el so de silenci"</string>
- <string name="volume_call" msgid="7625321655265747433">"Volum en trucada"</string>
- <string name="volume_bluetooth_call" msgid="2930204618610115061">"Volum en trucada per Bluetooth"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Volum a la trucada"</string>
+ <string name="volume_bluetooth_call" msgid="2930204618610115061">"Volum a la trucada per Bluetooth"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Volum d\'alarma"</string>
<string name="volume_notification" msgid="6864412249031660057">"Volum de notificacions"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Volum"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1a51067..38cbde6 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -2044,7 +2044,7 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector del acceso directo de accesibilidad en pantalla"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Acceso directo de accesibilidad"</string>
<string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de subtítulos de <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Se colocó <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> en el depósito RESTRICTED"</string>
+ <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Se colocó <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> en el bucket RESTRICTED"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"envió una imagen"</string>
<string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversación"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 1529f13..d2a16e3 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1629,7 +1629,7 @@
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Al mantener pulsadas ambas teclas de volumen durante unos segundos se activa <xliff:g id="SERVICE">%1$s</xliff:g>, una función de accesibilidad. Esta función puede modificar el funcionamiento del dispositivo.\n\nPuedes asignar este acceso directo a otra función en Ajustes > Accesibilidad."</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"Activar"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"No activar"</string>
- <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SÍ"</string>
+ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVADO"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NO"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"¿Permitir que <xliff:g id="SERVICE">%1$s</xliff:g> pueda controlar totalmente tu dispositivo?"</string>
<string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si activas <xliff:g id="SERVICE">%1$s</xliff:g>, el dispositivo no utilizará el bloqueo de pantalla para mejorar el cifrado de datos."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 6b5741c..d26bccd 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1216,7 +1216,7 @@
<string name="dump_heap_ready_text" msgid="5849618132123045516">"Protsessi <xliff:g id="PROC">%1$s</xliff:g> mälutõmmis on jagamiseks saadaval. Olge ettevaatlik: see mälutõmmis võib sisaldada tundlikke isiklikke andmeid, millele protsessil on juurdepääs. See võib hõlmata teie sisestatud teavet."</string>
<string name="sendText" msgid="493003724401350724">"Valige teksti jaoks toiming"</string>
<string name="volume_ringtone" msgid="134784084629229029">"Helina helitugevus"</string>
- <string name="volume_music" msgid="7727274216734955095">"Meediumi helitugevus"</string>
+ <string name="volume_music" msgid="7727274216734955095">"Meedia helitugevus"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Esitatakse Bluetoothi kaudu"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Valitud on hääletu märguanne"</string>
<string name="volume_call" msgid="7625321655265747433">"Kõne helitugevus"</string>
@@ -1227,7 +1227,7 @@
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Bluetoothi maht"</string>
<string name="volume_icon_description_ringer" msgid="2187800636867423459">"Helina tugevus"</string>
<string name="volume_icon_description_incall" msgid="4491255105381227919">"Kõne helitugevus"</string>
- <string name="volume_icon_description_media" msgid="4997633254078171233">"Meediumi helitugevus"</string>
+ <string name="volume_icon_description_media" msgid="4997633254078171233">"Meedia helitugevus"</string>
<string name="volume_icon_description_notification" msgid="579091344110747279">"Teatise helitugevus"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Vaikehelin"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Vaikimisi (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 11af9f2..0903e00 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -589,9 +589,9 @@
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"لطفاً چهرهتان را مجدداً ثبت کنید."</string>
<string name="face_acquired_too_different" msgid="4699657338753282542">"دیگر چهره را تشخیص نمیدهد. دوباره امتحان کنید."</string>
<string name="face_acquired_too_similar" msgid="7684650785108399370">"بسیار شبیه قبلی است، لطفاً قیافه دیگری بگیرید."</string>
- <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"سرتان را کمی پایین آورید."</string>
- <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"سرتان را کمی پایین آورید."</string>
- <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"سرتان را کمی پایین آورید."</string>
+ <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"سرتان را کمی صاف بگیرید."</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"سرتان را کمی صاف بگیرید."</string>
+ <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"سرتان را کمی صاف بگیرید."</string>
<string name="face_acquired_obscured" msgid="4917643294953326639">"هرچیزی را که حائل چهرهتان است بردارید."</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"بالای صفحه و همچنین نوار مشکی را تمیز کنید."</string>
<string-array name="face_acquired_vendor">
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index aee6739..2294a69 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1792,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Järjestelmänvalvoja päivitti tämän."</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Järjestelmänvalvoja poisti tämän."</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Parantaakseen akunkestoa Virransäästö\n\n•·laittaa tumman teeman päälle\n•·laittaa pois päältä tai rajoittaa taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. Hei Google).\n\n"<annotation id="url">"Lue lisää"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"Parantaakseen akunkestoa Virransäästö\n\n•·laittaa tumman teeman päälle\n•·laittaa pois päältä tai rajoittaa taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. Hei Google)."</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Parantaakseen akunkestoa Virransäästö\n\n•·laittaa tumman teeman päälle\n•·laittaa pois päältä tai rajoittaa taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. OK Google).\n\n"<annotation id="url">"Lue lisää"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"Parantaakseen akunkestoa Virransäästö\n\n•·laittaa tumman teeman päälle\n•·laittaa pois päältä tai rajoittaa taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. OK Google)."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Data Saver estää joitakin sovelluksia lähettämästä tai vastaanottamasta tietoja taustalla, jotta datan käyttöä voidaan vähentää. Käytössäsi oleva sovellus voi yhä käyttää dataa, mutta se saattaa tehdä niin tavallista harvemmin. Tämä voi tarkoittaa esimerkiksi sitä, että kuva ladataan vasta, kun kosketat sitä."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Otetaanko Data Saver käyttöön?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Ota käyttöön"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 2b42c12..9d6105f 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -52,6 +52,7 @@
<string name="enablePin" msgid="2543771964137091212">"Opération infructueuse. Activez le verrouillage SIM/RUIM."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
<item quantity="one">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM soit verrouillée.</item>
+ <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
<item quantity="other">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM soit verrouillée.</item>
</plurals>
<string name="imei" msgid="2157082351232630390">"Code IIEM"</string>
@@ -179,6 +180,7 @@
<string name="low_memory" product="default" msgid="2539532364144025569">"La mémoire du téléphone est pleine. Veuillez supprimer des fichiers pour libérer de l\'espace."</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
<item quantity="one">Autorité de certification installée</item>
+ <item quantity="many">Certificate authorities installed</item>
<item quantity="other">Autorités de certification installées</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Par un tiers inconnu"</string>
@@ -251,6 +253,7 @@
<string name="bugreport_option_full_summary" msgid="1975130009258435885">"Utilisez cette option pour qu\'il y ait le moins d\'interférences système possible lorsque votre appareil ne répond pas ou qu\'il est trop lent, ou lorsque vous avez besoin de toutes les sections du rapport de bogue. Aucune capture d\'écran supplémentaire ne peut être capturée, et vous ne pouvez entrer aucune autre information."</string>
<plurals name="bugreport_countdown" formatted="false" msgid="3906120379260059206">
<item quantity="one">Saisie d\'écran pour le rapport de bogue dans <xliff:g id="NUMBER_1">%d</xliff:g> seconde.</item>
+ <item quantity="many">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
<item quantity="other">Saisie d\'écran pour le rapport de bogue dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes.</item>
</plurals>
<string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Capture d\'écran prise avec le rapport de bogue"</string>
@@ -683,9 +686,9 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"Verrouiller l\'écran"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Gérer le mode et les conditions de verrouillage de l\'écran"</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Effacer toutes les données"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Effacer les données de la tablette sans avertissement, en rétablissant la configuration d\'usine"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Effacer les données de la tablette sans avertissement, en rétablissant les paramètres par défaut"</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Effacez les données de votre appareil Android TV sans avertissement en effectuant une réinitialisation des paramètres d\'usine."</string>
- <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Effacer les données du téléphone sans avertissement, en rétablissant la configuration d\'usine"</string>
+ <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Effacer les données du téléphone sans avertissement en rétablissant les paramètres par défaut"</string>
<string name="policylab_wipeData_secondaryUser" msgid="413813645323433166">"Effacer les données de l\'utilisateur"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Effacer les données de l\'utilisateur sur cette tablette sans avertissement."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Effacez les données de cet utilisateur sur cet appareil Android TV sans avertissement."</string>
@@ -863,12 +866,12 @@
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%2$d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre tablette à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Vous avez dessiné votre schéma de déverrouillage incorrectement à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprise(s). Après <xliff:g id="NUMBER_1">%2$d</xliff:g> autre(s) tentative(s) incorrecte(s), vous devrez déverrouiller votre appareil Android TV en vous connectant à votre compte Google.\n\n Réessayez dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%2$d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre téléphone à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ses paramètres par défaut seront rétablis, et toutes les données d\'utilisateur seront perdues."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Vous avez tenté de déverrouiller votre appareil Android TV incorrectement à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprise(s). Après <xliff:g id="NUMBER_1">%2$d</xliff:g> autre(s) tentative(s) incorrecte(s), votre appareil Android TV sera réinitialisé à ses valeurs d\'usine et toutes les données personnelles seront supprimées."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ses paramètres par défaut seront rétablis, et toutes les données d\'utilisateur seront perdues."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Ses paramètres par défaut vont être rétablis."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Vous avez tenté de déverrouiller votre appareil Android TV incorrectement à <xliff:g id="NUMBER">%d</xliff:g> reprise(s). Votre appareil Android TV sera maintenant réinitialisé à ses valeurs d\'usine."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Ses paramètres par défaut vont être rétablis."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Veuillez réessayer dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Schéma oublié?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Déverrouillage du compte"</string>
@@ -994,6 +997,7 @@
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Il y a plus d\'un mois"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
<item quantity="one">Le dernier <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="many">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item>
<item quantity="other">Le dernier <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
</plurals>
<string name="last_month" msgid="1528906781083518683">"Le mois dernier"</string>
@@ -1016,66 +1020,82 @@
<string name="now_string_shortest" msgid="3684914126941650330">"maintenant"</string>
<plurals name="duration_minutes_shortest" formatted="false" msgid="7519574894537185135">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
</plurals>
<plurals name="duration_hours_shortest" formatted="false" msgid="2838655994500499651">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
</plurals>
<plurals name="duration_days_shortest" formatted="false" msgid="3686058472983158496">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
</plurals>
<plurals name="duration_years_shortest" formatted="false" msgid="8299112348723640338">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_shortest_future" formatted="false" msgid="849196137176399440">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>m</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
</plurals>
<plurals name="duration_hours_shortest_future" formatted="false" msgid="5386373597343170388">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>h</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
</plurals>
<plurals name="duration_days_shortest_future" formatted="false" msgid="814754627092787227">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>d</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
</plurals>
<plurals name="duration_years_shortest_future" formatted="false" msgid="7683731800140202145">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_relative" formatted="false" msgid="6569851308583028344">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> minutes ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
</plurals>
<plurals name="duration_hours_relative" formatted="false" msgid="420434788589102019">
<item quantity="one">il y a<xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> hours ago</item>
<item quantity="other">il y a<xliff:g id="COUNT_1">%d</xliff:g> heures</item>
</plurals>
<plurals name="duration_days_relative" formatted="false" msgid="6056425878237482431">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> days ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
</plurals>
<plurals name="duration_years_relative" formatted="false" msgid="2179998228861172159">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> an</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
</plurals>
<plurals name="duration_minutes_relative_future" formatted="false" msgid="5759885720917567723">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
</plurals>
<plurals name="duration_hours_relative_future" formatted="false" msgid="8963511608507707959">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
</plurals>
<plurals name="duration_days_relative_future" formatted="false" msgid="1964709470979250702">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
</plurals>
<plurals name="duration_years_relative_future" formatted="false" msgid="3985129025134896371">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
</plurals>
<string name="VideoView_error_title" msgid="5750686717225068016">"Problème vidéo"</string>
@@ -1446,6 +1466,7 @@
<string name="find_on_page" msgid="5400537367077438198">"Rechercher sur la page"</string>
<plurals name="matches_found" formatted="false" msgid="1101758718194295554">
<item quantity="one"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
+ <item quantity="many"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item>
<item quantity="other"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
</plurals>
<string name="action_mode_done" msgid="2536182504764803222">"Terminé"</string>
@@ -1582,6 +1603,7 @@
<string name="kg_wrong_pin" msgid="3680925703673166482">"NIP incorrect."</string>
<plurals name="kg_too_many_failed_attempts_countdown" formatted="false" msgid="236717428673283568">
<item quantity="one">Réessayer dans <xliff:g id="NUMBER">%d</xliff:g> seconde.</item>
+ <item quantity="many">Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds.</item>
<item quantity="other">Réessayer dans <xliff:g id="NUMBER">%d</xliff:g> secondes.</item>
</plurals>
<string name="kg_pattern_instructions" msgid="8366024510502517748">"Dessinez votre schéma."</string>
@@ -1608,12 +1630,12 @@
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Vous avez saisi un NIP incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ses paramètres par défaut seront rétablis, et toutes les données d\'utilisateur seront perdues."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Vous avez tenté de déverrouiller votre appareil Android TV incorrectement à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprise(s). Après <xliff:g id="NUMBER_1">%2$d</xliff:g> autre(s) tentative(s) incorrecte(s), votre appareil Android TV sera réinitialisé à ses valeurs d\'usine et toutes les données personnelles seront supprimées."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ses paramètres par défaut seront rétablis, et toutes les données d\'utilisateur seront perdues."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Ses paramètres par défaut vont être rétablis."</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Vous avez tenté de déverrouiller votre appareil Android TV incorrectement à <xliff:g id="NUMBER">%d</xliff:g> reprise(s). Votre appareil Android TV sera maintenant réinitialisé à ses valeurs d\'usine."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Ses paramètres par défaut vont être rétablis."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Vous avez dessiné votre schéma de déverrouillage incorrectement à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprise(s). Après <xliff:g id="NUMBER_1">%2$d</xliff:g> autre(s) tentative(s) incorrecte(s), vous devrez déverrouiller votre appareil Android TV à l\'aide d\'un compte de courriel.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
@@ -1768,6 +1790,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Le NIP est trop court. Il doit comporter au moins 4 chiffres."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
<item quantity="one">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> seconde</item>
+ <item quantity="many">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
<item quantity="other">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> secondes</item>
</plurals>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Réessayez plus tard"</string>
@@ -1799,34 +1822,42 @@
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activer"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
<item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="4230730310318858312">
<item quantity="one">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d min (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="7725354244196466758">
<item quantity="one">Pendant %1$d heure (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d heures (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="588719069121765642">
<item quantity="one">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d hr (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="1148568456958944998">
<item quantity="one">Pendant %d minute</item>
+ <item quantity="many">For %d minutes</item>
<item quantity="other">Pendant %d minutes</item>
</plurals>
<plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2742377799995454859">
<item quantity="one">Pendant %d min</item>
+ <item quantity="many">For %d min</item>
<item quantity="other">Pendant %d min</item>
</plurals>
<plurals name="zen_mode_duration_hours" formatted="false" msgid="525401855645490022">
<item quantity="one">Pendant %d heure</item>
+ <item quantity="many">For %d hours</item>
<item quantity="other">Pendant %d heures</item>
</plurals>
<plurals name="zen_mode_duration_hours_short" formatted="false" msgid="7644653189680911640">
<item quantity="one">Pendant %d h</item>
+ <item quantity="many">For %d hr</item>
<item quantity="other">Pendant %d h</item>
</plurals>
<string name="zen_mode_until" msgid="2250286190237669079">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
@@ -1842,7 +1873,7 @@
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Événement"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sommeil"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> désactive certains sons"</string>
- <string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à sa configuration d\'usine."</string>
+ <string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à ses paramètres par défaut."</string>
<string name="system_error_manufacturer" msgid="703545241070116315">"Un problème interne est survenu avec votre appareil. Communiquez avec le fabricant pour obtenir plus de détails."</string>
<string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"La demande USSD a été remplacée par une demande d\'appel régulier"</string>
<string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"La demande USSD a été remplacée par une demande SS"</string>
@@ -1867,6 +1898,7 @@
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
</plurals>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
@@ -1934,6 +1966,7 @@
<string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Aucune suggestion de remplissage automatique"</string>
<plurals name="autofill_picker_some_suggestions" formatted="false" msgid="6651883186966959978">
<item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> suggestion de remplissage automatique</item>
+ <item quantity="many"><xliff:g id="COUNT">%1$s</xliff:g> autofill suggestions</item>
<item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> suggestions de remplissage automatique</item>
</plurals>
<string name="autofill_save_title" msgid="7719802414283739775">"Enregistrer sous "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
@@ -2027,6 +2060,7 @@
<string name="car_loading_profile" msgid="8219978381196748070">"Chargement en cours…"</string>
<plurals name="file_count" formatted="false" msgid="7063513834724389247">
<item quantity="one"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichier</item>
+ <item quantity="many"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> files</item>
<item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichiers</item>
</plurals>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index d4978c3..6441b04 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -52,6 +52,7 @@
<string name="enablePin" msgid="2543771964137091212">"Échec de l\'opération. Veuillez activer le verrouillage de la carte SIM/RUIM."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
<item quantity="one">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM ne soit verrouillée.</item>
+ <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
<item quantity="other">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM ne soit verrouillée.</item>
</plurals>
<string name="imei" msgid="2157082351232630390">"Code IMEI"</string>
@@ -179,6 +180,7 @@
<string name="low_memory" product="default" msgid="2539532364144025569">"La mémoire du téléphone est pleine. Veuillez supprimer des fichiers pour libérer de l\'espace."</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
<item quantity="one">Autorité de certification installée</item>
+ <item quantity="many">Certificate authorities installed</item>
<item quantity="other">Autorités de certification installées</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Par un tiers inconnu"</string>
@@ -251,6 +253,7 @@
<string name="bugreport_option_full_summary" msgid="1975130009258435885">"Utilisez cette option pour qu\'il y ait le moins d\'interférences système possible lorsque votre appareil ne répond pas ou qu\'il est trop lent, ou lorsque vous avez besoin de toutes les sections du rapport de bug. Aucune capture d\'écran supplémentaire ne peut être prise, et vous ne pouvez saisir aucune autre information."</string>
<plurals name="bugreport_countdown" formatted="false" msgid="3906120379260059206">
<item quantity="one">Capture d\'écran pour le rapport de bug dans <xliff:g id="NUMBER_1">%d</xliff:g> seconde</item>
+ <item quantity="many">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
<item quantity="other">Capture d\'écran pour le rapport de bug dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes</item>
</plurals>
<string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Capture d\'écran avec rapport de bug effectuée"</string>
@@ -994,6 +997,7 @@
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Il y a plus d\'un mois"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
<item quantity="one">Le dernier jour (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="many">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item>
<item quantity="other">Les <xliff:g id="COUNT_1">%d</xliff:g> derniers jours</item>
</plurals>
<string name="last_month" msgid="1528906781083518683">"Le mois dernier"</string>
@@ -1016,66 +1020,82 @@
<string name="now_string_shortest" msgid="3684914126941650330">"mainten."</string>
<plurals name="duration_minutes_shortest" formatted="false" msgid="7519574894537185135">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
</plurals>
<plurals name="duration_hours_shortest" formatted="false" msgid="2838655994500499651">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
</plurals>
<plurals name="duration_days_shortest" formatted="false" msgid="3686058472983158496">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
</plurals>
<plurals name="duration_years_shortest" formatted="false" msgid="8299112348723640338">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_shortest_future" formatted="false" msgid="849196137176399440">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>m</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
</plurals>
<plurals name="duration_hours_shortest_future" formatted="false" msgid="5386373597343170388">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>h</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
</plurals>
<plurals name="duration_days_shortest_future" formatted="false" msgid="814754627092787227">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>d</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
</plurals>
<plurals name="duration_years_shortest_future" formatted="false" msgid="7683731800140202145">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_relative" formatted="false" msgid="6569851308583028344">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> minutes ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
</plurals>
<plurals name="duration_hours_relative" formatted="false" msgid="420434788589102019">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> hours ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
</plurals>
<plurals name="duration_days_relative" formatted="false" msgid="6056425878237482431">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> days ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
</plurals>
<plurals name="duration_years_relative" formatted="false" msgid="2179998228861172159">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> an</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
</plurals>
<plurals name="duration_minutes_relative_future" formatted="false" msgid="5759885720917567723">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
</plurals>
<plurals name="duration_hours_relative_future" formatted="false" msgid="8963511608507707959">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
</plurals>
<plurals name="duration_days_relative_future" formatted="false" msgid="1964709470979250702">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
</plurals>
<plurals name="duration_years_relative_future" formatted="false" msgid="3985129025134896371">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> an</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
</plurals>
<string name="VideoView_error_title" msgid="5750686717225068016">"Problème vidéo"</string>
@@ -1231,7 +1251,7 @@
<string name="volume_icon_description_notification" msgid="579091344110747279">"Volume des notifications"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Sonnerie par défaut"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Sonnerie par défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="397111123930141876">"Aucun(e)"</string>
+ <string name="ringtone_silent" msgid="397111123930141876">"Aucun"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"Sonneries"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Sons de l\'alarme"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Sons de notification"</string>
@@ -1446,6 +1466,7 @@
<string name="find_on_page" msgid="5400537367077438198">"Rechercher sur la page"</string>
<plurals name="matches_found" formatted="false" msgid="1101758718194295554">
<item quantity="one"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
+ <item quantity="many"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item>
<item quantity="other"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
</plurals>
<string name="action_mode_done" msgid="2536182504764803222">"OK"</string>
@@ -1582,6 +1603,7 @@
<string name="kg_wrong_pin" msgid="3680925703673166482">"Code PIN incorrect."</string>
<plurals name="kg_too_many_failed_attempts_countdown" formatted="false" msgid="236717428673283568">
<item quantity="one">Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> seconde.</item>
+ <item quantity="many">Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds.</item>
<item quantity="other">Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes.</item>
</plurals>
<string name="kg_pattern_instructions" msgid="8366024510502517748">"Dessinez votre schéma."</string>
@@ -1768,6 +1790,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Le code PIN est trop court. Il doit comporter au moins 4 chiffres."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
<item quantity="one">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> seconde</item>
+ <item quantity="many">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
<item quantity="other">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> secondes</item>
</plurals>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Veuillez réessayer ultérieurement."</string>
@@ -1799,34 +1822,42 @@
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activer"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
<item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="4230730310318858312">
<item quantity="one">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d min (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="7725354244196466758">
<item quantity="one">Pendant %1$d heure (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d heures (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="588719069121765642">
<item quantity="one">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d hr (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="1148568456958944998">
<item quantity="one">Pendant %d minute</item>
+ <item quantity="many">For %d minutes</item>
<item quantity="other">Pendant %d minutes</item>
</plurals>
<plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2742377799995454859">
<item quantity="one">Pendant %d min</item>
+ <item quantity="many">For %d min</item>
<item quantity="other">Pendant %d min</item>
</plurals>
<plurals name="zen_mode_duration_hours" formatted="false" msgid="525401855645490022">
<item quantity="one">Pendant %d heure</item>
+ <item quantity="many">For %d hours</item>
<item quantity="other">Pendant %d heures</item>
</plurals>
<plurals name="zen_mode_duration_hours_short" formatted="false" msgid="7644653189680911640">
<item quantity="one">Pendant %d h</item>
+ <item quantity="many">For %d hr</item>
<item quantity="other">Pendant %d h</item>
</plurals>
<string name="zen_mode_until" msgid="2250286190237669079">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
@@ -1867,6 +1898,7 @@
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
</plurals>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
@@ -1934,6 +1966,7 @@
<string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Aucune suggestion de saisie automatique"</string>
<plurals name="autofill_picker_some_suggestions" formatted="false" msgid="6651883186966959978">
<item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> suggestion de saisie automatique</item>
+ <item quantity="many"><xliff:g id="COUNT">%1$s</xliff:g> autofill suggestions</item>
<item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> suggestions de saisie automatique</item>
</plurals>
<string name="autofill_save_title" msgid="7719802414283739775">"Enregistrer dans "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ?"</string>
@@ -2027,6 +2060,7 @@
<string name="car_loading_profile" msgid="8219978381196748070">"Chargement…"</string>
<plurals name="file_count" formatted="false" msgid="7063513834724389247">
<item quantity="one"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichier</item>
+ <item quantity="many"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> files</item>
<item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichiers</item>
</plurals>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index e4ac021..b3259e5 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1587,7 +1587,7 @@
<string name="kg_pattern_instructions" msgid="8366024510502517748">"Debuxa o teu padrón"</string>
<string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Introduce o PIN da tarxeta SIM"</string>
<string name="kg_pin_instructions" msgid="7355933174673539021">"Introduce o PIN"</string>
- <string name="kg_password_instructions" msgid="7179782578809398050">"Insire o teu contrasinal"</string>
+ <string name="kg_password_instructions" msgid="7179782578809398050">"Escribe o teu contrasinal"</string>
<string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"Agora a tarxeta SIM está desactivada. Introduce o código PUK para continuar. Ponte en contacto co operador para obter información detallada."</string>
<string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Introduce o código PIN desexado"</string>
<string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Confirma o código PIN desexado"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index b3d704d..c81f90c 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -189,7 +189,7 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"આ ઉપકરણ પર તમારી કાર્યાલયની પ્રોફાઇલ હવે ઉપલબ્ધ નથી"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"પાસવર્ડના ઘણા વધુ પ્રયત્નો"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"વ્યવસ્થાપકે ડિવાઇસ વ્યક્તિગત ઉપયોગ માટે આપી દીધું છે"</string>
- <string name="network_logging_notification_title" msgid="554983187553845004">"ઉપકરણ સંચાલિત છે"</string>
+ <string name="network_logging_notification_title" msgid="554983187553845004">"ડિવાઇસ મેનેજ થયેલ છે"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"તમારી સંસ્થા આ ઉપકરણનું સંચાલન કરે છે અને નેટવર્ક ટ્રાફિફનું નિયમન કરી શકે છે. વિગતો માટે ટૅપ કરો."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ઍપ તમારા સ્થાનને ઍક્સેસ કરી શકે છે"</string>
<string name="location_changed_notification_text" msgid="7158423339982706912">"વધુ જાણવા માટે તમારા IT વ્યવસ્થાપકનો સંપર્ક કરો"</string>
@@ -312,7 +312,7 @@
<string name="permgrouplab_calllog" msgid="7926834372073550288">"કૉલ લૉગ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ફોન કૉલ લૉગ વાંચો અને લખો"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ફોન"</string>
- <string name="permgroupdesc_phone" msgid="270048070781478204">"ફોન કૉલ કરો અને સંચાલિત કરો"</string>
+ <string name="permgroupdesc_phone" msgid="270048070781478204">"ફોન કૉલ કરો અને મેનેજ કરો"</string>
<string name="permgrouplab_sensors" msgid="9134046949784064495">"બૉડી સેન્સર"</string>
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"તમારા મહત્વપૂર્ણ ચિહ્નો વિશે સેન્સર ડેટા ઍક્સેસ કરો"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"વિંડો કન્ટેન્ટ પુનઃપ્રાપ્ત કરો"</string>
@@ -363,7 +363,7 @@
<string name="permdesc_receiveWapPush" msgid="1638677888301778457">"એપ્લિકેશનને WAP સંદેશા પ્રાપ્ત કરવાની અને તેના પર પ્રક્રિયા કરવાની મંજૂરી આપે છે. આ પરવાનગીમાં તમને દર્શાવ્યા વિના તમને મોકલેલ સંદેશાઓનું નિરીક્ષણ કરવાની અને કાઢી નાખવાની ક્ષમતાનો સમાવેશ થાય છે."</string>
<string name="permlab_getTasks" msgid="7460048811831750262">"ચાલુ ઍપ્લિકેશનો પુનઃપ્રાપ્ત કરો"</string>
<string name="permdesc_getTasks" msgid="7388138607018233726">"એપ્લિકેશનને વર્તમાનમાં અને તાજેતરમાં ચાલી રહેલ Tasks વિશેની વિગતવાર માહિતી પુનઃપ્રાપ્ત કરવાની મંજૂરી આપે છે. આ એપ્લિકેશનને ઉપકરણ પર કઈ એપ્લિકેશન્સનો ઉપયોગ થાય છે તેના વિશેની માહિતી શોધવાની મંજૂરી આપી શકે છે."</string>
- <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"પ્રોફાઇલ અને ઉપકરણ માલિકોને સંચાલિત કરો"</string>
+ <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"પ્રોફાઇલ અને ડિવાઇસ માલિકોને મેનેજ કરો"</string>
<string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"એપ્લિકેશન્સને પ્રોફાઇલ માલિકો અને ઉપકરણ માલિકો સેટ કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_reorderTasks" msgid="7598562301992923804">"ચાલુ એપ્લિકેશન્સને ફરી ગોઠવો"</string>
<string name="permdesc_reorderTasks" msgid="8796089937352344183">"ઍપ્લિકેશનને અગ્રભૂમિ અને પૃષ્ટભૂમિમાં Tasks ખસેડવાની મંજૂરી આપે છે. તમારા ઇનપુટ વિના ઍપ્લિકેશન આ કરી શકે છે."</string>
@@ -524,7 +524,7 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ઍપને સ્ક્રીન લૉકની જટિલતાનું લેવલ (ઊંચું, મધ્યમ, નીચું અથવા કોઈ નહીં) જાણવાની મંજૂરી આપે છે, જે સ્ક્રીન લૉકના પ્રકાર અને લંબાઈની સંભવિત શ્રેણી સૂચવે છે. ઍપ વપરાશકર્તાઓને સ્ક્રીન લૉકને ચોક્કસ લેવલ સુધી અપડેટ કરવાનું સૂચન પણ કરી શકે છે, પરંતુ વપરાશકર્તાઓ મુક્ત રીતે અવગણીને નૅવિગેટ કરી શકે છે. નોંધી લો કે સ્ક્રીન લૉકનો plaintextમાં સંગ્રહ કરવામાં આવતો નથી, તેથી ઍપને ચોક્કસ પાસવર્ડની જાણ હોતી નથી."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરો"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"ઍપને પ્રમાણીકરણ માટે બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
- <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ફિંગરપ્રિન્ટ હાર્ડવેરને સંચાલિત કરો"</string>
+ <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ફિંગરપ્રિન્ટ હાર્ડવેરને મેનેજ કરો"</string>
<string name="permdesc_manageFingerprint" msgid="2025616816437339865">"ઍપને ઉપયોગ માટે ફિંગરપ્રિન્ટ નમૂના ઉમેરવા અને કાઢી નાખવા માટે પદ્ધતિઓની વિનંતી કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"ફિંગરપ્રિન્ટ હાર્ડવેરનો ઉપયોગ કરો"</string>
<string name="permdesc_useFingerprint" msgid="412463055059323742">"ઍપને પ્રમાણીકરણ માટે ફિંગરપ્રિન્ટ હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
@@ -627,8 +627,8 @@
<string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"એપ્લિકેશનને નવા ટેલિકોમ સિમ કનેક્શન્સની નોંધણી કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_register_call_provider" msgid="6135073566140050702">"નવા ટેલિકોમ કનેક્શન્સની નોંધણી કરો"</string>
<string name="permdesc_register_call_provider" msgid="4201429251459068613">"એપ્લિકેશનને નવા ટેલિકોમ કનેક્શન્સની નોંધણી કરવાની મંજૂરી આપે છે."</string>
- <string name="permlab_connection_manager" msgid="3179365584691166915">"ટેલિકોમ કનેક્શન્સ સંચાલિત કરો"</string>
- <string name="permdesc_connection_manager" msgid="1426093604238937733">"એપ્લિકેશનને ટેલીકોમ કનેક્શન્સને સંચાલિત કરવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_connection_manager" msgid="3179365584691166915">"ટેલિકોમ કનેક્શનને મેનેજ કરો"</string>
+ <string name="permdesc_connection_manager" msgid="1426093604238937733">"ઍપને ટેલિકોમ કનેક્શનને મેનેજ કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_bind_incall_service" msgid="5990625112603493016">"ઇન-કૉલ સ્ક્રીન વડે ક્રિયાપ્રતિક્રિયા કરો"</string>
<string name="permdesc_bind_incall_service" msgid="4124917526967765162">"વપરાશકર્તા ઇન-કૉલ સ્ર્કીન ક્યારે અને કેવી રીતે જુએ છે તે નિયંત્રિત કરવાની એપ્લિકેશનને મંજૂરી આપે છે."</string>
<string name="permlab_bind_connection_service" msgid="5409268245525024736">"ટેલિફોની સેવાઓ સાથે વાર્તાલાપ કરો"</string>
@@ -637,8 +637,8 @@
<string name="permdesc_control_incall_experience" msgid="5896723643771737534">"એપ્લિકેશનને કૉલમાં વપરાશકર્તા અનુભવ પ્રદાન કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"ઐતિહાસિક નેટવર્ક ઉપયોગ વાંચો"</string>
<string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"એપ્લિકેશનને ચોક્કસ નેટવર્ક્સ અને ઍપ્લિકેશનો માટે ઐતિહાસિક નેટવર્ક વપરાશ વાંચવાની મંજૂરી આપે છે."</string>
- <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"નેટવર્ક નીતિ સંચાલિત કરો"</string>
- <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"ઍપ્લિકેશનને નેટવર્ક નીતિઓ સંચાલિત કરવાની અને ઍપ્લિકેશન-વિશિષ્ટ નિયમો નિર્ધારિત કરવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"નેટવર્ક નીતિ મેનેજ કરો"</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"ઍપને નેટવર્ક નીતિઓ મેનેજ કરવાની અને ઍપ-વિશિષ્ટ નિયમો નિર્ધારિત કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"નેટવર્ક વપરાશ એકાઉન્ટિંગ સંશોધિત કરો"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"એપ્લિકેશનને કેવી રીતે ઍપ્લિકેશનો સામે નેટવર્ક વપરાશ ગણવામાં આવે છે તે સંશોધિત કરવાની મંજૂરી આપે છે. સામાન્ય ઍપ્લિકેશનો દ્વારા ઉપયોગમાં લેવા માટે નથી."</string>
<string name="permlab_accessNotifications" msgid="7130360248191984741">"ઍક્સેસ સૂચનાઓ"</string>
@@ -1426,8 +1426,8 @@
<string name="notification_ranker_binding_label" msgid="432708245635563763">"સૂચના રેંકર સેવા"</string>
<string name="vpn_title" msgid="5906991595291514182">"VPN સક્રિય કર્યું"</string>
<string name="vpn_title_long" msgid="6834144390504619998">"<xliff:g id="APP">%s</xliff:g> દ્વારા VPN સક્રિય થયું"</string>
- <string name="vpn_text" msgid="2275388920267251078">"નેટવર્કને સંચાલિત કરવા માટે ટૅપ કરો."</string>
- <string name="vpn_text_long" msgid="278540576806169831">"<xliff:g id="SESSION">%s</xliff:g> થી કનેક્ટ થયાં. નેટવર્કને સંચાલિત કરવા માટે ટૅપ કરો."</string>
+ <string name="vpn_text" msgid="2275388920267251078">"નેટવર્કને મેનેજ કરવા માટે ટૅપ કરો."</string>
+ <string name="vpn_text_long" msgid="278540576806169831">"<xliff:g id="SESSION">%s</xliff:g> થી કનેક્ટ થયાં. નેટવર્કને મેનેજ કરવા માટે ટૅપ કરો."</string>
<string name="vpn_lockdown_connecting" msgid="6096725311950342607">"હંમેશા-ચાલુ VPN કનેક્ટ થઈ રહ્યું છે…"</string>
<string name="vpn_lockdown_connected" msgid="2853127976590658469">"હંમેશા-ચાલુ VPN કનેક્ટ થયું"</string>
<string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"હંમેશાં-ચાલુ VPN થી ડિસ્કનેક્ટ થયું"</string>
@@ -1904,7 +1904,7 @@
<string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g>ને પિન કરો"</string>
<string name="unpin_target" msgid="3963318576590204447">"અનપિન કરો"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g>ને અનપિન કરો"</string>
- <string name="app_info" msgid="6113278084877079851">"ઍપ્લિકેશન માહિતી"</string>
+ <string name="app_info" msgid="6113278084877079851">"ઍપની માહિતી"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ડેમો પ્રારંભ કરી રહ્યાં છે…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"ઉપકરણ ફરીથી સેટ કરી રહ્યાં છે…"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 99bcffc..4ae96f6 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1219,7 +1219,7 @@
<string name="volume_music" msgid="7727274216734955095">"Մեդիա ձայնի բարձրություն"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Նվագարկում է Bluetooth-ի միջոցով"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Սահմանվել է անձայն զանգերանգ"</string>
- <string name="volume_call" msgid="7625321655265747433">"Մուտքային զանգի ձայնի ուժգնությունը"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Խոսակցություն"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Bluetooth-ի ներզանգի բարձրություն"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Զարթուցիչի ձայնը"</string>
<string name="volume_notification" msgid="6864412249031660057">"Ծանուցումների ձայնի ուժգնությունը"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index a368319..7616372 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1219,7 +1219,7 @@
<string name="volume_music" msgid="7727274216734955095">"Volume media"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Memutar melalui Bluetooth"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Nada dering senyap disetel"</string>
- <string name="volume_call" msgid="7625321655265747433">"Volume saat-memanggil"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Volume dalam panggilan"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Volume saat-memanggil bluetooth"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Volume alarm"</string>
<string name="volume_notification" msgid="6864412249031660057">"Volume pemberitahuan"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 78b23aa..89da9dd 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1231,7 +1231,7 @@
<string name="volume_icon_description_notification" msgid="579091344110747279">"Volume notifiche"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Suoneria predefinita"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Predefinita (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="397111123930141876">"Nessuna"</string>
+ <string name="ringtone_silent" msgid="397111123930141876">"Nessuno"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"Suonerie"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Suoni delle sveglie"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Suoni di notifica"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index aa60234..33e5176 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -61,7 +61,7 @@
<string name="ColpMmi" msgid="4736462893284419302">"Қосылған желі идентификаторы"</string>
<string name="ColrMmi" msgid="5889782479745764278">"Қосылған желі идентификаторын шектеу"</string>
<string name="CfMmi" msgid="8390012691099787178">"Қоңырауды басқа нөмірге бағыттау"</string>
- <string name="CwMmi" msgid="3164609577675404761">"Күтудегі қоңырау"</string>
+ <string name="CwMmi" msgid="3164609577675404761">"Қоңырауды ұстап тұру"</string>
<string name="BaMmi" msgid="7205614070543372167">"Қоңырауды бөгеу"</string>
<string name="PwdMmi" msgid="3360991257288638281">"Құпия сөз өзгерту"</string>
<string name="PinMmi" msgid="7133542099618330959">"PIN өзгерту"</string>
@@ -317,7 +317,7 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ағза күйінің көрсеткіштері туралы сенсор деректеріне қатынасу"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Терезе мазмұнын оқып отыру"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Ашық тұрған терезе мазмұнын тексеру."</string>
- <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Explore by Touch функциясын қосу"</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Түртілген элементтерді дыбыстау функциясын қосу"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Түртілген элементтер дауыстап айтылады және экранды қимылдар арқылы зерттеуге болады."</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Терілген мәтінді тексеру"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Несиелік карта нөмірі және құпия сөздер сияқты жеке деректі қоса."</string>
@@ -987,9 +987,9 @@
<string name="searchview_description_clear" msgid="1989371719192982900">"Сұрақты өшіру"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"Сұрақ жіберу"</string>
<string name="searchview_description_voice" msgid="42360159504884679">"Дауыс арқылы іздеу"</string>
- <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Explore by Touch функциясы қосылсын ба?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> қызметі Explore by Touch мүмкіндігін қосқысы келеді. Explore by Touch мүмкіндігі қосылған кезде, саусағыңыздың астындағы нәрсенің сипаттамаларын естисіз не көресіз немесе планшетпен өзара байланысу үшін қимылдайсыз."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> қызметі Explore by Touch мүмкіндігін қосқысы келеді. Explore by Touch мүмкіндігі қосылған кезде, саусағыңыздың астындағы нәрсенің сипаттамаларын естисіз не көресіз немесе телефонмен өзара байланысу үшін қимылдайсыз."</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Түртілген элементтерді дыбыстау функциясы қосылсын ба?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> қызметі Түртілген элементтерді дыбыстау функциясын қосуға рұқсат сұрап тұр. Ол қосылған кезде, саусағыңыздың астындағы элементтің сипаттамасын естіп не көріп тұрасыз немесе планшетті қимылмен басқарасыз."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> қызметі Түртілген элементтерді дыбыстау функциясын қосуға рұқсат сұрап тұр. Ол қосылған кезде, саусағыңыздың астындағы элементтің сипаттамасын естіп не көріп тұрасыз немесе телефонды қимылмен басқарасыз."</string>
<string name="oneMonthDurationPast" msgid="4538030857114635777">"1 ай бұрын"</string>
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Осыған дейін 1 ай бұрын"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
@@ -1219,9 +1219,9 @@
<string name="volume_music" msgid="7727274216734955095">"Mультимeдиа дыбыс деңгейі"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth арқылы ойнату"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Үнсіз қоңырау әуенін орнату"</string>
- <string name="volume_call" msgid="7625321655265747433">"Келетін қоңырау дыбысының қаттылығы"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Сөйлесу кезіндегі дыбыс деңгейі"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Bluetooth қоңырауының қаттылығы"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"Дабыл дыбысының қаттылығы"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"Дабыл дыбысының деңгейі"</string>
<string name="volume_notification" msgid="6864412249031660057">"Хабар дыбысының қаттылығы"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Дыбыс қаттылығы"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Bluetooth дыбысының қаттылығы"</string>
@@ -1307,7 +1307,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Аналогтық аудиожабдық анықталды"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Жалғанған құрылғы бұл телефонмен үйлесімсіз. Қосымша ақпарат алу үшін түртіңіз."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"USB арқылы түзету қосылған"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"USB арқылы түзетуді өшіру үшін түртіңіз"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"USB арқылы түзетуді өшіру үшін түртіңіз."</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB арқылы түзетуді өшіру үшін таңдаңыз."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Сымсыз түзету байланыстырылды"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Сымсыз түзетуді өшіру үшін түртіңіз."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index c700a39..c60727f 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1219,8 +1219,8 @@
<string name="volume_music" msgid="7727274216734955095">"កម្រិតសំឡេងមេឌៀ"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"ចាក់តាមប៊្លូធូស"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"កំណត់សំឡេងរោទ៍ស្ងាត់"</string>
- <string name="volume_call" msgid="7625321655265747433">"កម្រិតសំឡេងហៅចូល"</string>
- <string name="volume_bluetooth_call" msgid="2930204618610115061">"កម្រិតសំឡេងហៅចូលតាមប៊្លូធូស"</string>
+ <string name="volume_call" msgid="7625321655265747433">"កម្រិតសំឡេងក្នុងពេលនិយាយទូរសព្ទ"</string>
+ <string name="volume_bluetooth_call" msgid="2930204618610115061">"កម្រិតសំឡេងក្នុងពេលនិយាយទូរសព្ទតាមប៊្លូធូស"</string>
<string name="volume_alarm" msgid="4486241060751798448">"កម្រិតសំឡេងម៉ោងរោទ៍"</string>
<string name="volume_notification" msgid="6864412249031660057">"កម្រិតសំឡេងការជូនដំណឹង"</string>
<string name="volume_unknown" msgid="4041914008166576293">"កម្រិតសំឡេង"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 22dc3f1..34358c4 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1221,7 +1221,7 @@
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ಶಾಂತ ರಿಂಗ್ಟೋನ್ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
<string name="volume_call" msgid="7625321655265747433">"ಒಳ-ಕರೆಯ ವಾಲ್ಯೂಮ್"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"ಬ್ಲೂಟೂತ್ ಒಳ-ಕರೆಯ ವಾಲ್ಯೂಮ್"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"ಅಲಾರಮ್ ವಾಲ್ಯೂಮ್"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"ಅಲಾರಂ ವಾಲ್ಯೂಮ್"</string>
<string name="volume_notification" msgid="6864412249031660057">"ಅಧಿಸೂಚನೆಯ ವಾಲ್ಯೂಮ್"</string>
<string name="volume_unknown" msgid="4041914008166576293">"ವಾಲ್ಯೂಮ್"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"ಬ್ಲೂಟೂತ್ ವಾಲ್ಯೂಮ್"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 30b2525..d21acfb 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -857,12 +857,12 @@
<string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Колдонуучунун нускамасын караңыз же Кардарларды тейлөө борборуна кайрылыңыз."</string>
<string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"SIM-карта бөгөттөлгөн."</string>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"SIM-карта бөгөттөн чыгарылууда…"</string>
- <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"PIN-кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, планшетиңиздин кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, планшетиңиздин кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Графикалык ачкычыңызды <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес чийдиңиз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүздүн кулпусун Google аккаунтуңузга кирип ачышыңыз керек болот.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайталап көрүңүз."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, телефонуңуздун кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, телефонуңуздун кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Сиз планшетиңизди бөгөттөн чыгарууга <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес аракет кылдыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> аракеттен кийин, планшет баштапкы абалына келтирилет жана бардык маалыматтар өчүрүлөт."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Android TV түзмөгүңүздүн кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүз демейки жөндөөлөргө кайтарылып, бардык колдонуучу дайындары жоголот."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Сиз телефонуңузду бөгөттөн чыгарууга <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес аракет кылдыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> аракеттен кийин, телефон баштапкы абалына келтирилет жана бардык маалыматтар өчүрүлөт."</string>
@@ -1219,7 +1219,7 @@
<string name="volume_music" msgid="7727274216734955095">"Мультимедианын катуулугу"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth аркылуу ойнотулууда"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Үнсүз рингтон орнотулду"</string>
- <string name="volume_call" msgid="7625321655265747433">"Чалуудагы үн көлөмү"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Сүйлөшүүнүн катуулугу"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Bluetooth чалуудагы үн көлөмү"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Ойготкучтун катуулугу"</string>
<string name="volume_notification" msgid="6864412249031660057">"Эскертме үн көлөмү"</string>
@@ -1792,7 +1792,7 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Администраторуңуз жаңыртып койгон"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Администраторуңуз жок кылып салган"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ЖАРАЙТ"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Батареянын мөөнөтүн узартуу үчүн, Батареяны үнөмдөгүч режими төмөнкүлөрдү аткарат:\n\n•Караңгы теманы күйгүзөт\n•Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт\n\n"<annotation id="url">"Кеңири маалымат"</annotation></string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Батареянын мөөнөтүн узартуу үчүн Батареяны үнөмдөгүч режими төмөнкүлөрдү аткарат:\n\n•Караңгы теманы күйгүзөт\n•Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт\n\n"<annotation id="url">"Кеңири маалымат"</annotation></string>
<string name="battery_saver_description" msgid="8587408568232177204">"Батареянын иштешин узартуу үчүн, Батареяны үнөмдөөчү режим:\n\n•Караңгы теманы күйгүзөт\n•Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт"</string>
<string name="data_saver_description" msgid="4995164271550590517">"Трафикти үнөмдөө режиминде айрым колдонмолор дайын-даректерди фондо өткөрө алышпайт. Учурда сиз пайдаланып жаткан колдонмо дайын-даректерди жөнөтүп/ала алат, бирок адаттагыдан азыраак өткөргөндүктөн, анын айрым функциялары талаптагыдай иштебей коюшу мүмкүн. Мисалы, сүрөттөр басылмайынча жүктөлбөйт."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Трафикти үнөмдөө режимин иштетесизби?"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 5063002..35d39cb 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -155,19 +155,19 @@
<string name="fcError" msgid="5325116502080221346">"Проблем со поврзувањето или неважечки код за карактеристиката."</string>
<string name="httpErrorOk" msgid="6206751415788256357">"Во ред"</string>
<string name="httpError" msgid="3406003584150566720">"Настана грешка на мрежа."</string>
- <string name="httpErrorLookup" msgid="3099834738227549349">"Не можеше да се најде URL."</string>
+ <string name="httpErrorLookup" msgid="3099834738227549349">"Не може да се најде URL."</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="3976195595501606787">"Шемата за автентикација на локацијата не е поддржана."</string>
- <string name="httpErrorAuth" msgid="469553140922938968">"Не можеше да се автентицира."</string>
+ <string name="httpErrorAuth" msgid="469553140922938968">"Не може да се автентицира."</string>
<string name="httpErrorProxyAuth" msgid="7229662162030113406">"Автентикацијата преку прокси серверот беше неуспешна."</string>
- <string name="httpErrorConnect" msgid="3295081579893205617">"Не можеше да се поврзе со серверот."</string>
- <string name="httpErrorIO" msgid="3860318696166314490">"Не можеше да се комуницира со серверот. Обидете се повторно подоцна."</string>
+ <string name="httpErrorConnect" msgid="3295081579893205617">"Не може да се поврзе со серверот."</string>
+ <string name="httpErrorIO" msgid="3860318696166314490">"Не може да се комуницира со серверот. Обидете се повторно подоцна."</string>
<string name="httpErrorTimeout" msgid="7446272815190334204">"Времето за поврзување до серверот истече."</string>
<string name="httpErrorRedirectLoop" msgid="8455757777509512098">"Страницата содржи премногу пренасочувања од серверот."</string>
<string name="httpErrorUnsupportedScheme" msgid="2664108769858966374">"Протоколот не е поддржан."</string>
- <string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"Не можеше да се воспостави безбедна врска."</string>
- <string name="httpErrorBadUrl" msgid="754447723314832538">"Страницата не можеше да се отвори, бидејќи URL е неважечки."</string>
- <string name="httpErrorFile" msgid="3400658466057744084">"Не можеше да се пристапи до датотеката."</string>
- <string name="httpErrorFileNotFound" msgid="5191433324871147386">"Не можеше да се најде бараната датотека."</string>
+ <string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"Не може да се воспостави безбедна врска."</string>
+ <string name="httpErrorBadUrl" msgid="754447723314832538">"Страницата не може да се отвори, бидејќи URL е неважечки."</string>
+ <string name="httpErrorFile" msgid="3400658466057744084">"Не може да се пристапи до датотеката."</string>
+ <string name="httpErrorFileNotFound" msgid="5191433324871147386">"Не може да се најде бараната датотека."</string>
<string name="httpErrorTooManyRequests" msgid="2149677715552037198">"Се обработуваат премногу барања. Обидете се повторно подоцна."</string>
<string name="notification_title" msgid="5783748077084481121">"Грешка при пријавување за <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
<string name="contentServiceSync" msgid="2341041749565687871">"Синхронизирај"</string>
@@ -543,7 +543,7 @@
<string name="biometric_error_canceled" msgid="8266582404844179778">"Проверката е откажана"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Не е поставен PIN, шема или лозинка"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Откриен е делумен отпечаток. Обидете се повторно."</string>
- <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатокот не можеше да се обработи. Обидете се повторно."</string>
+ <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатокот не може да се обработи. Обидете се повторно."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сензорот за отпечатоци е валкан. Исчистете го и обидете се повторно."</string>
<string name="fingerprint_acquired_too_fast" msgid="5151661932298844352">"Прстот се движеше пребрзо. Обидете се повторно."</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Прстот се движеше премногу бавно. Обидете се повторно."</string>
@@ -1396,7 +1396,7 @@
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"прашај дали да се игнорираат оптимизациите на батеријата"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Овозможува апликацијата да побара дозвола за игнорирање на оптимизациите на батеријата за таа апликација."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Допрете двапати за контрола на зумот"</string>
- <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Не можеше да се додаде виџет."</string>
+ <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Не може да се додаде виџет."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Оди"</string>
<string name="ime_action_search" msgid="4501435960587287668">"Пребарај"</string>
<string name="ime_action_send" msgid="8456843745664334138">"Испрати"</string>
@@ -1431,7 +1431,7 @@
<string name="vpn_lockdown_connecting" msgid="6096725311950342607">"Поврзување со секогаш вклучена VPN..."</string>
<string name="vpn_lockdown_connected" msgid="2853127976590658469">"Поврзани со секогаш вклучена VPN"</string>
<string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Исклучено од секогаш вклучената VPN"</string>
- <string name="vpn_lockdown_error" msgid="4453048646854247947">"Не можеше да се поврзе на секогаш вклучената VPN"</string>
+ <string name="vpn_lockdown_error" msgid="4453048646854247947">"Не може да се поврзе на секогаш вклучената VPN"</string>
<string name="vpn_lockdown_config" msgid="8331697329868252169">"Променете ја мрежата или поставките за VPN"</string>
<string name="upload_file" msgid="8651942222301634271">"Избери датотека"</string>
<string name="no_file_chosen" msgid="4146295695162318057">"Не е избрана датотека"</string>
@@ -1975,9 +1975,9 @@
<string name="popup_window_default_title" msgid="6907717596694826919">"Појавен прозорец"</string>
<string name="slice_more_content" msgid="3377367737876888459">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
<string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Верзијата на апликацијата е постара или не е компатибилна со кратенкава"</string>
- <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Не можеше да се врати кратенката бидејќи апликацијата не поддржува бекап и враќање"</string>
- <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Не можеше да се врати кратенката бидејќи потписот на апликацијата не се совпаѓа"</string>
- <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Не можеше да се врати кратенката"</string>
+ <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Не може да се врати кратенката бидејќи апликацијата не поддржува бекап и враќање"</string>
+ <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Не може да се врати кратенката бидејќи потписот на апликацијата не се совпаѓа"</string>
+ <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Не може да се врати кратенката"</string>
<string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Кратенката е оневозможена"</string>
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ДЕИНСТАЛИРАЈ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"СЕПАК ОТВОРИ"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 9ef1402..656227a 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -273,7 +273,7 @@
<string name="notification_channel_car_mode" msgid="2123919247040988436">"Машины горим"</string>
<string name="notification_channel_account" msgid="6436294521740148173">"Бүртгэлийн төлөв"</string>
<string name="notification_channel_developer" msgid="1691059964407549150">"Хөгжүүлэгчийн мессеж"</string>
- <string name="notification_channel_developer_important" msgid="7197281908918789589">"Хөгжүүлэгчийн чухал зурвас"</string>
+ <string name="notification_channel_developer_important" msgid="7197281908918789589">"Хөгжүүлэгчийн чухал мессеж"</string>
<string name="notification_channel_updates" msgid="7907863984825495278">"Шинэчлэлтүүд"</string>
<string name="notification_channel_network_status" msgid="2127687368725272809">"Сүлжээний төлөв"</string>
<string name="notification_channel_network_alerts" msgid="6312366315654526528">"Сүлжээний сануулга"</string>
@@ -356,9 +356,9 @@
<string name="permlab_sendSms" msgid="7757368721742014252">"SMS мессежийг илгээх, харах"</string>
<string name="permdesc_sendSms" msgid="6757089798435130769">"Апп нь SMS мессеж илгээх боломжтой. Энэ нь санаандгүй төлбөрт оруулж болзошгүй. Хортой апп нь таны зөвшөөрөлгүйгээр мессеж илгээн таныг төлбөрт оруулж болзошгүй."</string>
<string name="permlab_readSms" msgid="5164176626258800297">"таны текст мессежийг унших(SMS эсвэл MMS)"</string>
- <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Энэ апп таны таблетад хадгалсан бүх SMS (текст) зурвасыг унших боломжтой."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Энэ апп таны таблетад хадгалсан бүх SMS (текст) мессежийг унших боломжтой."</string>
<string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Энэ апп таны Android TV төхөөрөмжид хадгалсан бүх SMS (текст) мессежийг уншиж чадна."</string>
- <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Энэ апп таны утсанд хадгалсан бүх SMS (текст) зурвасыг унших боломжтой."</string>
+ <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Энэ апп таны утсанд хадгалсан бүх SMS (текст) мессежийг унших боломжтой."</string>
<string name="permlab_receiveWapPush" msgid="4223747702856929056">"текст мессеж(WAP) хүлээн авах"</string>
<string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Апп нь WAP мессежийг хүлээн авах болон биелүүлэх боломжтой. Энэ зөвшөөрөл нь танд илгээсэн мессежийг танд харуулалгүйгээр хянах эсвэл устгах боломжийг агуулна."</string>
<string name="permlab_getTasks" msgid="7460048811831750262">"ажиллаж байгаа апп-г дуудах"</string>
@@ -416,9 +416,9 @@
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Энэ апп таны Android TV төхөөрөмжид хадгалсан календарийн бүх арга хэмжээг унших болон таны календарийн өгөгдлийг хуваалцах эсвэл хадгалах боломжтой."</string>
<string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Энэ апп таны утсанд хадгалсан хуанлийн бүх арга хэмжээг унших, хуанлийн өгөгдлийг хуваалцах, хадгалах боломжтой."</string>
<string name="permlab_writeCalendar" msgid="6422137308329578076">"календарын хуваарийг нэмэх эсвэл өөрчлөх болон эзэмшигчид мэдэгдэлгүйгээр зочидруу имэйл илгээх"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Энэ апп таны таблет дээр хуанлийн арга хэмжээг нэмэх, устгах, эсвэл өөрчлөх боломжтой. Энэ апп нь хуанли эзэмшигчээс зурвас илгээсэн мэт харагдах, эсвэл эзэмшигчид мэдэгдэлгүйгээр арга хэмжээг өөрчлөх боломжтой."</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Энэ апп таны таблет дээр хуанлийн арга хэмжээг нэмэх, устгах, эсвэл өөрчлөх боломжтой. Энэ апп нь хуанли эзэмшигчээс мессеж илгээсэн мэт харагдах, эсвэл эзэмшигчид мэдэгдэлгүйгээр арга хэмжээг өөрчлөх боломжтой."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Энэ апп таны Android TV төхөөрөмжид календарийн арга хэмжээ нэмэх, үүнийг устгах, эсвэл өөрчлөх боломжтой. Энэ апп календарийн өмчлөгчөөс ирсэн мэт харагдаж болох мессеж илгээх эсвэл арга хэмжээг өмчлөгчид нь мэдэгдэлгүйгээр өөрчлөх боломжтой."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Энэ апп таны утсанд хуанлийн арга хэмжээг нэмэх, устгах, эсвэл өөрчлөх боломжтой. Энэ апп нь хуанли эзэмшигчээс зурвас илгээсэн мэт харагдах, эсвэл эзэмшигчид мэдэгдэлгүйгээр арга хэмжээг өөрчлөх боломжтой."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Энэ апп таны утсанд хуанлийн арга хэмжээг нэмэх, устгах, эсвэл өөрчлөх боломжтой. Энэ апп нь хуанли эзэмшигчээс мессеж илгээсэн мэт харагдах, эсвэл эзэмшигчид мэдэгдэлгүйгээр арга хэмжээг өөрчлөх боломжтой."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"байршил нийлүүлэгчийн нэмэлт тушаалд хандах"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Апп нь байршил нийлүүлэгчийн нэмэлт тушаалд хандах боломжтой. Энэ нь апп-д GPS эсвэл бусад байршлын үйлчилгээний ажиллагаанд нөлөөлөх боломжийг олгоно."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"нарийвчилсан байршилд зөвхөн нүүр хэсэгт хандах"</string>
@@ -661,8 +661,8 @@
<string name="permdesc_handoverStatus" msgid="3842269451732571070">"Одоогийн Андройд Бийм дамжуулалтын мэдээллийг хүлээн авахыг аппликейшнд зөвшөөрөх"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"DRM сертификатыг устгах"</string>
<string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Аппликейшнд DRM сертификатыг устгахыг зөвшөөрнө. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
- <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"зөөгч зурвасын үйлчилгээнд холбох"</string>
- <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Эзэмшигчид зөөгч зурвасын үйлчилгээний түвшний интерфэйст холбогдохыг зөвшөөрдөг. Энгийн апп-д шаардлагагүй."</string>
+ <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"зөөгч мессежийн үйлчилгээнд холбох"</string>
+ <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Эзэмшигчид зөөгч мессежийн үйлчилгээний түвшний интерфэйст холбогдохыг зөвшөөрдөг. Энгийн апп-д шаардлагагүй."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"Үүрэн холбооны үйлчилгээ үзүүлэгчтэй холбогдох"</string>
<string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Аливаа эзэмшигчийг үүрэн холбооны үйлчилгээ үзүүлэгчтэй холбодог. Энгийн аппд шаардлагагүй."</string>
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"Бүү саад бол тохируулгад хандалт хийх"</string>
@@ -959,7 +959,7 @@
<string name="permlab_setAlarm" msgid="1158001610254173567">"сэрүүлэг тохируулах"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"Апп нь суулгагдсан сэрүүлэгний апп дээр сэрүүлэг тохируулах боломжтой. Зарим сэрүүлэгний апп нь энэ функцийг дэмжихгүй байж болзошгүй."</string>
<string name="permlab_addVoicemail" msgid="4770245808840814471">"дуут шуудан нэмэх"</string>
- <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Таны дуут шуудангийн ирсэн мэйлд зурвас нэмэхийг апп-д зөвшөөрөх."</string>
+ <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Таны дуут шуудангийн ирсэн мэйлд мессеж нэмэхийг апп-д зөвшөөрөх."</string>
<string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"Хөтчийн геобайршлын зөвшөөрлийг өөрчлөх"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Апп нь Хөтчийн гео байршлын зөвшөөрлийг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан дурын веб хуудасруу байршлын мэдээллийг илгээх боломжтой."</string>
<string name="save_password_message" msgid="2146409467245462965">"Та хөтчид энэ нууц үгийг сануулах уу?"</string>
@@ -1893,7 +1893,7 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> яг одоо боломжгүй байна."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Энэ аппыг Андройдын хуучин хувилбарт зориулсан бөгөөд буруу ажиллаж болзошгүй. Шинэчлэлтийг шалгаж эсвэл хөгжүүлэгчтэй холбогдоно уу."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шинэчлэлтийг шалгах"</string>
- <string name="new_sms_notification_title" msgid="6528758221319927107">"Танд шинэ зурвасууд байна"</string>
+ <string name="new_sms_notification_title" msgid="6528758221319927107">"Танд шинэ мессежүүд байна"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Үзэхийн тулд SMS аппыг нээх"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Зарим функцийг хязгаарласан байж болзошгүй"</string>
<string name="profile_encrypted_detail" msgid="5279730442756849055">"Ажлын профайлыг түгжсэн"</string>
@@ -1961,7 +1961,7 @@
<string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"Тайван байж, ойролцоох нуугдах газар хайна уу."</string>
<string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"Эргийн бүс, голын эргийн бүсээс өндөрлөг газар зэрэг аюулгүй газар руу нэн даруй шилжинэ үү."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="4888224011071875068">"Тайван байж, ойролцоох нуугдах газар хайна уу."</string>
- <string name="etws_primary_default_message_test" msgid="4583367373909549421">"Онцгой байдлын зурвасын тест"</string>
+ <string name="etws_primary_default_message_test" msgid="4583367373909549421">"Онцгой байдлын мессежийн тест"</string>
<string name="notification_reply_button_accessibility" msgid="5235776156579456126">"Хариу бичих"</string>
<string name="etws_primary_default_message_others" msgid="7958161706019130739"></string>
<string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIM-г дуу хоолойд зөвшөөрдөггүй"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 46ab050..d639d39 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -142,7 +142,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi कलिङ"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
- <string name="wifi_calling_off_summary" msgid="5626710010766902560">"निष्क्रिय"</string>
+ <string name="wifi_calling_off_summary" msgid="5626710010766902560">"अफ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi मार्फत कल गर्नुहोस्"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"मोबाइल नेटवर्कमार्फत कल गर्नुहोस्"</string>
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi मात्र"</string>
@@ -201,7 +201,7 @@
<string name="factory_reset_message" msgid="2657049595153992213">"प्रशासकको एप प्रयोग गर्न मिल्दैन। तपाईंको यन्त्रको डेटा अब मेटाइने छ।\n\nतपाईंसँग प्रश्नहरू भएका खण्डमा आफ्नो संगठनका प्रशासकसँग सम्पर्क गर्नुहोस्।"</string>
<string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ले छाप्ने कार्यलाई असक्षम पार्यो।"</string>
<string name="personal_apps_suspension_title" msgid="7561416677884286600">"आफ्नो कार्य प्रोफाइल सक्रिय गर्नुहोस्"</string>
- <string name="personal_apps_suspension_text" msgid="6115455688932935597">"तपाईंले आफ्नो कार्य प्रोफाइल सक्रिय नगरुन्जेल तपाईंका व्यक्तिगत अनुप्रयोगहरूलाई रोक लगाइन्छ"</string>
+ <string name="personal_apps_suspension_text" msgid="6115455688932935597">"तपाईंले आफ्नो कार्य प्रोफाइल सक्रिय नगरुन्जेल तपाईंका व्यक्तिगत एपहरूलाई रोक लगाइन्छ"</string>
<string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"मिति <xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> बजे व्यक्तिगत एपहरूलाई रोक लगाइने छ। तपाईंका IT एडमिन तपाईंलाई आफ्नो कार्य प्रोफाइल <xliff:g id="NUMBER">%3$d</xliff:g> भन्दा धेरै दिन निष्क्रिय राख्ने अनुमति दिनुहुन्न।"</string>
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"सक्रिय गर्नुहोस्"</string>
<string name="me" msgid="6207584824693813140">"मलाई"</string>
@@ -229,7 +229,7 @@
<string name="shutdown_confirm" product="default" msgid="136816458966692315">"तपाईँको फोन बन्द हुने छ।"</string>
<string name="shutdown_confirm_question" msgid="796151167261608447">"के तपाईं बन्द गर्न चाहनुहुन्छ?"</string>
<string name="reboot_safemode_title" msgid="5853949122655346734">"सुरक्षित मोडमा पुनःबुट गर्नुहोस्"</string>
- <string name="reboot_safemode_confirm" msgid="1658357874737219624">"सुरक्षित मोडमा तपाईं पुनःबुट गर्न चाहनु हुन्छ? तपाईंले स्थापना गरेका सबै तेस्रो पक्षका अनुप्रयोगहरूलाई असक्षम गराउने छ।"</string>
+ <string name="reboot_safemode_confirm" msgid="1658357874737219624">"सुरक्षित मोडमा तपाईं पुनःबुट गर्न चाहनु हुन्छ? तपाईंले स्थापना गरेका सबै तेस्रो पक्षका एपहरूलाई असक्षम गराउने छ।"</string>
<string name="recent_tasks_title" msgid="8183172372995396653">"नयाँ"</string>
<string name="no_recent_tasks" msgid="9063946524312275906">"कुनै नयाँ एपहरू छैनन्।"</string>
<string name="global_actions" product="tablet" msgid="4412132498517933867">"ट्याब्लेट विकल्पहरू"</string>
@@ -364,13 +364,13 @@
<string name="permlab_getTasks" msgid="7460048811831750262">"चलिरहेका एपहरू पुनःबहाली गर्नुहोस्"</string>
<string name="permdesc_getTasks" msgid="7388138607018233726">"वर्तमानमा र भरखरै चलिरहेका कार्यहरू बारेको सूचना पुनःबहाली गर्न एपलाई अनुमित दिन्छ। यसले उपकरणमा प्रयोग भएका अनुप्रयोगहरूको बारेमा सूचना पत्ता लगाउन एपलाई अनुमति दिन सक्छ।"</string>
<string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"प्रोफाइल र यन्त्र मालिकहरूको व्यवस्थापन गराउनुहोस्"</string>
- <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"अनुप्रयोगहरूलाई प्रोफाइल र यन्त्र मालिकहरू सेट गर्न अनुमति दिनुहोस्।"</string>
- <string name="permlab_reorderTasks" msgid="7598562301992923804">"चलिरहेका अनुप्रयोगहरूलाई पुनःक्रम गराउनुहोस्"</string>
+ <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"एपहरूलाई प्रोफाइल र यन्त्र मालिकहरू सेट गर्न अनुमति दिनुहोस्।"</string>
+ <string name="permlab_reorderTasks" msgid="7598562301992923804">"चलिरहेका एपहरूलाई पुनःक्रम गराउनुहोस्"</string>
<string name="permdesc_reorderTasks" msgid="8796089937352344183">"कामहरूलाई अग्रभाग र पृष्ठभूमिमा सार्न एपलाई अनुमति दिन्छ। अनुप्रयोगले यो तपाईँको इनपुट बिना नै गर्न सक्छ।"</string>
<string name="permlab_enableCarMode" msgid="893019409519325311">"कार मोड सक्षम गर्नुहोस्"</string>
<string name="permdesc_enableCarMode" msgid="56419168820473508">"कार मोडलाई सक्षम पार्न एपलाई अनुमति दिन्छ।"</string>
<string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"एपहरू बन्द गर्नुहोस्"</string>
- <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"एपलाई अन्य अनुप्रयोगहरूको पृष्ठभूमि प्रक्रियाहरू बन्द गर्न अनुमति दिन्छ। यसले अन्य अनुप्रयोगहरूलाई चल्नबाट रोक्न सक्दछ।"</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"एपलाई अन्य अनुप्रयोगहरूको पृष्ठभूमि प्रक्रियाहरू बन्द गर्न अनुमति दिन्छ। यसले अन्य एपहरूलाई चल्नबाट रोक्न सक्दछ।"</string>
<string name="permlab_systemAlertWindow" msgid="5757218350944719065">"यो एप अन्य एपहरूमाथि देखा पर्न सक्छ"</string>
<string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"यो एप अन्य एपहरूमाथि वा स्क्रिनका अन्य भागहरूमा देखा पर्न सक्छ। यसले एपको सामान्य प्रयोगमा अवरोध पुर्याउन सक्छ र अन्य एपहरू देखा पर्ने तरिकालाई परिवर्तन गर्न सक्छ।"</string>
<string name="permlab_runInBackground" msgid="541863968571682785">"पृष्ठभूमिमा चलाउनुहोस्"</string>
@@ -378,7 +378,7 @@
<string name="permlab_useDataInBackground" msgid="783415807623038947">"पृष्ठभूमिमा डेटा प्रयोग गर्नुहोस्"</string>
<string name="permdesc_useDataInBackground" msgid="1230753883865891987">"यो अनुप्रयोगले पृष्ठभूमिमा डेटा प्रयोग गर्नसक्छ। यसले गर्दा धेरै डेटा प्रयोग हुनसक्छ।"</string>
<string name="permlab_persistentActivity" msgid="464970041740567970">"एपहरू जहिले पनि चल्ने बनाउनुहोस्"</string>
- <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"यसको आफ्नै मेमोरीमा दृढ भएकोको अंश बनाउनको लागि एपलाई अनुमति दिन्छ। ट्याब्लेटलाई ढिलो गराउँदै गरेका अन्य अनुप्रयोगहरूलाई सीमित मात्रामा यसले मेमोरी उपलब्ध गराउन सक्छ।"</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"यसको आफ्नै मेमोरीमा दृढ भएकोको अंश बनाउनको लागि एपलाई अनुमति दिन्छ। ट्याब्लेटलाई ढिलो गराउँदै गरेका अन्य एपहरूलाई सीमित मात्रामा यसले मेमोरी उपलब्ध गराउन सक्छ।"</string>
<string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"एपलाई आफ्ना केही अंशहरू मेमोरीमा स्थायी रूपमा राख्ने अनुमति दिन्छ। यसले गर्दा अन्य अनुप्रयोगहरूका लागि मेमोरीको अभाव हुन सक्ने भएकाले तपाईंको Android टिभी यन्त्र सुस्त हुन सक्छ।"</string>
<string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"एपलाई मेमोरीमा आफैंको निरन्तरको अंश बनाउन अनुमति दिन्छ। यसले फोनलाई ढिला बनाएर अन्य एपहरूमा मेमोरी SIMित गर्न सक्दछन्।"</string>
<string name="permlab_foregroundService" msgid="1768855976818467491">"अग्रभूमिको सेवा सञ्चालन गर्नुहोस्"</string>
@@ -396,9 +396,9 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"एपलाई प्रसारण समाप्त भइसकेपछि पनि रहिरहने स्टिकी प्रसारणहरू पठाउने अनुमति दिन्छ। यो सुविधाको अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग हुने भएकाले तपाईंको Android टिभी यन्त्र सुस्त वा अस्थिर हुन सक्छ।"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"औपचारिक प्रसारणलाई पठाउनको लागि एक एपलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले फोनलाई ढिलो र अस्थिर बनाउन सक्छ।"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"तपाईँका सम्पर्कहरू पढ्नुहोस्"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"एपलाई तपाईंको ट्याब्लेटमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको ट्याब्लेटमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
- <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"एपलाई तपाईंको Android टिभी यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा पढ्न अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको Android टिभी यन्त्रमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
- <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"एपलाई तपाईंको फोनमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको फोनमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"एपलाई तपाईंको ट्याब्लेटमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको ट्याब्लेटमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"एपलाई तपाईंको Android टिभी यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा पढ्न अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको Android टिभी यन्त्रमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"एपलाई तपाईंको फोनमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको फोनमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"तपाईँका सम्पर्कहरू परिवर्तन गर्नुहोस्"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"एपलाई तपाईंको ट्याब्लेटमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string>
<string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"एपलाई तपाईंको Android टिभी यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string>
@@ -614,7 +614,7 @@
<string name="permlab_readSyncSettings" msgid="6250532864893156277">"समीकरण सेटिङहरू पढ्नुहोस्"</string>
<string name="permdesc_readSyncSettings" msgid="1325658466358779298">"एपलाई खाताको लागि सिंक सेटिङहरू पढ्न अनुमति दिन्छ। उदाहरणको लागि यसले व्यक्तिहरको एप खातासँग सिंक भएको नभएको निर्धारण गर्न सक्दछ।"</string>
<string name="permlab_writeSyncSettings" msgid="6583154300780427399">"टगल सिंक खुला र बन्द"</string>
- <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"अनुप्रयोगहरूलाई खाताको लागि सिंक सेटिङहरू परिमार्जन गर्न अनुमति दिन्छ। उदाहरणको लागि, यो खातासँग व्यक्ति एपको सिंक सक्षम गर्न प्रयोग गर्न सकिन्छ।"</string>
+ <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"एपहरूलाई खाताको लागि सिंक सेटिङहरू परिमार्जन गर्न अनुमति दिन्छ। उदाहरणको लागि, यो खातासँग व्यक्ति एपको सिंक सक्षम गर्न प्रयोग गर्न सकिन्छ।"</string>
<string name="permlab_readSyncStats" msgid="3747407238320105332">"सिंक तथ्याङ्कहरू पढ्नुहोस्"</string>
<string name="permdesc_readSyncStats" msgid="3867809926567379434">"एपलाई खाताको लागि समीकरणको आँकडा समीकरण घटनाहरूको इतिहास र समीकरण गरिएको डेटाको मापन समेत, पढ्न अनुमति दिन्छ।"</string>
<string name="permlab_sdcardRead" msgid="5791467020950064920">"आफ्नो आदान प्रदान गरिएको भण्डारणको सामग्रीहरूहरू पढ्नुहोस्"</string>
@@ -642,9 +642,9 @@
<string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"नेटवर्क उपयोग लेखालाई परिमार्जन गर्नुहोस्"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"एपलाई कसरी अनुप्रयोगहरूको विरूद्धमा कसरी नेटवर्क उपयोगी अकाउन्टेड छ भनेर परिमार्जन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूद्वारा प्रयोगको लागि होइन।"</string>
<string name="permlab_accessNotifications" msgid="7130360248191984741">"सूचनाहरू पहुँच गर्नुहोस्"</string>
- <string name="permdesc_accessNotifications" msgid="761730149268789668">"अन्य अनुप्रयोगहरूबाट पोस्ट गरिएकासहित पुनःप्राप्त गर्न, परीक्षण गर्न र सूचनाहरू हटाउन अनुप्रयोगहरूलाई अनुमति दिन्छ।"</string>
+ <string name="permdesc_accessNotifications" msgid="761730149268789668">"अन्य अनुप्रयोगहरूबाट पोस्ट गरिएकासहित पुनःप्राप्त गर्न, परीक्षण गर्न र सूचनाहरू हटाउन एपहरूलाई अनुमति दिन्छ।"</string>
<string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"जानकारी श्रोता सेवामा बाँध्नुहोस्"</string>
- <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"होल्डरलाई सूचना श्रोता सेवाको शीर्ष-स्तरको इन्टरफेस बाँध्न अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
+ <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"होल्डरलाई सूचना श्रोता सेवाको शीर्ष-स्तरको इन्टरफेस बाँध्न अनुमति दिन्छ। सामान्य एपहरूलाई कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
<string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"सर्त प्रदायक सेवामा जोड्न"</string>
<string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"सर्त प्रदायक सेवाको माथिल्लो स्तरको इन्टरफेसमा जोड्न बाहकलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
<string name="permlab_bindDreamService" msgid="4776175992848982706">"सपना सेवामा बाँध्नुहोस्"</string>
@@ -668,7 +668,7 @@
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"बाधा नपुर्याउँनुहोस् पहुँच गर्नुहोस्"</string>
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"बाधा नपुर्याउँनुहोस् कन्फिगरेसन पढ्न र लेख्नको लागि एपलाई अनुमति दिनुहोस्।"</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"हेर्ने अनुमतिको प्रयोग सुरु गर्नुहोस्"</string>
- <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"वाहकलाई कुनै अनुप्रयोगसम्बन्धी अनुमतिको प्रयोग सुरु गर्न दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक नपर्नु पर्ने हो।"</string>
+ <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"वाहकलाई कुनै एपसम्बन्धी अनुमतिको प्रयोग सुरु गर्न दिन्छ। साधारण एपहरूलाई कहिल्यै आवश्यक नपर्नु पर्ने हो।"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियमहरू मिलाउनुहोस्"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"स्क्रिन लक पासवर्ड र PIN हरूमा अनुमति दिइएको लम्बाइ र वर्णहरूको नियन्त्रण गर्नुहोस्।"</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"मनिटरको स्क्रिन अनलक गर्ने प्रयासहरू"</string>
@@ -1119,7 +1119,7 @@
<string name="dialog_alert_title" msgid="651856561974090712">"सावधानी"</string>
<string name="loading" msgid="3138021523725055037">"लोड हुँदै..."</string>
<string name="capital_on" msgid="2770685323900821829">"चालु"</string>
- <string name="capital_off" msgid="7443704171014626777">"बन्द"</string>
+ <string name="capital_off" msgid="7443704171014626777">"अफ"</string>
<string name="checked" msgid="9179896827054513119">"जाँच गरिएको"</string>
<string name="not_checked" msgid="7972320087569023342">"जाँच गरिएको छैन"</string>
<string name="whichApplication" msgid="5432266899591255759">"प्रयोग गरेर कारबाही पुरा गर्नुहोस्"</string>
@@ -1872,7 +1872,7 @@
<string name="default_notification_channel_label" msgid="3697928973567217330">"वर्गीकरण नगरिएको"</string>
<string name="importance_from_user" msgid="2782756722448800447">"तपाईंले यी सूचनाहरूको महत्त्व सेट गर्नुहोस् ।"</string>
<string name="importance_from_person" msgid="4235804979664465383">"यसमा सङ्लग्न भएका मानिसहरूको कारणले गर्दा यो महत्वपूर्ण छ।"</string>
- <string name="notification_history_title_placeholder" msgid="7748630986182249599">"अनुप्रयोगसम्बन्धी आफ्नो रोजाइअनुसारको सूचना"</string>
+ <string name="notification_history_title_placeholder" msgid="7748630986182249599">"एपसम्बन्धी आफ्नो रोजाइअनुसारको सूचना"</string>
<string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (यस खाताको प्रयोगकर्ता पहिले नै अवस्थित छ) मा नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string>
<string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="ACCOUNT">%2$s</xliff:g> मा नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string>
<string name="language_selection_title" msgid="52674936078683285">"भाषा थप्नुहोस्"</string>
@@ -1904,7 +1904,7 @@
<string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g> लाई पिन गर्नुहोस्"</string>
<string name="unpin_target" msgid="3963318576590204447">"अनपिन गर्नुहोस्"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g> लाई अनपिन गर्नुहोस्"</string>
- <string name="app_info" msgid="6113278084877079851">"अनुप्रयोगका बारे जानकारी"</string>
+ <string name="app_info" msgid="6113278084877079851">"एपका बारे जानकारी"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"डेमो सुरु गर्दै…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"यन्त्रलाई रिसेट गर्दै…"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2627b53..0565f2c 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1216,18 +1216,18 @@
<string name="dump_heap_ready_text" msgid="5849618132123045516">"ਸਾਂਝਾ ਕਰਨ ਲਈ <xliff:g id="PROC">%1$s</xliff:g> ਦੀ ਪ੍ਰਕਿਰਿਆ ਦਾ ਹੀਪ ਡੰਪ ਤੁਹਾਡੇ ਲਈ ਉਪਲਬਧ ਹੈ। ਸਾਵਧਾਨ ਰਹੋ: ਸ਼ਾਇਦ ਇਸ ਹੀਪ ਡੰਪ ਵਿੱਚ ਕੋਈ ਵੀ ਸੰਵੇਦਨਸ਼ੀਲ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੋਵੇ, ਜਿਸ \'ਤੇ ਪ੍ਰਕਿਰਿਆ ਦੀ ਪਹੁੰਚ ਹੈ, ਜਿਸ ਵਿੱਚ ਸ਼ਾਇਦ ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤੀਆਂ ਚੀਜ਼ਾਂ ਸ਼ਾਮਲ ਹੋਣ।"</string>
<string name="sendText" msgid="493003724401350724">"ਲਿਖਤ ਲਈ ਕੋਈ ਕਾਰਵਾਈ ਚੁਣੋ"</string>
<string name="volume_ringtone" msgid="134784084629229029">"ਰਿੰਗਰ ਵੌਲਿਊਮ"</string>
- <string name="volume_music" msgid="7727274216734955095">"ਮੀਡੀਆ ਵੌਲਿਊਮ"</string>
+ <string name="volume_music" msgid="7727274216734955095">"ਮੀਡੀਆ ਦੀ ਅਵਾਜ਼"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth ਰਾਹੀਂ ਪਲੇ ਕਰ ਰਿਹਾ ਹੈ"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ਖਾਮੋਸ਼ ਰਿੰਗਟੋਨ ਸੈੱਟ ਕੀਤੀ"</string>
<string name="volume_call" msgid="7625321655265747433">"ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"ਬਲੂਟੁੱਥ ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"ਅਲਾਰਮ ਵੌਲਿਊਮ"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"ਅਲਾਰਮ ਦੀ ਅਵਾਜ਼"</string>
<string name="volume_notification" msgid="6864412249031660057">"ਸੂਚਨਾ ਵੌਲਿਊਮ"</string>
<string name="volume_unknown" msgid="4041914008166576293">"ਵੌਲਿਊਮ"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Bluetooth ਵੌਲਿਊਮ"</string>
<string name="volume_icon_description_ringer" msgid="2187800636867423459">"ਰਿੰਗਟੋਨ ਵੌਲਿਊਮ"</string>
<string name="volume_icon_description_incall" msgid="4491255105381227919">"ਕਾਲ ਅਵਾਜ਼"</string>
- <string name="volume_icon_description_media" msgid="4997633254078171233">"ਮੀਡੀਆ ਵੌਲਿਊਮ"</string>
+ <string name="volume_icon_description_media" msgid="4997633254078171233">"ਮੀਡੀਆ ਦੀ ਅਵਾਜ਼"</string>
<string name="volume_icon_description_notification" msgid="579091344110747279">"ਸੂਚਨਾ ਵੌਲਿਊਮ"</string>
<string name="ringtone_default" msgid="9118299121288174597">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰਿੰਗਟੋਨ"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"ਪੂਰਵ-ਨਿਰਧਾਰਤ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 254f1d0..4374e7f 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -186,10 +186,10 @@
<item quantity="one">Urząd certyfikacji został zainstalowany</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Przez nieznany podmiot zewnętrzny"</string>
- <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Przez administratora Twojego profilu do pracy"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Przez administratora Twojego profilu służbowego"</string>
<string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Przez <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
<string name="work_profile_deleted" msgid="5891181538182009328">"Usunięto profil służbowy"</string>
- <string name="work_profile_deleted_details" msgid="3773706828364418016">"Brakuje aplikacji administratora profilu do pracy lub jest ona uszkodzona. Dlatego Twój profil służbowy i związane z nim dane zostały usunięte. Skontaktuj się ze swoim administratorem, by uzyskać pomoc."</string>
+ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Brakuje aplikacji administratora profilu służbowego lub jest ona uszkodzona. Dlatego Twój profil służbowy i związane z nim dane zostały usunięte. Skontaktuj się ze swoim administratorem, by uzyskać pomoc."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Twój profil służbowy nie jest już dostępny na tym urządzeniu"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Zbyt wiele prób podania hasła"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator odstąpił urządzenie do użytku osobistego"</string>
@@ -204,8 +204,8 @@
<string name="factory_reset_warning" msgid="6858705527798047809">"Twoje urządzenie zostanie wyczyszczone"</string>
<string name="factory_reset_message" msgid="2657049595153992213">"Nie można użyć aplikacji administratora. Dane z urządzenia zostaną wykasowane.\n\nJeśli masz pytania, skontaktuj się z administratorem organizacji."</string>
<string name="printing_disabled_by" msgid="3517499806528864633">"Drukowanie wyłączone przez: <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
- <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Włącz profil do pracy"</string>
- <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Zablokowano aplikacje osobiste do czasu włączenia profilu do pracy"</string>
+ <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Włącz profil służbowy"</string>
+ <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Zablokowano aplikacje osobiste do czasu włączenia profilu służbowego"</string>
<string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"Aplikacje osobiste zostaną zablokowane <xliff:g id="DATE">%1$s</xliff:g> o <xliff:g id="TIME">%2$s</xliff:g>. Administrator IT nie pozwala na wyłączenie profilu służbowego na dłużej niż <xliff:g id="NUMBER">%3$d</xliff:g> dni."</string>
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"Włącz"</string>
<string name="me" msgid="6207584824693813140">"Ja"</string>
@@ -709,7 +709,7 @@
<string-array name="phoneTypes">
<item msgid="8996339953292723951">"Dom"</item>
<item msgid="7740243458912727194">"Komórka"</item>
- <item msgid="8526146065496663766">"Praca"</item>
+ <item msgid="8526146065496663766">"Służbowy"</item>
<item msgid="8150904584178569699">"Faks w pracy"</item>
<item msgid="4537253139152229577">"Faks domowy"</item>
<item msgid="6751245029698664340">"Pager"</item>
@@ -718,24 +718,24 @@
</string-array>
<string-array name="emailAddressTypes">
<item msgid="7786349763648997741">"Dom"</item>
- <item msgid="435564470865989199">"Praca"</item>
+ <item msgid="435564470865989199">"Służbowy"</item>
<item msgid="4199433197875490373">"Inne"</item>
<item msgid="3233938986670468328">"Niestandardowy"</item>
</string-array>
<string-array name="postalAddressTypes">
<item msgid="3861463339764243038">"Dom"</item>
- <item msgid="5472578890164979109">"Praca"</item>
+ <item msgid="5472578890164979109">"Służbowy"</item>
<item msgid="5718921296646594739">"Inny"</item>
<item msgid="5523122236731783179">"Niestandardowy"</item>
</string-array>
<string-array name="imAddressTypes">
<item msgid="588088543406993772">"Dom"</item>
- <item msgid="5503060422020476757">"Praca"</item>
+ <item msgid="5503060422020476757">"Służbowy"</item>
<item msgid="2530391194653760297">"Inne"</item>
<item msgid="7640927178025203330">"Niestandardowy"</item>
</string-array>
<string-array name="organizationTypes">
- <item msgid="6144047813304847762">"Praca"</item>
+ <item msgid="6144047813304847762">"Służbowy"</item>
<item msgid="7402720230065674193">"Inne"</item>
<item msgid="808230403067569648">"Niestandardowy"</item>
</string-array>
@@ -1453,8 +1453,8 @@
<string name="deny" msgid="6632259981847676572">"Odmów"</string>
<string name="permission_request_notification_title" msgid="1810025922441048273">"Prośba o pozwolenie"</string>
<string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Prośba o pozwolenie\ndotyczące konta <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
- <string name="forward_intent_to_owner" msgid="4620359037192871015">"Używasz tej aplikacji poza profilem do pracy"</string>
- <string name="forward_intent_to_work" msgid="3620262405636021151">"Używasz tej aplikacji w swoim profilu do pracy"</string>
+ <string name="forward_intent_to_owner" msgid="4620359037192871015">"Używasz tej aplikacji poza profilem służbowym"</string>
+ <string name="forward_intent_to_work" msgid="3620262405636021151">"Używasz tej aplikacji w swoim profilu służbowym"</string>
<string name="input_method_binding_label" msgid="1166731601721983656">"Sposób wprowadzania tekstu"</string>
<string name="sync_binding_label" msgid="469249309424662147">"Synchronizacja"</string>
<string name="accessibility_binding_label" msgid="1974602776545801715">"Ułatwienia dostępu"</string>
@@ -1591,7 +1591,7 @@
<string name="SetupCallDefault" msgid="5581740063237175247">"Odebrać połączenie?"</string>
<string name="activity_resolver_use_always" msgid="5575222334666843269">"Zawsze"</string>
<string name="activity_resolver_use_once" msgid="948462794469672658">"Tylko raz"</string>
- <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s nie obsługuje profilu do pracy"</string>
+ <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s nie obsługuje profilu służbowego"</string>
<string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"Tablet"</string>
<string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Telewizor"</string>
<string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
@@ -1828,7 +1828,7 @@
<string name="select_day" msgid="2060371240117403147">"Wybierz miesiąc i dzień"</string>
<string name="select_year" msgid="1868350712095595393">"Wybierz rok"</string>
<string name="deleted_key" msgid="9130083334943364001">"<xliff:g id="KEY">%1$s</xliff:g> usunięte"</string>
- <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (praca)"</string>
+ <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (służbowy)"</string>
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> – praca 2"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> – praca 3"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Podaj PIN, aby odpiąć"</string>
@@ -1950,8 +1950,8 @@
<string name="app_suspended_default_message" msgid="6451215678552004172">"Aplikacja <xliff:g id="APP_NAME_0">%1$s</xliff:g> nie jest teraz dostępna. Zarządza tym aplikacja <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"Więcej informacji"</string>
<string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Wznów działanie aplikacji"</string>
- <string name="work_mode_off_title" msgid="5503291976647976560">"Włączyć profil do pracy?"</string>
- <string name="work_mode_off_message" msgid="8417484421098563803">"Aplikacje do pracy, powiadomienia, dane i inne funkcje profilu do pracy zostaną włączone"</string>
+ <string name="work_mode_off_title" msgid="5503291976647976560">"Włączyć profil służbowy?"</string>
+ <string name="work_mode_off_message" msgid="8417484421098563803">"Aplikacje służbowe, powiadomienia, dane i inne funkcje profilu służbowego zostaną włączone"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Włącz"</string>
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacja jest niedostępna"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest obecnie niedostępna."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 5dc9e5d..3f2c6df 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1261,7 +1261,7 @@
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Выбран режим \"Без звука\""</string>
<string name="volume_call" msgid="7625321655265747433">"Громкость при разговоре"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Громкость при разговоре"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"Громкость сигнала предупреждения"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"Громкость будильника"</string>
<string name="volume_notification" msgid="6864412249031660057">"Громкость уведомления"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Громкость"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Громкость Bluetooth-устройства"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 7ec6d23..105ee44 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -123,28 +123,28 @@
<string name="roamingText11" msgid="5245687407203281407">"Банер роминга је укључен"</string>
<string name="roamingText12" msgid="673537506362152640">"Банер роминга је искључен"</string>
<string name="roamingTextSearching" msgid="5323235489657753486">"Претраживање услуге"</string>
- <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Подешавање позивања преко WiFi-ја није успело"</string>
+ <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Подешавање позивања преко WiFi-а није успело"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="468830943567116703">"Да бисте упућивали позиве и слали поруке преко WiFi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко WiFi-ја. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ <item msgid="468830943567116703">"Да бисте упућивали позиве и слали поруке преко WiFi-а, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко WiFi-а. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
<item msgid="4795145070505729156">"Проблем у вези са регистровањем позивања преко Wi‑Fi-ја код мобилног оператера: <xliff:g id="CODE">%1$s</xliff:g>"</item>
</string-array>
<!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
<skip />
- <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> позивање преко WiFi-ја"</string>
- <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – позивање преко WiFi-ја"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> позивање преко WiFi-а"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – позивање преко WiFi-а"</string>
<string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN позив"</string>
<string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN позив"</string>
<string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> WiFi"</string>
- <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Позивање преко WiFi-ја | <xliff:g id="SPN">%s</xliff:g>"</string>
+ <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Позивање преко WiFi-а | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
- <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Позивање преко WiFi-ја"</string>
+ <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Позивање преко WiFi-а"</string>
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WiFi"</string>
- <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Позивање преко WiFi-ја"</string>
+ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Позивање преко WiFi-а"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Искључено"</string>
- <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Позивање преко WiFi-ја"</string>
+ <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Позивање преко WiFi-а"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Позив преко мобилне мреже"</string>
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Само WiFi"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2476a2d..45a0354 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -305,7 +305,7 @@
<string name="permgroupdesc_storage" msgid="6351503740613026600">"ifikie picha, maudhui na faili kwenye kifaa chako"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Maikrofoni"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"irekodi sauti"</string>
- <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Shughuli za kimwili"</string>
+ <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Mazoezi ya mwili"</string>
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ifikie shughuli zako za kimwili"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ipige picha na kurekodi video"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 32ea979..9b0d9a2 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1307,7 +1307,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"அனலாக் ஆடியோ துணைக்கருவி கண்டறியப்பட்டது"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"இணைத்துள்ள சாதனமானது இந்த மொபைலுடன் இணங்கவில்லை. மேலும் அறிய, தட்டவும்."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"USB பிழைதிருத்தத்தை ஆஃப் செய்ய தட்டவும்"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"USB பிழைதிருத்தத்தை ஆஃப் செய்யத் தட்டவும்"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB பிழைதிருத்தத்தை முடக்க, தேர்ந்தெடுக்கவும்."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"வைஃபை பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"வைஃபை பிழைதிருத்தத்தை ஆஃப் செய்ய தட்டவும்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index b3137e6..b97c6c7 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -822,12 +822,12 @@
<string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"అన్లాక్ చేయడానికి పాస్వర్డ్ను టైప్ చేయండి"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"అన్లాక్ చేయడానికి పిన్ను టైప్ చేయండి"</string>
<string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"చెల్లని పిన్ కోడ్."</string>
- <string name="keyguard_label_text" msgid="3841953694564168384">"అన్లాక్ చేయడానికి, మెను ఆపై 0ని నొక్కండి."</string>
+ <string name="keyguard_label_text" msgid="3841953694564168384">"అన్లాక్ చేయడానికి, మెనూ ఆపై 0ని నొక్కండి."</string>
<string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"అత్యవసర నంబర్"</string>
<string name="lockscreen_carrier_default" msgid="6192313772955399160">"సేవ లేదు"</string>
<string name="lockscreen_screen_locked" msgid="7364905540516041817">"స్క్రీన్ లాక్ చేయబడింది."</string>
- <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"అన్లాక్ చేయడానికి లేదా అత్యవసర కాల్ చేయడానికి మెను నొక్కండి."</string>
- <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"అన్లాక్ చేయడానికి మెను నొక్కండి."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"అన్లాక్ చేయడానికి లేదా అత్యవసర కాల్ చేయడానికి మెనూ నొక్కండి."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"అన్లాక్ చేయడానికి మెనూ నొక్కండి."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"అన్లాక్ చేయడానికి నమూనాను గీయండి"</string>
<string name="lockscreen_emergency_call" msgid="7500692654885445299">"అత్యవసరం"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"కాల్కు తిరిగి వెళ్లు"</string>
@@ -970,7 +970,7 @@
<string name="text_copied" msgid="2531420577879738860">"వచనం క్లిప్బోర్డ్కు కాపీ చేయబడింది."</string>
<string name="copied" msgid="4675902854553014676">"కాపీ చేయబడింది"</string>
<string name="more_item_label" msgid="7419249600215749115">"ఎక్కువ"</string>
- <string name="prepend_shortcut_label" msgid="1743716737502867951">"మెను+"</string>
+ <string name="prepend_shortcut_label" msgid="1743716737502867951">"మెనూ+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
<string name="menu_ctrl_shortcut_label" msgid="131911133027196485">"Ctrl+"</string>
<string name="menu_alt_shortcut_label" msgid="343761069945250991">"Alt+"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4cea142..03c6568 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1792,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Na-update ng iyong admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Na-delete ng iyong admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Para patagalin ang baterya, ginagawa ng Pangtipid sa Baterya na:\n\n•I-on ang Madilim na tema\n•I-off o paghigpitan ang aktibidad sa background, ilang visual effect, at iba pang feature gaya ng “Hey Google”\n\n"<annotation id="url">"Matuto pa"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"Para patagalin ang baterya, ginagawa ng Pangtipid sa Baterya na:\n\n•I-on ang Madilim na tema\n•I-off o paghigpitan ang aktibidad sa background, ilang visual effect, at iba pang feature gaya ng “Hey Google”"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Para patagalin ang baterya, ginagawa ng Pantipid ng Baterya na:\n\n•I-on ang Madilim na tema\n•I-off o paghigpitan ang aktibidad sa background, ilang visual effect, at iba pang feature gaya ng “Hey Google”\n\n"<annotation id="url">"Matuto pa"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"Para patagalin ang baterya, ginagawa ng Pantipid ng Baterya na:\n\n•I-on ang Madilim na tema\n•I-off o paghigpitan ang aktibidad sa background, ilang visual effect, at iba pang feature gaya ng “Hey Google”"</string>
<string name="data_saver_description" msgid="4995164271550590517">"Upang makatulong na mabawasan ang paggamit ng data, pinipigilan ng Data Saver ang ilang app na magpadala o makatanggap ng data sa background. Maaaring mag-access ng data ang isang app na ginagamit mo sa kasalukuyan, ngunit mas bihira na nito magagawa iyon. Halimbawa, maaaring hindi lumabas ang mga larawan hangga\'t hindi mo nata-tap ang mga ito."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"I-on ang Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"I-on"</string>
@@ -1999,9 +1999,9 @@
<string name="notification_appops_overlay_active" msgid="5571732753262836481">"ipinapakita sa ibabaw ng ibang app sa iyong screen"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification ng impormasyon ng Routine Mode"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Maaaring maubos ang baterya bago ang karaniwang pag-charge"</string>
- <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Na-activate ang Pangtipid sa Baterya para patagalin ang buhay ng baterya"</string>
- <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Pangtipid sa Baterya"</string>
- <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Na-off ang Pangtipid sa Baterya"</string>
+ <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Na-activate ang Pantipid ng Baterya para patagalin ang buhay ng baterya"</string>
+ <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Pantipid ng Baterya"</string>
+ <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Na-off ang Pantipid ng Baterya"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"May sapat na charge ang telepono. Hindi na pinaghihigpitan ang mga feature."</string>
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"May sapat na charge ang tablet. Hindi na pinaghihigpitan ang mga feature."</string>
<string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"May sapat na charge ang device. Hindi na pinaghihigpitan ang mga feature."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 09b670b..1f00a5d 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1259,9 +1259,9 @@
<string name="volume_music" msgid="7727274216734955095">"Гучність медіа"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Відтвор. через Bluetooth"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Установлено сигнал дзвінка без звуку"</string>
- <string name="volume_call" msgid="7625321655265747433">"Обсяг вхідних"</string>
- <string name="volume_bluetooth_call" msgid="2930204618610115061">"Обсяг вхідних Bluetooth"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"Гучн. сповіщ."</string>
+ <string name="volume_call" msgid="7625321655265747433">"Гучність під час розмови"</string>
+ <string name="volume_bluetooth_call" msgid="2930204618610115061">"Гучність у викликах Bluetooth"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"Гучність будильника"</string>
<string name="volume_notification" msgid="6864412249031660057">"Гучність сповіщень"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Гучність"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Гучність Bluetooth"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 44c217c..34c4896 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1219,7 +1219,7 @@
<string name="volume_music" msgid="7727274216734955095">"Multimedia tovushi"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth orqali ijro etilmoqda"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Ovozsiz rejim tanlandi"</string>
- <string name="volume_call" msgid="7625321655265747433">"Suhbat vaqtidagi tovush balandligi"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Suhbat tovushi"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Kiruvchi bluetooth tovushi"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Signal tovushi"</string>
<string name="volume_notification" msgid="6864412249031660057">"Eslatma tovushi"</string>
@@ -1231,7 +1231,7 @@
<string name="volume_icon_description_notification" msgid="579091344110747279">"Eslatma tovushi"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Standart rington"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Standart (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="397111123930141876">"Yo‘q"</string>
+ <string name="ringtone_silent" msgid="397111123930141876">"Hech qanday"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"Ringtonlar"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Signal ovozlari"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Bildirishnoma ovozlari"</string>
diff --git a/graphics/java/android/graphics/GraphicsStatsService.java b/graphics/java/android/graphics/GraphicsStatsService.java
index 8dfd6ee..2d6848b 100644
--- a/graphics/java/android/graphics/GraphicsStatsService.java
+++ b/graphics/java/android/graphics/GraphicsStatsService.java
@@ -16,7 +16,6 @@
package android.graphics;
-import android.annotation.SystemApi;
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.content.Context;
@@ -100,7 +99,6 @@
private Handler mWriteOutHandler;
private boolean mRotateIsScheduled = false;
- @SystemApi
public GraphicsStatsService(Context context) {
mContext = context;
mAppOps = context.getSystemService(AppOpsManager.class);
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index f82d8b6..f1eea82 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
@@ -46,7 +45,6 @@
* @hide
*/
@SystemApi
-@TestApi
public abstract class AttestationUtils {
private AttestationUtils() {
}
diff --git a/keystore/java/android/security/keystore/DeviceIdAttestationException.java b/keystore/java/android/security/keystore/DeviceIdAttestationException.java
index 8ba0317..4f9f9e6 100644
--- a/keystore/java/android/security/keystore/DeviceIdAttestationException.java
+++ b/keystore/java/android/security/keystore/DeviceIdAttestationException.java
@@ -18,7 +18,6 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
/**
* Thrown when {@link AttestationUtils} is unable to attest the given device ids.
@@ -26,7 +25,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class DeviceIdAttestationException extends Exception {
/**
* Constructs a new {@code DeviceIdAttestationException} with the current stack trace and the
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index 9aa0c87..fa3815c 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -17,7 +17,6 @@
package android.location;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Bundle;
@@ -73,7 +72,6 @@
* gps locations separate from other locations for coarsening. Providers that do not need to
* support platforms below Android R should not use this constant.
*/
- @TestApi
@SystemApi
@Deprecated
public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
@@ -1062,7 +1060,6 @@
* @see #isComplete
* @hide
*/
- @TestApi
@SystemApi
public void makeComplete() {
if (mProvider == null) mProvider = "?";
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 2a2aaea..0c7d96d 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -514,7 +514,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(WRITE_SECURE_SETTINGS)
public void setLocationEnabledForUser(boolean enabled, @NonNull UserHandle userHandle) {
try {
@@ -708,7 +707,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void getCurrentLocation(@NonNull LocationRequest locationRequest,
@Nullable CancellationSignal cancellationSignal,
@@ -1130,7 +1128,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestLocationUpdates(
@Nullable LocationRequest locationRequest,
@@ -1158,7 +1155,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestLocationUpdates(
@Nullable LocationRequest locationRequest,
@@ -1209,7 +1205,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestLocationUpdates(
@Nullable LocationRequest locationRequest,
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 5f0acc8..1708c25 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -21,7 +21,6 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
@@ -94,7 +93,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class LocationRequest implements Parcelable {
/**
* Used with {@link #setQuality} to request the most accurate locations available.
diff --git a/media/java/android/media/AudioFocusInfo.java b/media/java/android/media/AudioFocusInfo.java
index 675cf73..3647b6e 100644
--- a/media/java/android/media/AudioFocusInfo.java
+++ b/media/java/android/media/AudioFocusInfo.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,7 +28,6 @@
* @hide
* A class to encapsulate information about an audio focus owner or request.
*/
-@TestApi
@SystemApi
public final class AudioFocusInfo implements Parcelable {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 3ac71b2..83e7fb5 100755
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3449,7 +3449,6 @@
* @param requestResult the result to the focus request to be passed to the requester
* @param ap a valid registered {@link AudioPolicy} configured as a focus policy.
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public void setFocusRequestResult(@NonNull AudioFocusInfo afi,
@@ -3489,7 +3488,6 @@
* if there was an error sending the request.
* @throws NullPointerException if the {@link AudioFocusInfo} or {@link AudioPolicy} are null.
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int dispatchAudioFocusChange(@NonNull AudioFocusInfo afi, int focusChange,
@@ -3752,7 +3750,6 @@
* {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission,
* {@link #SUCCESS} otherwise.
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int registerAudioPolicy(@NonNull AudioPolicy policy) {
@@ -3787,7 +3784,6 @@
* Unregisters an {@link AudioPolicy} asynchronously.
* @param policy the non-null {@link AudioPolicy} to unregister.
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public void unregisterAudioPolicyAsync(@NonNull AudioPolicy policy) {
@@ -3814,7 +3810,6 @@
* associated with mixes of this policy.
* @param policy the non-null {@link AudioPolicy} to unregister.
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public void unregisterAudioPolicy(@NonNull AudioPolicy policy) {
@@ -5153,7 +5148,6 @@
*/
/** @hide */
- @TestApi
@SystemApi
public static final int SUCCESS = AudioSystem.SUCCESS;
/**
diff --git a/media/java/android/media/MediaMetrics.java b/media/java/android/media/MediaMetrics.java
index eaf86bb..3a5216e 100644
--- a/media/java/android/media/MediaMetrics.java
+++ b/media/java/android/media/MediaMetrics.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.TestApi;
import android.os.Bundle;
import java.nio.ByteBuffer;
@@ -583,7 +582,6 @@
*
* @return a Bundle with the keys set according to data in the Item's buffer.
*/
- @TestApi
public Bundle toBundle() {
updateHeader();
@@ -596,23 +594,14 @@
// The following constants are used for tests to extract
// the content of the Bundle for CTS testing.
- @TestApi
public static final String BUNDLE_TOTAL_SIZE = "_totalSize";
- @TestApi
public static final String BUNDLE_HEADER_SIZE = "_headerSize";
- @TestApi
public static final String BUNDLE_VERSION = "_version";
- @TestApi
public static final String BUNDLE_KEY_SIZE = "_keySize";
- @TestApi
public static final String BUNDLE_KEY = "_key";
- @TestApi
public static final String BUNDLE_PID = "_pid";
- @TestApi
public static final String BUNDLE_UID = "_uid";
- @TestApi
public static final String BUNDLE_TIMESTAMP = "_timestamp";
- @TestApi
public static final String BUNDLE_PROPERTY_COUNT = "_propertyCount";
/**
@@ -623,7 +612,6 @@
* @param buffer contains the byte data serialized according to the byte string version.
* @return a Bundle with the keys set according to data in the buffer.
*/
- @TestApi
public static Bundle toBundle(ByteBuffer buffer) {
final Bundle bundle = new Bundle();
diff --git a/media/java/android/media/Utils.java b/media/java/android/media/Utils.java
index 7a4e7b8..ecb6b3d 100644
--- a/media/java/android/media/Utils.java
+++ b/media/java/android/media/Utils.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.TestApi;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
@@ -440,7 +439,6 @@
*
* @param <V> The class of the object returned to the listener.
*/
- @TestApi
public static class ListenerList<V> {
/**
* The Listener interface for callback.
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index 61113bc..4e451c6 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -19,7 +19,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
@@ -32,7 +31,6 @@
/**
* @hide
*/
-@TestApi
@SystemApi
public class AudioMix {
diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java
index 68c9593..f6f982a 100644
--- a/media/java/android/media/audiopolicy/AudioMixingRule.java
+++ b/media/java/android/media/audiopolicy/AudioMixingRule.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.media.AudioAttributes;
import android.os.Parcel;
@@ -42,7 +41,6 @@
* .build();
* </pre>
*/
-@TestApi
@SystemApi
public class AudioMixingRule {
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index d3e9c7e..098b65c 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -58,7 +58,6 @@
* @hide
* AudioPolicy provides access to the management of audio routing and audio focus.
*/
-@TestApi
@SystemApi
public class AudioPolicy {
@@ -418,7 +417,6 @@
* @param devices list of devices to which the audio stream of the application may be routed.
* @return true if the change was successful, false otherwise.
*/
- @TestApi
@SystemApi
public boolean setUidDeviceAffinity(int uid, @NonNull List<AudioDeviceInfo> devices) {
if (devices == null) {
@@ -460,7 +458,6 @@
* @param uid UID of the application affected.
* @return true if the change was successful, false otherwise.
*/
- @TestApi
@SystemApi
public boolean removeUidDeviceAffinity(int uid) {
synchronized (mLock) {
@@ -486,7 +483,6 @@
* {@link UserHandle#getIdentifier}. Not to be confused with application uid.
* @return true if the change was successful, false otherwise.
*/
- @TestApi
@SystemApi
public boolean removeUserIdDeviceAffinity(@UserIdInt int userId) {
synchronized (mLock) {
@@ -519,7 +515,6 @@
* @param devices list of devices to which the audio stream of the application may be routed.
* @return true if the change was successful, false otherwise.
*/
- @TestApi
@SystemApi
public boolean setUserIdDeviceAffinity(@UserIdInt int userId,
@NonNull List<AudioDeviceInfo> devices) {
diff --git a/media/java/android/media/audiopolicy/AudioProductStrategy.java b/media/java/android/media/audiopolicy/AudioProductStrategy.java
index 090f78e..fca3498 100644
--- a/media/java/android/media/audiopolicy/AudioProductStrategy.java
+++ b/media/java/android/media/audiopolicy/AudioProductStrategy.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.media.AudioAttributes;
import android.media.AudioSystem;
import android.media.MediaRecorder;
@@ -108,7 +107,6 @@
* @param id the ID for the invalid strategy, always use a different one than in use
* @return an invalid instance that cannot successfully be used for volume groups or routing
*/
- @TestApi
@SystemApi
public static @NonNull AudioProductStrategy createInvalidAudioProductStrategy(int id) {
return new AudioProductStrategy("dummy strategy", id, new AudioAttributesGroup[0]);
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index 5f15216..086ba81 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -3712,7 +3712,7 @@
ctor public ActionBar.LayoutParams(int);
ctor public ActionBar.LayoutParams(android.app.ActionBar.LayoutParams);
ctor public ActionBar.LayoutParams(android.view.ViewGroup.LayoutParams);
- field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=0xffffffff, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.NO_GRAVITY, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.TOP, to="TOP"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.BOTTOM, to="BOTTOM"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.LEFT, to="LEFT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.RIGHT, to="RIGHT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.START, to="START"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.END, to="END"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_VERTICAL, to="CENTER_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_VERTICAL, to="FILL_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_HORIZONTAL, to="CENTER_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_HORIZONTAL, to="FILL_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL, to="FILL")}) public int gravity;
+ field public int gravity;
}
public static interface ActionBar.OnMenuVisibilityListener {
@@ -10092,7 +10092,7 @@
method public final <T> T getSystemService(@NonNull Class<T>);
method @Nullable public abstract String getSystemServiceName(@NonNull Class<?>);
method @NonNull public final CharSequence getText(@StringRes int);
- method @android.view.ViewDebug.ExportedProperty(deepExport=true) public abstract android.content.res.Resources.Theme getTheme();
+ method public abstract android.content.res.Resources.Theme getTheme();
method @Deprecated public abstract android.graphics.drawable.Drawable getWallpaper();
method @Deprecated public abstract int getWallpaperDesiredMinimumHeight();
method @Deprecated public abstract int getWallpaperDesiredMinimumWidth();
@@ -51999,13 +51999,13 @@
method @Nullable public CharSequence getAccessibilityPaneTitle();
method @IdRes public int getAccessibilityTraversalAfter();
method @IdRes public int getAccessibilityTraversalBefore();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getAlpha();
+ method public float getAlpha();
method public android.view.animation.Animation getAnimation();
method @Nullable public android.graphics.Matrix getAnimationMatrix();
method public android.os.IBinder getApplicationWindowToken();
method @NonNull public int[] getAttributeResolutionStack(@AttrRes int);
method @NonNull public java.util.Map<java.lang.Integer,java.lang.Integer> getAttributeSourceResourceMap();
- method @android.view.ViewDebug.ExportedProperty @Nullable public String[] getAutofillHints();
+ method @Nullable public String[] getAutofillHints();
method public final android.view.autofill.AutofillId getAutofillId();
method public int getAutofillType();
method @Nullable public android.view.autofill.AutofillValue getAutofillValue();
@@ -52013,8 +52013,8 @@
method @Nullable public android.graphics.BlendMode getBackgroundTintBlendMode();
method @Nullable public android.content.res.ColorStateList getBackgroundTintList();
method @Nullable public android.graphics.PorterDuff.Mode getBackgroundTintMode();
- method @android.view.ViewDebug.ExportedProperty(category="layout") public int getBaseline();
- method @android.view.ViewDebug.CapturedViewProperty public final int getBottom();
+ method public int getBaseline();
+ method public final int getBottom();
method protected float getBottomFadingEdgeStrength();
method protected int getBottomPaddingOffset();
method public float getCameraDistance();
@@ -52022,10 +52022,10 @@
method public boolean getClipBounds(android.graphics.Rect);
method public final boolean getClipToOutline();
method @Nullable public final android.view.contentcapture.ContentCaptureSession getContentCaptureSession();
- method @android.view.ViewDebug.ExportedProperty(category="accessibility") public CharSequence getContentDescription();
- method @android.view.ViewDebug.CapturedViewProperty public final android.content.Context getContext();
+ method public CharSequence getContentDescription();
+ method public final android.content.Context getContext();
method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean getDefaultFocusHighlightEnabled();
+ method public final boolean getDefaultFocusHighlightEnabled();
method public static int getDefaultSize(int, int);
method public android.view.Display getDisplay();
method public final int[] getDrawableState();
@@ -52035,11 +52035,11 @@
method @Deprecated public int getDrawingCacheQuality();
method public void getDrawingRect(android.graphics.Rect);
method public long getDrawingTime();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getElevation();
+ method public float getElevation();
method @StyleRes public int getExplicitStyle();
- method @android.view.ViewDebug.ExportedProperty public boolean getFilterTouchesWhenObscured();
- method @android.view.ViewDebug.ExportedProperty public boolean getFitsSystemWindows();
- method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.NOT_FOCUSABLE, to="NOT_FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE, to="FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE_AUTO, to="FOCUSABLE_AUTO")}, category="focus") public int getFocusable();
+ method public boolean getFilterTouchesWhenObscured();
+ method public boolean getFitsSystemWindows();
+ method public int getFocusable();
method public java.util.ArrayList<android.view.View> getFocusables(int);
method public void getFocusedRect(android.graphics.Rect);
method public android.graphics.drawable.Drawable getForeground();
@@ -52051,23 +52051,23 @@
method public final boolean getGlobalVisibleRect(android.graphics.Rect);
method public android.os.Handler getHandler();
method public final boolean getHasOverlappingRendering();
- method @android.view.ViewDebug.ExportedProperty(category="layout") public final int getHeight();
+ method public final int getHeight();
method public void getHitRect(android.graphics.Rect);
method public int getHorizontalFadingEdgeLength();
method protected int getHorizontalScrollbarHeight();
method @Nullable public android.graphics.drawable.Drawable getHorizontalScrollbarThumbDrawable();
method @Nullable public android.graphics.drawable.Drawable getHorizontalScrollbarTrackDrawable();
- method @android.view.ViewDebug.CapturedViewProperty @IdRes public int getId();
- method @android.view.ViewDebug.ExportedProperty(category="accessibility", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS, to="noHideDescendants")}) public int getImportantForAccessibility();
- method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForAutofill();
- method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForContentCapture();
+ method @IdRes public int getId();
+ method public int getImportantForAccessibility();
+ method public int getImportantForAutofill();
+ method public int getImportantForContentCapture();
method public boolean getKeepScreenOn();
method public android.view.KeyEvent.DispatcherState getKeyDispatcherState();
- method @android.view.ViewDebug.ExportedProperty(category="accessibility") @IdRes public int getLabelFor();
+ method @IdRes public int getLabelFor();
method public int getLayerType();
- method @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.LAYOUT_DIRECTION_LTR, to="RESOLVED_DIRECTION_LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.LAYOUT_DIRECTION_RTL, to="RESOLVED_DIRECTION_RTL")}) public int getLayoutDirection();
- method @android.view.ViewDebug.ExportedProperty(deepExport=true, prefix="layout_") public android.view.ViewGroup.LayoutParams getLayoutParams();
- method @android.view.ViewDebug.CapturedViewProperty public final int getLeft();
+ method public int getLayoutDirection();
+ method public android.view.ViewGroup.LayoutParams getLayoutParams();
+ method public final int getLeft();
method protected float getLeftFadingEdgeStrength();
method protected int getLeftPaddingOffset();
method public final boolean getLocalVisibleRect(android.graphics.Rect);
@@ -52076,10 +52076,10 @@
method public void getLocationOnScreen(@Size(2) int[]);
method public android.graphics.Matrix getMatrix();
method public final int getMeasuredHeight();
- method @android.view.ViewDebug.ExportedProperty(category="measurement", flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.View.MEASURED_STATE_MASK, equals=android.view.View.MEASURED_STATE_TOO_SMALL, name="MEASURED_STATE_TOO_SMALL")}) public final int getMeasuredHeightAndState();
+ method public final int getMeasuredHeightAndState();
method public final int getMeasuredState();
method public final int getMeasuredWidth();
- method @android.view.ViewDebug.ExportedProperty(category="measurement", flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.View.MEASURED_STATE_MASK, equals=android.view.View.MEASURED_STATE_TOO_SMALL, name="MEASURED_STATE_TOO_SMALL")}) public final int getMeasuredWidthAndState();
+ method public final int getMeasuredWidthAndState();
method public int getMinimumHeight();
method public int getMinimumWidth();
method @IdRes public int getNextClusterForwardId();
@@ -52102,51 +52102,51 @@
method public int getPaddingTop();
method public final android.view.ViewParent getParent();
method public android.view.ViewParent getParentForAccessibility();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getPivotX();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getPivotY();
+ method public float getPivotX();
+ method public float getPivotY();
method public android.view.PointerIcon getPointerIcon();
method public android.content.res.Resources getResources();
method public final boolean getRevealOnFocusHint();
- method @android.view.ViewDebug.CapturedViewProperty public final int getRight();
+ method public final int getRight();
method protected float getRightFadingEdgeStrength();
method protected int getRightPaddingOffset();
method public android.view.View getRootView();
method public android.view.WindowInsets getRootWindowInsets();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotation();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotationX();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotationY();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getScaleX();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getScaleY();
+ method public float getRotation();
+ method public float getRotationX();
+ method public float getRotationY();
+ method public float getScaleX();
+ method public float getScaleY();
method public int getScrollBarDefaultDelayBeforeFade();
method public int getScrollBarFadeDuration();
method public int getScrollBarSize();
- method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_INSIDE_OVERLAY, to="INSIDE_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_INSIDE_INSET, to="INSIDE_INSET"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_OUTSIDE_OVERLAY, to="OUTSIDE_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_OUTSIDE_INSET, to="OUTSIDE_INSET")}) public int getScrollBarStyle();
+ method public int getScrollBarStyle();
method public int getScrollIndicators();
method public final int getScrollX();
method public final int getScrollY();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") @ColorInt public int getSolidColor();
+ method @ColorInt public int getSolidColor();
method @LayoutRes public int getSourceLayoutResId();
- method @android.view.ViewDebug.ExportedProperty(category="accessibility") @Nullable public final CharSequence getStateDescription();
+ method @Nullable public final CharSequence getStateDescription();
method public android.animation.StateListAnimator getStateListAnimator();
method protected int getSuggestedMinimumHeight();
method protected int getSuggestedMinimumWidth();
method @NonNull public java.util.List<android.graphics.Rect> getSystemGestureExclusionRects();
method @Deprecated public int getSystemUiVisibility();
- method @android.view.ViewDebug.ExportedProperty public Object getTag();
+ method public Object getTag();
method public Object getTag(int);
- method @android.view.ViewDebug.ExportedProperty(category="text", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_INHERIT, to="INHERIT"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_GRAVITY, to="GRAVITY"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_TEXT_START, to="TEXT_START"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_TEXT_END, to="TEXT_END"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_VIEW_START, to="VIEW_START"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_VIEW_END, to="VIEW_END")}) public int getTextAlignment();
- method @android.view.ViewDebug.ExportedProperty(category="text", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_INHERIT, to="INHERIT"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG, to="FIRST_STRONG"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_ANY_RTL, to="ANY_RTL"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_LTR, to="LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_RTL, to="RTL"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_LOCALE, to="LOCALE"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG_LTR, to="FIRST_STRONG_LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG_RTL, to="FIRST_STRONG_RTL")}) public int getTextDirection();
+ method public int getTextAlignment();
+ method public int getTextDirection();
method @Nullable public CharSequence getTooltipText();
- method @android.view.ViewDebug.CapturedViewProperty public final int getTop();
+ method public final int getTop();
method protected float getTopFadingEdgeStrength();
method protected int getTopPaddingOffset();
method public android.view.TouchDelegate getTouchDelegate();
method public java.util.ArrayList<android.view.View> getTouchables();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTransitionAlpha();
- method @android.view.ViewDebug.ExportedProperty public String getTransitionName();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationX();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationY();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationZ();
+ method public float getTransitionAlpha();
+ method public String getTransitionName();
+ method public float getTranslationX();
+ method public float getTranslationY();
+ method public float getTranslationZ();
method public long getUniqueDrawingId();
method public int getVerticalFadingEdgeLength();
method public int getVerticalScrollbarPosition();
@@ -52154,8 +52154,8 @@
method @Nullable public android.graphics.drawable.Drawable getVerticalScrollbarTrackDrawable();
method public int getVerticalScrollbarWidth();
method public android.view.ViewTreeObserver getViewTreeObserver();
- method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.VISIBLE, to="VISIBLE"), @android.view.ViewDebug.IntToString(from=android.view.View.INVISIBLE, to="INVISIBLE"), @android.view.ViewDebug.IntToString(from=android.view.View.GONE, to="GONE")}) public int getVisibility();
- method @android.view.ViewDebug.ExportedProperty(category="layout") public final int getWidth();
+ method public int getVisibility();
+ method public final int getWidth();
method protected int getWindowAttachCount();
method public android.view.WindowId getWindowId();
method @Nullable public android.view.WindowInsetsController getWindowInsetsController();
@@ -52163,18 +52163,18 @@
method public android.os.IBinder getWindowToken();
method public int getWindowVisibility();
method public void getWindowVisibleDisplayFrame(android.graphics.Rect);
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getX();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getY();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getZ();
+ method public float getX();
+ method public float getY();
+ method public float getZ();
method public boolean hasExplicitFocusable();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean hasFocus();
+ method public boolean hasFocus();
method public boolean hasFocusable();
method public boolean hasNestedScrollingParent();
method public boolean hasOnClickListeners();
method public boolean hasOnLongClickListeners();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean hasOverlappingRendering();
+ method public boolean hasOverlappingRendering();
method public boolean hasPointerCapture();
- method @android.view.ViewDebug.ExportedProperty(category="layout") public boolean hasTransientState();
+ method public boolean hasTransientState();
method public boolean hasWindowFocus();
method public static android.view.View inflate(android.content.Context, @LayoutRes int, android.view.ViewGroup);
method @Deprecated public void invalidate(android.graphics.Rect);
@@ -52184,50 +52184,50 @@
method public void invalidateOutline();
method public boolean isAccessibilityFocused();
method public boolean isAccessibilityHeading();
- method @android.view.ViewDebug.ExportedProperty public boolean isActivated();
+ method public boolean isActivated();
method public boolean isAttachedToWindow();
- method @android.view.ViewDebug.ExportedProperty public boolean isClickable();
+ method public boolean isClickable();
method public boolean isContextClickable();
method public boolean isDirty();
- method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isDrawingCacheEnabled();
+ method @Deprecated public boolean isDrawingCacheEnabled();
method public boolean isDuplicateParentStateEnabled();
- method @android.view.ViewDebug.ExportedProperty public boolean isEnabled();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusable();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusableInTouchMode();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean isFocused();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusedByDefault();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isForceDarkAllowed();
- method @android.view.ViewDebug.ExportedProperty public boolean isHapticFeedbackEnabled();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isHardwareAccelerated();
+ method public boolean isEnabled();
+ method public final boolean isFocusable();
+ method public final boolean isFocusableInTouchMode();
+ method public boolean isFocused();
+ method public final boolean isFocusedByDefault();
+ method public boolean isForceDarkAllowed();
+ method public boolean isHapticFeedbackEnabled();
+ method public boolean isHardwareAccelerated();
method public boolean isHorizontalFadingEdgeEnabled();
method public boolean isHorizontalScrollBarEnabled();
- method @android.view.ViewDebug.ExportedProperty public boolean isHovered();
+ method public boolean isHovered();
method public boolean isImportantForAccessibility();
method public final boolean isImportantForAutofill();
method public final boolean isImportantForContentCapture();
method public boolean isInEditMode();
method public boolean isInLayout();
- method @android.view.ViewDebug.ExportedProperty public boolean isInTouchMode();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isKeyboardNavigationCluster();
+ method public boolean isInTouchMode();
+ method public final boolean isKeyboardNavigationCluster();
method public boolean isLaidOut();
method public boolean isLayoutDirectionResolved();
method public boolean isLayoutRequested();
method public boolean isLongClickable();
method public boolean isNestedScrollingEnabled();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isOpaque();
+ method public boolean isOpaque();
method protected boolean isPaddingOffsetRequired();
method public boolean isPaddingRelative();
method public boolean isPivotSet();
- method @android.view.ViewDebug.ExportedProperty public boolean isPressed();
+ method public boolean isPressed();
method public boolean isSaveEnabled();
method public boolean isSaveFromParentEnabled();
method public boolean isScreenReaderFocusable();
method public boolean isScrollContainer();
method public boolean isScrollbarFadingEnabled();
- method @android.view.ViewDebug.ExportedProperty public boolean isSelected();
+ method public boolean isSelected();
method public final boolean isShowingLayoutBounds();
method public boolean isShown();
- method @android.view.ViewDebug.ExportedProperty public boolean isSoundEffectsEnabled();
+ method public boolean isSoundEffectsEnabled();
method public final boolean isTemporarilyDetached();
method public boolean isTextAlignmentResolved();
method public boolean isTextDirectionResolved();
@@ -52518,8 +52518,8 @@
method public void unscheduleDrawable(android.graphics.drawable.Drawable);
method public final void updateDragShadow(android.view.View.DragShadowBuilder);
method @CallSuper protected boolean verifyDrawable(@NonNull android.graphics.drawable.Drawable);
- method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean willNotCacheDrawing();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean willNotDraw();
+ method @Deprecated public boolean willNotCacheDrawing();
+ method public boolean willNotDraw();
field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
@@ -52960,9 +52960,9 @@
method public static int getChildMeasureSpec(int, int, int);
method protected boolean getChildStaticTransformation(android.view.View, android.view.animation.Transformation);
method public boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point);
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean getClipChildren();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean getClipToPadding();
- method @android.view.ViewDebug.ExportedProperty(category="focus", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_BEFORE_DESCENDANTS, to="FOCUS_BEFORE_DESCENDANTS"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_AFTER_DESCENDANTS, to="FOCUS_AFTER_DESCENDANTS"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_BLOCK_DESCENDANTS, to="FOCUS_BLOCK_DESCENDANTS")}) public int getDescendantFocusability();
+ method public boolean getClipChildren();
+ method public boolean getClipToPadding();
+ method public int getDescendantFocusability();
method public android.view.View getFocusedChild();
method public android.view.animation.LayoutAnimationController getLayoutAnimation();
method public android.view.animation.Animation.AnimationListener getLayoutAnimationListener();
@@ -52970,14 +52970,14 @@
method public android.animation.LayoutTransition getLayoutTransition();
method public int getNestedScrollAxes();
method public android.view.ViewGroupOverlay getOverlay();
- method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_NO_CACHE, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_ANIMATION_CACHE, to="ANIMATION"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_SCROLLING_CACHE, to="SCROLLING"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_ALL_CACHES, to="ALL")}) public int getPersistentDrawingCache();
- method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean getTouchscreenBlocksFocus();
+ method @Deprecated public int getPersistentDrawingCache();
+ method public boolean getTouchscreenBlocksFocus();
method public int indexOfChild(android.view.View);
method @Deprecated public final void invalidateChild(android.view.View, android.graphics.Rect);
method @Deprecated public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
method @Deprecated public boolean isAlwaysDrawnWithCacheEnabled();
method @Deprecated public boolean isAnimationCacheEnabled();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") protected boolean isChildrenDrawingOrderEnabled();
+ method protected boolean isChildrenDrawingOrderEnabled();
method @Deprecated protected boolean isChildrenDrawnWithCacheEnabled();
method public boolean isLayoutSuppressed();
method public boolean isMotionEventSplittingEnabled();
@@ -53068,9 +53068,9 @@
field @Deprecated public static final int FILL_PARENT = -1; // 0xffffffff
field public static final int MATCH_PARENT = -1; // 0xffffffff
field public static final int WRAP_CONTENT = -2; // 0xfffffffe
- field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.MATCH_PARENT, to="MATCH_PARENT"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.WRAP_CONTENT, to="WRAP_CONTENT")}) public int height;
+ field public int height;
field public android.view.animation.LayoutAnimationController.AnimationParameters layoutAnimationParameters;
- field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.MATCH_PARENT, to="MATCH_PARENT"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.WRAP_CONTENT, to="WRAP_CONTENT")}) public int width;
+ field public int width;
}
public static class ViewGroup.MarginLayoutParams extends android.view.ViewGroup.LayoutParams {
@@ -53086,10 +53086,10 @@
method public void setMarginEnd(int);
method public void setMarginStart(int);
method public void setMargins(int, int, int, int);
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int bottomMargin;
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int leftMargin;
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int rightMargin;
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int topMargin;
+ field public int bottomMargin;
+ field public int leftMargin;
+ field public int rightMargin;
+ field public int topMargin;
}
public static interface ViewGroup.OnHierarchyChangeListener {
@@ -53886,11 +53886,11 @@
field public float alpha;
field public float buttonBrightness;
field public float dimAmount;
- field @android.view.ViewDebug.ExportedProperty(flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, name="ALLOW_LOCK_WHILE_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND, equals=android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND, name="DIM_BEHIND"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND, equals=android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND, name="BLUR_BEHIND"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, name="NOT_FOCUSABLE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, name="NOT_TOUCHABLE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, name="NOT_TOUCH_MODAL"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, equals=android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, name="TOUCHABLE_WHEN_WAKING"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, name="KEEP_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, name="LAYOUT_IN_SCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, name="LAYOUT_NO_LIMITS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN, name="FULLSCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, name="FORCE_NOT_FULLSCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DITHER, equals=android.view.WindowManager.LayoutParams.FLAG_DITHER, name="DITHER"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SECURE, equals=android.view.WindowManager.LayoutParams.FLAG_SECURE, name="SECURE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SCALED, equals=android.view.WindowManager.LayoutParams.FLAG_SCALED, name="SCALED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES, equals=android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES, name="IGNORE_CHEEK_PRESSES"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR, name="LAYOUT_INSET_DECOR"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, equals=android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, name="ALT_FOCUSABLE_IM"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, equals=android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, name="WATCH_OUTSIDE_TOUCH"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, equals=android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, name="SHOW_WHEN_LOCKED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER, equals=android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER, name="SHOW_WALLPAPER"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, name="TURN_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, equals=android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, name="DISMISS_KEYGUARD"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, equals=android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, name="SPLIT_TOUCH"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, equals=android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, name="HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN, name="LOCAL_FOCUS_MODE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, equals=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, name="TRANSLUCENT_STATUS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, equals=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, name="TRANSLUCENT_NAVIGATION"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE, equals=android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE, name="LOCAL_FOCUS_MODE"), @android.view.ViewDebug.FlagToString(mask=0x20000000, equals=0x20000000, name="FLAG_SLIPPERY"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR, name="FLAG_LAYOUT_ATTACHED_IN_DECOR"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, equals=android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, name="DRAWS_SYSTEM_BAR_BACKGROUNDS")}, formatToHexString=true) public int flags;
+ field public int flags;
field public int format;
field public int gravity;
field public float horizontalMargin;
- field @android.view.ViewDebug.ExportedProperty public float horizontalWeight;
+ field public float horizontalWeight;
field public int layoutInDisplayCutoutMode;
field @Deprecated public int memoryType;
field public String packageName;
@@ -53903,12 +53903,12 @@
field public int softInputMode;
field @Deprecated public int systemUiVisibility;
field public android.os.IBinder token;
- field @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION, to="BASE_APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION, to="APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING, to="APPLICATION_STARTING"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION, to="DRAWN_APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, to="APPLICATION_PANEL"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA, to="APPLICATION_MEDIA"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL, to="APPLICATION_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=0x3ed, to="APPLICATION_ABOVE_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG, to="APPLICATION_ATTACHED_DIALOG"), @android.view.ViewDebug.IntToString(from=0x3ec, to="APPLICATION_MEDIA_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR, to="STATUS_BAR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR, to="SEARCH_BAR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PHONE, to="PHONE"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, to="SYSTEM_ALERT"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_TOAST, to="TOAST"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, to="SYSTEM_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE, to="PRIORITY_PHONE"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG, to="SYSTEM_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, to="KEYGUARD_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, to="SYSTEM_ERROR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD, to="INPUT_METHOD"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG, to="INPUT_METHOD_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_WALLPAPER, to="WALLPAPER"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, to="STATUS_BAR_PANEL"), @android.view.ViewDebug.IntToString(from=0x7df, to="SECURE_SYSTEM_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7e0, to="DRAG"), @android.view.ViewDebug.IntToString(from=0x7e1, to="STATUS_BAR_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=0x7e2, to="POINTER"), @android.view.ViewDebug.IntToString(from=0x7e3, to="NAVIGATION_BAR"), @android.view.ViewDebug.IntToString(from=0x7e4, to="VOLUME_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7e5, to="BOOT_PROGRESS"), @android.view.ViewDebug.IntToString(from=0x7e6, to="INPUT_CONSUMER"), @android.view.ViewDebug.IntToString(from=0x7e8, to="NAVIGATION_BAR_PANEL"), @android.view.ViewDebug.IntToString(from=0x7ea, to="DISPLAY_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7eb, to="MAGNIFICATION_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7f5, to="PRESENTATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION, to="PRIVATE_PRESENTATION"), @android.view.ViewDebug.IntToString(from=0x7ef, to="VOICE_INTERACTION"), @android.view.ViewDebug.IntToString(from=0x7f1, to="VOICE_INTERACTION_STARTING"), @android.view.ViewDebug.IntToString(from=0x7f2, to="DOCK_DIVIDER"), @android.view.ViewDebug.IntToString(from=0x7f3, to="QS_DIALOG"), @android.view.ViewDebug.IntToString(from=0x7f4, to="SCREENSHOT"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, to="APPLICATION_OVERLAY")}) public int type;
+ field public int type;
field public float verticalMargin;
- field @android.view.ViewDebug.ExportedProperty public float verticalWeight;
+ field public float verticalWeight;
field public int windowAnimations;
- field @android.view.ViewDebug.ExportedProperty public int x;
- field @android.view.ViewDebug.ExportedProperty public int y;
+ field public int x;
+ field public int y;
}
public final class WindowMetrics {
@@ -56645,21 +56645,21 @@
method public void flingScroll(int, int);
method @Deprecated public void freeMemory();
method @Nullable public android.net.http.SslCertificate getCertificate();
- method @android.view.ViewDebug.ExportedProperty(category="webview") public int getContentHeight();
+ method public int getContentHeight();
method @Nullable public static android.content.pm.PackageInfo getCurrentWebViewPackage();
method @Nullable public android.graphics.Bitmap getFavicon();
method @NonNull public android.webkit.WebView.HitTestResult getHitTestResult();
method @Deprecated @Nullable public String[] getHttpAuthUsernamePassword(String, String);
- method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getOriginalUrl();
+ method @Nullable public String getOriginalUrl();
method public int getProgress();
method public boolean getRendererPriorityWaivedWhenNotVisible();
method public int getRendererRequestedPriority();
method @NonNull public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
- method @Deprecated @android.view.ViewDebug.ExportedProperty(category="webview") public float getScale();
+ method @Deprecated public float getScale();
method @NonNull public android.webkit.WebSettings getSettings();
method @NonNull public android.view.textclassifier.TextClassifier getTextClassifier();
- method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getTitle();
- method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getUrl();
+ method @Nullable public String getTitle();
+ method @Nullable public String getUrl();
method @Nullable public android.webkit.WebChromeClient getWebChromeClient();
method @NonNull public static ClassLoader getWebViewClassLoader();
method @NonNull public android.webkit.WebViewClient getWebViewClient();
@@ -56861,7 +56861,7 @@
method public void fling(int);
method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
method @ColorInt public int getBottomEdgeEffectColor();
- method @android.view.ViewDebug.ExportedProperty(category="drawing") @ColorInt public int getCacheColorHint();
+ method @ColorInt public int getCacheColorHint();
method public int getCheckedItemCount();
method public long[] getCheckedItemIds();
method public int getCheckedItemPosition();
@@ -56871,7 +56871,7 @@
method public int getListPaddingLeft();
method public int getListPaddingRight();
method public int getListPaddingTop();
- method @android.view.ViewDebug.ExportedProperty public android.view.View getSelectedView();
+ method public android.view.View getSelectedView();
method public android.graphics.drawable.Drawable getSelector();
method public CharSequence getTextFilter();
method @ColorInt public int getTopEdgeEffectColor();
@@ -56881,13 +56881,13 @@
method public void invalidateViews();
method public boolean isDrawSelectorOnTop();
method public boolean isFastScrollAlwaysVisible();
- method @android.view.ViewDebug.ExportedProperty public boolean isFastScrollEnabled();
+ method public boolean isFastScrollEnabled();
method protected boolean isInFilterMode();
method public boolean isItemChecked(int);
- method @android.view.ViewDebug.ExportedProperty public boolean isScrollingCacheEnabled();
- method @android.view.ViewDebug.ExportedProperty public boolean isSmoothScrollbarEnabled();
- method @android.view.ViewDebug.ExportedProperty public boolean isStackFromBottom();
- method @android.view.ViewDebug.ExportedProperty public boolean isTextFilterEnabled();
+ method public boolean isScrollingCacheEnabled();
+ method public boolean isSmoothScrollbarEnabled();
+ method public boolean isStackFromBottom();
+ method public boolean isTextFilterEnabled();
method protected void layoutChildren();
method public void onFilterComplete(int);
method public void onGlobalLayout();
@@ -57084,7 +57084,7 @@
ctor public AdapterView(android.content.Context, android.util.AttributeSet, int);
ctor public AdapterView(android.content.Context, android.util.AttributeSet, int, int);
method public abstract T getAdapter();
- method @android.view.ViewDebug.CapturedViewProperty public int getCount();
+ method public int getCount();
method public android.view.View getEmptyView();
method public int getFirstVisiblePosition();
method public Object getItemAtPosition(int);
@@ -57095,8 +57095,8 @@
method @Nullable public final android.widget.AdapterView.OnItemSelectedListener getOnItemSelectedListener();
method public int getPositionForView(android.view.View);
method public Object getSelectedItem();
- method @android.view.ViewDebug.CapturedViewProperty public long getSelectedItemId();
- method @android.view.ViewDebug.CapturedViewProperty public int getSelectedItemPosition();
+ method public long getSelectedItemId();
+ method public int getSelectedItemPosition();
method public abstract android.view.View getSelectedView();
method public boolean performItemClick(android.view.View, int, long);
method public abstract void setAdapter(T);
@@ -57397,7 +57397,7 @@
method @Nullable public android.graphics.BlendMode getCheckMarkTintBlendMode();
method @Nullable public android.content.res.ColorStateList getCheckMarkTintList();
method @Nullable public android.graphics.PorterDuff.Mode getCheckMarkTintMode();
- method @android.view.ViewDebug.ExportedProperty public boolean isChecked();
+ method public boolean isChecked();
method public void setCheckMarkDrawable(@DrawableRes int);
method public void setCheckMarkDrawable(@Nullable android.graphics.drawable.Drawable);
method public void setCheckMarkTintBlendMode(@Nullable android.graphics.BlendMode);
@@ -57438,7 +57438,7 @@
method @Nullable public android.graphics.BlendMode getButtonTintBlendMode();
method @Nullable public android.content.res.ColorStateList getButtonTintList();
method @Nullable public android.graphics.PorterDuff.Mode getButtonTintMode();
- method @android.view.ViewDebug.ExportedProperty public boolean isChecked();
+ method public boolean isChecked();
method public void setButtonDrawable(@DrawableRes int);
method public void setButtonDrawable(@Nullable android.graphics.drawable.Drawable);
method public void setButtonTintBlendMode(@Nullable android.graphics.BlendMode);
@@ -57827,7 +57827,7 @@
method public int getColumnWidth();
method public int getGravity();
method public int getHorizontalSpacing();
- method @android.view.ViewDebug.ExportedProperty public int getNumColumns();
+ method public int getNumColumns();
method public int getRequestedColumnWidth();
method public int getRequestedHorizontalSpacing();
method public int getStretchMode();
@@ -58018,8 +58018,8 @@
ctor public LinearLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
ctor public LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams);
method public String debug(String);
- field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=0xffffffff, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.NO_GRAVITY, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.TOP, to="TOP"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.BOTTOM, to="BOTTOM"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.LEFT, to="LEFT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.RIGHT, to="RIGHT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.START, to="START"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.END, to="END"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_VERTICAL, to="CENTER_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_VERTICAL, to="FILL_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_HORIZONTAL, to="CENTER_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_HORIZONTAL, to="FILL_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL, to="FILL")}) public int gravity;
- field @android.view.ViewDebug.ExportedProperty(category="layout") public float weight;
+ field public int gravity;
+ field public float weight;
}
public interface ListAdapter extends android.widget.Adapter {
@@ -58408,13 +58408,13 @@
method @Nullable public android.content.res.ColorStateList getIndeterminateTintList();
method @Nullable public android.graphics.PorterDuff.Mode getIndeterminateTintMode();
method public android.view.animation.Interpolator getInterpolator();
- method @android.view.ViewDebug.ExportedProperty(category="progress") public int getMax();
+ method public int getMax();
method @Px public int getMaxHeight();
method @Px public int getMaxWidth();
- method @android.view.ViewDebug.ExportedProperty(category="progress") public int getMin();
+ method public int getMin();
method @Px public int getMinHeight();
method @Px public int getMinWidth();
- method @android.view.ViewDebug.ExportedProperty(category="progress") public int getProgress();
+ method public int getProgress();
method @Nullable public android.graphics.BlendMode getProgressBackgroundTintBlendMode();
method @Nullable public android.content.res.ColorStateList getProgressBackgroundTintList();
method @Nullable public android.graphics.PorterDuff.Mode getProgressBackgroundTintMode();
@@ -58422,14 +58422,14 @@
method @Nullable public android.graphics.BlendMode getProgressTintBlendMode();
method @Nullable public android.content.res.ColorStateList getProgressTintList();
method @Nullable public android.graphics.PorterDuff.Mode getProgressTintMode();
- method @android.view.ViewDebug.ExportedProperty(category="progress") public int getSecondaryProgress();
+ method public int getSecondaryProgress();
method @Nullable public android.graphics.BlendMode getSecondaryProgressTintBlendMode();
method @Nullable public android.content.res.ColorStateList getSecondaryProgressTintList();
method @Nullable public android.graphics.PorterDuff.Mode getSecondaryProgressTintMode();
method public final void incrementProgressBy(int);
method public final void incrementSecondaryProgressBy(int);
method public boolean isAnimating();
- method @android.view.ViewDebug.ExportedProperty(category="progress") public boolean isIndeterminate();
+ method public boolean isIndeterminate();
method public void onRestoreInstanceState(android.os.Parcelable);
method public android.os.Parcelable onSaveInstanceState();
method public void setIndeterminate(boolean);
@@ -58580,7 +58580,7 @@
method public int getRule(int);
method public int[] getRules();
method public void removeRule(int);
- field @android.view.ViewDebug.ExportedProperty(category="layout") public boolean alignWithParent;
+ field public boolean alignWithParent;
}
public class RemoteViews implements android.view.LayoutInflater.Filter android.os.Parcelable {
@@ -59139,8 +59139,8 @@
ctor public TableRow.LayoutParams(int);
ctor public TableRow.LayoutParams(android.view.ViewGroup.LayoutParams);
ctor public TableRow.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int column;
- field @android.view.ViewDebug.ExportedProperty(category="layout") public int span;
+ field public int column;
+ field public int span;
}
@android.widget.RemoteViews.RemoteView public class TextClock extends android.widget.TextView {
@@ -59148,8 +59148,8 @@
ctor public TextClock(android.content.Context, android.util.AttributeSet);
ctor public TextClock(android.content.Context, android.util.AttributeSet, int);
ctor public TextClock(android.content.Context, android.util.AttributeSet, int, int);
- method @android.view.ViewDebug.ExportedProperty public CharSequence getFormat12Hour();
- method @android.view.ViewDebug.ExportedProperty public CharSequence getFormat24Hour();
+ method public CharSequence getFormat12Hour();
+ method public CharSequence getFormat24Hour();
method public String getTimeZone();
method public boolean is24HourModeEnabled();
method public void refreshTime();
@@ -59208,7 +59208,7 @@
method protected boolean getDefaultEditable();
method protected android.text.method.MovementMethod getDefaultMovementMethod();
method public android.text.Editable getEditableText();
- method @android.view.ViewDebug.ExportedProperty public android.text.TextUtils.TruncateAt getEllipsize();
+ method public android.text.TextUtils.TruncateAt getEllipsize();
method public CharSequence getError();
method public int getExtendedPaddingBottom();
method public int getExtendedPaddingTop();
@@ -59219,7 +59219,7 @@
method public boolean getFreezesText();
method public int getGravity();
method @ColorInt public int getHighlightColor();
- method @android.view.ViewDebug.CapturedViewProperty public CharSequence getHint();
+ method public CharSequence getHint();
method public final android.content.res.ColorStateList getHintTextColors();
method public int getHyphenationFrequency();
method public int getImeActionId();
@@ -59255,14 +59255,14 @@
method public android.text.TextPaint getPaint();
method public int getPaintFlags();
method public String getPrivateImeOptions();
- method @android.view.ViewDebug.ExportedProperty(category="text") public int getSelectionEnd();
- method @android.view.ViewDebug.ExportedProperty(category="text") public int getSelectionStart();
+ method public int getSelectionEnd();
+ method public int getSelectionStart();
method @ColorInt public int getShadowColor();
method public float getShadowDx();
method public float getShadowDy();
method public float getShadowRadius();
method public final boolean getShowSoftInputOnFocus();
- method @android.view.ViewDebug.CapturedViewProperty public CharSequence getText();
+ method public CharSequence getText();
method @NonNull public android.view.textclassifier.TextClassifier getTextClassifier();
method public final android.content.res.ColorStateList getTextColors();
method @Nullable public android.graphics.drawable.Drawable getTextCursorDrawable();
@@ -59274,7 +59274,7 @@
method @Nullable public android.graphics.drawable.Drawable getTextSelectHandle();
method @Nullable public android.graphics.drawable.Drawable getTextSelectHandleLeft();
method @Nullable public android.graphics.drawable.Drawable getTextSelectHandleRight();
- method @android.view.ViewDebug.ExportedProperty(category="text") public float getTextSize();
+ method public float getTextSize();
method public int getTextSizeUnit();
method public int getTotalPaddingBottom();
method public int getTotalPaddingEnd();
diff --git a/non-updatable-api/system-lint-baseline.txt b/non-updatable-api/system-lint-baseline.txt
index 2829243..395ddc1 100644
--- a/non-updatable-api/system-lint-baseline.txt
+++ b/non-updatable-api/system-lint-baseline.txt
@@ -1,74 +1,88 @@
// Baseline format: 1.0
ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
- Method should return Collection<CharSequence> (or subclass) instead of raw array; was `java.lang.CharSequence[]`
+
+
+
+BuilderSetStyle: android.net.IpSecTransform.Builder#buildTunnelModeTransform(java.net.InetAddress, android.net.IpSecManager.SecurityParameterIndex):
+ Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.IpSecTransform.Builder.buildTunnelModeTransform(java.net.InetAddress,android.net.IpSecManager.SecurityParameterIndex)
GenericException: android.app.prediction.AppPredictor#finalize():
- Methods must not throw generic exceptions (`java.lang.Throwable`)
+
GenericException: android.hardware.location.ContextHubClient#finalize():
- Methods must not throw generic exceptions (`java.lang.Throwable`)
+
GenericException: android.net.IpSecManager.IpSecTunnelInterface#finalize():
- Methods must not throw generic exceptions (`java.lang.Throwable`)
+
GenericException: android.service.autofill.augmented.FillWindow#finalize():
- Methods must not throw generic exceptions (`java.lang.Throwable`)
+
KotlinKeyword: android.app.Notification#when:
- Avoid field names that are Kotlin hard keywords ("when"); see https://android.github.io/kotlin-guides/interop.html#no-hard-keywords
+
+
+
+MissingGetterMatchingBuilder: android.security.keystore.KeyGenParameterSpec.Builder#setUid(int):
+ android.security.keystore.KeyGenParameterSpec does not declare a `getUid()` method matching method android.security.keystore.KeyGenParameterSpec.Builder.setUid(int)
+MissingGetterMatchingBuilder: android.service.autofill.Dataset.Builder#setFieldInlinePresentation(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, java.util.regex.Pattern, android.service.autofill.InlinePresentation):
+ android.service.autofill.Dataset does not declare a `getFieldInlinePresentation()` method matching method android.service.autofill.Dataset.Builder.setFieldInlinePresentation(android.view.autofill.AutofillId,android.view.autofill.AutofillValue,java.util.regex.Pattern,android.service.autofill.InlinePresentation)
+MissingGetterMatchingBuilder: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallViaAudioProcessing(boolean):
+ android.telecom.CallScreeningService.CallResponse does not declare a `shouldScreenCallViaAudioProcessing()` method matching method android.telecom.CallScreeningService.CallResponse.Builder.setShouldScreenCallViaAudioProcessing(boolean)
+MissingGetterMatchingBuilder: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
+ android.telephony.mbms.DownloadRequest does not declare a `getServiceId()` method matching method android.telephony.mbms.DownloadRequest.Builder.setServiceId(String)
MissingNullability: android.media.soundtrigger.SoundTriggerDetectionService#onUnbind(android.content.Intent) parameter #0:
- Missing nullability on parameter `intent` in method `onUnbind`
+
MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #0:
- Missing nullability on parameter `inputId` in method `onEvent`
+
MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #1:
- Missing nullability on parameter `eventType` in method `onEvent`
+
MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #2:
- Missing nullability on parameter `eventArgs` in method `onEvent`
+
MissingNullability: android.printservice.recommendation.RecommendationService#attachBaseContext(android.content.Context) parameter #0:
- Missing nullability on parameter `base` in method `attachBaseContext`
+
MissingNullability: android.provider.ContactsContract.MetadataSync#CONTENT_URI:
- Missing nullability on field `CONTENT_URI` in class `class android.provider.ContactsContract.MetadataSync`
+
MissingNullability: android.provider.ContactsContract.MetadataSync#METADATA_AUTHORITY_URI:
- Missing nullability on field `METADATA_AUTHORITY_URI` in class `class android.provider.ContactsContract.MetadataSync`
+
MissingNullability: android.provider.ContactsContract.MetadataSyncState#CONTENT_URI:
- Missing nullability on field `CONTENT_URI` in class `class android.provider.ContactsContract.MetadataSyncState`
+
MissingNullability: android.provider.SearchIndexablesProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #0:
- Missing nullability on parameter `context` in method `attachInfo`
+
MissingNullability: android.provider.SearchIndexablesProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #1:
- Missing nullability on parameter `info` in method `attachInfo`
+
MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#onUnbind(android.content.Intent) parameter #0:
- Missing nullability on parameter `intent` in method `onUnbind`
+
MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
- Missing nullability on parameter `fd` in method `dump`
+
MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
- Missing nullability on parameter `pw` in method `dump`
+
MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
- Missing nullability on parameter `args` in method `dump`
+
MissingNullability: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context) parameter #0:
- Missing nullability on parameter `base` in method `attachBaseContext`
+
MissingNullability: android.telephony.NetworkService#onUnbind(android.content.Intent) parameter #0:
- Missing nullability on parameter `intent` in method `onUnbind`
+
MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringDaily(java.time.ZonedDateTime) parameter #0:
- Missing nullability on parameter `start` in method `createRecurringDaily`
+
MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringMonthly(java.time.ZonedDateTime) parameter #0:
- Missing nullability on parameter `start` in method `createRecurringMonthly`
+
MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringWeekly(java.time.ZonedDateTime) parameter #0:
- Missing nullability on parameter `start` in method `createRecurringWeekly`
+
MissingNullability: android.telephony.data.DataService#onUnbind(android.content.Intent) parameter #0:
- Missing nullability on parameter `intent` in method `onUnbind`
+
MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
- Missing nullability on method `setServiceId` return
+
MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String) parameter #0:
- Missing nullability on parameter `serviceId` in method `setServiceId`
+
ProtectedMember: android.printservice.recommendation.RecommendationService#attachBaseContext(android.content.Context):
- Protected methods not allowed; must be public: method android.printservice.recommendation.RecommendationService.attachBaseContext(android.content.Context)}
+
ProtectedMember: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
- Protected methods not allowed; must be public: method android.service.contentcapture.ContentCaptureService.dump(java.io.FileDescriptor,java.io.PrintWriter,String[])}
+
ProtectedMember: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context):
- Protected methods not allowed; must be public: method android.service.notification.NotificationAssistantService.attachBaseContext(android.content.Context)}
+
SamShouldBeLast: android.accounts.AccountManager#addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
@@ -168,7 +182,7 @@
SamShouldBeLast: android.media.AudioRouting#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
SamShouldBeLast: android.media.AudioTrack#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
- SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioTrack.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+
SamShouldBeLast: android.media.MediaRecorder#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
SamShouldBeLast: android.media.MediaRecorder#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback):
diff --git a/packages/CarSystemUI/res/values-ca/strings.xml b/packages/CarSystemUI/res/values-ca/strings.xml
index 083f9d0..375fc5c 100644
--- a/packages/CarSystemUI/res/values-ca/strings.xml
+++ b/packages/CarSystemUI/res/values-ca/strings.xml
@@ -24,7 +24,7 @@
<string name="start_guest_session" msgid="497784785761754874">"Convidat"</string>
<string name="car_add_user" msgid="4067337059622483269">"Afegeix un usuari"</string>
<string name="car_new_user" msgid="6637442369728092473">"Usuari nou"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar el seu espai."</string>
+ <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quan s\'afegeix un usuari nou, aquesta persona ha de configurar el seu espai."</string>
<string name="user_add_user_message_update" msgid="7061671307004867811">"Qualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"S\'està carregant"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"S\'està carregant l\'usuari (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
diff --git a/packages/CarSystemUI/res/values-es-rUS/strings.xml b/packages/CarSystemUI/res/values-es-rUS/strings.xml
index c1c21d1..027242a 100644
--- a/packages/CarSystemUI/res/values-es-rUS/strings.xml
+++ b/packages/CarSystemUI/res/values-es-rUS/strings.xml
@@ -25,7 +25,7 @@
<string name="car_add_user" msgid="4067337059622483269">"Agregar usuario"</string>
<string name="car_new_user" msgid="6637442369728092473">"Usuario nuevo"</string>
<string name="user_add_user_message_setup" msgid="1035578846007352323">"Cuando agregues un usuario nuevo, esa persona deberá configurar su espacio."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario podrá actualizar las apps de otras personas."</string>
+ <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Cargando"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Cargando usuario (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
</resources>
diff --git a/packages/CarSystemUI/res/values-fi/strings.xml b/packages/CarSystemUI/res/values-fi/strings.xml
index 6068969..6abf92f 100644
--- a/packages/CarSystemUI/res/values-fi/strings.xml
+++ b/packages/CarSystemUI/res/values-fi/strings.xml
@@ -25,7 +25,7 @@
<string name="car_add_user" msgid="4067337059622483269">"Lisää käyttäjä"</string>
<string name="car_new_user" msgid="6637442369728092473">"Uusi käyttäjä"</string>
<string name="user_add_user_message_setup" msgid="1035578846007352323">"Kun lisäät uuden käyttäjän, hänen on valittava oman tilansa asetukset."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Kaikki käyttäjät voivat päivittää muiden käyttäjien sovelluksia."</string>
+ <string name="user_add_user_message_update" msgid="7061671307004867811">"Kaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Ladataan"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ladataan käyttäjäprofiilia (<xliff:g id="FROM_USER">%1$d</xliff:g>–<xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
</resources>
diff --git a/packages/CarSystemUI/res/values-in/strings.xml b/packages/CarSystemUI/res/values-in/strings.xml
index 901cbe7..1145dc3 100644
--- a/packages/CarSystemUI/res/values-in/strings.xml
+++ b/packages/CarSystemUI/res/values-in/strings.xml
@@ -24,7 +24,7 @@
<string name="start_guest_session" msgid="497784785761754874">"Tamu"</string>
<string name="car_add_user" msgid="4067337059622483269">"Tambahkan Pengguna"</string>
<string name="car_new_user" msgid="6637442369728092473">"Pengguna Baru"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri."</string>
+ <string name="user_add_user_message_setup" msgid="1035578846007352323">"Jika ditambahkan, pengguna baru harus menyiapkan ruangnya sendiri."</string>
<string name="user_add_user_message_update" msgid="7061671307004867811">"Setiap pengguna dapat mengupdate aplikasi untuk semua pengguna lain."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Memuat"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Memuat pengguna (dari <xliff:g id="FROM_USER">%1$d</xliff:g> menjadi <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
diff --git a/packages/CarSystemUI/res/values-kk/strings.xml b/packages/CarSystemUI/res/values-kk/strings.xml
index f9449be..5220aa5 100644
--- a/packages/CarSystemUI/res/values-kk/strings.xml
+++ b/packages/CarSystemUI/res/values-kk/strings.xml
@@ -24,7 +24,7 @@
<string name="start_guest_session" msgid="497784785761754874">"Қонақ"</string>
<string name="car_add_user" msgid="4067337059622483269">"Пайдаланушыны енгізу"</string>
<string name="car_new_user" msgid="6637442369728092473">"Жаңа пайдаланушы"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Енгізілген жаңа пайдаланушы өз профилін реттеуі керек."</string>
+ <string name="user_add_user_message_setup" msgid="1035578846007352323">"Қосылған жаңа пайдаланушы өз профилін реттеуі керек."</string>
<string name="user_add_user_message_update" msgid="7061671307004867811">"Кез келген пайдаланушы қолданбаларды басқа пайдаланушылар үшін жаңарта алады."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Жүктелуде"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Пайдаланушы профилі жүктелуде (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
diff --git a/packages/CarSystemUI/res/values-ky/strings.xml b/packages/CarSystemUI/res/values-ky/strings.xml
index b093363..b3b355a 100644
--- a/packages/CarSystemUI/res/values-ky/strings.xml
+++ b/packages/CarSystemUI/res/values-ky/strings.xml
@@ -25,7 +25,7 @@
<string name="car_add_user" msgid="4067337059622483269">"Колдонуучу кошуу"</string>
<string name="car_new_user" msgid="6637442369728092473">"Жаңы колдонуучу"</string>
<string name="user_add_user_message_setup" msgid="1035578846007352323">"Жаңы колдонуучу кошулганда, ал өзүнүн профилин жөндөп алышы керек."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Колдонмолорду бир колдонуучу калган бардык колдонуучулар үчүн да жаңырта алат."</string>
+ <string name="user_add_user_message_update" msgid="7061671307004867811">"Колдонмолорду бир колдонуучу жаңыртканда, ал калган бардык колдонуучулар үчүн да жаңырат."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Жүктөлүүдө"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Колдонуучу тууралуу маалымат жүктөлүүдө (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
</resources>
diff --git a/packages/CarSystemUI/res/values-ne/strings.xml b/packages/CarSystemUI/res/values-ne/strings.xml
index 70bcfc7..40639de 100644
--- a/packages/CarSystemUI/res/values-ne/strings.xml
+++ b/packages/CarSystemUI/res/values-ne/strings.xml
@@ -25,7 +25,7 @@
<string name="car_add_user" msgid="4067337059622483269">"प्रयोगकर्ता थप्नुहोस्"</string>
<string name="car_new_user" msgid="6637442369728092473">"नयाँ प्रयोगकर्ता"</string>
<string name="user_add_user_message_setup" msgid="1035578846007352323">"तपाईंले नयाँ प्रयोगकर्ता थप्दा ती व्यक्तिले आफ्नो स्थान सेटअप गर्नु पर्छ।"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"सबै प्रयोगकर्ताले अन्य प्रयोगकर्ताका अनुप्रयोगहरू अद्यावधिक गर्न सक्छन्।"</string>
+ <string name="user_add_user_message_update" msgid="7061671307004867811">"सबै प्रयोगकर्ताले अन्य प्रयोगकर्ताका एपहरू अद्यावधिक गर्न सक्छन्।"</string>
<string name="car_loading_profile" msgid="4507385037552574474">"लोड गरिँदै"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"प्रयोगकर्तासम्बन्धी जानकारी लोड गरिँदै (<xliff:g id="FROM_USER">%1$d</xliff:g> बाट <xliff:g id="TO_USER">%2$d</xliff:g> मा)"</string>
</resources>
diff --git a/packages/CarSystemUI/res/values-sk/strings.xml b/packages/CarSystemUI/res/values-sk/strings.xml
index ea99f0f..2016b7b 100644
--- a/packages/CarSystemUI/res/values-sk/strings.xml
+++ b/packages/CarSystemUI/res/values-sk/strings.xml
@@ -25,7 +25,7 @@
<string name="car_add_user" msgid="4067337059622483269">"Pridať používateľa"</string>
<string name="car_new_user" msgid="6637442369728092473">"Nový používateľ"</string>
<string name="user_add_user_message_setup" msgid="1035578846007352323">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Ktorýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string>
+ <string name="user_add_user_message_update" msgid="7061671307004867811">"Každý používateľ môže aktualizovať aplikácie pre všetkých ostatných používateľov."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Načítava sa"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Načítava sa používateľ (predchádzajúci: <xliff:g id="FROM_USER">%1$d</xliff:g>, nasledujúci: <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
</resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
index 2b9fa41..47eeb83 100644
--- a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
@@ -2,7 +2,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="keyguard_description" msgid="8582605799129954556">"Geef je wachtwoord op en ga door naar \'Dynamische systeemupdates\'"</string>
- <string name="notification_install_completed" msgid="6252047868415172643">"Dynamisch systeem is klaar. Start je apparaat opnieuw op om het te gebruiken."</string>
+ <string name="notification_install_completed" msgid="6252047868415172643">"Dynamisch systeem is gereed. Start je apparaat opnieuw op om het te gebruiken."</string>
<string name="notification_install_inprogress" msgid="7383334330065065017">"Installatie wordt uitgevoerd"</string>
<string name="notification_install_failed" msgid="4066039210317521404">"Installatie mislukt"</string>
<string name="notification_image_validation_failed" msgid="2720357826403917016">"Valideren van afbeelding mislukt. Installatie afbreken."</string>
diff --git a/packages/DynamicSystemInstallationService/res/values-ur/strings.xml b/packages/DynamicSystemInstallationService/res/values-ur/strings.xml
index 1e098fb..48dddbe 100644
--- a/packages/DynamicSystemInstallationService/res/values-ur/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ur/strings.xml
@@ -5,7 +5,7 @@
<string name="notification_install_completed" msgid="6252047868415172643">"ڈائنیمک سسٹم تیار ہے۔ اس کا استعمال شروع کرنے کے لیے، اپنا آلہ ری سٹارٹ کریں۔"</string>
<string name="notification_install_inprogress" msgid="7383334330065065017">"انسٹال جاری ہے"</string>
<string name="notification_install_failed" msgid="4066039210317521404">"انسٹال ناکام ہو گیا"</string>
- <string name="notification_image_validation_failed" msgid="2720357826403917016">"ڈسک امیج کی توثیق ناکام ہو گئی۔ انسٹالیشن منسوخ کریں۔"</string>
+ <string name="notification_image_validation_failed" msgid="2720357826403917016">"تصویر کی توثیق ناکام ہو گئی۔ انسٹالیشن منسوخ کریں-"</string>
<string name="notification_dynsystem_in_use" msgid="1053194595682188396">"فی الحال ہم ایک ڈائنیمک سسٹم چلا رہے ہیں۔ Android کا اصل ورژن استعمال کرنے کے لیے ری سٹارٹ کریں۔"</string>
<string name="notification_action_cancel" msgid="5929299408545961077">"منسوخ کریں"</string>
<string name="notification_action_discard" msgid="1817481003134947493">"مسترد کریں"</string>
diff --git a/packages/InputDevices/res/values-ru/strings.xml b/packages/InputDevices/res/values-ru/strings.xml
index 4232437..49bf0b7 100644
--- a/packages/InputDevices/res/values-ru/strings.xml
+++ b/packages/InputDevices/res/values-ru/strings.xml
@@ -42,6 +42,6 @@
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"испанский (Латинская Америка)"</string>
<string name="keyboard_layout_latvian" msgid="4405417142306250595">"латышский"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"Персидский"</string>
- <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"азербайджанский"</string>
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Азербайджанский"</string>
<string name="keyboard_layout_polish" msgid="1121588624094925325">"польский"</string>
</resources>
diff --git a/packages/OsuLogin/Android.bp b/packages/OsuLogin/Android.bp
deleted file mode 100644
index 445c81b..0000000
--- a/packages/OsuLogin/Android.bp
+++ /dev/null
@@ -1,18 +0,0 @@
-android_app {
- name: "OsuLogin",
- defaults: ["wifi-module-sdk-version-defaults"],
- static_libs: ["androidx.legacy_legacy-support-v4"],
- resource_dirs: ["res"],
- srcs: ["src/**/*.java"],
- sdk_version: "system_current",
- certificate: ":com.android.hotspot2.osulogin.certificate",
- apex_available: [
- "com.android.wifi",
- "test_com.android.wifi",
- ],
-}
-
-android_app_certificate {
- name: "com.android.hotspot2.osulogin.certificate",
- certificate: "certs/com.android.hotspot2.osulogin"
-}
diff --git a/packages/OsuLogin/AndroidManifest.xml b/packages/OsuLogin/AndroidManifest.xml
deleted file mode 100644
index a428cb3..0000000
--- a/packages/OsuLogin/AndroidManifest.xml
+++ /dev/null
@@ -1,41 +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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.hotspot2.osulogin">
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
- <uses-permission android:name="android.permission.INTERNET"/>
-
- <application
- android:networkSecurityConfig="@xml/network_security_config"
- android:enabled="true"
- android:label="@string/app_name"
- android:configChanges="keyboardHidden|orientation|screenSize"
- android:supportsRtl="true">
- <activity android:name="com.android.hotspot2.osulogin.OsuLoginActivity"
- android:label="@string/action_bar_label"
- android:theme="@style/AppTheme"
- android:configChanges="keyboardHidden|orientation|screenSize">
- <intent-filter>
- <action android:name="android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW"/>
- <category android:name="android.intent.category.DEFAULT"/>
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/packages/OsuLogin/OWNERS b/packages/OsuLogin/OWNERS
deleted file mode 100644
index aa7c3e6..0000000
--- a/packages/OsuLogin/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-satk@google.com
-etancohen@google.com
diff --git a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.pk8 b/packages/OsuLogin/certs/com.android.hotspot2.osulogin.pk8
deleted file mode 100644
index 87fd622..0000000
--- a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.pk8
+++ /dev/null
Binary files differ
diff --git a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.x509.pem b/packages/OsuLogin/certs/com.android.hotspot2.osulogin.x509.pem
deleted file mode 100644
index 1dfe701..0000000
--- a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.x509.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGDzCCA/egAwIBAgIUHzkh0UCF/H+1mZZp0ROX4nXKOUowDQYJKoZIhvcNAQEL
-BQAwgZUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMREwDwYDVQQDDAhPc3VMb2dpbjEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBh
-bmRyb2lkLmNvbTAgFw0yMDAzMjUwMjQ5MTNaGA80NzU4MDIxOTAyNDkxM1owgZUx
-CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3Vu
-dGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRyb2lkMREw
-DwYDVQQDDAhPc3VMb2dpbjEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lk
-LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMJDnjAeIZ2KUvKc
-ONwxuzIhLvXr6LRm+Uz0ebjz++5IzQJLwr/COPBG9zbIm8izj2acp+l4WVEYT6I4
-Es5LEp556ySCuZx8IjOd0Zd6NCdaKmYouDTjYTrELWUlZjfA7Km2L5x2M6ArnDO5
-zJ1BIsQ06S3C7iR3ktAQ1cFdidg6Ha2gainS0A1JKN3kL9BL1pvHRLzWZX4gsNhB
-C/6Ue3W3Sx2JRQkaaLksDdoKq0QswEk5tGfKbVr9+hHv/pztaaqEXSeV6f305cAx
-Hzd6+QJ8f8AJz2Rhnv43y72UO8b02CSP3laUj8geidR8XXw+R7Kzu8NfFDL7uVIh
-ktPaBxfWPNYtedp3JrGeZhkzljsushY+bVHECEzROhY2CiUZBEn+wwZLWe2W7oee
-VCL1EZBYctK5CfrrV6x0wvbBUF/ViwV+2LQXQNp08xB8bJBqoBn4KZjK0tTN86Dq
-qRALyoVIVh5VDU9Wbi3vrJb0/9TEQtMjuo0DS3hdtnowdRyAyhwbQHO26dqnnzBI
-XtTAve4RkOwnb8QzZde56qvRgweDE9Im1jpx4E+MMGqVYs8Txurmd/t6bCjTvp1P
-4i88crk/zqCoHEQEbiaNdfkULJAWg9wqxPjqPCTVNtOXoJwuHsNymQVSztIUSySz
-ZQ8Trk0ApqQf8yH2mjM6HJJZoNpBAgMBAAGjUzBRMB0GA1UdDgQWBBRdpduh1P+I
-BMbg5S4n1kbj5hQsOzAfBgNVHSMEGDAWgBRdpduh1P+IBMbg5S4n1kbj5hQsOzAP
-BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQB+FzSuoA7LCvn8l86V
-sSI4lH1KLLH+wrXp20w/wYcBY+s4hYPpAJ8YbEMOT9uibK/HpEWYFqiVCqk4gKXr
-Qraxvmtqq0WNSwkjeopTYlZeBzTC/If3UoOCp7KCfMdydIcxvk6LNokMWWqSCNP8
-QiD872XuBvj/uQeBsbHZTqruqPnu+LZwpuHFVRp/Pyj9rT61PsvGitb7q/chW0G7
-7csHOc5q2223LKlNknPsfbcR6nVEg4KfN7kPKny8iJtl2pdbfBjFDp+73nzW8qZU
-5JWO5nWL7cJh4mt5sPGrzpt/Hf8/Dngg69sImRqjv/6/wCV0pEmmNjKJkXcMaZ0T
-2TSs+A7K6l15NYk8exkMymTU7jk+iDud3tnQ68YHf/A9pDu15OCw6U/pTgOgu9co
-rBLLhGV0Tb6XAnsWKe9tsLcumQXU5ZUn9m5VJl58wQHNhUqpT7L0fWtpiTMTStVA
-/yZbndPO4SbjR5rjcAk1xge8lyIIp0WBWmwoQ/1y4DXF/yPaX733wO7uWUljgKuy
-MM/zM4zklB8nFjXfPNf3j24Bzqmy7rqy4XB64enVmYQ2mVNqfwXvINoo2XOrAmj/
-bhSWXiCFltJFM7fmJGOMEEHBt9QfbmCgmM4aoWMgH7P+HxGW+Vc3tGixBbsxNRC+
-/VrPAINQV4x5q8zGYNQBqNFn/A==
------END CERTIFICATE-----
diff --git a/packages/OsuLogin/certs/key.pem b/packages/OsuLogin/certs/key.pem
deleted file mode 100644
index f560a8d..0000000
--- a/packages/OsuLogin/certs/key.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDCQ54wHiGdilLy
-nDjcMbsyIS716+i0ZvlM9Hm48/vuSM0CS8K/wjjwRvc2yJvIs49mnKfpeFlRGE+i
-OBLOSxKeeeskgrmcfCIzndGXejQnWipmKLg042E6xC1lJWY3wOypti+cdjOgK5wz
-ucydQSLENOktwu4kd5LQENXBXYnYOh2toGop0tANSSjd5C/QS9abx0S81mV+ILDY
-QQv+lHt1t0sdiUUJGmi5LA3aCqtELMBJObRnym1a/foR7/6c7WmqhF0nlen99OXA
-MR83evkCfH/ACc9kYZ7+N8u9lDvG9Ngkj95WlI/IHonUfF18Pkeys7vDXxQy+7lS
-IZLT2gcX1jzWLXnadyaxnmYZM5Y7LrIWPm1RxAhM0ToWNgolGQRJ/sMGS1ntlu6H
-nlQi9RGQWHLSuQn661esdML2wVBf1YsFfti0F0DadPMQfGyQaqAZ+CmYytLUzfOg
-6qkQC8qFSFYeVQ1PVm4t76yW9P/UxELTI7qNA0t4XbZ6MHUcgMocG0Bztunap58w
-SF7UwL3uEZDsJ2/EM2XXueqr0YMHgxPSJtY6ceBPjDBqlWLPE8bq5nf7emwo076d
-T+IvPHK5P86gqBxEBG4mjXX5FCyQFoPcKsT46jwk1TbTl6CcLh7DcpkFUs7SFEsk
-s2UPE65NAKakH/Mh9pozOhySWaDaQQIDAQABAoICAGgX7XKhIqgVD59aoIk0yLby
-2wQBdf780ocu1O6LJiqnrdqWF/PCsdnmXN9pHTitJqD4Pm03BL0Uhs9ItqL9zStH
-7vzwY177kSQRY9aEL+AKS3/UP+hvEpF3v09ce+pSIT5LFjYDjGQ+GgQJgh+dYHC8
-XVodAphdzjhZXQCxC4TmlzKLK3ffs4X69r/3XruBd6yfWTDKvTWZdMlcCX5Pt9v6
-7HAWNvzKvuTCO2Xjo6PzStGx7v5SlMhWISJtdARInv80z+m/RdPD3zxd1flXloiD
-h7yyRQPn31cfNLgP7vwMBKmKwbuo/WZhHr/SKBHEGY0jC/CDSQKMqd/dh5ynTnbC
-vi/qjKFIHofmhzgQ+fiHMeMsAO1c9eYs8a6bDeJjhA5qJP1HjSie9Ss9z94mp6Ww
-TRkU93yVX04DU4TCCf0IcFpKdbtKp84i6iLV9lKGh9juM42hSOFUV6bhxmlJ9zvM
-yl7vfhhuFHy1SypmaK/oJ+nwac4vIMaHCX9ifl6hm/z4PrGFSYJGQoJtVOz0vT15
-lSwCJVdHkGAe0LI+3iFn5jJlluD7TqsLmZLxqTTmzDZ3U9WhAslmn5TcZd92mL0i
-ZVTfCkjyl1wUHeif2992oTUH6CFZ1jKd8xwdWvyKkvQcjhiS9GUsm7j6jolR/QI7
-VPQlocM/vCCusrMWnR7xAoIBAQDv9O8kboz6WzN6Xw5UC7MWpi2jZg1bTs/uKcfz
-biAEC96iJQ33YSkYi6QzV4jSaackU99vGkHbQIdaBTkudz+FK5XqH0auImB2xxcR
-Xu9G2j2fhzESchVTtOnotVgjiuv18SLZ/GQoSIccs0QxcisPiTa5Ij9pl8xVoS6J
-sxfqAe15hASqLh+9Ula3+Orb1kCkqK0UwU0nM9nfUH88BKvUwQIMA7kipTA8jJog
-MJOlYPQUGxkltlim8Vip//P336E7CWT6fWbfo62US6IEu6HcC6T8u8jcLjIKsmjJ
-YJyqrepZqAVMPlv2Z+mNhxRR0ct6blfjJSrEZEtxBRn98kZ1AoIBAQDPQJ1z7Mfy
-AOfjSO6Dlfr7V9SWmGvexosH0gu6H8KO+n1/ZPH5fHGt7ORubUDhkNI/fqZK0Hls
-Q9Jwgq1QI9UwMTogF8DgmZ6L6jiXhUScIk0BFhUxOBoplugaI0jdTW350D2quFUJ
-LjYo+VcRapTfXXVehHSjbUh3nmTWj0WboA+//7xq8q9KHPb1Sbiwjf7N1iYD5R8p
-PaaG0DMET+l90bxI+QVX1enwjZGcFjo8VI+qXGGkpB/1zK5yWm29ZWypLw8TZreM
-7rLUdBY1/m7MB54zOaJ2jSsxLQSXIVSGPI1ugkmFr6OxeuLdcCLN4yca3+HYHewa
-w3GCBP3kfYMdAoIBAAxG0slhYpMYgWy8WkZQhuwcum8GtJ48TQUZXCKHOtoaJVzU
-Wn+SmACqfE8oJlblkuiX5fGQPVhTV9lyNPe8oCJXFYdx7DLSjW7mRrbbzZApcEeu
-KgOQlKjAs8r1JDpFTEc7/BV9BT7OXyNHxLBm7+8OjR8xsl7bplenNHNVF18glB7I
-c1ilnXgZM1icQp/WuV3zR0+tiB3+WCJFwwy2DHiJG2qz8g/ktbATXXtSIOuwJyy0
-Kjg0uRppdKjV8Ix5A426sFDkg5PjkujoabSmSOSyL9HCZcdmEadcc2ICMGHHHhtS
-Lls1QY08ycU06QQ6oJd198cmSqbbnsR8h1TnxVUCggEBAI2zF/QSiAImLGVxj+HX
-wWnneyobvGTsSlJmgi4XWOZ4zSU011xEgVTxCp2VhS6z3YwcA4ZTUzF6jX7vWZ/Z
-YAE7JwqaMv1dCtGOqnKuY2J88Tk05/hm6zxUOQzl4wOr1O1gO0lmDn3gYpdRIv59
-aJvvQjgFR9oU9d8TJM6t1mG45gvXxfM5Si/Z7d93MBdGflgteoBfPxbrV9gEsVzZ
-ZkLoC1u5JrYPQ4t8v3mAmQB2sGNCFmCC9ncQIpV8zlsX5VsnGZ+iMwzghtRLKoRw
-GUDWVIuhdDqp+kX9CY5q82d0Lx7HZY1JsRm/cy0DZkhubmYpfDhO/QavagQDdbOr
-POECggEAXOliqX4yFvy6USXihHVM44s63gK+yH0+0iRppqoB3+E5tDyhvvvBMPLZ
-7EBkhd7ILTDXbc0c8nSl8I/556YSlIaOB4Xbf4UQbsmD4fNGEnNWFbCzcEWYOjpQ
-5QyXjIzK/k8eg22OZlC3XNjGHgb/mA5f+v2enGQNuy7WRTl1mKYZB2h/2p6xy+jV
-CGhd4btB2bOu+1XR/B2KFvI5NdtPPti05LmsYgsU00yYJfQkpc7VvOSH5Jyy3eZL
-L9xTAy7NWBQ3LGdIpX+V1jcn3SzVits0m6hOUCtJLT1snMXAKFweTvWAQynuGomc
-VPf88ITMTOBjOH6YC8jKd/n2lVWLjw==
------END PRIVATE KEY-----
diff --git a/packages/OsuLogin/res/layout/osu_web_view.xml b/packages/OsuLogin/res/layout/osu_web_view.xml
deleted file mode 100644
index 4436aab..0000000
--- a/packages/OsuLogin/res/layout/osu_web_view.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.android.hotspot2.osulogin.OsuLoginActivity">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="4dp">
-
- <!-- Eliminates ProgressBar padding by boxing it into a 4dp high container -->
- <ProgressBar
- android:id="@+id/progress_bar"
- style="@android:style/Widget.Material.Light.ProgressBar.Horizontal"
- android:indeterminate="false"
- android:max="100"
- android:progress="0"
- android:layout_gravity="center"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- </FrameLayout>
- <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
- android:id="@+id/swipe_refresh"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <WebView
- android:id="@+id/webview"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentBottom="false"
- android:layout_alignParentRight="false"/>
- </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
- </LinearLayout>
-</FrameLayout>
diff --git a/packages/OsuLogin/res/values-af/strings.xml b/packages/OsuLogin/res/values-af/strings.xml
deleted file mode 100644
index bfeee10..0000000
--- a/packages/OsuLogin/res/values-af/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Sluit aanlyn aan"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Kon nie aanmeld nie"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-am/strings.xml b/packages/OsuLogin/res/values-am/strings.xml
deleted file mode 100644
index e27c578..0000000
--- a/packages/OsuLogin/res/values-am/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"የመስመር ላይ ምዝገባ"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ምዝገባ አልተሳካም"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ar/strings.xml b/packages/OsuLogin/res/values-ar/strings.xml
deleted file mode 100644
index b72d7c1..0000000
--- a/packages/OsuLogin/res/values-ar/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"الاشتراك على الإنترنت"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"تعذّر الاشتراك."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-as/strings.xml b/packages/OsuLogin/res/values-as/strings.xml
deleted file mode 100644
index 422de32..0000000
--- a/packages/OsuLogin/res/values-as/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"অনলাইনত ছাই আপ কৰক"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ছাইন আপ কৰিব পৰা নগ’ল"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-az/strings.xml b/packages/OsuLogin/res/values-az/strings.xml
deleted file mode 100644
index 977f939..0000000
--- a/packages/OsuLogin/res/values-az/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Onlayn Qeydiyyat"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Qeydiyyat alınmadı"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-b+sr+Latn/strings.xml b/packages/OsuLogin/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 6eb2cc1..0000000
--- a/packages/OsuLogin/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Onlajn registracija"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-be/strings.xml b/packages/OsuLogin/res/values-be/strings.xml
deleted file mode 100644
index 158c3f2..0000000
--- a/packages/OsuLogin/res/values-be/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Зарэгістравацца ў інтэрнэце"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Не ўдалося зарэгістравацца"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bg/strings.xml b/packages/OsuLogin/res/values-bg/strings.xml
deleted file mode 100644
index ea3145d..0000000
--- a/packages/OsuLogin/res/values-bg/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлайн регистрация"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Регистрацията не бе успешна"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bn/strings.xml b/packages/OsuLogin/res/values-bn/strings.xml
deleted file mode 100644
index c9f615e..0000000
--- a/packages/OsuLogin/res/values-bn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"অনলাইনে সাইন-আপ করুন"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"সাইন-আপ করা যায়নি"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bs/strings.xml b/packages/OsuLogin/res/values-bs/strings.xml
deleted file mode 100644
index e9b9751..0000000
--- a/packages/OsuLogin/res/values-bs/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online registracija"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspjela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ca/strings.xml b/packages/OsuLogin/res/values-ca/strings.xml
deleted file mode 100644
index 7d93096..0000000
--- a/packages/OsuLogin/res/values-ca/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registre en línia"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Ha fallat el registre"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-cs/strings.xml b/packages/OsuLogin/res/values-cs/strings.xml
deleted file mode 100644
index b9cb794..0000000
--- a/packages/OsuLogin/res/values-cs/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online registrace"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registrace selhala"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-da/strings.xml b/packages/OsuLogin/res/values-da/strings.xml
deleted file mode 100644
index 68c93b7..0000000
--- a/packages/OsuLogin/res/values-da/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online registrering"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registrering mislykkedes"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-de/strings.xml b/packages/OsuLogin/res/values-de/strings.xml
deleted file mode 100644
index 7e5a310..0000000
--- a/packages/OsuLogin/res/values-de/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online-Registrierung"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registrierung fehlgeschlagen"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-el/strings.xml b/packages/OsuLogin/res/values-el/strings.xml
deleted file mode 100644
index a58e481..0000000
--- a/packages/OsuLogin/res/values-el/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Εγγραφή στο διαδίκτυο"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Αποτυχία εγγραφής"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rAU/strings.xml b/packages/OsuLogin/res/values-en-rAU/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rCA/strings.xml b/packages/OsuLogin/res/values-en-rCA/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rGB/strings.xml b/packages/OsuLogin/res/values-en-rGB/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rIN/strings.xml b/packages/OsuLogin/res/values-en-rIN/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rXC/strings.xml b/packages/OsuLogin/res/values-en-rXC/strings.xml
deleted file mode 100644
index af7ff67..0000000
--- a/packages/OsuLogin/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online Sign Up"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-es-rUS/strings.xml b/packages/OsuLogin/res/values-es-rUS/strings.xml
deleted file mode 100644
index 144804c..0000000
--- a/packages/OsuLogin/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registrarse en línea"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Se produjo un error de registro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-es/strings.xml b/packages/OsuLogin/res/values-es/strings.xml
deleted file mode 100644
index 3ad95cd..0000000
--- a/packages/OsuLogin/res/values-es/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registro online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Error al completar el registro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-et/strings.xml b/packages/OsuLogin/res/values-et/strings.xml
deleted file mode 100644
index 94c5cea..0000000
--- a/packages/OsuLogin/res/values-et/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Veebis registreerimine"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registreerimine ebaõnnestus"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-eu/strings.xml b/packages/OsuLogin/res/values-eu/strings.xml
deleted file mode 100644
index 30caa87..0000000
--- a/packages/OsuLogin/res/values-eu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Sarean izen-ematea"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Ezin izan da eman izena"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fa/strings.xml b/packages/OsuLogin/res/values-fa/strings.xml
deleted file mode 100644
index 3005203..0000000
--- a/packages/OsuLogin/res/values-fa/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ثبتنام آنلاین"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ثبتنام انجام نشد"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fi/strings.xml b/packages/OsuLogin/res/values-fi/strings.xml
deleted file mode 100644
index 24eac8a..0000000
--- a/packages/OsuLogin/res/values-fi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Rekisteröidy verkossa"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Rekisteröityminen ei onnistunut"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fr-rCA/strings.xml b/packages/OsuLogin/res/values-fr-rCA/strings.xml
deleted file mode 100644
index bcaa662..0000000
--- a/packages/OsuLogin/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Inscription en ligne"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Échec de l\'inscription"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fr/strings.xml b/packages/OsuLogin/res/values-fr/strings.xml
deleted file mode 100644
index bcaa662..0000000
--- a/packages/OsuLogin/res/values-fr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Inscription en ligne"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Échec de l\'inscription"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-gl/strings.xml b/packages/OsuLogin/res/values-gl/strings.xml
deleted file mode 100644
index 5fc4444..0000000
--- a/packages/OsuLogin/res/values-gl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Rexistro en liña"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Produciuse un erro co rexistro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-gu/strings.xml b/packages/OsuLogin/res/values-gu/strings.xml
deleted file mode 100644
index 8449963..0000000
--- a/packages/OsuLogin/res/values-gu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ઑનલાઇન સાઇન અપ કરો"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"સાઇન અપ નિષ્ફળ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hi/strings.xml b/packages/OsuLogin/res/values-hi/strings.xml
deleted file mode 100644
index 9e07438..0000000
--- a/packages/OsuLogin/res/values-hi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ऑनलाइन साइन अप करें"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"साइन अप नहीं किया जा सका"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hr/strings.xml b/packages/OsuLogin/res/values-hr/strings.xml
deleted file mode 100644
index e9b9751..0000000
--- a/packages/OsuLogin/res/values-hr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online registracija"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspjela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hu/strings.xml b/packages/OsuLogin/res/values-hu/strings.xml
deleted file mode 100644
index cb0e036..0000000
--- a/packages/OsuLogin/res/values-hu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online regisztráció"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"A regisztráció nem sikerült"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hy/strings.xml b/packages/OsuLogin/res/values-hy/strings.xml
deleted file mode 100644
index ae1c36a..0000000
--- a/packages/OsuLogin/res/values-hy/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Առցանց գրանցում"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Չհաջողվեց գրանցվել"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-in/strings.xml b/packages/OsuLogin/res/values-in/strings.xml
deleted file mode 100644
index 6aaf694..0000000
--- a/packages/OsuLogin/res/values-in/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Pendaftaran Online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Pendaftaran gagal"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-is/strings.xml b/packages/OsuLogin/res/values-is/strings.xml
deleted file mode 100644
index f1ae520..0000000
--- a/packages/OsuLogin/res/values-is/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Skráning á netinu"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Skráning mistókst"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-it/strings.xml b/packages/OsuLogin/res/values-it/strings.xml
deleted file mode 100644
index fbff7b0..0000000
--- a/packages/OsuLogin/res/values-it/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registrazione online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registrazione non riuscita"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-iw/strings.xml b/packages/OsuLogin/res/values-iw/strings.xml
deleted file mode 100644
index 866ef88..0000000
--- a/packages/OsuLogin/res/values-iw/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"הרשמה אונליין"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ההרשמה נכשלה"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ja/strings.xml b/packages/OsuLogin/res/values-ja/strings.xml
deleted file mode 100644
index 8a220d6..0000000
--- a/packages/OsuLogin/res/values-ja/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"オンライン登録"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"登録できませんでした"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ka/strings.xml b/packages/OsuLogin/res/values-ka/strings.xml
deleted file mode 100644
index bf08006..0000000
--- a/packages/OsuLogin/res/values-ka/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ონლაინ რეგისტრაცია"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"რეგისტრაცია ვერ მოხერხდა"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-kk/strings.xml b/packages/OsuLogin/res/values-kk/strings.xml
deleted file mode 100644
index 8b87356..0000000
--- a/packages/OsuLogin/res/values-kk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлайн тіркелу"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Тіркелмеді."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-km/strings.xml b/packages/OsuLogin/res/values-km/strings.xml
deleted file mode 100644
index f58ccc3..0000000
--- a/packages/OsuLogin/res/values-km/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ការចុះឈ្មោះលើអ៊ីនធឺណិត"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ការចុះឈ្មោះមិនបានសម្រេច"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-kn/strings.xml b/packages/OsuLogin/res/values-kn/strings.xml
deleted file mode 100644
index 49a6562..0000000
--- a/packages/OsuLogin/res/values-kn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ಆನ್ಲೈನ್ ಸೈನ್ ಅಪ್"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ಸೈನ್ ಅಪ್ ವಿಫಲವಾಗಿದೆ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ko/strings.xml b/packages/OsuLogin/res/values-ko/strings.xml
deleted file mode 100644
index e647ca0..0000000
--- a/packages/OsuLogin/res/values-ko/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"온라인 가입"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"가입에 실패했습니다."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ky/strings.xml b/packages/OsuLogin/res/values-ky/strings.xml
deleted file mode 100644
index 42da248..0000000
--- a/packages/OsuLogin/res/values-ky/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Интернет аркылуу катталуу"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Катталган жоксуз"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lo/strings.xml b/packages/OsuLogin/res/values-lo/strings.xml
deleted file mode 100644
index 9ff2241..0000000
--- a/packages/OsuLogin/res/values-lo/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ສະໝັກອອນລາຍ"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ສະໝັກບໍ່ສຳເລັດ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lt/strings.xml b/packages/OsuLogin/res/values-lt/strings.xml
deleted file mode 100644
index 1a4c06e..0000000
--- a/packages/OsuLogin/res/values-lt/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Internetinis prisiregistravimas"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Nepavyko prisiregistruoti"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lv/strings.xml b/packages/OsuLogin/res/values-lv/strings.xml
deleted file mode 100644
index 11cdb97..0000000
--- a/packages/OsuLogin/res/values-lv/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Reģistrācija tiešsaistē"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Reģistrācija neizdevās."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mk/strings.xml b/packages/OsuLogin/res/values-mk/strings.xml
deleted file mode 100644
index de608e1..0000000
--- a/packages/OsuLogin/res/values-mk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлајн регистрација"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Регистрацијата не успеа"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ml/strings.xml b/packages/OsuLogin/res/values-ml/strings.xml
deleted file mode 100644
index 8e797c8..0000000
--- a/packages/OsuLogin/res/values-ml/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ഓൺലെെൻ സെെൻ അപ്പ്"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"സൈൻ അപ്പ് ചെയ്യാനായില്ല"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mn/strings.xml b/packages/OsuLogin/res/values-mn/strings.xml
deleted file mode 100644
index 59d79d0..0000000
--- a/packages/OsuLogin/res/values-mn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлайнаар бүртгүүлэх"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Бүртгүүлж чадсангүй"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mr/strings.xml b/packages/OsuLogin/res/values-mr/strings.xml
deleted file mode 100644
index 15479a6..0000000
--- a/packages/OsuLogin/res/values-mr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ऑनलाइन साइन अप करा"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"साइन-अप करता आले नाही"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ms/strings.xml b/packages/OsuLogin/res/values-ms/strings.xml
deleted file mode 100644
index 7e1cf95..0000000
--- a/packages/OsuLogin/res/values-ms/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Pendaftaran Dalam Talian"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Pendaftaran gagal"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-my/strings.xml b/packages/OsuLogin/res/values-my/strings.xml
deleted file mode 100644
index 1bd992e..0000000
--- a/packages/OsuLogin/res/values-my/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"အွန်လိုင်း အကောင့်ဖွင့်ရန်"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"အကောင့်ဖွင့်၍ မရပါ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-nb/strings.xml b/packages/OsuLogin/res/values-nb/strings.xml
deleted file mode 100644
index 2e0c47a1..0000000
--- a/packages/OsuLogin/res/values-nb/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registrering på nettet"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registreringen mislyktes"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ne/strings.xml b/packages/OsuLogin/res/values-ne/strings.xml
deleted file mode 100644
index 16bd92f..0000000
--- a/packages/OsuLogin/res/values-ne/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"अनलाइन साइन अप"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"साइन अप गर्न सकिएन"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-nl/strings.xml b/packages/OsuLogin/res/values-nl/strings.xml
deleted file mode 100644
index 7cf8bd2..0000000
--- a/packages/OsuLogin/res/values-nl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online aanmelding"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Aanmelding mislukt"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-or/strings.xml b/packages/OsuLogin/res/values-or/strings.xml
deleted file mode 100644
index e0584d7..0000000
--- a/packages/OsuLogin/res/values-or/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ଅନଲାଇନ୍ ସାଇନ୍ ଅପ୍ କରନ୍ତୁ"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ସାଇନ୍ ଅପ୍ ବିଫଳ ହୋଇଛି"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pa/strings.xml b/packages/OsuLogin/res/values-pa/strings.xml
deleted file mode 100644
index 7e47d0e..0000000
--- a/packages/OsuLogin/res/values-pa/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ਆਨਲਾਈਨ ਸਾਈਨ-ਅੱਪ ਕਰੋ"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ਸਾਈਨ-ਅੱਪ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pl/strings.xml b/packages/OsuLogin/res/values-pl/strings.xml
deleted file mode 100644
index c0722ab..0000000
--- a/packages/OsuLogin/res/values-pl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Rejestracja online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Nie udało się zarejestrować"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt-rBR/strings.xml b/packages/OsuLogin/res/values-pt-rBR/strings.xml
deleted file mode 100644
index c9fe377..0000000
--- a/packages/OsuLogin/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Inscrição on-line"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt-rPT/strings.xml b/packages/OsuLogin/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 0059281..0000000
--- a/packages/OsuLogin/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Inscrição online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt/strings.xml b/packages/OsuLogin/res/values-pt/strings.xml
deleted file mode 100644
index c9fe377..0000000
--- a/packages/OsuLogin/res/values-pt/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Inscrição on-line"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ro/strings.xml b/packages/OsuLogin/res/values-ro/strings.xml
deleted file mode 100644
index eead127..0000000
--- a/packages/OsuLogin/res/values-ro/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Înscriere online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Nu s-a înscris"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ru/strings.xml b/packages/OsuLogin/res/values-ru/strings.xml
deleted file mode 100644
index a271ef7..0000000
--- a/packages/OsuLogin/res/values-ru/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Регистрация в Интернете"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Не удалось зарегистрироваться."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-si/strings.xml b/packages/OsuLogin/res/values-si/strings.xml
deleted file mode 100644
index 52e5979..0000000
--- a/packages/OsuLogin/res/values-si/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"සබැඳි ලියාපදිංචිය"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ලියාපදිංචිය අසාර්ථක විය"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sk/strings.xml b/packages/OsuLogin/res/values-sk/strings.xml
deleted file mode 100644
index f6b9f70..0000000
--- a/packages/OsuLogin/res/values-sk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online registrácia"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registrácia zlyhala"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sl/strings.xml b/packages/OsuLogin/res/values-sl/strings.xml
deleted file mode 100644
index 6e6b95c..0000000
--- a/packages/OsuLogin/res/values-sl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Spletna registracija"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registracija ni uspela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sq/strings.xml b/packages/OsuLogin/res/values-sq/strings.xml
deleted file mode 100644
index f67a238..0000000
--- a/packages/OsuLogin/res/values-sq/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Regjistrimi në linjë"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Regjistrimi dështoi"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sr/strings.xml b/packages/OsuLogin/res/values-sr/strings.xml
deleted file mode 100644
index 14e0828..0000000
--- a/packages/OsuLogin/res/values-sr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлајн регистрација"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Регистрација није успела"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sv/strings.xml b/packages/OsuLogin/res/values-sv/strings.xml
deleted file mode 100644
index ea5fdfd..0000000
--- a/packages/OsuLogin/res/values-sv/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registrering online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registreringen misslyckades"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sw/strings.xml b/packages/OsuLogin/res/values-sw/strings.xml
deleted file mode 100644
index c20a402..0000000
--- a/packages/OsuLogin/res/values-sw/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Kujisajili Mtandaoni"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Imeshindwa kukusajili"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ta/strings.xml b/packages/OsuLogin/res/values-ta/strings.xml
deleted file mode 100644
index e2eb567..0000000
--- a/packages/OsuLogin/res/values-ta/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ஆன்லைனில் பதிவு செய்"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"பதிவு செய்ய முடியவில்லை"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-te/strings.xml b/packages/OsuLogin/res/values-te/strings.xml
deleted file mode 100644
index 56b0b44..0000000
--- a/packages/OsuLogin/res/values-te/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ఆన్లైన్ సైన్ అప్"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"సైన్-అప్ విఫలమయ్యింది"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-th/strings.xml b/packages/OsuLogin/res/values-th/strings.xml
deleted file mode 100644
index 552dca2..0000000
--- a/packages/OsuLogin/res/values-th/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"การลงชื่อสมัครใช้ออนไลน์"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ลงชื่อสมัครใช้ไม่สำเร็จ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-tl/strings.xml b/packages/OsuLogin/res/values-tl/strings.xml
deleted file mode 100644
index ba89e96..0000000
--- a/packages/OsuLogin/res/values-tl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Pag-sign Up Online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Hindi nakapag-sign up"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-tr/strings.xml b/packages/OsuLogin/res/values-tr/strings.xml
deleted file mode 100644
index 1d927fe..0000000
--- a/packages/OsuLogin/res/values-tr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online Kaydolma"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Kaydolma işlemi başarısız oldu"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-uk/strings.xml b/packages/OsuLogin/res/values-uk/strings.xml
deleted file mode 100644
index 6e60ff0..0000000
--- a/packages/OsuLogin/res/values-uk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлайн-реєстрація"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Не вдалося зареєструватись"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ur/strings.xml b/packages/OsuLogin/res/values-ur/strings.xml
deleted file mode 100644
index eed7686..0000000
--- a/packages/OsuLogin/res/values-ur/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"آن لائن سائن اپ کریں"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"سائن اپ ناکام ہو گیا"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-uz/strings.xml b/packages/OsuLogin/res/values-uz/strings.xml
deleted file mode 100644
index 152d129..0000000
--- a/packages/OsuLogin/res/values-uz/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Onlayn registratsiya"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registratsiya qilinmadi"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-vi/strings.xml b/packages/OsuLogin/res/values-vi/strings.xml
deleted file mode 100644
index 84558076..0000000
--- a/packages/OsuLogin/res/values-vi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Đăng ký trực tuyến"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Không đăng ký được"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rCN/strings.xml b/packages/OsuLogin/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 7f13647..0000000
--- a/packages/OsuLogin/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"在线注册"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"注册失败"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rHK/strings.xml b/packages/OsuLogin/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 8731791..0000000
--- a/packages/OsuLogin/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"網上申請"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"無法申請"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rTW/strings.xml b/packages/OsuLogin/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 79208c8..0000000
--- a/packages/OsuLogin/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"線上註冊"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"註冊失敗"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zu/strings.xml b/packages/OsuLogin/res/values-zu/strings.xml
deleted file mode 100644
index 27ac6bb..0000000
--- a/packages/OsuLogin/res/values-zu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"I-OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Ukubhalisa Okuku-inthanethi"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Ukubhalisa kuhlulekile"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values/dimens.xml b/packages/OsuLogin/res/values/dimens.xml
deleted file mode 100644
index 47c8224..0000000
--- a/packages/OsuLogin/res/values/dimens.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<resources>
- <!-- Default screen margins, per the Android Design guidelines. -->
- <dimen name="activity_horizontal_margin">16dp</dimen>
- <dimen name="activity_vertical_margin">16dp</dimen>
-</resources>
diff --git a/packages/OsuLogin/res/values/strings.xml b/packages/OsuLogin/res/values/strings.xml
deleted file mode 100644
index 14de0f5..0000000
--- a/packages/OsuLogin/res/values/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<resources>
- <!-- application name [CHAR LIMIT=32] -->
- <string name="app_name">OsuLogin</string>
- <!-- action bar label [CHAR LIMIT=32] -->
- <string name="action_bar_label">Online Sign Up</string>
- <!-- toast message [CHAR LIMIT=32] -->
- <string name="sign_up_failed">Sign-up failed</string>
-</resources>
diff --git a/packages/OsuLogin/res/values/styles.xml b/packages/OsuLogin/res/values/styles.xml
deleted file mode 100644
index f6c2339..0000000
--- a/packages/OsuLogin/res/values/styles.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<resources>
-
- <!--
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
- -->
- <style name="AppBaseTheme" parent="@android:style/Theme.DeviceDefault.Settings">
- <!--
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
- -->
- </style>
-
- <!-- Application theme. -->
- <style name="AppTheme" parent="AppBaseTheme">
- <!-- All customizations that are NOT specific to a particular API-level can go here. -->
- </style>
-</resources>
diff --git a/packages/OsuLogin/res/xml/network_security_config.xml b/packages/OsuLogin/res/xml/network_security_config.xml
deleted file mode 100644
index 3ef4b84..0000000
--- a/packages/OsuLogin/res/xml/network_security_config.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<network-security-config>
-<base-config cleartextTrafficPermitted="true">
- <trust-anchors>
- <certificates src="system" />
- <certificates src="wfa" />
- </trust-anchors>
-</base-config>
-</network-security-config>
diff --git a/packages/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java b/packages/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java
deleted file mode 100644
index 9797846..0000000
--- a/packages/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java
+++ /dev/null
@@ -1,281 +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.hotspot2.osulogin;
-
-import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.webkit.WebChromeClient;
-import android.webkit.WebResourceError;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.ProgressBar;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * Online Sign Up Login Web View launched during Provision Process of Hotspot 2.0 rel2.
- */
-public class OsuLoginActivity extends Activity {
- private static final String TAG = "OsuLogin";
- private static final boolean DBG = true;
-
- private String mUrl;
- private String mHostName;
- private Network mNetwork;
- private ConnectivityManager mCm;
- private ConnectivityManager.NetworkCallback mNetworkCallback;
- private WifiManager mWifiManager;
- private WebView mWebView;
- private SwipeRefreshLayout mSwipeRefreshLayout;
- private ProgressBar mProgressBar;
- private boolean mForceDisconnect = true;
- boolean mRedirectResponseReceived = false;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (DBG) {
- Log.d(TAG, "onCreate: Opening OSU Web View");
- }
-
- mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
- if (mWifiManager == null) {
- Log.e(TAG, "Cannot get wifi service");
- finishAndRemoveTask();
- return;
- }
-
- if (getIntent() == null) {
- Log.e(TAG, "Intent is null");
- finishAndRemoveTask();
- return;
- }
-
- mNetwork = getIntent().getParcelableExtra(WifiManager.EXTRA_OSU_NETWORK);
- if (mNetwork == null) {
- Log.e(TAG, "Cannot get the network instance for OSU from intent");
- finishAndRemoveTask();
- return;
- }
-
- mUrl = getIntent().getStringExtra(WifiManager.EXTRA_URL);
- if (mUrl == null) {
- Log.e(TAG, "Cannot get OSU server url from intent");
- finishAndRemoveTask();
- return;
- }
-
- mHostName = getHost(mUrl);
- if (mHostName == null) {
- Log.e(TAG, "Cannot get host from the url");
- finishAndRemoveTask();
- return;
- }
-
- mCm = (ConnectivityManager) getApplicationContext().getSystemService(
- Context.CONNECTIVITY_SERVICE);
- if (mCm == null) {
- Log.e(TAG, "Cannot get connectivity service");
- finishAndRemoveTask();
- return;
- }
-
- if (!mCm.bindProcessToNetwork(mNetwork)) {
- Log.e(TAG, "Network is no longer valid");
- finishAndRemoveTask();
- return;
- }
-
- final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork);
- if (networkCapabilities == null || !networkCapabilities.hasTransport(
- NetworkCapabilities.TRANSPORT_WIFI)) {
- Log.e(TAG, "WiFi is not supported for the Network");
- finishAndRemoveTask();
- return;
- }
-
- getActionBar().setDisplayShowHomeEnabled(false);
- getActionBar().setElevation(0); // remove shadow
- getActionBar().setTitle(getString(R.string.action_bar_label));
- getActionBar().setSubtitle("");
- setContentView(R.layout.osu_web_view);
-
- // Exit this app if network disappeared.
- mNetworkCallback = new ConnectivityManager.NetworkCallback() {
- @Override
- public void onLost(Network network) {
- if (DBG) {
- Log.d(TAG, "Lost for the current Network, close the browser");
- }
- mForceDisconnect = false; // It is already disconnected.
- if (!mRedirectResponseReceived) {
- showSignUpFailedToast();
- }
- if (mNetwork.equals(network)) {
- finishAndRemoveTask();
- }
- }
- };
-
- mCm.registerNetworkCallback(
- new NetworkRequest.Builder().addTransportType(
- NetworkCapabilities.TRANSPORT_WIFI).removeCapability(
- NET_CAPABILITY_TRUSTED).build(),
- mNetworkCallback);
-
- mWebView = findViewById(R.id.webview);
- mWebView.clearCache(true);
- WebSettings webSettings = mWebView.getSettings();
- webSettings.setJavaScriptEnabled(true);
- webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
- webSettings.setUseWideViewPort(true);
- webSettings.setLoadWithOverviewMode(true);
- webSettings.setSupportZoom(true);
- webSettings.setBuiltInZoomControls(true);
- webSettings.setDisplayZoomControls(false);
- mProgressBar = findViewById(R.id.progress_bar);
- mWebView.setWebViewClient(new OsuWebViewClient());
- mWebView.setWebChromeClient(new WebChromeClient() {
- @Override
- public void onProgressChanged(WebView view, int newProgress) {
- mProgressBar.setProgress(newProgress);
- }
- });
-
- if (DBG) {
- Log.d(TAG, "OSU Web View to " + mUrl);
- }
-
- mWebView.loadUrl(mUrl);
- mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
- mSwipeRefreshLayout.setOnRefreshListener(() -> {
- mWebView.reload();
- mSwipeRefreshLayout.setRefreshing(true);
- });
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- // Check if the key event was the Back button.
- if ((keyCode == KeyEvent.KEYCODE_BACK)) {
- // If there is a history to move back
- if (mWebView.canGoBack()) {
- mWebView.goBack();
- return true;
- }
- }
- return super.onKeyDown(keyCode, event);
- }
-
- @Override
- protected void onDestroy() {
- if (mNetworkCallback != null) {
- mCm.unregisterNetworkCallback(mNetworkCallback);
- mNetworkCallback = null;
- }
- if (mWifiManager != null && mForceDisconnect) {
- mWifiManager.disconnect();
- mWifiManager = null;
- }
- super.onDestroy();
- }
-
- private String getHost(String url) {
- try {
- return new URL(url).getHost();
- } catch (MalformedURLException e) {
- Log.e(TAG, "Invalid URL " + url);
- }
- return null;
- }
-
- private String getHeaderSubtitle(String urlString) {
- try {
- URL url = new URL(urlString);
- return url.getProtocol() + "://" + url.getHost();
- } catch (MalformedURLException e) {
- Log.e(TAG, "Invalid URL " + urlString);
- }
- return "";
- }
-
- private void showSignUpFailedToast() {
- Toast.makeText(getApplicationContext(), R.string.sign_up_failed,
- Toast.LENGTH_SHORT).show();
- }
-
- private class OsuWebViewClient extends WebViewClient {
- boolean mPageError = false;
-
- @Override
- public void onPageStarted(WebView view, String urlString, Bitmap favicon) {
- String subtitle = getHeaderSubtitle(urlString);
- getActionBar().setSubtitle(subtitle);
- mProgressBar.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onPageFinished(WebView view, String url) {
- mProgressBar.setVisibility(View.INVISIBLE);
- mSwipeRefreshLayout.setRefreshing(false);
-
- // Do not show the page error on UI.
- if (mPageError) {
- if (mRedirectResponseReceived) {
- // Do not disconnect current connection while provisioning is in progress.
- mForceDisconnect = false;
- }
- finishAndRemoveTask();
- }
- }
-
- @Override
- public void onReceivedError(WebView view, WebResourceRequest request,
- WebResourceError error) {
- if (request.getUrl().toString().startsWith("http://127.0.0.1")) {
- mRedirectResponseReceived = true;
- view.stopLoading();
- }
-
- if (request.isForMainFrame()) {
- // This happens right after getting HTTP redirect response from an OSU server
- // since no more Http request is allowed to send to the OSU server.
- mPageError = true;
- Log.e(TAG, "onReceived Error for MainFrame: " + error.getErrorCode());
- }
- }
- }
-}
diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp
index 9420954..75bd32e 100644
--- a/packages/PackageInstaller/Android.bp
+++ b/packages/PackageInstaller/Android.bp
@@ -20,6 +20,7 @@
certificate: "platform",
privileged: true,
platform_apis: true,
+ rename_resources_package: false,
static_libs: [
"xz-java",
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
index c840374..87f89ce 100644
--- a/packages/PackageInstaller/res/values-ar/strings.xml
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -57,7 +57,7 @@
<string name="uninstall_application_text_all_users" msgid="575491774380227119">"هل تريد إزالة هذا التطبيق "<b>"لكل"</b>" المستخدمين؟ ستتم إزالة التطبيق وبياناته من "<b>"كل"</b>" المستخدمين على هذا الجهاز."</string>
<string name="uninstall_application_text_user" msgid="498072714173920526">"هل تريد إزالة هذا التطبيق للمستخدم <xliff:g id="USERNAME">%1$s</xliff:g>؟"</string>
<string name="uninstall_update_text" msgid="863648314632448705">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات."</string>
- <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"هل تريد إعادة ضبط هذا التطبيق على الإعدادات الأصلية؟ سؤدي ذلك إلى إزالة جميع البيانات، كما سيؤثر على جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string>
+ <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات. وسيؤثر هذا في جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"الاحتفاظ بالحجم <xliff:g id="SIZE">%1$s</xliff:g> من بيانات التطبيق."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"عمليات إلغاء التثبيت الجارية"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"عمليات إلغاء التثبيت غير الناجحة"</string>
diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml
index d3a9589..108c86f 100644
--- a/packages/PackageInstaller/res/values-nl/strings.xml
+++ b/packages/PackageInstaller/res/values-nl/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Pakket-installatie"</string>
<string name="install" msgid="711829760615509273">"Installeren"</string>
- <string name="done" msgid="6632441120016885253">"Klaar"</string>
+ <string name="done" msgid="6632441120016885253">"Gereed"</string>
<string name="cancel" msgid="1018267193425558088">"Annuleren"</string>
<string name="installing" msgid="4921993079741206516">"Installeren…"</string>
<string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installeren…"</string>
diff --git a/packages/PrintSpooler/res/values-as/strings.xml b/packages/PrintSpooler/res/values-as/strings.xml
index b6b287f..a93fceb 100644
--- a/packages/PrintSpooler/res/values-as/strings.xml
+++ b/packages/PrintSpooler/res/values-as/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDFৰ জৰিয়তে ছেভ কৰক"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"প্ৰিণ্ট বিকল্পসমূহ বিস্তাৰ কৰা হ’ল"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"প্ৰিণ্ট বিকল্পসমূহ সংকুচিত কৰা হ’ল"</string>
- <string name="search" msgid="5421724265322228497">"Search"</string>
+ <string name="search" msgid="5421724265322228497">"সন্ধান কৰক"</string>
<string name="all_printers_label" msgid="3178848870161526399">"সকলো প্ৰিণ্টাৰ"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"সেৱা যোগ কৰক"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"সন্ধান বাকচটো দেখুওৱা হ’ল"</string>
diff --git a/packages/PrintSpooler/res/values-bn/strings.xml b/packages/PrintSpooler/res/values-bn/strings.xml
index b2e1eed..637becb 100644
--- a/packages/PrintSpooler/res/values-bn/strings.xml
+++ b/packages/PrintSpooler/res/values-bn/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"পিডিএফ হিসাবে সেভ করুন"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"প্রিন্ট বিকল্প প্রসারিত হয়েছে"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"প্রিন্ট বিকল্প সংকুচিত হয়েছে"</string>
- <string name="search" msgid="5421724265322228497">"সার্চ"</string>
+ <string name="search" msgid="5421724265322228497">"খুঁজুন"</string>
<string name="all_printers_label" msgid="3178848870161526399">"সমস্ত প্রিন্টার"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"পরিষেবা যোগ করুন"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"সার্চ বাক্স দেখানো হচ্ছে"</string>
diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml
index 719fc92..596947d 100644
--- a/packages/PrintSpooler/res/values-fa/strings.xml
+++ b/packages/PrintSpooler/res/values-fa/strings.xml
@@ -31,7 +31,7 @@
<string name="template_all_pages" msgid="3322235982020148762">"همه <xliff:g id="PAGE_COUNT">%1$s</xliff:g> صفحه"</string>
<string name="template_page_range" msgid="428638530038286328">"محدوده <xliff:g id="PAGE_COUNT">%1$s</xliff:g> صفحه"</string>
<string name="pages_range_example" msgid="8558694453556945172">"مثلاً ۱—۵،۹،۷—۱۰"</string>
- <string name="print_preview" msgid="8010217796057763343">"پیشنمای چاپ"</string>
+ <string name="print_preview" msgid="8010217796057763343">"پیشنمایش چاپ"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"نصب نمایشگر PDF برای پیشنمایش"</string>
<string name="printing_app_crashed" msgid="854477616686566398">"برنامه چاپ خراب شد"</string>
<string name="generating_print_job" msgid="3119608742651698916">"در حال ایجاد کار چاپ"</string>
diff --git a/packages/PrintSpooler/res/values-kn/strings.xml b/packages/PrintSpooler/res/values-kn/strings.xml
index 261fe4b..150ede4 100644
--- a/packages/PrintSpooler/res/values-kn/strings.xml
+++ b/packages/PrintSpooler/res/values-kn/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDF ಗೆ ಉಳಿಸು"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"ಪ್ರಿಂಟ್ ಆಯ್ಕೆಗಳನ್ನು ವಿಸ್ತರಿಸಲಾಗಿದೆ"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"ಪ್ರಿಂಟ್ ಆಯ್ಕೆಗಳನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
- <string name="search" msgid="5421724265322228497">"Search"</string>
+ <string name="search" msgid="5421724265322228497">"ಹುಡುಕಿ"</string>
<string name="all_printers_label" msgid="3178848870161526399">"ಎಲ್ಲಾ ಪ್ರಿಂಟರ್ಗಳು"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"ಸೇವೆಯನ್ನು ಸೇರಿಸು"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ಹುಡುಕಾಟ ಪೆಟ್ಟಿಗೆಯನ್ನು ತೋರಿಸಲಾಗಿದೆ"</string>
diff --git a/packages/PrintSpooler/res/values-ml/strings.xml b/packages/PrintSpooler/res/values-ml/strings.xml
index 73af95d..dbcd34b 100644
--- a/packages/PrintSpooler/res/values-ml/strings.xml
+++ b/packages/PrintSpooler/res/values-ml/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDF-ൽ സംരക്ഷിക്കുക"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്ഷനുകൾ വിപുലീകരിച്ചു"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്ഷനുകൾ ചുരുക്കി"</string>
- <string name="search" msgid="5421724265322228497">"Search"</string>
+ <string name="search" msgid="5421724265322228497">"തിരയൽ"</string>
<string name="all_printers_label" msgid="3178848870161526399">"എല്ലാ പ്രിന്ററുകളും"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"സേവനം ചേർക്കുക"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"തിരയൽ ബോക്സ് ദൃശ്യമാക്കിയിരിക്കുന്നു"</string>
diff --git a/packages/PrintSpooler/res/values-mr/strings.xml b/packages/PrintSpooler/res/values-mr/strings.xml
index 8119439..44456b4 100644
--- a/packages/PrintSpooler/res/values-mr/strings.xml
+++ b/packages/PrintSpooler/res/values-mr/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"पीडीएफ वर सेव्ह करा"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"प्रिंट पर्याय विस्तृत झाले"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"प्रिंट पर्याय संक्षिप्त झाले"</string>
- <string name="search" msgid="5421724265322228497">"Search"</string>
+ <string name="search" msgid="5421724265322228497">"शोध"</string>
<string name="all_printers_label" msgid="3178848870161526399">"सर्व प्रिंटर"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"सेवा जोडा"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"शोध बॉक्स दर्शविला"</string>
@@ -63,7 +63,7 @@
<string name="printer_info_desc" msgid="7181988788991581654">"या प्रिंटर विषयी अधिक माहिती"</string>
<string name="notification_channel_progress" msgid="872788690775721436">"प्रिंट कार्ये चालवणे"</string>
<string name="notification_channel_failure" msgid="9042250774797916414">"अयशस्वी प्रिंट कार्ये"</string>
- <string name="could_not_create_file" msgid="3425025039427448443">"फाइल तयार करणेे शक्य झाले नाही"</string>
+ <string name="could_not_create_file" msgid="3425025039427448443">"फाईल तयार करणेे शक्य झाले नाही"</string>
<string name="print_services_disabled_toast" msgid="9089060734685174685">"काही प्रिंट सेवा अक्षम केल्या आहेत"</string>
<string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिंटर शोधत आहे"</string>
<string name="print_no_print_services" msgid="8561247706423327966">"कोणत्याही प्रिंट सेवा सक्षम केलेल्या नाहीत"</string>
diff --git a/packages/PrintSpooler/res/values-or/strings.xml b/packages/PrintSpooler/res/values-or/strings.xml
index 7000b95..a1675fa 100644
--- a/packages/PrintSpooler/res/values-or/strings.xml
+++ b/packages/PrintSpooler/res/values-or/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDFରେ ସେଭ୍ କରନ୍ତୁ"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ବଡ଼ କରାଯାଇଛି"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ଛୋଟ କରାଯାଇଛି"</string>
- <string name="search" msgid="5421724265322228497">"Search"</string>
+ <string name="search" msgid="5421724265322228497">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
<string name="all_printers_label" msgid="3178848870161526399">"ସମସ୍ତ ପ୍ରିଣ୍ଟର୍"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"ସେବା ଯୋଗ କରନ୍ତୁ"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ସର୍ଚ୍ଚ ବକ୍ସ ଦେଖାଯାଇଛି"</string>
diff --git a/packages/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml
index 79944bb..b01b50a 100644
--- a/packages/PrintSpooler/res/values-te/strings.xml
+++ b/packages/PrintSpooler/res/values-te/strings.xml
@@ -47,7 +47,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDF వలె సేవ్ చేయి"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"ముద్రణ ఎంపికలు విస్తరించబడ్డాయి"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"ముద్రణ ఎంపికలు కుదించబడ్డాయి"</string>
- <string name="search" msgid="5421724265322228497">"సెర్చ్"</string>
+ <string name="search" msgid="5421724265322228497">"వెతుకు"</string>
<string name="all_printers_label" msgid="3178848870161526399">"అన్ని ప్రింటర్లు"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"సేవను జోడించు"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"శోధన పెట్టె చూపబడింది"</string>
diff --git a/packages/PrintSpooler/res/values-uz/strings.xml b/packages/PrintSpooler/res/values-uz/strings.xml
index ea0a6ea..d17bce7 100644
--- a/packages/PrintSpooler/res/values-uz/strings.xml
+++ b/packages/PrintSpooler/res/values-uz/strings.xml
@@ -100,7 +100,7 @@
</string-array>
<string-array name="orientation_labels">
<item msgid="4061931020926489228">"Tik holat"</item>
- <item msgid="3199660090246166812">"Yotiq"</item>
+ <item msgid="3199660090246166812">"Eniga"</item>
</string-array>
<string name="print_write_error_message" msgid="5787642615179572543">"Faylga yozib bo‘lmadi"</string>
<string name="print_error_default_message" msgid="8602678405502922346">"Xatolik yuz berdi. Qaytadan urining."</string>
diff --git a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java
index 6125b85..5dc0b72 100644
--- a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java
+++ b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java
@@ -52,6 +52,9 @@
public static String getAppContentDescription(Context context, String packageName,
int userId) {
final CharSequence appLabel = getApplicationLabel(context.getPackageManager(), packageName);
+ if (appLabel == null) {
+ return "";
+ }
return context.getSystemService(UserManager.class).isManagedProfile(userId)
? context.getString(R.string.accessibility_work_profile_app_description, appLabel)
: appLabel.toString();
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 08e9224..df7a260 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -85,7 +85,7 @@
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"المكالمات الهاتفية"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"نقل الملف"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"جهاز الإرسال"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"الدخول إلى الإنترنت"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"استخدام الإنترنت"</string>
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"مشاركة جهة الاتصال"</string>
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"استخدام مع مشاركة جهة الاتصال"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"مشاركة اتصال الإنترنت"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 7a83b3b..00a6bfc 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Узровень зараду: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Л: акумулятар: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, П: акумулятар: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Уключана"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Аўдыё медыяпрылады"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Аўдыя медыяфайлаў"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Тэлефонныя выклікі"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Перадача файлаў"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Прылада ўводу"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index dbec19b..a68b9a4 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -211,9 +211,9 @@
<string name="adb_wireless_error" msgid="721958772149779856">"সমস্যা"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"ওয়্যারলেস ডিবাগিং"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"কোন কোন ডিভাইস উপলভ্য আছে তা দেখে নিয়ে ব্যবহার করার জন্য, ওয়্যারলেস ডিবাগিং চালু করুন"</string>
- <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR কোড ব্যবহার করে ডিভাইস যোগ করুন"</string>
+ <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR কোড ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR কোড স্ক্যানার ব্যবহার করে নতুন ডিভাইস যোগ করুন"</string>
- <string name="adb_pair_method_code_title" msgid="1122590300445142904">"যোগ করার কোড ব্যবহার করে ডিভাইস যোগ করুন"</string>
+ <string name="adb_pair_method_code_title" msgid="1122590300445142904">"পেয়ারিং কোড ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ছয় সংখ্যার কোড ব্যবহার করে নতুন ডিভাইস যোগ করুন"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"যোগ করা ডিভাইস"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"এখন কানেক্ট রয়েছে"</string>
@@ -222,16 +222,16 @@
<string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"ডিভাইসে আঙ্গুলের ছাপ: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"কানেক্ট করা যায়নি"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>টি সঠিক নেটওয়ার্কে কানেক্ট আছে কিনা দেখে নিন"</string>
- <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"ডিভাইসের সাথে যোগ করুন"</string>
- <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"ওয়াই-ফাই যোগ করার কোড"</string>
- <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"যোগ করা যায়নি"</string>
+ <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"ডিভাইসের সাথে পেয়ার করুন"</string>
+ <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"ওয়াই-ফাইয়ের সাথে পেয়ার করার কোড"</string>
+ <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"পেয়ার করা যায়নি"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"ডিভাইসটি একই নেটওয়ার্কে কানেক্ট আছে কিনা দেখে নিন।"</string>
- <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR কোড স্ক্যান করে ওয়াই-ফাই ব্যবহার করে ডিভাইস যোগ করুন"</string>
+ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR কোড স্ক্যান করে ওয়াই-ফাই ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"ডিভাইস যোগ করা হচ্ছে…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ডিভাইস যোগ করা যায়নি। এটি দুটি কারণে হয়ে থাকে - QR কোডটি সঠিক নয় বা ডিভাইসটি একই নেটওয়ার্কে কানেক্ট করা নেই।"</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP অ্যাড্রেস ও পোর্ট"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR কোড স্ক্যান করুন"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR কোড স্ক্যান করে ওয়াই-ফাইয়ের সাহায্যে ডিভাইস যোগ করুন"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR কোড স্ক্যান করে ওয়াই-ফাই ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"একটি ওয়াই-ফাই নেটওয়ার্কের সাথে কানেক্ট করুন"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"ত্রুটি প্রতিবেদনের শর্টকাট"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 3ca9d52..3363fdd 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -66,7 +66,7 @@
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconnectat"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"S\'està desconnectant..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"S\'està connectant…"</string>
- <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat"</string>
+ <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> Connectat"</string>
<string name="bluetooth_pairing" msgid="4269046942588193600">"S\'està vinculant..."</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat (sense accés al telèfon)"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat (sense contingut multimèdia)"</string>
@@ -532,7 +532,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Perfil restringit"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Vols afegir un usuari nou?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Pots compartir aquest dispositiu amb altres persones creant usuaris addicionals. Cada usuari té el seu propi espai, que pot personalitzar amb aplicacions i fons de pantalla, entre d\'altres. Els usuaris també poden ajustar opcions de configuració del dispositiu, com ara la Wi-Fi, que afecten els altres usuaris.\n\nQuan afegeixis un usuari nou, haurà de configurar el seu espai.\n\nTots els usuaris poden actualitzar les aplicacions de la resta. És possible que la configuració i els serveis d\'accessibilitat no es transfereixin a l\'usuari nou."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar el seu espai.\n\nQualsevol usuari pot actualitzar les aplicacions dels altres usuaris."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Quan s\'afegeix un usuari nou, aquesta persona ha de configurar el seu espai.\n\nQualsevol usuari pot actualitzar les aplicacions dels altres usuaris."</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Vols configurar l\'usuari ara?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"Assegura\'t que la persona estigui disponible per accedir al dispositiu i configurar el seu espai."</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Vols configurar el perfil ara?"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 287a1ac..8b4ae9e 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -196,7 +196,7 @@
<string name="choose_profile" msgid="343803890897657450">"Elegir perfil"</string>
<string name="category_personal" msgid="6236798763159385225">"Personal"</string>
<string name="category_work" msgid="4014193632325996115">"Trabajo"</string>
- <string name="development_settings_title" msgid="140296922921597393">"Opciones para programadores"</string>
+ <string name="development_settings_title" msgid="140296922921597393">"Opciones para desarrolladores"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Activar opciones para programador"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Establecer opciones para desarrollar aplicaciones"</string>
<string name="development_settings_not_available" msgid="355070198089140951">"Las opciones de programador no están disponibles para este usuario."</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index d003ef0..dcb23d8 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> akut"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> akut, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> akut"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiivne"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Meedia heli"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Meediaheli"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonikõned"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failiedastus"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Sisendseade"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 140d4ce..cb601c1 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -142,7 +142,7 @@
<string name="process_kernel_label" msgid="950292573930336765">"Système d\'exploitation Android"</string>
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Applications supprimées"</string>
<string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Applications et utilisateurs supprimés"</string>
- <string name="data_usage_ota" msgid="7984667793701597001">"Mises à jour système"</string>
+ <string name="data_usage_ota" msgid="7984667793701597001">"Mises à jour du système"</string>
<string name="tether_settings_title_usb" msgid="3728686573430917722">"Partage de connexion par USB"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Point d\'accès Wi-Fi mobile"</string>
<string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Partage connexion Bluetooth"</string>
@@ -489,6 +489,7 @@
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"Les adresses MAC sont randomisées"</string>
<plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
<item quantity="one">%1$d appareil connecté</item>
+ <item quantity="many">%1$d devices connected</item>
<item quantity="other">%1$d appareils connectés</item>
</plurals>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Plus longtemps."</string>
@@ -498,7 +499,7 @@
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jamais"</string>
- <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Priorités seulement"</string>
+ <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Prioritaires seulement"</string>
<string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="zen_alarm_warning_indef" msgid="4146527909616457163">"Vous n\'entendrez pas votre prochaine alarme à <xliff:g id="WHEN">%1$s</xliff:g> sauf si vous désactivez préalablement cette option"</string>
<string name="zen_alarm_warning" msgid="245729928048586280">"Vous n\'entendrez pas votre prochaine alarme à <xliff:g id="WHEN">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index bb5959e..d4d7949 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -489,6 +489,7 @@
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"La sélection des adresses MAC est aléatoire"</string>
<plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
<item quantity="one">%1$d appareil connecté</item>
+ <item quantity="many">%1$d devices connected</item>
<item quantity="other">%1$d appareils connectés</item>
</plurals>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Plus longtemps."</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 0ce52f8..eac8ba8 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -33,11 +33,11 @@
<string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' સાથે કનેક્ટ કરી શકાતું નથી"</string>
<string name="wifi_check_password_try_again" msgid="8817789642851605628">"પાસવર્ડ તપાસો અને ફરી પ્રયાસ કરો"</string>
<string name="wifi_not_in_range" msgid="1541760821805777772">"રેન્જમાં નથી"</string>
- <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"આપમેળે કનેક્ટ કરશે નહીં"</string>
+ <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ઑટોમૅટિક રીતે કનેક્ટ કરશે નહીં"</string>
<string name="wifi_no_internet" msgid="1774198889176926299">"કોઈ ઇન્ટરનેટ ઍક્સેસ નથી"</string>
<string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા સચવાયું"</string>
<string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s દ્વારા સ્વત: કનેક્ટ થયેલ"</string>
- <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"નેટવર્ક રેટિંગ પ્રદાતા દ્વારા આપમેળે કનેક્ટ થયું"</string>
+ <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"નેટવર્ક રેટિંગ પ્રદાતા દ્વારા ઑટોમૅટિક રીતે કનેક્ટ થયું"</string>
<string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
<string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કનેક્ટ થયેલ"</string>
<string name="available_via_passpoint" msgid="1716000261192603682">"%1$s દ્વારા ઉપલબ્ધ"</string>
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> બૅટરી, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> બૅટરી"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"સક્રિય"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"મીડિયા ઑડિઓ"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"મીડિયા ઑડિયો"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"ફોન કૉલ"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ફાઇલ સ્થાનાંતરણ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ઇનપુટ ઉપકરણ"</string>
@@ -113,7 +113,7 @@
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"ઇનપુટ માટે ઉપયોગ કરો"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"શ્રવણ યંત્રો માટે ઉપયોગ કરો"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"જોડી"</string>
- <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"જોડાણ બનાવો"</string>
+ <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"જોડી કરો"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"રદ કરો"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"એ કનેક્ટ કરેલ હોય ત્યારે જોડાણ બનાવવાથી તમારા સંપર્કો અને કૉલ ઇતિહાસનો અૅક્સેસ મળે છે."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> સાથે જોડી કરી શક્યાં નહીં."</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 50fdfc9..94cd9f66 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -66,7 +66,7 @@
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Disconnesso"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Disconnessione…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Connessione…"</string>
- <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso"</string>
+ <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> Connesso"</string>
<string name="bluetooth_pairing" msgid="4269046942588193600">"Accoppiamento…"</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (telefono escluso)"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (contenuti multimediali esclusi)"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 03065e8..98c4f10 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -85,7 +85,7 @@
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"ការហៅទូរសព្ទ"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ផ្ទេរឯកសារ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ឧបករណ៍បញ្ចូល"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ចូលអ៊ីនធឺណិត"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ការចូលប្រើអ៊ីនធឺណិត"</string>
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ការចែករំលែកទំនាក់ទំនង"</string>
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ប្រើសម្រាប់ការចែករំលែកទំនាក់ទំនង"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ចែករំលែកការតភ្ជាប់អ៊ីនធឺណិត"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 71c5e49..ddaf970 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -307,7 +307,7 @@
<string name="adb_keys_warning_message" msgid="2968555274488101220">"ನೀವು ಹಿಂದೆ ಅಧಿಕೃತಗೊಳಿಸಿದ ಎಲ್ಲ ಕಂಪ್ಯೂಟರ್ಗಳಿಂದ USB ಡೀಬಗ್ಗೆ ಪ್ರವೇಶವನ್ನು ರದ್ದುಗೊಳಿಸುವುದೇ?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"ಅಭಿವೃದ್ಧಿಯ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"ಈ ಸೆಟ್ಟಿಂಗ್ಗಳು ಅಭಿವೃದ್ಧಿಯ ಬಳಕೆಗೆ ಮಾತ್ರ. ಅವುಗಳು ನಿಮ್ಮ ಸಾಧನ ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಧಕ್ಕೆ ಮಾಡಬಹುದು ಅಥವಾ ಅವು ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದಿರುವಂತೆ ಮಾಡಬಹುದು."</string>
- <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB ಮೂಲಕ ಆಪ್ ಪರಿಶೀಲಿಸಿ"</string>
+ <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB ಮೂಲಕ ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ಹಾನಿಮಾಡುವಂತಹ ವರ್ತನೆಗಾಗಿ ADB/ADT ಮೂಲಕ ಸ್ಥಾಪಿಸಲಾದ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"ಹೆಸರುಗಳಿಲ್ಲದ (ಕೇವಲ MAC ವಿಳಾಸಗಳು ಮಾತ್ರ) ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಪ್ರದರ್ಶಿಸಲಾಗುತ್ತದೆ"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ರಿಮೋಟ್ ಸಾಧನಗಳಲ್ಲಿ ಕಂಡುಬರುವ ಸ್ವೀಕಾರಾರ್ಹವಲ್ಲದ ಜೋರಾದ ವಾಲ್ಯೂಮ್ ಅಥವಾ ನಿಯಂತ್ರಣದ ಕೊರತೆಯಂತಹ ವಾಲ್ಯೂಮ್ ಸಮಸ್ಯೆಗಳಂತಹ ಸಂದರ್ಭದಲ್ಲಿ ಬ್ಲೂಟೂತ್ನ ನಿಚ್ಚಳ ವಾಲ್ಯೂಮ್ ವೈಶಿಷ್ಟ್ಯವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 15322dd..4cb93fa 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -112,7 +112,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Файл өткөрүү үчүн колдонулсун"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Киргизүү үчүн колдонулсун"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Угуу аппараттары үчүн колдонуу"</string>
- <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Жупташтыруу"</string>
+ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Байланыштыруу"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ЖУПТАШТЫРУУ"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Жок"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Жупташканда байланыштарыңыз менен чалуу таржымалыңызды пайдалана аласыз."</string>
@@ -223,7 +223,7 @@
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Байланышкан жок"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> туура тармакка туташып турганын текшериңиз"</string>
<string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Түзмөктү жупташтыруу"</string>
- <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi жупташтыруучу коду"</string>
+ <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi аркылуу байланыштыруу коду"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Туташкан жок"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Түзмөк бир тармакка туташып турушу керек."</string>
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR кодун скандап, түзмөктү Wi‑Fi аркылуу жупташтырыңыз"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index c4c7201..b353295 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -51,9 +51,9 @@
<string name="connected_via_carrier" msgid="1968057009076191514">"Поврзано преку %1$s"</string>
<string name="available_via_carrier" msgid="465598683092718294">"Достапно преку %1$s"</string>
<string name="osu_opening_provider" msgid="4318105381295178285">"Се отвора <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
- <string name="osu_connect_failed" msgid="9107873364807159193">"Не можеше да се поврзе"</string>
+ <string name="osu_connect_failed" msgid="9107873364807159193">"Не може да се поврзе"</string>
<string name="osu_completing_sign_up" msgid="8412636665040390901">"Се завршува регистрацијата…"</string>
- <string name="osu_sign_up_failed" msgid="5605453599586001793">"Не можеше да се заврши регистрацијата. Допрете за да се обидете повторно."</string>
+ <string name="osu_sign_up_failed" msgid="5605453599586001793">"Не може да се заврши регистрацијата. Допрете за да се обидете повторно."</string>
<string name="osu_sign_up_complete" msgid="7640183358878916847">"Регистрацијата е завршена. Се поврзува…"</string>
<string name="speed_label_very_slow" msgid="8526005255731597666">"Многу бавна"</string>
<string name="speed_label_slow" msgid="6069917670665664161">"Бавна"</string>
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерија, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерија"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активен"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Аудио на медиуми"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Звук на аудио/видео"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Телефонски повици"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Пренос на датотека"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Влезен уред"</string>
@@ -116,8 +116,8 @@
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"СПАРИ"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Откажи"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Кога е поврзано, спарувањето одобрува пристап до контактите и историјата на повиците."</string>
- <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Не можеше да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Не можеше да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g> поради погрешен PIN или лозинка."</string>
+ <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Не може да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Не може да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g> поради погрешен PIN или лозинка."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Не може да комуницира со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Спарувањето е одбиено од <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Компјутер"</string>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index c5e87bc..aebbe98 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -171,11 +171,11 @@
</string-array>
<string-array name="select_logd_size_summaries">
<item msgid="409235464399258501">"Идэвхгүй"</item>
- <item msgid="4195153527464162486">"лог буфер бүрт 64K"</item>
- <item msgid="7464037639415220106">"лог буфер бүрт 256K"</item>
- <item msgid="8539423820514360724">"лог буфер бүрт 1M"</item>
- <item msgid="1984761927103140651">"лог буфер бүрт 4M"</item>
- <item msgid="7892098981256010498">"лог буфер бүрт 16M"</item>
+ <item msgid="4195153527464162486">"лог буфер бүрд 64K"</item>
+ <item msgid="7464037639415220106">"лог буфер бүрд 256K"</item>
+ <item msgid="8539423820514360724">"лог буфер бүрд 1M"</item>
+ <item msgid="1984761927103140651">"лог буфер бүрд 4M"</item>
+ <item msgid="7892098981256010498">"лог буфер бүрд 16M"</item>
</string-array>
<string-array name="select_logpersist_titles">
<item msgid="704720725704372366">"Идэвхгүй"</item>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 8407db6..ed7fdc7 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -70,7 +70,7 @@
<string name="bluetooth_pairing" msgid="4269046942588193600">"Хослуулж байна…"</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Холбогдсон (утас байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Холбогдсон (медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Холбогдсон (зурвасын хандалт байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Холбогдсон (мессежийн хандалт байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Холбогдсон (утас эсвэл медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Холбогдсон (утас байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
@@ -288,7 +288,7 @@
<string name="wifi_metered_label" msgid="8737187690304098638">"Хязгаартай"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"Хязгааргүй"</string>
<string name="select_logd_size_title" msgid="1604578195914595173">"Логгерын буферын хэмжээ"</string>
- <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Лог буфер бүрт ногдох логгерын хэмжээг сонгоно уу"</string>
+ <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Лог буфер бүрд ногдох логгерын хэмжээг сонгоно уу"</string>
<string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Нэвтрэгчийн тогтмол санг устгах уу?"</string>
<string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Бид байнгын логоор хянаагүй үед таны төхөөрөмжтэй холбоотой нэвтрэгч өгөгдлийг устгах шаардлагатай."</string>
<string name="select_logpersist_title" msgid="447071974007104196">"Төхөөрөмжид тогтмол нэвтрэгчийн өгөгдлийн сан"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index d576496..136c6fd 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -112,7 +112,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"फाइल ट्रान्सफरका लागि प्रयोग गर्नुहोस्"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"इनपुटको लागि प्रयोग गर्नुहोस्"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"श्रवण यन्त्रहरूका लागि प्रयोग गर्नुहोस्"</string>
- <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"जोडी"</string>
+ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"जोडा बनाउनुहोस्"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"जोडी"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"रद्द गर्नुहोस्"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"जब जडान हुन्छ जोडी अनुदानले तपाईँको सम्पर्कहरू पहुँच गर्छ र इतिहास सम्झाउँछ।"</string>
@@ -306,7 +306,7 @@
<string name="adbwifi_warning_message" msgid="8005936574322702388">"वायरलेस डिबगिङ डिभलपमेन्ट प्रयोजनका लागि मात्रै हो। यसलाई आफ्ना कम्प्युटर र उपकरणका बिच डेटा प्रतिलिपि गर्न, सूचना नदिई आफ्नो उपकरणमा एपहरू स्थापना गर्न र लग डेटा पढ्न प्रयोग गर्नुहोस्।"</string>
<string name="adb_keys_warning_message" msgid="2968555274488101220">"तपाईं पहिले नै अधिकृत गर्नुभएका सबै कम्प्यूटरबाट USB डिबग गर्नको लागि पहुँच रद्द गर्ने हो?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"विकास सेटिङहरू अनुमति दिने हो?"</string>
- <string name="dev_settings_warning_message" msgid="37741686486073668">"यी सेटिङहरू केवल विकास प्रयोगको लागि विचार गरिएको हो। तिनीहरूले तपाईंको उपकरण र अनुप्रयोगहरूलाई विच्छेदन गर्न वा दुर्व्यवहार गर्न सक्दछ।"</string>
+ <string name="dev_settings_warning_message" msgid="37741686486073668">"यी सेटिङहरू केवल विकास प्रयोगको लागि विचार गरिएको हो। तिनीहरूले तपाईंको उपकरण र एपहरूलाई विच्छेदन गर्न वा दुर्व्यवहार गर्न सक्दछ।"</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB मा एपहरू रुजु गर्नुहोस्"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"हानिकारक व्यवहारको लागि ADB/ADT को माध्यमबाट स्थापित अनुप्रयोगहरूको जाँच गर्नुहोस्।"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"नामकरण नगरिएका ब्लुटुथ यन्त्रहरू (MAC ठेगाना भएका मात्र) देखाइनेछ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 1120c50..6d66e20 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -148,7 +148,7 @@
<string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Tethering przez Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Tethering"</string>
<string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering i punkt dostępu"</string>
- <string name="managed_user_title" msgid="449081789742645723">"Wszystkie aplikacje do pracy"</string>
+ <string name="managed_user_title" msgid="449081789742645723">"Wszystkie aplikacje służbowe"</string>
<string name="user_guest" msgid="6939192779649870792">"Gość"</string>
<string name="unknown" msgid="3544487229740637809">"Nieznana"</string>
<string name="running_process_item_user_label" msgid="3988506293099805796">"Użytkownik: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 4214a27..10ad329 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -147,7 +147,7 @@
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Ponto de acesso portátil"</string>
<string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Tethering Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Tethering"</string>
- <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e acesso portátil"</string>
+ <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e ponto de acesso"</string>
<string name="managed_user_title" msgid="449081789742645723">"Todos os apps de trabalho"</string>
<string name="user_guest" msgid="6939192779649870792">"Convidado"</string>
<string name="unknown" msgid="3544487229740637809">"Desconhecido"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 4214a27..10ad329 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -147,7 +147,7 @@
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Ponto de acesso portátil"</string>
<string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Tethering Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Tethering"</string>
- <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e acesso portátil"</string>
+ <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e ponto de acesso"</string>
<string name="managed_user_title" msgid="449081789742645723">"Todos os apps de trabalho"</string>
<string name="user_guest" msgid="6939192779649870792">"Convidado"</string>
<string name="unknown" msgid="3544487229740637809">"Desconhecido"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index f39a741..d2560d4 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Ľ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batérie, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batérie"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktívne"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk medií"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk médií"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonické hovory"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos súborov"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vstupné zariadenie"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index bb911ec..053579e 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -112,7 +112,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Använd för filöverföring"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Använd för inmatning"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Använd med hörapparater"</string>
- <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Parkoppling"</string>
+ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Parkoppla"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PARKOPPLA"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Avbryt"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Om du kopplar enheten får du tillgång till dina kontakter och din samtalshistorik när du är ansluten."</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 85275c1..306c1fb 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -81,11 +81,11 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ya betri, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ya betri"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Kimeunganishwa"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media ya sauti"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Sauti ya maudhui"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Simu"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Uhamishaji wa faili"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Kifaa cha kuingiza"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ufikiaji wa mtandao"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ufikiaji wa intaneti"</string>
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kushiriki anwani"</string>
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Tumia kwa kushiriki anwani"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Kushiriki muunganisho wa tovuti"</string>
@@ -107,7 +107,7 @@
<string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Tumia kuunganisha kwenye intaneti"</string>
<string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Tumia kwa ramani"</string>
<string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Tumia kwa ufikiaji wa SIM"</string>
- <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Tumia kwa sauti ya media"</string>
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Tumia kwa sauti ya maudhui"</string>
<string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Tumia kwa sauti ya simu"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Tumia kwa hali faili"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Tumia kwa kuingiza"</string>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index 23256ee..a93defa 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -86,7 +86,7 @@
<item msgid="8147982633566548515">"map14"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_titles">
- <item msgid="2494959071796102843">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="2494959071796102843">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="4055460186095649420">"SBC"</item>
<item msgid="720249083677397051">"AAC"</item>
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ఆడియో"</item>
@@ -94,7 +94,7 @@
<item msgid="3825367753087348007">"LDAC"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
- <item msgid="8868109554557331312">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="8868109554557331312">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="9024885861221697796">"SBC"</item>
<item msgid="4688890470703790013">"AAC"</item>
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ఆడియో"</item>
@@ -102,38 +102,38 @@
<item msgid="2553206901068987657">"LDAC"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
- <item msgid="926809261293414607">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="926809261293414607">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="8003118270854840095">"44.1 kHz"</item>
<item msgid="3208896645474529394">"48.0 kHz"</item>
<item msgid="8420261949134022577">"88.2 kHz"</item>
<item msgid="8887519571067543785">"96.0 kHz"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
- <item msgid="2284090879080331090">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="2284090879080331090">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="1872276250541651186">"44.1 kHz"</item>
<item msgid="8736780630001704004">"48.0 kHz"</item>
<item msgid="7698585706868856888">"88.2 kHz"</item>
<item msgid="8946330945963372966">"96.0 kHz"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
- <item msgid="2574107108483219051">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="2574107108483219051">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="4671992321419011165">"16 బిట్లు/నమూనా"</item>
<item msgid="1933898806184763940">"24 బిట్లు/నమూనా"</item>
<item msgid="1212577207279552119">"32 బిట్లు/నమూనా"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
- <item msgid="9196208128729063711">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="9196208128729063711">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="1084497364516370912">"16 బిట్లు/నమూనా"</item>
<item msgid="2077889391457961734">"24 బిట్లు/నమూనా"</item>
<item msgid="3836844909491316925">"32 బిట్లు/నమూనా"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_titles">
- <item msgid="3014194562841654656">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="3014194562841654656">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="5982952342181788248">"మోనో"</item>
<item msgid="927546067692441494">"స్టీరియో"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
- <item msgid="1997302811102880485">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="1997302811102880485">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="8005696114958453588">"మోనో"</item>
<item msgid="1333279807604675720">"స్టీరియో"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 20955ba..4aa131d 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -156,14 +156,14 @@
<string name="launch_defaults_none" msgid="8049374306261262709">"ఆటోమేటిక్ ఆప్షన్లు ఏవీ సెట్ చేయలేదు"</string>
<string name="tts_settings" msgid="8130616705989351312">"వచనం నుండి ప్రసంగం సెట్టింగ్లు"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"టెక్స్ట్-టు-స్పీచ్ అవుట్పుట్"</string>
- <string name="tts_default_rate_title" msgid="3964187817364304022">"ప్రసంగం రేట్"</string>
+ <string name="tts_default_rate_title" msgid="3964187817364304022">"స్పీచ్ రేట్"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"వచనాన్ని చదివి వినిపించాల్సిన వేగం"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"పిచ్"</string>
<string name="tts_default_pitch_summary" msgid="9132719475281551884">"సమన్వయం చేసిన ప్రసంగం యొక్క టోన్ను ప్రభావితం చేస్తుంది"</string>
<string name="tts_default_lang_title" msgid="4698933575028098940">"భాష"</string>
<string name="tts_lang_use_system" msgid="6312945299804012406">"సిస్టమ్ భాషను ఉపయోగించు"</string>
<string name="tts_lang_not_selected" msgid="7927823081096056147">"భాష ఎంచుకోబడలేదు"</string>
- <string name="tts_default_lang_summary" msgid="9042620014800063470">"చదవి వినిపించబడే వచనం కోసం భాష-నిర్దిష్ట వాయిస్ను సెట్ చేస్తుంది"</string>
+ <string name="tts_default_lang_summary" msgid="9042620014800063470">"టెక్స్ట్ను చదివి వినిపించేటప్పుడు, ఒక్కో భాషకు వాడాల్సిన నిర్దిష్ట వాయిస్ను సెట్ చేస్తుంది"</string>
<string name="tts_play_example_title" msgid="1599468547216481684">"ఒక ఉదాహరణ వినండి"</string>
<string name="tts_play_example_summary" msgid="634044730710636383">"ప్రసంగ సమన్వయం గురించి సంక్షిప్త ప్రదర్శనను ప్లే చేయి"</string>
<string name="tts_install_data_title" msgid="1829942496472751703">"వాయిస్ డేటాను ఇన్స్టాల్ చేయి"</string>
@@ -196,7 +196,7 @@
<string name="choose_profile" msgid="343803890897657450">"ప్రొఫైల్ను ఎంచుకోండి"</string>
<string name="category_personal" msgid="6236798763159385225">"వ్యక్తిగతం"</string>
<string name="category_work" msgid="4014193632325996115">"ఆఫీస్"</string>
- <string name="development_settings_title" msgid="140296922921597393">"డెవలపర్ ఎంపికలు"</string>
+ <string name="development_settings_title" msgid="140296922921597393">"డెవలపర్ ఆప్షన్లు"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"డెవలపర్ ఎంపికలను ప్రారంభించండి"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"అనువర్తన అభివృద్ధి కోసం ఎంపికలను సెట్ చేయండి"</string>
<string name="development_settings_not_available" msgid="355070198089140951">"ఈ వినియోగదారు కోసం డెవలపర్ ఎంపికలు అందుబాటులో లేవు"</string>
@@ -281,7 +281,7 @@
<string name="private_dns_mode_provider" msgid="3619040641762557028">"ప్రైవేట్ DNS ప్రదాత హోస్ట్పేరు"</string>
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS ప్రదాత యొక్క హోస్ట్పేరును నమోదు చేయండి"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
- <string name="wifi_display_certification_summary" msgid="8111151348106907513">"వైర్లెస్ ప్రదర్శన సర్టిఫికెట్ కోసం ఎంపికలను చూపు"</string>
+ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"వైర్లెస్ డిస్ప్లే సర్టిఫికేషన్ ఆప్షన్లను చూపు"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"బ్యాటరీ శక్తి వినియోగాన్ని తగ్గించి & నెట్వర్క్ పనితీరును మెరుగుపరుస్తుంది"</string>
<string name="wifi_enhanced_mac_randomization_summary" msgid="1210663439867489931">"ఈ మోడ్ ఎనేబుల్ అయ్యాక, MAC ర్యాండమైజేషన్ను ఎనేబుల్ చేసిన నెట్వర్క్తో కనెక్ట్ అయ్యే ప్రతిసారీ ఈ పరికరం MAC అడ్రస్ మారవచ్చు."</string>
@@ -367,7 +367,7 @@
<string name="overlay_display_devices_title" msgid="5411894622334469607">"ప్రత్యామ్నాయ ప్రదర్శనలను అనుకరించండి"</string>
<string name="debug_applications_category" msgid="5394089406638954196">"యాప్లు"</string>
<string name="immediately_destroy_activities" msgid="1826287490705167403">"కార్యకలాపాలను ఉంచవద్దు"</string>
- <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ప్రతి కార్యకలాపాన్ని వినియోగదారు నిష్క్రమించిన వెంటనే తొలగించండి"</string>
+ <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"యూజర్ నిష్క్రమించాక పూర్తి యాక్టివిటీ తొలగింపు"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"బ్యాక్గ్రౌండ్ ప్రాసెస్ పరిమితి"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"బ్యాక్గ్రౌండ్ ANRలను చూపు"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"నేపథ్య యాప్ల కోసం యాప్ ప్రతిస్పందించడం లేదు అనే డైలాగ్ను చూపు"</string>
@@ -473,7 +473,7 @@
<string name="screen_zoom_summary_very_large" msgid="7317423942896999029">"చాలా పెద్దగా"</string>
<string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"అతి పెద్దగా"</string>
<string name="screen_zoom_summary_custom" msgid="3468154096832912210">"అనుకూలం (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
- <string name="content_description_menu_button" msgid="6254844309171779931">"మెను"</string>
+ <string name="content_description_menu_button" msgid="6254844309171779931">"మెనూ"</string>
<string name="retail_demo_reset_message" msgid="5392824901108195463">"డెమో మోడ్లో ఫ్యాక్టరీ రీసెట్ను నిర్వహించడానికి పాస్వర్డ్ను నమోదు చేయండి"</string>
<string name="retail_demo_reset_next" msgid="3688129033843885362">"తర్వాత"</string>
<string name="retail_demo_reset_title" msgid="1866911701095959800">"పాస్వర్డ్ అవసరం"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index f81731a..48940a2 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -22,7 +22,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="2333336097603822490">"Tarmoqlarni tekshirib chiqishni iloji bo‘lmadi"</string>
<string name="wifi_security_none" msgid="7392696451280611452">"Hech qanday"</string>
- <string name="wifi_remembered" msgid="3266709779723179188">"Saqlandi"</string>
+ <string name="wifi_remembered" msgid="3266709779723179188">"Saqlangan"</string>
<string name="wifi_disconnected" msgid="7054450256284661757">"Ulanmagan"</string>
<string name="wifi_disabled_generic" msgid="2651916945380294607">"Yoqilmagan"</string>
<string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP manzilini sozlab bo‘lmadi"</string>
@@ -81,11 +81,11 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Faol"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media audio"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"A2DP profili"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefon chaqiruvlari"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fayl uzatish"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Kiritish qurilmasi"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetga kirish"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetga ulanish"</string>
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktlarni ulashish"</string>
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Kontaktlarni ulashish uchun ishlatilsin"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet aloqasi ulashmasi"</string>
@@ -112,7 +112,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Fayl almashinish uchun foydalanish"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Kiritish qurilmasi sifatida foydalanish"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Eshitish apparatlari uchun foydalanish"</string>
- <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Biriktirish"</string>
+ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"OK"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ULANISH"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Bekor qilish"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Agar ulanishga ruxsat bersangiz, ulangan vaqtda kontakt va qo‘ng‘iroqlaringiz tarixiga kirishi mumkin."</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index b7ccf8d..b6ac92f 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Trái: Mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Phải: Mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Đang hoạt động"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Âm thanh của phương tiện"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Âm thanh nội dung nghe nhìn"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Cuộc gọi điện thoại"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Chuyển tệp"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Thiết bị đầu vào"</string>
@@ -95,7 +95,7 @@
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Âm thanh HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Thiết bị trợ thính"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Đã kết nối với Thiết bị trợ thính"</string>
- <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Đã kết nối với âm thanh phương tiện"</string>
+ <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Đã kết nối với âm thanh nội dung nghe nhìn"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Đã kết nối với âm thanh điện thoại"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Đã kết nối với máy chủ chuyển tệp"</string>
<string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"Đã kết nối với bản đồ"</string>
@@ -107,7 +107,7 @@
<string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Sử dụng để truy cập Internet"</string>
<string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Sử dụng cho bản đồ"</string>
<string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Sử dụng để truy cập SIM"</string>
- <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Sử dụng cho âm thanh phương tiện"</string>
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Sử dụng cho âm thanh nội dung nghe nhìn"</string>
<string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Sử dụng cho âm thanh điện thoại"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Sử dụng để chuyển tệp"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Sử dụng để nhập"</string>
@@ -306,7 +306,7 @@
<string name="adbwifi_warning_message" msgid="8005936574322702388">"Tính năng gỡ lỗi qua Wi-Fi chỉ dành cho mục đích phát triển. Hãy sử dụng tính năng này để sao chép dữ liệu giữa máy tính và thiết bị của bạn, cài đặt ứng dụng trên thiết bị mà không thông báo và đọc dữ liệu nhật ký."</string>
<string name="adb_keys_warning_message" msgid="2968555274488101220">"Thu hồi quyền truy cập gỡ lỗi USB từ tất cả máy tính mà bạn đã ủy quyền trước đó?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Cho phép cài đặt phát triển?"</string>
- <string name="dev_settings_warning_message" msgid="37741686486073668">"Những cài đặt này chỉ dành cho mục đích phát triển. Chúng có thể làm cho thiết bị và ứng dụng trên thiết bị của bạn bị lỗi và hoạt động sai."</string>
+ <string name="dev_settings_warning_message" msgid="37741686486073668">"Những tùy chọn cài đặt này chỉ dành cho mục đích phát triển. Chúng có thể làm cho thiết bị và ứng dụng trên thiết bị của bạn bị lỗi và hoạt động không đúng cách."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Xác minh ứng dụng qua USB"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kiểm tra các ứng dụng được cài đặt qua ADB/ADT để xem có hoạt động gây hại hay không."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Các thiết bị Bluetooth không có tên (chỉ có địa chỉ MAC) sẽ được hiển thị"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 6b8739f..237b584 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -113,7 +113,7 @@
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Isetshenziselwa okufakwayo"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Sebenzisa izinsiza zokuzwa"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Bhangqa"</string>
- <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"BHANQA"</string>
+ <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"BHANGQA"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Khansela"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Ukubhanqa kunika ukufinyelela koxhumana nabo nomlando wekholi uma uxhumekile."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Ayikwazanga ukuhlangana ne <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
diff --git a/packages/Shell/res/values-mr/strings.xml b/packages/Shell/res/values-mr/strings.xml
index a957184..9595e28 100644
--- a/packages/Shell/res/values-mr/strings.xml
+++ b/packages/Shell/res/values-mr/strings.xml
@@ -31,8 +31,8 @@
<string name="bugreport_confirm" msgid="5917407234515812495">"बग रीपोर्टांमध्ये तुम्ही संवेदनशील (अॅप-वापर आणि स्थान डेटा यासारखा) डेटा म्हणून विचार करता त्या डेटाच्या समावेशासह सिस्टीमच्या विविध लॉग फायलींमधील डेटा असतो. ज्या लोकांवर आणि अॅपवर तुमचा विश्वास आहे केवळ त्यांच्यासह हा बग रीपोर्ट शेअर करा."</string>
<string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"पुन्हा दर्शवू नका"</string>
<string name="bugreport_storage_title" msgid="5332488144740527109">"बग रीपोर्ट"</string>
- <string name="bugreport_unreadable_text" msgid="586517851044535486">"बग रीपोर्ट फाइल वाचणे शक्य झाले नाही"</string>
- <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"झिप फाइल मध्ये बग रीपोर्ट तपशील जोडणे शक्य झाले नाही"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"बग रीपोर्ट फाईल वाचणे शक्य झाले नाही"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"झिप फाईल मध्ये बग रीपोर्ट तपशील जोडणे शक्य झाले नाही"</string>
<string name="bugreport_unnamed" msgid="2800582406842092709">"अनामित"</string>
<string name="bugreport_info_action" msgid="2158204228510576227">"तपशील"</string>
<string name="bugreport_screenshot_action" msgid="8677781721940614995">"स्क्रीनशॉट"</string>
diff --git a/packages/SoundPicker/res/values-ar/strings.xml b/packages/SoundPicker/res/values-ar/strings.xml
index f8844e9..a917955 100644
--- a/packages/SoundPicker/res/values-ar/strings.xml
+++ b/packages/SoundPicker/res/values-ar/strings.xml
@@ -25,5 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"حذف"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"يتعذر إضافة نغمة رنين مخصصة"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"يتعذر حذف نغمة الرنين المخصصة"</string>
- <string name="app_label" msgid="3091611356093417332">"الأصوات"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sounds"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-cs/strings.xml b/packages/SoundPicker/res/values-cs/strings.xml
index dc67c96..e8fc97e 100644
--- a/packages/SoundPicker/res/values-cs/strings.xml
+++ b/packages/SoundPicker/res/values-cs/strings.xml
@@ -16,14 +16,14 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="ringtone_default" msgid="798836092118824500">"Výchozí vyzvánění"</string>
+ <string name="ringtone_default" msgid="798836092118824500">"Výchozí vyzváněcí tón"</string>
<string name="notification_sound_default" msgid="8133121186242636840">"Výchozí zvuk oznámení"</string>
<string name="alarm_sound_default" msgid="4787646764557462649">"Výchozí zvuk budíku"</string>
- <string name="add_ringtone_text" msgid="6642389991738337529">"Přidat vyzvánění"</string>
+ <string name="add_ringtone_text" msgid="6642389991738337529">"Přidat vyzváněcí tón"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"Přidat budík"</string>
<string name="add_notification_text" msgid="4431129543300614788">"Přidat oznámení"</string>
<string name="delete_ringtone_text" msgid="201443984070732499">"Smazat"</string>
- <string name="unable_to_add_ringtone" msgid="4583511263449467326">"Vlastní vyzvánění se nepodařilo přidat"</string>
- <string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Vlastní vyzvánění se nepodařilo smazat"</string>
+ <string name="unable_to_add_ringtone" msgid="4583511263449467326">"Vlastní vyzváněcí tón se nepodařilo přidat"</string>
+ <string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Vlastní vyzváněcí tón se nepodařilo smazat"</string>
<string name="app_label" msgid="3091611356093417332">"Zvuky"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-uz/strings.xml b/packages/SoundPicker/res/values-uz/strings.xml
index a617733..9018e66 100644
--- a/packages/SoundPicker/res/values-uz/strings.xml
+++ b/packages/SoundPicker/res/values-uz/strings.xml
@@ -21,7 +21,7 @@
<string name="alarm_sound_default" msgid="4787646764557462649">"Standart signal tovushi"</string>
<string name="add_ringtone_text" msgid="6642389991738337529">"Rington qo‘shish"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"Signal qo‘shish"</string>
- <string name="add_notification_text" msgid="4431129543300614788">"Bildirishnoma kiritish"</string>
+ <string name="add_notification_text" msgid="4431129543300614788">"Bildirishnoma qo‘shish"</string>
<string name="delete_ringtone_text" msgid="201443984070732499">"O‘chirish"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Maxsus rington qo‘shib bo‘lmadi"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Maxsus ringtonni o‘chirib bo‘lmadi"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 65e3f0d..6d86a78 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -112,7 +112,7 @@
<string name="kg_pin_accepted" msgid="1625501841604389716">"تم قبول الرمز"</string>
<string name="keyguard_carrier_default" msgid="6359808469637388586">"لا تتوفر خدمة."</string>
<string name="accessibility_ime_switch_button" msgid="9082358310194861329">"تبديل أسلوب الإدخال"</string>
- <string name="airplane_mode" msgid="2528005343938497866">"وضع الطيران"</string>
+ <string name="airplane_mode" msgid="2528005343938497866">"وضع الطائرة"</string>
<string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"يجب رسم النقش بعد إعادة تشغيل الجهاز"</string>
<string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"يجب إدخال رقم التعريف الشخصي بعد إعادة تشغيل الجهاز"</string>
<string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"يجب إدخال كلمة المرور بعد إعادة تشغيل الجهاز"</string>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index 52b7fab..24b5c23 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -100,7 +100,7 @@
<string name="kg_pin_accepted" msgid="1625501841604389716">"កូដត្រូវបានទទួលយក!"</string>
<string name="keyguard_carrier_default" msgid="6359808469637388586">"គ្មានសេវាទេ។"</string>
<string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ប្ដូរវិធីបញ្ចូល"</string>
- <string name="airplane_mode" msgid="2528005343938497866">"ពេលជិះយន្តហោះ"</string>
+ <string name="airplane_mode" msgid="2528005343938497866">"មុខងារពេលជិះយន្តហោះ"</string>
<string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"តម្រូវឲ្យប្រើលំនាំ បន្ទាប់ពីឧបករណ៍ចាប់ផ្តើមឡើងវិញ"</string>
<string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"តម្រូវឲ្យបញ្ចូលកូដ PIN បន្ទាប់ពីឧបករណ៍ចាប់ផ្តើមឡើងវិញ"</string>
<string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"តម្រូវឲ្យបញ្ចូលពាក្យសម្ងាត់ បន្ទាប់ពីឧបករណ៍ចាប់ផ្តើមឡើងវិញ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index d44003b..74386bc 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -134,7 +134,7 @@
<item quantity="other">SIM ఇప్పుడు నిలిపివేయబడింది. PUK కోడ్ను నమోదు చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="_NUMBER_1">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి. వివరాల కోసం కారియర్ను సంప్రదించండి.</item>
<item quantity="one">SIM ఇప్పుడు నిలిపివేయబడింది. PUK కోడ్ను నమోదు చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="_NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది వివరాల కోసం కారియర్ను సంప్రదించండి.</item>
</plurals>
- <string name="clock_title_default" msgid="6342735240617459864">"ఆటోమేటిక్"</string>
+ <string name="clock_title_default" msgid="6342735240617459864">"డిఫాల్ట్"</string>
<string name="clock_title_bubble" msgid="2204559396790593213">"బబుల్"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"ఎనలాగ్"</string>
</resources>
diff --git a/packages/SystemUI/res-product/values-in/strings.xml b/packages/SystemUI/res-product/values-in/strings.xml
index 1451e2c..2e0580f 100644
--- a/packages/SystemUI/res-product/values-in/strings.xml
+++ b/packages/SystemUI/res-product/values-in/strings.xml
@@ -26,10 +26,10 @@
<string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"Tidak ada kartu SIM dalam tablet."</string>
<string name="keyguard_missing_sim_message" product="default" msgid="7053347843877341391">"Tidak ada kartu SIM dalam ponsel."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"Kode PIN tidak cocok"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, tablet ini akan direset, sehingga semua datanya akan dihapus."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, ponsel ini akan direset, sehingga semua datanya akan dihapus."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Tablet ini akan direset, sehingga semua datanya akan dihapus."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Ponsel ini akan direset, sehingga semua datanya akan dihapus."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, tablet ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, ponsel ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Tablet ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Ponsel ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus."</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus."</string>
<string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci tablet dengan tidak benar. Pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 30a09d3..8710cb8 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -73,7 +73,7 @@
<string name="usb_contaminant_message" msgid="7730476585174719805">"መሣሪያዎን ከፈሳሽ ወይም ፍርስራሽ ለመጠበቅ ሲባል የዩኤስቢ ወደቡ ተሰናክሏል፣ እና ማናቸውም ተቀጥላዎችን አያገኝም።\n\nየዩኤስቢ ወደቡን እንደገና መጠቀም ችግር በማይኖረው ጊዜ ማሳወቂያ ይደርሰዎታል።"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ኃይል መሙያዎችን እና ተጨማሪ መሣሪያዎችን ፈልጎ ለማግኘት የነቃ የዩኤስቢ ወደብ"</string>
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"ዩኤስቢ አንቃ"</string>
- <string name="learn_more" msgid="4690632085667273811">"የበለጠ ለመረዳት"</string>
+ <string name="learn_more" msgid="4690632085667273811">"የበለጠ መረዳት"</string>
<string name="compat_mode_on" msgid="4963711187149440884">"ማያ እንዲሞላ አጉላ"</string>
<string name="compat_mode_off" msgid="7682459748279487945">"ማያ ለመሙለት ሳብ"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"ቅጽበታዊ ገጽ እይታ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 872bca8..ec1e076 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -234,7 +234,7 @@
<string name="not_default_data_content_description" msgid="6757881730711522517">"لم يتم الضبط على استخدام البيانات"</string>
<string name="cell_data_off" msgid="4886198950247099526">"غير مفعّلة"</string>
<string name="accessibility_bluetooth_tether" msgid="6327291292208790599">"التوصيل عبر البلوتوث"</string>
- <string name="accessibility_airplane_mode" msgid="1899529214045998505">"وضع الطيران."</string>
+ <string name="accessibility_airplane_mode" msgid="1899529214045998505">"وضع الطائرة."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"الشبكة الافتراضية الخاصة (VPN) قيد التفعيل."</string>
<string name="accessibility_no_sims" msgid="5711270400476534667">"ليس هناك شريحة SIM."</string>
<string name="carrier_network_change_mode" msgid="5174141476991149918">"جارٍ تغيير شبكة مشغِّل شبكة الجوّال."</string>
@@ -269,10 +269,10 @@
<string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"تم تفعيل Wifi."</string>
<string name="accessibility_quick_settings_mobile" msgid="1817825313718492906">"الجوّال <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="533594896310663853">"البطارية <xliff:g id="STATE">%s</xliff:g>."</string>
- <string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"إيقاف وضع الطيران."</string>
- <string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"تفعيل وضع الطيران."</string>
- <string name="accessibility_quick_settings_airplane_changed_off" msgid="8880183481476943754">"تم إيقاف وضع الطيران."</string>
- <string name="accessibility_quick_settings_airplane_changed_on" msgid="6327378061894076288">"تم تفعيل وضع الطيران."</string>
+ <string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"إيقاف وضع الطائرة."</string>
+ <string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"تفعيل وضع الطائرة."</string>
+ <string name="accessibility_quick_settings_airplane_changed_off" msgid="8880183481476943754">"تم إيقاف وضع الطائرة."</string>
+ <string name="accessibility_quick_settings_airplane_changed_on" msgid="6327378061894076288">"تم تفعيل وضع الطائرة."</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"كتم الصوت تمامًا"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"المنبِّهات فقط"</string>
<string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"عدم الإزعاج"</string>
@@ -320,7 +320,7 @@
<string name="data_usage_disabled_dialog" msgid="7933201635215099780">"تم الوصول إلى حد البيانات الذي عيَّنته. لم يُعد بإمكانك استخدام بيانات الجوال.\n\nفي حالة الاستئناف، قد يتم تطبيق الرسوم لاستخدام البيانات."</string>
<string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"استئناف"</string>
<string name="gps_notification_searching_text" msgid="231304732649348313">"جارٍ البحث عن GPS"</string>
- <string name="gps_notification_found_text" msgid="3145873880174658526">"تم ضبط الموقع بواسطة GPS"</string>
+ <string name="gps_notification_found_text" msgid="3145873880174658526">"تم تعيين الموقع بواسطة GPS"</string>
<string name="accessibility_location_active" msgid="2845747916764660369">"طلبات الموقع نشطة"</string>
<string name="accessibility_sensors_off_active" msgid="2619725434618911551">"أجهزة الاستشعار غير مفعّلة"</string>
<string name="accessibility_clear_all" msgid="970525598287244592">"محو جميع الإشعارات."</string>
@@ -666,7 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"إيثرنت"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"المنبّه"</string>
<string name="status_bar_work" msgid="5238641949837091056">"الملف الشخصي للعمل"</string>
- <string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطيران"</string>
+ <string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطائرة"</string>
<string name="add_tile" msgid="6239678623873086686">"إضافة فئة"</string>
<string name="broadcast_tile" msgid="5224010633596487481">"إرسال فئة"</string>
<string name="zen_alarm_warning_indef" msgid="5252866591716504287">"لن تسمع المنبّه القادم في <xliff:g id="WHEN">%1$s</xliff:g> إلا إذا أوقفت هذا قبل الموعد"</string>
@@ -699,7 +699,7 @@
<string name="tuner_full_importance_settings" msgid="1388025816553459059">"عناصر التحكم في إشعارات التشغيل"</string>
<string name="tuner_full_importance_settings_on" msgid="917981436602311547">"تشغيل"</string>
<string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"إيقاف"</string>
- <string name="power_notification_controls_description" msgid="1334963837572708952">"باستخدام عناصر التحكم في إشعار التشغيل، يمكنك ضبط مستوى الأهمية من 0 إلى 5 لإشعارات التطبيق. \n\n"<b>"المستوى 5"</b>" \n- العرض أعلى قائمة الإشعارات \n- يسمح بمقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 4"</b>" \n- منع مقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 3"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n\n"<b>"المستوى 2"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات واهتزاز \n\n"<b>"المستوى 1"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات أو اهتزاز أبدًا \n- الإخفاء من شاشة القفل وشريط الحالة \n- العرض أسفل قائمة الإشعارات \n\n"<b>"المستوى 0"</b>" \n- حظر جميع الإشعارات من التطبيق"</string>
+ <string name="power_notification_controls_description" msgid="1334963837572708952">"باستخدام عناصر التحكم في إشعار التشغيل، يمكنك تعيين مستوى الأهمية من 0 إلى 5 لإشعارات التطبيق. \n\n"<b>"المستوى 5"</b>" \n- العرض أعلى قائمة الإشعارات \n- يسمح بمقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 4"</b>" \n- منع مقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 3"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n\n"<b>"المستوى 2"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات واهتزاز \n\n"<b>"المستوى 1"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات أو اهتزاز أبدًا \n- الإخفاء من شاشة القفل وشريط الحالة \n- العرض أسفل قائمة الإشعارات \n\n"<b>"المستوى 0"</b>" \n- حظر جميع الإشعارات من التطبيق"</string>
<string name="notification_header_default_channel" msgid="225454696914642444">"الإشعارات"</string>
<string name="notification_channel_disabled" msgid="928065923928416337">"لن تتلقى هذه الإشعارات بعد الآن."</string>
<string name="notification_channel_minimized" msgid="6892672757877552959">"سيتم تصغير هذه الإشعارات."</string>
@@ -1062,7 +1062,7 @@
<string name="accessibility_control_favorite" msgid="8694362691985545985">"تمت الإضافة إلى المفضّلة"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"تمت الإضافة إلى المفضّلة، الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="accessibility_control_not_favorite" msgid="1291760269563092359">"تمت الإزالة من المفضّلة"</string>
- <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"إضافة إلى المحتوى المفضّل"</string>
+ <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"إضافة إلى المُفضلة"</string>
<string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"إزالة من المفضّلة"</string>
<string name="accessibility_control_move" msgid="8980344493796647792">"نقل إلى الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"عناصر التحكّم"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 43bfa89..289efd5 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -125,7 +125,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"দিব্যাংগসকলৰ বাবে থকা সুবিধাসমূহ"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"স্ক্ৰীণ ঘূৰাওক"</string>
<string name="accessibility_recent" msgid="901641734769533575">"অৱলোকন"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"Search"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"সন্ধান কৰক"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"কেমেৰা"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ফ\'ন"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"কণ্ঠধ্বনিৰে সহায়"</string>
@@ -441,7 +441,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"বেটাৰিৰ চ্চাৰ্জ সম্পূর্ণ হ\'বলৈ <xliff:g id="CHARGING_TIME">%s</xliff:g> বাকী"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"চ্চার্জ কৰি থকা নাই"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"নেটৱৰ্ক \nনিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
- <string name="description_target_search" msgid="3875069993128855865">"Search"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"অনুসন্ধান কৰক"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>ৰ বাবে ওপৰলৈ শ্লাইড কৰক।"</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>ৰ বাবে বাওঁফাললৈ শ্লাইড কৰক।"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"আপুনি নিৰ্দিষ্ট কৰা এলাৰ্ম, ৰিমাইণ্ডাৰ, ইভেন্ট আৰু কল কৰোঁতাৰ বাহিৰে আন কোনো শব্দৰ পৰা আপুনি অসুবিধা নাপাব। কিন্তু, সংগীত, ভিডিঅ\' আৰু খেলসমূহকে ধৰি আপুনি প্লে কৰিব খোজা যিকোনো বস্তু তথাপি শুনিব পাৰিব।"</string>
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"বেটাৰি সঞ্চয়কাৰী অন হৈ আছে"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"কাৰ্যদক্ষতা আৰু নেপথ্য ডেটা হ্ৰাস কৰে"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"বেটাৰি সঞ্চয়কাৰী অফ কৰক"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>এ আপোনাৰ স্ক্ৰীনত দৃশ্যমান হোৱা অথবা ৰেকর্ডিং অথবা কাষ্টিঙৰ সময়ত আপোনাৰ ডিভাইচত প্লে\' কৰা সকলো তথ্যলৈ এক্সেছ পাব। এইটোত পাছৱর্ড, পৰিশোধৰ সবিশেষ, ফট\', বার্তাসমূহ আৰু আপুনি প্লে\' কৰা অডিঅ\'ৰ দৰে তথ্য অন্তর্ভুক্ত হয়।"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>এ আপোনাৰ স্ক্ৰীনত দৃশ্যমান হোৱা অথবা ৰেকর্ডিং অথবা কাষ্টিংৰ সময়ত আপোনাৰ ডিভাইচত প্লে\' কৰা সকলো তথ্যলৈ এক্সেছ পাব। এইটোত পাছৱর্ড, পৰিশোধৰ সবিশেষ, ফট\', বার্তাসমূহ আৰু আপুনি প্লে\' কৰা অডিঅ\'ৰ দৰে তথ্য অন্তর্ভুক্ত হয়।"</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"এই সুবিধাটো প্ৰদান কৰা সেৱাটোৱে আপোনাৰ স্ক্ৰীনত দৃশ্যমান হোৱা অথবা ৰেকর্ডিং অথবা কাষ্টিংৰ সময়ত আপোনাৰ ডিভাইচত প্লে\' কৰা সকলো তথ্যলৈ এক্সেছ পাব। এইটোত পাছৱর্ড, পৰিশোধৰ সবিশেষ, ফট\', বার্তাসমূহ আৰু আপুনি প্লে\' কৰা অডিঅ\'ৰ দৰে তথ্য অন্তর্ভুক্ত হয়।"</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ৰেকর্ডিং অথবা কাষ্টিং আৰম্ভ কৰিবনে?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ৰ জৰিয়তে ৰেকর্ডিং অথবা কাষ্টিং আৰম্ভ কৰিবনে ?"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index c4693be..93db53e 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -405,7 +405,7 @@
<item quantity="one">%d cihaz</item>
</plurals>
<string name="quick_settings_notifications_label" msgid="3379631363952582758">"Bildirişlər"</string>
- <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Fənər"</string>
+ <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"İşartı"</string>
<string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera istifadə olunur"</string>
<string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobil data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Data istifadəsi"</string>
@@ -791,7 +791,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Yuxarı Səhifə"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Aşağı Səhifə"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Silin"</string>
- <string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
+ <string name="keyboard_key_move_home" msgid="3496502501803911971">"Əsas səhifə"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Son"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Daxil edin"</string>
<string name="keyboard_key_num_lock" msgid="7209960042043090548">"Nömrələr"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index e526114..6ff5d5d 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -38,7 +38,7 @@
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Uključi"</string>
<string name="battery_saver_start_action" msgid="4553256017945469937">"Uključi Uštedu baterije"</string>
<string name="status_bar_settings_settings_button" msgid="534331565185171556">"Podešavanja"</string>
- <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"WiFi"</string>
+ <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatsko rotiranje ekrana"</string>
<string name="status_bar_settings_mute_label" msgid="914392730086057522">"UGASI"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="2151934479226017725">"AUTOM."</string>
@@ -226,7 +226,7 @@
<string name="data_connection_cdma" msgid="7678457855627313518">"1X"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roming"</string>
<string name="data_connection_edge" msgid="6316755666481405762">"EDGE"</string>
- <string name="accessibility_data_connection_wifi" msgid="4422160347472742434">"WiFi"</string>
+ <string name="accessibility_data_connection_wifi" msgid="4422160347472742434">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="1140839832913084973">"Nema SIM kartice."</string>
<string name="accessibility_cell_data" msgid="172950885786007392">"Mobilni podaci"</string>
<string name="accessibility_cell_data_on" msgid="691666434519443162">"Mobilni podaci su uključeni"</string>
@@ -265,8 +265,8 @@
<string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključan ekran za posao"</string>
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
<string name="accessibility_quick_settings_wifi" msgid="167707325133803052">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
- <string name="accessibility_quick_settings_wifi_changed_off" msgid="2230487165558877262">"WiFi je isključen."</string>
- <string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"WiFi je uključen."</string>
+ <string name="accessibility_quick_settings_wifi_changed_off" msgid="2230487165558877262">"Wi-Fi je isključen."</string>
+ <string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"Wi-Fi je uključen."</string>
<string name="accessibility_quick_settings_mobile" msgid="1817825313718492906">"Mobilna mreža: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="533594896310663853">"Baterija: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"Režim rada u avionu je isključen."</string>
@@ -375,19 +375,19 @@
<string name="quick_settings_user_label" msgid="1253515509432672496">"Ja"</string>
<string name="quick_settings_user_title" msgid="8673045967216204537">"Korisnik"</string>
<string name="quick_settings_user_new_user" msgid="3347905871336069666">"Novi korisnik"</string>
- <string name="quick_settings_wifi_label" msgid="2879507532983487244">"WiFi"</string>
+ <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
<string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Veza nije uspostavljena"</string>
<string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"Nema mreže"</string>
- <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"WiFi je isključen"</string>
- <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"WiFi je uključen"</string>
- <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Nije dostupna nijedna WiFi mreža"</string>
+ <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"Wi-Fi je isključen"</string>
+ <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi je uključen"</string>
+ <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Nije dostupna nijedna Wi-Fi mreža"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Uključuje se..."</string>
<string name="quick_settings_cast_title" msgid="2279220930629235211">"Prebacivanje ekrana"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"Prebacivanje"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Neimenovani uređaj"</string>
<string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"Spremno za prebacivanje"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Nije dostupan nijedan uređaj"</string>
- <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"WiFi nije povezan"</string>
+ <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Wi-Fi nije povezan"</string>
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Osvetljenost"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"AUTOMATSKA"</string>
<string name="quick_settings_inversion_label" msgid="5078769633069667698">"Obrni boje"</string>
@@ -643,8 +643,8 @@
<string name="output_none_found" msgid="5488087293120982770">"Nije pronađen nijedan uređaj"</string>
<string name="output_none_found_service_off" msgid="935667567681386368">"Nije pronađen nijedan uređaj. Probajte da uključite uslugu <xliff:g id="SERVICE">%1$s</xliff:g>"</string>
<string name="output_service_bt" msgid="4315362133973911687">"Bluetooth"</string>
- <string name="output_service_wifi" msgid="9003667810868222134">"WiFi"</string>
- <string name="output_service_bt_wifi" msgid="7186882540475524124">"Bluetooth i WiFi"</string>
+ <string name="output_service_wifi" msgid="9003667810868222134">"Wi-Fi"</string>
+ <string name="output_service_bt_wifi" msgid="7186882540475524124">"Bluetooth i Wi-Fi"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"Tjuner za korisnički interfejs sistema"</string>
<string name="show_battery_percentage" msgid="6235377891802910455">"Prikazuj ugrađeni procenat baterije"</string>
<string name="show_battery_percentage_summary" msgid="9053024758304102915">"Prikazivanje nivoa napunjenosti baterije u procentima unutar ikone na statusnoj traci kada se baterija ne puni"</string>
@@ -964,7 +964,7 @@
<string name="mobile_data" msgid="4564407557775397216">"Mobilni podaci"</string>
<string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
- <string name="wifi_is_off" msgid="5389597396308001471">"WiFi je isključen"</string>
+ <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi je isključen"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Režim Ne uznemiravaj je isključen"</string>
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>) je uključilo režim Ne uznemiravaj."</string>
@@ -976,7 +976,7 @@
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije pokrenute u pozadini"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Želite da isključite mobilne podatke?"</string>
- <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ili internetu preko mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo preko WiFi veze."</string>
+ <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ili internetu preko mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo preko Wi-Fi veze."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"mobilni operater"</string>
<string name="touch_filtered_warning" msgid="8119511393338714836">"Podešavanja ne mogu da verifikuju vaš odgovor jer aplikacija skriva zahtev za dozvolu."</string>
<string name="slice_permission_title" msgid="3262615140094151017">"Želite li da dozvolite aplikaciji <xliff:g id="APP_0">%1$s</xliff:g> da prikazuje isečke iz aplikacije <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 5416e03..41d7fa81 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -722,7 +722,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"У залежнасці ад налад тэлефона магчымы званок або вібрацыя"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"У залежнасці ад налад тэлефона магчымы званок або вібрацыя. Размовы ў праграме \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" стандартна паяўляюцца ў выглядзе ўсплывальных апавяшчэнняў."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Прыцягвае ўвагу да гэтага змесціва ўсплывальнай кнопкай."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Паказваецца ўверсе раздзела размоў, як усплывальнае апавяшчэнне, паказвае фота профілю на экране блакіроўкі"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Паказваецца ўверсе раздзела размоў у выглядзе ўсплывальнага апавяшчэння, а на экране блакіроўкі – у выглядзе відарыса профілю"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Налады"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Прыярытэт"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не падтрымлівае функцыі размовы"</string>
diff --git a/packages/SystemUI/res/values-be/strings_tv.xml b/packages/SystemUI/res/values-be/strings_tv.xml
index c75a492..14a4e55 100644
--- a/packages/SystemUI/res/values-be/strings_tv.xml
+++ b/packages/SystemUI/res/values-be/strings_tv.xml
@@ -22,7 +22,7 @@
<string name="notification_channel_tv_pip" msgid="844249465483874817">"Відарыс у відарысе"</string>
<string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Праграма без назвы)"</string>
<string name="pip_close" msgid="5775212044472849930">"Закрыць PIP"</string>
- <string name="pip_fullscreen" msgid="3877997489869475181">"Ва ўвесь экран"</string>
+ <string name="pip_fullscreen" msgid="3877997489869475181">"Поўнаэкранны рэжым"</string>
<string name="mic_active" msgid="5766614241012047024">"Мікрафон актыўны"</string>
<string name="app_accessed_mic" msgid="2754428675130470196">"Праграма \"%1$s\" атрымала доступ да мікрафона"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index afb4441..7913674 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Може да звъни или да вибрира въз основа на настройките за телефона"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Може да звъни или да вибрира въз основа на настройките за телефона. Разговорите от <xliff:g id="APP_NAME">%1$s</xliff:g> се показват като балончета по подразбиране."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Задържа вниманието ви посредством плаващ пряк път към това съдържание."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Показва се като плаващо балонче в горната част на секцията с разговори, показва снимката на потр. профил на заключения екран"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Показва се като плаващо балонче в горната част на секцията с разговори и показва снимката на потребителския профил на заключения екран"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Настройки"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддържа функциите за разговор"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index f9627ab..08cf5d1 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -125,7 +125,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"অ্যাক্সেসযোগ্যতা"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"স্ক্রিন ঘোরান"</string>
<string name="accessibility_recent" msgid="901641734769533575">"এক নজরে"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"সার্চ"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"খুঁজুন"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"ক্যামেরা"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ফোন"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ভয়েস সহায়তা"</string>
@@ -441,7 +441,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"পূর্ণ হতে <xliff:g id="CHARGING_TIME">%s</xliff:g> সময় লাগবে"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"চার্জ হচ্ছে না"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"নেটওয়ার্ক নিরীক্ষণ\nকরা হতে পারে"</string>
- <string name="description_target_search" msgid="3875069993128855865">"সার্চ"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"খুঁজুন"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> এর জন্য উপরের দিকে স্লাইড করুন৷"</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> এর জন্য বাঁ দিকে স্লাইড করুন৷"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"অ্যালার্ম, রিমাইন্ডার, ইভেন্ট, এবং আপনার নির্দিষ্ট করে দেওয়া ব্যক্তিদের কল ছাড়া অন্য কোনও আওয়াজ বা ভাইব্রেশন হবে না। তবে সঙ্গীত, ভিডিও, এবং গেম সহ আপনি যা কিছু চালাবেন তার আওয়াজ শুনতে পাবেন।"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 25c01f6..34f4b9f 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -651,9 +651,9 @@
<string name="quick_settings" msgid="6211774484997470203">"Brze postavke"</string>
<string name="status_bar" msgid="4357390266055077437">"Statusna traka"</string>
<string name="overview" msgid="3522318590458536816">"Pregled"</string>
- <string name="demo_mode" msgid="263484519766901593">"Način rada za demonstraciju Sistemskog UI-a"</string>
- <string name="enable_demo_mode" msgid="3180345364745966431">"Omogući način rada za demonstraciju"</string>
- <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži način rada za demonstraciju"</string>
+ <string name="demo_mode" msgid="263484519766901593">"Način demonstracije Sistemskog UI-a"</string>
+ <string name="enable_demo_mode" msgid="3180345364745966431">"Omogući način demonstracije"</string>
+ <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži način demonstracije"</string>
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil za posao"</string>
@@ -726,7 +726,7 @@
<string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nema nedavnih oblačića"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Nedavni i odbačeni oblačići će se pojaviti ovdje"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ta obavještenja se ne mogu izmijeniti."</string>
- <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ovu grupu obavještenja nije moguće konfigurirati ovdje"</string>
+ <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ovdje nije moguće konfigurirati ovu grupu obavještenja"</string>
<string name="notification_delegate_header" msgid="1264510071031479920">"Obavještenje preko proksi servera"</string>
<string name="notification_channel_dialog_title" msgid="6856514143093200019">"Sva obavještenja aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="see_more_title" msgid="7409317011708185729">"Prikaži više"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 658beec..f5330d3 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -92,10 +92,10 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processant gravació de pantalla"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificació en curs d\'una sessió de gravació de la pantalla"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Vols iniciar la gravació?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"Durant la gravació, el sistema Android pot capturar qualsevol informació sensible que es mostri a la pantalla o que es reprodueixi al dispositiu. Això inclou contrasenyes, informació de pagament, fotos, missatges i àudio."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"Quan graves contingut, el sistema Android pot capturar qualsevol informació sensible que es mostri a la pantalla o que es reprodueixi al dispositiu. Això inclou les contrasenyes, la informació de pagament, les fotos, els missatges i l\'àudio."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Grava l\'àudio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Àudio del dispositiu"</string>
- <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"So del dispositiu, com ara música, trucades i sons de trucada"</string>
+ <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sons del dispositiu, com ara la música, les trucades i els sons de trucada"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Micròfon"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Àudio del dispositiu i micròfon"</string>
<string name="screenrecord_start" msgid="330991441575775004">"Inicia"</string>
@@ -389,7 +389,7 @@
<string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"La Wi‑Fi no està connectada"</string>
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brillantor"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"AUTOMÀTICA"</string>
- <string name="quick_settings_inversion_label" msgid="5078769633069667698">"Inverteix colors"</string>
+ <string name="quick_settings_inversion_label" msgid="5078769633069667698">"Inverteix els colors"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"Mode de correcció de color"</string>
<string name="quick_settings_more_settings" msgid="2878235926753776694">"Més opcions"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"Fet"</string>
@@ -447,7 +447,7 @@
<string name="zen_priority_introduction" msgid="3159291973383796646">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes, recordatoris, esdeveniments i trucades de les persones que especifiquis. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalitza"</string>
- <string name="zen_silence_introduction_voice" msgid="853573681302712348">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música. Encara podràs fer trucades telefòniques."</string>
+ <string name="zen_silence_introduction_voice" msgid="853573681302712348">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música. Encara podràs fer trucades."</string>
<string name="zen_silence_introduction" msgid="6117517737057344014">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música."</string>
<string name="keyguard_more_overflow_text" msgid="5819512373606638727">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="7248696377626341060">"Notificacions menys urgents a continuació"</string>
@@ -709,7 +709,7 @@
<string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactiva les notificacions"</string>
<string name="inline_keep_showing_app" msgid="4393429060390649757">"Vols continuar rebent notificacions d\'aquesta aplicació?"</string>
<string name="notification_silence_title" msgid="8608090968400832335">"Silenci"</string>
- <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminat"</string>
+ <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminada"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"Bombolla"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sense so ni vibració"</string>
<string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sense so ni vibració i es mostra més avall a la secció de converses"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 484c631..40dce03 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -95,7 +95,7 @@
<string name="screenrecord_description" msgid="1123231719680353736">"Při nahrávání může systém Android zaznamenávat citlivé údaje, které jsou viditelné na obrazovce nebo které jsou přehrávány na zařízení. Týká se to hesel, údajů o platbě, fotek, zpráv a zvuků."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Nahrát zvuk"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvuk zařízení"</string>
- <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvuk ze zařízení, například hudba, hovory a vyzvánění"</string>
+ <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvuk ze zařízení, například hudba, hovory a vyzváněcí tóny"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Zvuk a mikrofon zařízení"</string>
<string name="screenrecord_start" msgid="330991441575775004">"Spustit"</string>
@@ -722,7 +722,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Může vyzvánět nebo vibrovat v závislosti na nastavení telefonu"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Může vyzvánět nebo vibrovat v závislosti na nastavení telefonu. Konverzace z aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> ve výchozím nastavení bublají."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Přitahuje pozornost pomocí plovoucí zkratky k tomuto obsahu."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Zobrazuje se v horní části sekce konverzací a má podobu plovoucí bubliny, zobrazuje profilovou fotku na obrazovce uzamčení"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Zobrazuje se v horní části sekce konverzace a má podobu plovoucí bubliny, zobrazuje profilovou fotku na obrazovce uzamčení"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Nastavení"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorita"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> funkce konverzace nepodporuje"</string>
@@ -1026,7 +1026,7 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostní režim"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Konverzace byla nastavena jako prioritní"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Chování prioritních konverzací:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Zobrazovat v horní části sekce konverzací"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Zobrazovat v horní části sekce konverzace"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Zobrazovat profilovou fotku na zámku obrazovky"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Zobrazuje se jako plovoucí bublina nad aplikacemi"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Přerušit režim Nerušit"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 334d896..59aaa5a 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Kan ringe eller vibrere baseret på telefonens indstillinger"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Kan ringe eller vibrere baseret på telefonens indstillinger. Samtaler fra <xliff:g id="APP_NAME">%1$s</xliff:g> vises som standard i bobler."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Fastholder din opmærksomhed med en svævende genvej til indholdet."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Vises øverst i samtalesektionen som en svævende boble og med profilbillede på låseskærmen"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Vises øverst i samtalesektionen, som en svævende boble og med profilbillede på låseskærmen"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Indstillinger"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> understøtter ikke samtalefunktioner"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index edee95f..e303886 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Energiesparmodus ist aktiviert"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduzierung der Leistung und Hintergrunddaten"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Energiesparmodus deaktivieren"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"Die App \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" erhält Zugriff auf alle Informationen, die auf deinem Bildschirm sichtbar sind oder von deinem Gerät wiedergegeben werden, während du aufnimmst oder streamst. Dazu gehören beispielsweise angezeigte Passwörter und Zahlungsdetails, Fotos, Nachrichten und Audioinhalte."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"Die App \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" erhält Zugriff auf alle Informationen, die auf deinem Bildschirm sichtbar sind oder von deinem Gerät wiedergegeben werden, während du aufnimmst oder streamst. Dazu gehören beispielsweise Passwörter, Zahlungsdetails, Fotos, Nachrichten und Audioinhalte."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Der Anbieter dieser App erhält Zugriff auf alle Informationen, die auf deinem Bildschirm sichtbar sind oder von deinem Gerät wiedergegeben werden, während du aufnimmst oder streamst. Dazu gehören beispielsweise Passwörter, Zahlungsdetails, Fotos, Nachrichten und Audioinhalte."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Aufnahme oder Stream starten?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Aufnehmen oder Streamen mit der App \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" starten?"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index becbaa4..b54b5f1 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -693,7 +693,7 @@
<string name="notification_channel_minimized" msgid="6892672757877552959">"Αυτές οι ειδοποιήσεις θα ελαχιστοποιηθούν"</string>
<string name="notification_channel_silenced" msgid="1995937493874511359">"Αυτές οι ειδοποιήσεις θα εμφανίζονται σιωπηλά"</string>
<string name="notification_channel_unsilenced" msgid="94878840742161152">"Αυτές οι ειδοποιήσεις θα σας ενημερώνουν"</string>
- <string name="inline_blocking_helper" msgid="2891486013649543452">"Συνήθως παραβλέπετε αυτές τις ειδοποιήσεις. \nΝα εξακολουθήσουν να εμφανίζονται;"</string>
+ <string name="inline_blocking_helper" msgid="2891486013649543452">"Συνήθως απορρίπτετε αυτές τις ειδοποιήσεις. \nΝα εξακολουθήσουν να εμφανίζονται;"</string>
<string name="inline_done_button" msgid="6043094985588909584">"Τέλος"</string>
<string name="inline_ok_button" msgid="603075490581280343">"Εφαρμογή"</string>
<string name="inline_keep_showing" msgid="8736001253507073497">"Να συνεχίσουν να εμφανίζονται αυτές οι ειδοποιήσεις;"</string>
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Ενδέχεται να κουδουνίζει ή να δονείται βάσει των ρυθμίσεων του τηλεφώνου"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Ενδέχεται να κουδουνίζει ή να δονείται βάσει των ρυθμίσεων του τηλεφώνου. Οι συζητήσεις από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εμφανίζονται σε συννεφάκι από προεπιλογή."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Κρατάει την προσοχή σας με μια κινούμενη συντόμευση προς αυτό το περιεχόμενο."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Εμφανίζεται επάνω στις συζητήσεις, προβάλλεται ως κιν. συννεφάκι, εμφανίζει τη φωτ. προφίλ στην οθ. κλειδ."</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Εμφανίζεται στο επάνω μέρος της ενότητας συζητήσεων, προβάλλεται ως κινούμενο συννεφάκι, εμφανίζει τη φωτογραφία προφίλ στην οθόνη κλειδώματος"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ρυθμίσεις"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Προτεραιότητα"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν υποστηρίζει τις λειτουργίες συζήτησης"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 1581c15..75410f2 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -92,7 +92,7 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Start recording?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"While recording, the Android System can capture any sensitive information that’s visible on your screen or played on your device. This includes passwords, payment info, photos, messages and audio."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"While recording, Android System can capture any sensitive information that’s visible on your screen or played on your device. This includes passwords, payment info, photos, messages and audio."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Device audio"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sound from your device, like music, calls and ringtones"</string>
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Battery Saver is on"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduces performance and background data"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Turn off Battery Saver"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information, such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Start recording or casting?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Start recording or casting with <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 937bf17..fa6db23 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -92,7 +92,7 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Start recording?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"While recording, the Android System can capture any sensitive information that’s visible on your screen or played on your device. This includes passwords, payment info, photos, messages and audio."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"While recording, Android System can capture any sensitive information that’s visible on your screen or played on your device. This includes passwords, payment info, photos, messages and audio."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Device audio"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sound from your device, like music, calls and ringtones"</string>
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Battery Saver is on"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduces performance and background data"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Turn off Battery Saver"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information, such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Start recording or casting?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Start recording or casting with <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 1581c15..75410f2 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -92,7 +92,7 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Start recording?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"While recording, the Android System can capture any sensitive information that’s visible on your screen or played on your device. This includes passwords, payment info, photos, messages and audio."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"While recording, Android System can capture any sensitive information that’s visible on your screen or played on your device. This includes passwords, payment info, photos, messages and audio."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Device audio"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sound from your device, like music, calls and ringtones"</string>
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Battery Saver is on"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduces performance and background data"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Turn off Battery Saver"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information, such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Start recording or casting?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Start recording or casting with <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 1581c15..75410f2 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -92,7 +92,7 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Start recording?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"While recording, the Android System can capture any sensitive information that’s visible on your screen or played on your device. This includes passwords, payment info, photos, messages and audio."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"While recording, Android System can capture any sensitive information that’s visible on your screen or played on your device. This includes passwords, payment info, photos, messages and audio."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Device audio"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sound from your device, like music, calls and ringtones"</string>
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Battery Saver is on"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduces performance and background data"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Turn off Battery Saver"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information, such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Start recording or casting?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Start recording or casting with <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 66aa3e7..f9f50ec 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -248,7 +248,7 @@
<string name="accessibility_remove_notification" msgid="1641455251495815527">"Eliminar notificación"</string>
<string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS habilitado"</string>
<string name="accessibility_gps_acquiring" msgid="896207402196024040">"Adquisición de GPS"</string>
- <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletipo habilitado"</string>
+ <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter habilitado"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Timbre en vibración"</string>
<string name="accessibility_ringer_silent" msgid="8994620163934249882">"Timbre en silencio"</string>
<!-- no translation found for accessibility_casting (8708751252897282313) -->
@@ -708,17 +708,17 @@
<string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Seguir recibiendo alertas"</string>
<string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactivar notificaciones"</string>
<string name="inline_keep_showing_app" msgid="4393429060390649757">"¿Quieres seguir viendo las notificaciones de esta app?"</string>
- <string name="notification_silence_title" msgid="8608090968400832335">"Silenciada"</string>
+ <string name="notification_silence_title" msgid="8608090968400832335">"Silencio"</string>
<string name="notification_alert_title" msgid="3656229781017543655">"Predeterminada"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"Cuadro"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sin sonido ni vibración"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No suena ni vibra, y aparece en la parte inferior de la sección de conversaciones."</string>
- <string name="notification_channel_summary_default" msgid="3282930979307248890">"Puede sonar o vibrar en función de la configuración del teléfono."</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No suena ni vibra, y aparece en una parte inferior de la sección de conversaciones"</string>
+ <string name="notification_channel_summary_default" msgid="3282930979307248890">"Puede sonar o vibrar en función de la configuración del teléfono"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Puede sonar o vibrar en función de la configuración del teléfono. Conversaciones de la burbuja de <xliff:g id="APP_NAME">%1$s</xliff:g> de forma predeterminada."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Retiene tu atención con un acceso directo flotante a este contenido."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Aparece en la parte superior de la sección de conversaciones, en forma de burbuja flotante, y muestra la foto de perfil en la pantalla de bloqueo."</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Aparece en la parte superior de la sección de conversaciones, en forma de burbuja flotante, y muestra la foto de perfil en la pantalla de bloqueo"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configuración"</string>
- <string name="notification_priority_title" msgid="2079708866333537093">"Prioritaria"</string>
+ <string name="notification_priority_title" msgid="2079708866333537093">"Prioridad"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
<string name="bubble_overflow_empty_title" msgid="3120029421991510842">"No hay burbujas recientes"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Las burbujas recientes y las que se descartaron aparecerán aquí"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index dc15bdc..0ebc975 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -98,7 +98,7 @@
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sonido de tu dispositivo, como música, llamadas y tonos de llamada"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Micrófono"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Audio y micrófono del dispositivo"</string>
- <string name="screenrecord_start" msgid="330991441575775004">"Iniciar"</string>
+ <string name="screenrecord_start" msgid="330991441575775004">"Empezar"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Grabando pantalla"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Grabando pantalla y audio"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar toques en la pantalla"</string>
@@ -397,7 +397,7 @@
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Conectado (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
<string name="quick_settings_connecting" msgid="2381969772953268809">"Conectando..."</string>
<string name="quick_settings_tethering_label" msgid="5257299852322475780">"Compartir conexión"</string>
- <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Punto de acceso"</string>
+ <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Zona Wi-Fi"</string>
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Activando…"</string>
<string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Ahorro de datos activado"</string>
<plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
@@ -502,10 +502,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Ahorro de batería activado"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduce el rendimiento y los datos en segundo plano"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Desactivar Ahorro de batería"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tendrá acceso a toda la información que se muestre en la pantalla o se reproduzca en el dispositivo mientras grabas o envías contenido, incluyendo contraseñas, detalles de pagos, fotos, mensajes y audios que reproduzcas."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"El servicio que ofrece esta función tendrá acceso a toda la información que se muestre en la pantalla o se reproduzca en el dispositivo mientras grabas o envías contenido, incluyendo contraseñas, detalles de pagos, fotos, mensajes y audios que reproduzcas."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tendrá acceso a toda la información que se muestre en pantalla o se reproduzca en el dispositivo mientras grabas o envías contenido, incluyendo contraseñas, detalles de pagos, fotos, mensajes y audios que reproduzcas."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"El servicio que ofrece esta función tendrá acceso a toda la información que se muestre en pantalla o se reproduzca en el dispositivo mientras grabas o envías contenido, incluyendo contraseñas, detalles de pagos, fotos, mensajes y audios que reproduzcas."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"¿Empezar a grabar o enviar contenido?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"¿Iniciar grabación o el envío de contenido en <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"¿Quieres iniciar la grabación o el envío de contenido con <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"No volver a mostrar"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestionar"</string>
@@ -662,7 +662,7 @@
<string name="alarm_template" msgid="2234991538018805736">"a las <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="3561752195856839456">"el <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="accessibility_quick_settings_detail" msgid="544463655956179791">"Ajustes rápidos, <xliff:g id="TITLE">%s</xliff:g>."</string>
- <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Punto de acceso"</string>
+ <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Zona Wi-Fi"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabajo"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Diversión solo para algunos"</string>
<string name="tuner_warning" msgid="1861736288458481650">"El configurador de UI del sistema te ofrece otras formas de modificar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string>
@@ -712,11 +712,11 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Predeterminado"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"Burbuja"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sin sonido ni vibración"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sin sonido ni vibración, y se muestra más abajo en la sección de conversaciones"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sin sonido ni vibración y se muestra más abajo en la sección de conversaciones"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Es posible que suene o vibre según los ajustes del teléfono"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Es posible que suene o vibre según los ajustes del teléfono. Las conversaciones de <xliff:g id="APP_NAME">%1$s</xliff:g> aparecen como burbujas de forma predeterminada."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Llama tu atención con un acceso directo flotante a este contenido."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Se muestra arriba en la sección de conversaciones, como burbuja flotante, y la imagen de perfil aparece en la pantalla de bloqueo"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Se muestra arriba en la sección de conversaciones en forma de burbuja flotante, y la imagen de perfil aparece en la pantalla de bloqueo"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ajustes"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioridad"</string>
<string name="no_shortcut" msgid="8257177117568230126">"No se pueden usar funciones de conversación con <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 050cb43..55a1822 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -554,7 +554,7 @@
<string name="monitoring_description_named_vpn" msgid="5749932930634037027">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora konektatuta zaude eta hark sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
<string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> eta <xliff:g id="VPN_APP_1">%2$s</xliff:g> aplikazioetara konektatuta zaude, eta haiek sareko jarduerak gainbegira ditzakete, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
<string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora dago konektatuta laneko profila, eta aplikazio horrek sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
- <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora konektatuta daukazu profil pertsonala, eta aplikazio horrek sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora konektatuta duzu profil pertsonala, eta aplikazio horrek sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
<string name="monitoring_description_do_header_generic" msgid="6130190408164834986">"<xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> aplikazioak kudeatzen du gailu hau."</string>
<string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundeak <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> erabiltzen du gailua kudeatzeko."</string>
<string name="monitoring_description_do_body" msgid="7700878065625769970">"Gailuko ezarpenak, enpresa-sarbidea, aplikazioak eta datuak gainbegira eta kudea ditzake administratzaileak, baita gailuaren kokapen-informazioa ere."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 60ea12d..6dde6e8 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -144,7 +144,7 @@
<string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"برای لغو راستیآزمایی ضربه بزنید"</string>
<string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"لطفاً دوباره امتحان کنید"</string>
<string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"درحال جستجوی چهره"</string>
- <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چهره اصالتسنجی شد"</string>
+ <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چهره احراز هویت شد"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تأیید شد"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"برای تکمیل، روی تأیید ضربه بزنید"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"راستیآزماییشده"</string>
@@ -248,7 +248,7 @@
<string name="accessibility_remove_notification" msgid="1641455251495815527">"پاک کردن اعلان"</string>
<string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS فعال شد."</string>
<string name="accessibility_gps_acquiring" msgid="896207402196024040">"دستیابی به GPS."</string>
- <string name="accessibility_tty_enabled" msgid="1123180388823381118">"تلهتایپ فعال شد."</string>
+ <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter فعال شد."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"زنگ لرزشی."</string>
<string name="accessibility_ringer_silent" msgid="8994620163934249882">"زنگ بیصدا."</string>
<!-- no translation found for accessibility_casting (8708751252897282313) -->
@@ -309,8 +309,8 @@
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"حالت کار روشن شد."</string>
<string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"صرفهجویی داده خاموش شد."</string>
<string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"صرفهجویی داده روشن شد."</string>
- <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="7608378211873807353">"«حریمخصوصی حسگر» خاموش است."</string>
- <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="4267393685085328801">"«حریمخصوصی حسگر» روشن است."</string>
+ <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="7608378211873807353">"«حریم خصوصی حسگر» خاموش است."</string>
+ <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="4267393685085328801">"«حریم خصوصی حسگر» روشن است."</string>
<string name="accessibility_brightness" msgid="5391187016177823721">"روشنایی نمایشگر"</string>
<string name="accessibility_ambient_display_charging" msgid="7725523068728128968">"درحال شارژ شدن"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5716594205739750015">"داده 2G-3G موقتاً متوقف شده است"</string>
@@ -433,7 +433,7 @@
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"شروع"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"توقف"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"دستگاه"</string>
- <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"برای تغییر برنامهها، تند بهبالا بکشید"</string>
+ <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"برای تغییر برنامهها، تند به بالا بکشید"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"برای جابهجایی سریع میان برنامهها، به چپ بکشید"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"تغییر وضعیت نمای کلی"</string>
<string name="expanded_header_battery_charged" msgid="5307907517976548448">"شارژ کامل شد"</string>
@@ -452,8 +452,8 @@
<string name="keyguard_more_overflow_text" msgid="5819512373606638727">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="7248696377626341060">"اعلانهای کمتر فوری در زیر"</string>
<string name="notification_tap_again" msgid="4477318164947497249">"دوباره ضربه بزنید تا باز شود"</string>
- <string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند بهبالا بکشید"</string>
- <string name="keyguard_retry" msgid="886802522584053523">"برای امتحان مجدد، انگشتتان را تند بهبالا بکشید"</string>
+ <string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند به بالا بکشید"</string>
+ <string name="keyguard_retry" msgid="886802522584053523">"برای امتحان مجدد، انگشتتان را تند به بالا بکشید"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"این دستگاه به سازمان شما تعلق دارد"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"این دستگاه به <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> تعلق دارد"</string>
<string name="phone_hint" msgid="6682125338461375925">"انگشتتان را از نماد تلفن تند بکشید"</string>
@@ -606,7 +606,7 @@
<string name="screen_pinning_positive" msgid="3285785989665266984">"متوجه شدم"</string>
<string name="screen_pinning_negative" msgid="6882816864569211666">"نه متشکرم"</string>
<string name="screen_pinning_start" msgid="7483998671383371313">"برنامه پین شد"</string>
- <string name="screen_pinning_exit" msgid="4553787518387346893">"سنجاق از برنامه برداشته شد"</string>
+ <string name="screen_pinning_exit" msgid="4553787518387346893">"پین برنامه برداشته شد"</string>
<string name="quick_settings_reset_confirmation_title" msgid="463533331480997595">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> مخفی شود؟"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"دفعه بعد که آن را روشن کنید، در تنظیمات نشان داده میشود."</string>
<string name="quick_settings_reset_confirmation_button" msgid="3341477479055016776">"پنهان کردن"</string>
@@ -802,7 +802,7 @@
<string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"برگشت"</string>
<string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"اعلانها"</string>
<string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"میانبرهای صفحهکلید"</string>
- <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"تغییر جانمایی صفحهکلید"</string>
+ <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"تغییر طرحبندی صفحهکلید"</string>
<string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"برنامهها"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"دستیار"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"مرورگر"</string>
@@ -979,7 +979,7 @@
<string name="slice_permission_text_2" msgid="6758906940360746983">"- میتواند در <xliff:g id="APP">%1$s</xliff:g> اقدام انجام دهد"</string>
<string name="slice_permission_checkbox" msgid="4242888137592298523">"به <xliff:g id="APP">%1$s</xliff:g> اجازه داده شود تکههایی از برنامهها نشان دهد"</string>
<string name="slice_permission_allow" msgid="6340449521277951123">"مجاز"</string>
- <string name="slice_permission_deny" msgid="6870256451658176895">"مجاز نبودن"</string>
+ <string name="slice_permission_deny" msgid="6870256451658176895">"رد کردن"</string>
<string name="auto_saver_title" msgid="6873691178754086596">"برای زمانبندی «بهینهسازی باتری» ضربه بزنید"</string>
<string name="auto_saver_text" msgid="3214960308353838764">"وقتی باتری روبهاتمام است، بهینهسازی باتری را روشن کنید"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"نه متشکرم"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 7573d29..1fe5ba2 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -381,7 +381,7 @@
<string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi on käytössä"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Ei Wi-Fi-verkkoja käytettävissä"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Otetaan käyttöön…"</string>
- <string name="quick_settings_cast_title" msgid="2279220930629235211">"Näytön striimaus"</string>
+ <string name="quick_settings_cast_title" msgid="2279220930629235211">"Näytön suoratoisto"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"Lähetetään"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Nimetön laite"</string>
<string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"Valmis lähetystä varten"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index e87bafd..8fc4e2c 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Économiseur de pile activé"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Réduire les performances et de fond"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Désactiver la fonction Économiseur de pile"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toute l\'information visible sur votre écran ou qui joue sur votre appareil durant l\'enregistrement ou la diffusion. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et le contenu audio que vous faites jouer."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toute l\'information visible sur votre écran ou qui joue sur votre appareil durant l\'enregistrement ou la diffusion. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et l\'audio que vous faites jouer."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Le service offrant cette fonction aura accès à toute l\'information qui est visible sur votre écran ou sur ce qui joue sur votre appareil durant l\'enregistrement ou la diffusion. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et le contenu audio que vous faites jouer."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Commencer à enregistrer ou à diffuser?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Commencer à enregistrer ou à diffuser avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index d9ab397..cfd5a98 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Économiseur de batterie activé"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Limite les performances et les données en arrière-plan."</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Désactiver l\'économiseur de batterie"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toutes les informations visibles sur votre écran ou lues depuis votre appareil pendant un enregistrement ou une diffusion de contenu. Il peut s\'agir de mots de passe, données de paiement, photos, messages ou encore contenus audio lus."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toutes les informations visibles sur votre écran ou lues depuis votre appareil lors d\'un enregistrement ou d\'une diffusion de contenu. Par exemple, vos mots de passe, vos données de paiement, vos photos, vos messages ou encore vos contenus audio lus."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Le service qui fournit cette fonction aura accès à toutes les informations visibles sur votre écran ou lues depuis votre appareil lors d\'un enregistrement ou d\'une diffusion de contenu. Cela comprend, entre autres, vos mots de passe, vos données de paiement, vos photos, vos messages ou encore les contenus audio que vous lisez."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Démarrer l\'enregistrement ou la diffusion ?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Démarrer l\'enregistrement ou la diffusion avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ?"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 2c47120..bd7686f 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -248,7 +248,7 @@
<string name="accessibility_remove_notification" msgid="1641455251495815527">"Eliminar notificación."</string>
<string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS activado"</string>
<string name="accessibility_gps_acquiring" msgid="896207402196024040">"Obtendo GPS."</string>
- <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletipo activado"</string>
+ <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter activado"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Timbre en vibración"</string>
<string name="accessibility_ringer_silent" msgid="8994620163934249882">"Timbre silenciado"</string>
<!-- no translation found for accessibility_casting (8708751252897282313) -->
@@ -712,11 +712,11 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Configuración predeterminada"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"Burbulla"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sen son nin vibración"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sen son nin vibración, e aparecen máis abaixo na sección de conversas"</string>
- <string name="notification_channel_summary_default" msgid="3282930979307248890">"Poderían soar ou vibrar en función da configuración do teléfono"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Non soa nin vibra, e aparece máis abaixo na sección de conversas"</string>
+ <string name="notification_channel_summary_default" msgid="3282930979307248890">"Podería soar ou vibrar en función da configuración do teléfono"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Podería soar ou vibrar en función da configuración do teléfono. Conversas desde a burbulla da aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> de forma predeterminada."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantén a túa atención cun atallo flotante a este contido."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Móstranse na parte superior da sección de conversas en forma de burbulla flotante e aparece a imaxe do perfil na pantalla de bloqueo"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Móstrase na parte superior da sección de conversas en forma de burbulla flotante e aparece a imaxe do perfil na pantalla de bloqueo"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configuración"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non admite funcións de conversa"</string>
@@ -786,7 +786,7 @@
<string name="keyboard_key_media_stop" msgid="1509943745250377699">"Deter"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Seguinte"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Anterior"</string>
- <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Retroceder"</string>
+ <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rebobinar"</string>
<string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"Avance rápido"</string>
<string name="keyboard_key_page_up" msgid="173914303254199845">"Re Páx"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Av Páx"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 6ab2a35..53e0fc9 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -125,7 +125,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"ઍક્સેસિબિલિટી"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"સ્ક્રીન ફેરવો"</string>
<string name="accessibility_recent" msgid="901641734769533575">"ઝલક"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"શોધ"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"શોધો"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"કૅમેરો"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ફોન"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"વૉઇસ સહાય"</string>
@@ -332,10 +332,10 @@
<string name="notification_summary_message_format" msgid="5158219088501909966">"<xliff:g id="CONTACT_NAME">%1$s</xliff:g>: <xliff:g id="MESSAGE_CONTENT">%2$s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="6818779631806163080">"સૂચનાઓની સેટિંગ્સ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5050006438806013903">"<xliff:g id="APP_NAME">%s</xliff:g> સેટિંગ"</string>
- <string name="accessibility_rotation_lock_off" msgid="3880436123632448930">"સ્ક્રીન ઑટોમૅટિક રીતે ફરશે."</string>
+ <string name="accessibility_rotation_lock_off" msgid="3880436123632448930">"સ્ક્રીન આપમેળે ફરશે."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"સ્ક્રીન લેન્ડસ્કેપ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"સ્ક્રીન પોટ્રેટ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
- <string name="accessibility_rotation_lock_off_changed" msgid="5772498370935088261">"સ્ક્રીન હવે ઑટોમૅટિક રીતે ફરશે."</string>
+ <string name="accessibility_rotation_lock_off_changed" msgid="5772498370935088261">"સ્ક્રીન હવે આપમેળે ફરશે."</string>
<string name="accessibility_rotation_lock_on_landscape_changed" msgid="5785739044300729592">"સ્ક્રીન હવે લેન્ડસ્કેપ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
<string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"સ્ક્રીન હવે પોટ્રેટ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
<string name="dessert_case" msgid="9104973640704357717">"ડેઝર્ટ કેસ"</string>
@@ -586,7 +586,7 @@
<string name="accessibility_volume_settings" msgid="1458961116951564784">"સાઉન્ડ સેટિંગ"</string>
<string name="accessibility_volume_expand" msgid="7653070939304433603">"વિસ્તૃત કરો"</string>
<string name="accessibility_volume_collapse" msgid="2746845391013829996">"સંકુચિત કરો"</string>
- <string name="volume_odi_captions_tip" msgid="8825655463280990941">"મીડિયામાં કૅપ્શન ઑટોમૅટિક રીતે ઉમેરો"</string>
+ <string name="volume_odi_captions_tip" msgid="8825655463280990941">"મીડિયામાં કૅપ્શન આપમેળે ઉમેરો"</string>
<string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"કૅપ્શન ટિપ બંધ કરો"</string>
<string name="volume_odi_captions_content_description" msgid="4172765742046013630">"કૅપ્શન ઓવરલે"</string>
<string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"ચાલુ કરો"</string>
@@ -859,7 +859,7 @@
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"ટાઇલને ફરીથી ગોઠવવા માટે આંગળી દબાવીને ખેંચો"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"દૂર કરવા માટે અહીં ખેંચો"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"તમને ઓછામાં ઓછી <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ટાઇલની જરૂર છે"</string>
- <string name="qs_edit" msgid="5583565172803472437">"ફેરફાર કરો"</string>
+ <string name="qs_edit" msgid="5583565172803472437">"સંપાદિત કરો"</string>
<string name="tuner_time" msgid="2450785840990529997">"સમય"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"કલાક, મિનિટ અને સેકન્ડ બતાવો"</item>
@@ -923,10 +923,10 @@
<string name="accessibility_action_pip_resize" msgid="8237306972921160456">"કદ બદલો"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"ફોન વધુ પડતી ગરમીને લીધે બંધ થઇ ગયો છે"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે"</string>
- <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"તમારો ફોન અત્યંત ગરમ હતો, તેથી તે ઠંડો થવા ઑટોમૅટિક રીતે બંધ થઈ ગયો છે. તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\n\nતમારો ફોન અત્યંત ગરમ થઈ શકે છે, જો તમે:\n • એવી ઍપ વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિયો, અથવા નેવિગેટ કરતી ઍપ)\n • મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n • તમારા ફોનનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
+ <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"તમારો ફોન અત્યંત ગરમ હતો, તેથી તે ઠંડો થવા આપમેળે બંધ થઇ ગયો છે. તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\n\nતમારો ફોન અત્યંત ગરમ થઇ શકે છે, જો તમે:\n • એવી ઍપ્લિકેશન વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિઓ, અથવા નેવિગેટ કરતી ઍપ્લિકેશનો)\n • મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n • તમારા ફોનનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
<string name="high_temp_title" msgid="2218333576838496100">"ફોન ગરમ થઈ રહ્યો છે"</string>
<string name="high_temp_notif_message" msgid="163928048626045592">"ફોન ઠંડો થાય ત્યાં સુધી કેટલીક સુવિધાઓ મર્યાદિત હોય છે"</string>
- <string name="high_temp_dialog_message" msgid="3793606072661253968">"તમારો ફોન ઑટોમૅટિક રીતે ઠંડો થવાનો પ્રયાસ કરશે. તમે હજી પણ તમારા ફોનનો ઉપયોગ કરી શકો છો, પરંતુ તે કદાચ થોડો ધીમો ચાલે.\n\nતમારો ફોન ઠંડો થઈ જવા પર, તે સામાન્ય રીતે ચાલશે."</string>
+ <string name="high_temp_dialog_message" msgid="3793606072661253968">"તમારો ફોન આપમેળે ઠંડો થવાનો પ્રયાસ કરશે. તમે હજી પણ તમારા ફોનનો ઉપયોગ કરી શકો છો, પરંતુ તે કદાચ થોડો ધીમો ચાલે.\n\nતમારો ફોન ઠંડો થઈ જવા પર, તે સામાન્ય રીતે ચાલશે."</string>
<string name="high_temp_alarm_title" msgid="2359958549570161495">"ચાર્જરને અનપ્લગ કરો"</string>
<string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"આ ડિવાઇસને ચાર્જ કરવામાં કોઈ સમસ્યા છે. પાવર અડૅપ્ટર અનપ્લગ કરો અને કાળજી લેજો કદાચ કેબલ થોડો ગરમ થયો હોઈ શકે છે."</string>
<string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"સારસંભાળના પગલાં જુઓ"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index b489088..44c0656 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -514,7 +514,7 @@
<string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"नई सूचनाएं"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"बिना आवाज़ किए मिलने वाली सूचनाएं"</string>
- <string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाएं"</string>
+ <string name="notification_section_header_alerting" msgid="5581175033680477651">"वाइब्रेशन या आवाज़ के साथ मिलने वाली सूचनाएं"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"बातचीत"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"बिना आवाज़ की सभी सूचनाएं हटाएं"</string>
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'परेशान न करें\' सुविधा के ज़रिए कुछ समय के लिए सूचनाएं दिखाना रोक दिया गया है"</string>
@@ -714,11 +714,11 @@
<string name="notification_alert_title" msgid="3656229781017543655">"डिफ़ॉल्ट"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"बबल"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"किसी तरह की आवाज़ या वाइब्रेशन न हो"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"इससे किसी तरह की आवाज़ या वाइब्रेशन नहीं होता और बातचीत, सेक्शन में सबसे नीचे दिखती है"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"इससे किसी तरह की आवाज़ या वाइब्रेशन नहीं होता और \'बातचीत\', सेक्शन में सबसे नीचे दिखती है"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"फ़ोन की सेटिंग के आधार पर, सूचना आने पर घंटी बज सकती है या वाइब्रेशन हो सकता है"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"फ़ोन की सेटिंग के आधार पर, सूचना आने पर घंटी बज सकती है या वाइब्रेशन हो सकता है. <xliff:g id="APP_NAME">%1$s</xliff:g> में होने वाली बातचीत, डिफ़ॉल्ट रूप से बबल के तौर पर दिखती है."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"फ़्लोट करने वाले शॉर्टकट की मदद से इस सामग्री पर आपका ध्यान बना रहता है."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"इससे बातचीत, सेक्शन में सबसे ऊपर और फ़्लोटिंग बबल के तौर पर दिखती है. साथ ही, लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो दिखती है"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"इससे बातचीत की सुविधा, सेक्शन में सबसे ऊपर और फ़्लोटिंग बबल के तौर पर दिखती है. साथ ही, लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो दिखती है"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"सेटिंग"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर बातचीत की सुविधाएं काम नहीं करतीं"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 492b558..0151eae 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -505,10 +505,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Štednja baterije je uključena"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Smanjuje količinu rada i pozadinske podatke"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Isključite Štednju baterije"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> imat će pristup svim podacima koji su vidljivi na vašem zaslonu ili koji se reproduciraju s vašeg uređaja tijekom snimanja ili emitiranja. To uključuje podatke kao što su zaporke, podaci o plaćanju, fotografije, poruke i audiozapisi koje reproducirate."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> imat će pristup svim podacima koji su vidljivi na vašem zaslonu ili koji se reproduciraju s vašeg uređaja tijekom snimanja ili emitiranja. To uključuje podatke kao što su zaporke, podaci o plaćanju, fotografije, poruke i audiozapisi koje reproducirate."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Usluga koja pruža ovu funkcionalnost imat će pristup svim podacima koji su vidljivi na vašem zaslonu ili koji se reproduciraju s vašeg uređaja tijekom snimanja ili emitiranja. To uključuje podatke kao što su zaporke, podaci o plaćanju, fotografije, poruke i audiozapisi koje reproducirate."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Započeti snimanje ili emitiranje?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"Započeti snimanje ili emitiranje pomoću aplikacije <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"Započeti snimanje ili emitiranja pomoću aplikacije <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Ne prikazuj ponovo"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Izbriši sve"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 7fb95ac..493e652 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -430,7 +430,7 @@
<string name="quick_settings_nfc_off" msgid="3465000058515424663">"Az NFC ki van kapcsolva"</string>
<string name="quick_settings_nfc_on" msgid="1004976611203202230">"Az NFC be van kapcsolva"</string>
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Képernyő rögzítése"</string>
- <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Indítás"</string>
+ <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Kezdés"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Leállítás"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Eszköz"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Váltás az alkalmazások között felfelé csúsztatással"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 6591006..3296799 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -248,7 +248,7 @@
<string name="accessibility_remove_notification" msgid="1641455251495815527">"Մաքրել ծանուցումը:"</string>
<string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS-ը միացված է:"</string>
<string name="accessibility_gps_acquiring" msgid="896207402196024040">"GPS-ի ստացում:"</string>
- <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Հեռատիպը միացված է:"</string>
+ <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Հեռամուտքագրիչը միացված է:"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Թրթռազանգ:"</string>
<string name="accessibility_ringer_silent" msgid="8994620163934249882">"Զանգակը լռեցված է:"</string>
<!-- no translation found for accessibility_casting (8708751252897282313) -->
@@ -337,7 +337,7 @@
<string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Էկրանը կողպված է ուղղաձիգ դիրքավորմամբ:"</string>
<string name="accessibility_rotation_lock_off_changed" msgid="5772498370935088261">"Էկրանն այժմ ավտոմատ կպտտվի:"</string>
<string name="accessibility_rotation_lock_on_landscape_changed" msgid="5785739044300729592">"Էկրանն այժմ կողպված է հորիզոնական դիրքում:"</string>
- <string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"Էկրանն այժմ կողպված է ուղղաձիգ դիրքում:"</string>
+ <string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"Էկրանն այժմ կողպված է ուղղահայաց դիրքում:"</string>
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Էկրանապահ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
@@ -513,7 +513,7 @@
<string name="notification_section_header_incoming" msgid="850925217908095197">"Նոր"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Անձայն"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Ծանուցումներ"</string>
- <string name="notification_section_header_conversations" msgid="821834744538345661">"Զրույցներ"</string>
+ <string name="notification_section_header_conversations" msgid="821834744538345661">"Խոսակցություններ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ջնջել բոլոր անձայն ծանուցումները"</string>
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ծանուցումները չեն ցուցադրվի «Չանհանգստացնել» ռեժիմում"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Սկսել հիմա"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index e4819bf..69d5714 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -599,7 +599,7 @@
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Ringkasan untuk melepas pin."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Beranda untuk melepas pin."</string>
<string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Data pribadi dapat diakses (seperti kontak dan konten email)."</string>
- <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Aplikasi yang disematkan dapat membuka aplikasi lain."</string>
+ <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Aplikasi yang dipasangi pin dapat membuka aplikasi lain."</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"Untuk melepas pin aplikasi ini, sentuh & lama tombol Kembali dan Ringkasan"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Untuk melepas pin aplikasi ini, sentuh & lama tombol Kembali dan Layar utama"</string>
<string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Untuk melepas pin aplikasi ini, geser ke atas & tahan"</string>
@@ -847,7 +847,7 @@
</string-array>
<string name="menu_ime" msgid="5677467548258017952">"Pengalih keyboard"</string>
<string name="save" msgid="3392754183673848006">"Simpan"</string>
- <string name="reset" msgid="8715144064608810383">"Reset"</string>
+ <string name="reset" msgid="8715144064608810383">"Setel ulang"</string>
<string name="adjust_button_width" msgid="8313444823666482197">"Sesuaikan lebar tombol"</string>
<string name="clipboard" msgid="8517342737534284617">"Papan klip"</string>
<string name="accessibility_key" msgid="3471162841552818281">"Tombol navigasi khusus"</string>
@@ -856,7 +856,7 @@
<string name="left_icon" msgid="5036278531966897006">"Ikon kiri"</string>
<string name="right_icon" msgid="1103955040645237425">"Ikon kanan"</string>
<string name="drag_to_add_tiles" msgid="8933270127508303672">"Tahan dan tarik untuk menambahkan kartu"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Tahan dan tarik untuk menata ulang kartu"</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Tahan dan tarik untuk mengatur ulang kartu"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Tarik ke sini untuk menghapus"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Anda membutuhkan setidaknya <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kartu"</string>
<string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 507bdc9..dc541c8 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -855,10 +855,10 @@
<string name="right_keycode" msgid="2480715509844798438">"Lykiltákn til hægri"</string>
<string name="left_icon" msgid="5036278531966897006">"Tákn til vinstri"</string>
<string name="right_icon" msgid="1103955040645237425">"Tákn til hægri"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Haltu inni og dragðu til að bæta við flísum"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Haltu inni og dragðu til að bæta við reitum"</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Haltu og dragðu til að endurraða flísum"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Dragðu hingað til að fjarlægja"</string>
- <string name="drag_to_remove_disabled" msgid="933046987838658850">"Flísarnar mega ekki vera færri en <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
+ <string name="drag_to_remove_disabled" msgid="933046987838658850">"Reitirnir mega ekki vera færri en <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Breyta"</string>
<string name="tuner_time" msgid="2450785840990529997">"Tími"</string>
<string-array name="clock_options">
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 5a735ae..7ed5f45 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Può suonare o vibrare in base alle impostazioni del telefono"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Può suonare o vibrare in base alle impostazioni del telefono. Conversazioni dalla bolla <xliff:g id="APP_NAME">%1$s</xliff:g> per impostazione predefinita."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantiene la tua attenzione con una scorciatoia mobile a questi contenuti."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Appare in cima alla sezione delle conversazioni e sotto forma di bolla mobile, mostra l\'immagine del profilo nella schermata di blocco"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Viene mostrata in cima alla sezione delle conversazioni, appare sotto forma di bolla mobile, mostra l\'immagine del profilo nella schermata di blocco"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Impostazioni"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorità"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non supporta le funzionalità delle conversazioni"</string>
@@ -987,7 +987,7 @@
<string name="auto_saver_enabled_text" msgid="7889491183116752719">"Il Risparmio energetico verrà attivato automaticamente quando la carica della batteria sarà inferiore a <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
<string name="open_saver_setting_action" msgid="2111461909782935190">"Impostazioni"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
- <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump heap SysUI"</string>
+ <string name="heap_dump_tile_name" msgid="2464189856478823046">"Esegui dump heap SysUI"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensori disattivati"</string>
<string name="device_services" msgid="1549944177856658705">"Servizi del dispositivo"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Senza titolo"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 1b7e1e8..61a5d5d 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -508,7 +508,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"תכונת החיסכון בסוללה פועלת"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"מפחית את הביצועים ונתונים ברקע"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"כיבוי תכונת החיסכון בסוללה"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"לאפליקציית <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> תהיה גישה לכל המידע הגלוי במסך שלך ולכל תוכן שמופעל במכשיר שלך בזמן הקלטה או העברה (casting). המידע הזה כולל פרטים כמו סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו שמושמע מהמכשיר."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"לאפליקציה <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> תהיה גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך בזמן הקלטה או העברה (cast). זה כולל פרטים כמו סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו שמושמע מהמכשיר."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"לשירות שמספק את הפונקציה הזו תהיה גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך בזמן הקלטה או העברה (cast). זה כולל פרטים כמו סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו שמושמע מהמכשיר."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"להתחיל להקליט או להעביר (cast)?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"להתחיל להקליט או להעביר (cast) באמצעות <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -522,7 +522,7 @@
<string name="notification_section_header_conversations" msgid="821834744538345661">"שיחות"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ניקוי כל ההתראות השקטות"</string>
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"התראות הושהו על ידי מצב \'נא לא להפריע\'"</string>
- <string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
+ <string name="media_projection_action_text" msgid="3634906766918186440">"התחל כעת"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"אין התראות"</string>
<string name="profile_owned_footer" msgid="2756770645766113964">"ייתכן שהפרופיל נתון למעקב"</string>
<string name="vpn_footer" msgid="3457155078010607471">"ייתכן שהרשת נמצאת במעקב"</string>
@@ -960,7 +960,7 @@
<string name="notification_channel_general" msgid="4384774889645929705">"הודעות כלליות"</string>
<string name="notification_channel_storage" msgid="2720725707628094977">"אחסון"</string>
<string name="notification_channel_hints" msgid="7703783206000346876">"טיפים"</string>
- <string name="instant_apps" msgid="8337185853050247304">"אפליקציות ללא התקנה"</string>
+ <string name="instant_apps" msgid="8337185853050247304">"אפליקציות אינסטנט"</string>
<string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> פועלת"</string>
<string name="instant_apps_message" msgid="6112428971833011754">"האפליקציה נפתחת בלי התקנה."</string>
<string name="instant_apps_message_with_help" msgid="1816952263531203932">"האפליקציה נפתחת בלי התקנה. אפשר להקיש כדי לקבל מידע נוסף."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index ce1498b..c94f4c7 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -502,10 +502,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"バッテリー セーバー ON"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"パフォーマンスとバックグラウンドデータを制限します"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"バッテリー セーバーを OFF"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> は、録画中やキャスト中に画面に表示されたり、デバイスで再生されるすべての情報にアクセスできます。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などが含まれます。"</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"この機能を提供するサービスは、録画中やキャスト中に画面に表示されたり、デバイスで再生されるすべての情報にアクセスできます。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などが含まれます。"</string>
- <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"録画やキャストを開始しますか?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> で録画やキャストを開始しますか?"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>は、記録中やキャスト中に画面上に表示またはデバイスから再生されるすべての情報にアクセスできます。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などの情報が含まれます。"</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"この機能を提供するサービスは、記録中やキャスト中に画面上に表示またはデバイスから再生されるすべての情報にアクセスできます。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などの情報が含まれます。"</string>
+ <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"記録やキャストを開始しますか?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>で記録やキャストを開始しますか?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"次回から表示しない"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"すべて消去"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index bf86881..9f94f9b 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"დარეკვა ან ვიბრაცია ტელეფონის პარამეტრების მიხედვით"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"დარეკვა ან ვიბრაცია ტელეფონის პარამეტრების მიხედვით. მიმოწერები <xliff:g id="APP_NAME">%1$s</xliff:g>-ის ბუშტიდან, ნაგულისხმევად."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"იპყრობს თქვენს ყურადღებას ამ კონტენტის მოლივლივე მალსახმობით."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"გამოჩნდება მიმოწერების ზედა ნაწილში ბუშტის სახით, აჩვენებს პროფილის სურათს ჩაკეტილ ეკრანზე"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"გამოჩნდება მიმოწერების სექციის ზედა ნაწილში მოლივლივე ბუშტის სახით, აჩვენებს პროფილის სურათს ჩაკეტილ ეკრანზე"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"პარამეტრები"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"პრიორიტეტი"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ს არ აქვს მიმოწერის ფუნქციების მხარდაჭერა"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 2232f3f..3113995 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -28,7 +28,7 @@
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> қалды"</string>
<string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"Пайдалану барысына байланысты <xliff:g id="PERCENTAGE">%1$s</xliff:g> заряд, шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
<string name="battery_low_percent_format_hybrid_short" msgid="5917433188456218857">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> заряд, шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
- <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"<xliff:g id="PERCENTAGE">%s</xliff:g> қалды. Батареяны үнемдеу режимі қосулы."</string>
+ <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"<xliff:g id="PERCENTAGE">%s</xliff:g> қалды. Battery Saver қосулы."</string>
<string name="invalid_charger" msgid="4370074072117767416">"USB арқылы зарядтау мүмкін емес. Құрылғымен бірге берілген зарядтау құралын пайдаланыңыз."</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB арқылы зарядтау мүмкін емес"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Құрылғымен бірге берілген зарядтау құралын пайдаланыңыз"</string>
@@ -421,7 +421,7 @@
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Қосылу уақыты: <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"<xliff:g id="TIME">%s</xliff:g> дейін"</string>
<string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Қараңғы тақырып"</string>
- <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Батареяны үнемдеу режимі"</string>
+ <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Battery Saver"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Күн батқанда қосу"</string>
<string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Күн шыққанға дейін"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Қосылу уақыты: <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -502,8 +502,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Battery saver қосулы"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Өнімділікті және фондық деректерді азайтады"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Battery saver функциясын өшіру"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> жазу не трансляциялау кезінде экранда көрсетілетін немесе дыбысталатын барлық ақпаратты пайдалана алады. Бұған құпия сөздер, төлем туралы мәліметтер, суреттер, хабарлар және аудиоматериалдар кіреді."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Осы функцияны ұсынатын қызмет жазу не трансляциялау кезінде экранда көрсетілетін немесе құрылғыда дыбысталатын ақпаратты пайдалана алады. Бұған құпия сөздер, төлем туралы мәліметтер, суреттер, хабарлар және аудиоматериалдар кіреді."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> экранда көрсетілетін немесе жазу не трансляциялау кезінде құрылғыда ойнатылған барлық ақпаратты пайдалана алады. Бұған құпия сөздер, төлем туралы мәліметтер, суреттер, хабарлар және ойнатылатын аудио сияқты ақпарат кіреді."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Осы функцияны ұсынатын қызмет экранда көрсетілетін немесе жазу не трансляциялау кезінде құрылғыда ойнатылған барлық ақпаратты пайдалана алады. Бұған құпия сөздер, төлем туралы мәліметтер, суреттер, хабарлар және ойнатылатын аудио сияқты ақпарат кіреді."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Жазу немесе трансляциялау басталсын ба?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> арқылы жазу немесе трансляциялау басталсын ба?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Қайта көрсетпеу"</string>
@@ -712,13 +712,13 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Әдепкі"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"Көпіршік"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Дыбыс не діріл қолданылмайды"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Дыбыс не діріл қолданылмайды, әңгімелер бөлімінің төмен жағында шығады"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Дыбыс не діріл қолданылмайды, төменде әңгімелер бөлімінде шығады"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Телефон параметрлеріне байланысты шылдырлауы не дірілдеуі мүмкін"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Телефон параметрлеріне байланысты шылдырлауы не дірілдеуі мүмкін. <xliff:g id="APP_NAME">%1$s</xliff:g> чаттары әдепкісінше қалқымалы етіп көрсетіледі."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Осы мазмұнға бекітілген қалқымалы таңбашамен назарыңызды өзіне тартады."</string>
<string name="notification_channel_summary_priority" msgid="7952654515769021553">"Әңгімелер бөлімінің жоғарғы жағында тұрады, қалқыма хабар түрінде шығады, құлыптаулы экранда профиль суретін көрсетеді"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Параметрлер"</string>
- <string name="notification_priority_title" msgid="2079708866333537093">"Маңызды"</string>
+ <string name="notification_priority_title" msgid="2079708866333537093">"Маңыздылығы"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> әңгімелесу функцияларын қолдамайды."</string>
<string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Жақындағы қалқыма хабарлар жоқ"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Соңғы және жабылған қалқыма хабарлар осы жерде көрсетіледі."</string>
@@ -768,7 +768,7 @@
</plurals>
<string name="battery_panel_title" msgid="5931157246673665963">"Батареяны пайдалану"</string>
<string name="battery_detail_charging_summary" msgid="8821202155297559706">"Зарядтау кезінде Батарея үнемдегіш қол жетімді емес"</string>
- <string name="battery_detail_switch_title" msgid="6940976502957380405">"Батареяны үнемдеу режимі"</string>
+ <string name="battery_detail_switch_title" msgid="6940976502957380405">"Battery Saver"</string>
<string name="battery_detail_switch_summary" msgid="3668748557848025990">"Өнімділікті және фондық деректерді азайтады"</string>
<string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> түймесі"</string>
<string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
@@ -859,7 +859,7 @@
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Элементтердің ретін өзгерту үшін оларды басып тұрып сүйреңіз"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Керексіздерін осы жерге сүйреңіз"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Кемінде <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> бөлшек қажет."</string>
- <string name="qs_edit" msgid="5583565172803472437">"Өзгерту"</string>
+ <string name="qs_edit" msgid="5583565172803472437">"Өңдеу"</string>
<string name="tuner_time" msgid="2450785840990529997">"Уақыт"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Сағаттарды, минуттарды және секундтарды көрсету"</item>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 8901a646..37df4e8 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -28,15 +28,15 @@
<string name="battery_low_percent_format" msgid="4276661262843170964">"នៅសល់ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"នៅសល់ <xliff:g id="PERCENTAGE">%1$s</xliff:g> អាចប្រើបានប្រហែល <xliff:g id="TIME">%2$s</xliff:g> ទៀតផ្អែកលើការប្រើប្រាស់របស់អ្នក"</string>
<string name="battery_low_percent_format_hybrid_short" msgid="5917433188456218857">"នៅសល់ <xliff:g id="PERCENTAGE">%1$s</xliff:g> អាចប្រើបានប្រហែល <xliff:g id="TIME">%2$s</xliff:g> ទៀត"</string>
- <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"នៅសល់ <xliff:g id="PERCENTAGE">%s</xliff:g>។ មុខងារសន្សំថ្មត្រូវបានបើក។"</string>
+ <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"នៅសល់ <xliff:g id="PERCENTAGE">%s</xliff:g> ។ កម្មវិធីសន្សំថ្មបានបើក។"</string>
<string name="invalid_charger" msgid="4370074072117767416">"មិនអាចសាកតាម USB បានទេ។ សូមប្រើឆ្នាំងសាកដែលភ្ជាប់មកជាមួយឧបករណ៍របស់អ្នក។"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"មិនអាចសាកតាម USB បានទេ"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"សូមប្រើឆ្នាំងសាកដែលភ្ជាប់មកជាមួយឧបករណ៍របស់អ្នក"</string>
<string name="battery_low_why" msgid="2056750982959359863">"ការកំណត់"</string>
- <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"បើកមុខងារសន្សំថ្ម?"</string>
- <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"អំពីមុខងារសន្សំថ្ម"</string>
+ <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"បើកកម្មវិធីសន្សំថ្ម?"</string>
+ <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"អំពីកម្មវិធីសន្សំថ្ម"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"បើក"</string>
- <string name="battery_saver_start_action" msgid="4553256017945469937">"បើកមុខងារសន្សំថ្ម"</string>
+ <string name="battery_saver_start_action" msgid="4553256017945469937">"បើកកម្មវិធីសន្សំថ្ម"</string>
<string name="status_bar_settings_settings_button" msgid="534331565185171556">"ការកំណត់"</string>
<string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"វ៉ាយហ្វាយ"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"បង្វិលអេក្រង់ស្វ័យប្រវត្តិ"</string>
@@ -421,7 +421,7 @@
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"បើកនៅម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"រហូតដល់ម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"រចនាប័ទ្មងងឹត"</string>
- <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"មុខងារសន្សំថ្ម"</string>
+ <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"កម្មវិធីសន្សំថ្ម"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"បើកនៅពេលថ្ងៃលិច"</string>
<string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"រហូតដល់ពេលថ្ងៃរះ"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"បើកនៅម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -499,13 +499,13 @@
<string name="user_remove_user_title" msgid="9124124694835811874">"យកអ្នកប្រើចេញ?"</string>
<string name="user_remove_user_message" msgid="6702834122128031833">"កម្មវិធី និងទិន្នន័យទាំងអស់របស់អ្នកប្រើនេះនឹងត្រូវបានលុប។"</string>
<string name="user_remove_user_remove" msgid="8387386066949061256">"យកចេញ"</string>
- <string name="battery_saver_notification_title" msgid="8419266546034372562">"មុខងារសន្សំថ្មបានបើក"</string>
+ <string name="battery_saver_notification_title" msgid="8419266546034372562">"កម្មវិធីសន្សំថ្មបានបើក"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"ការបន្ថយការប្រតិបត្តិ និងទិន្នន័យផ្ទៃខាងក្រោយ"</string>
- <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"បិទមុខងារសន្សំថ្ម"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> នឹងមានសិទ្ធិចូលប្រើព័ត៌មានទាំងអស់ដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬដែលចាក់ពីឧបករណ៍របស់អ្នក នៅពេលកំពុងថត ឬភ្ជាប់។ ព័ត៌មាននេះមានដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ រូបថត សារ និងសំឡេងដែលអ្នកចាក់ជាដើម។"</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"សេវាកម្មដែលផ្ដល់មុខងារនេះនឹងមានសិទ្ធិចូលប្រើព័ត៌មានទាំងអស់ដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬដែលចាក់ពីឧបករណ៍របស់អ្នក នៅពេលកំពុងថត ឬភ្ជាប់។ ព័ត៌មាននេះមានដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ រូបថត សារ និងសំឡេងដែលអ្នកចាក់ជាដើម។"</string>
+ <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"បិទកម្មវិធីសន្សំថ្ម"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> នឹងមានសិទ្ធិចូលប្រើព័ត៌មានទាំងអស់ដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬដែលចាក់ពីឧបករណ៍របស់អ្នក នៅពេលកំពុងថត ឬបញ្ជូន។ ព័ត៌មាននេះមានដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ រូបថត សារ និងសំឡេងដែលអ្នកចាក់ជាដើម។"</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"សេវាកម្មដែលផ្ដល់មុខងារនេះនឹងមានសិទ្ធិចូលប្រើព័ត៌មានទាំងអស់ដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬដែលចាក់ពីឧបករណ៍របស់អ្នក នៅពេលកំពុងថត ឬបញ្ជូន។ ព័ត៌មាននេះមានដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ រូបថត សារ និងសំឡេងដែលអ្នកចាក់ជាដើម។"</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ចាប់ផ្ដើមថត ឬបញ្ជូនមែនទេ?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"ចាប់ផ្ដើមថត ឬភ្ជាប់ដោយប្រើ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ឬ?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"ចាប់ផ្ដើមថត ឬបញ្ជូនដោយប្រើ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ឬ?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"កុំបង្ហាញម្ដងទៀត"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"សម្អាតទាំងអស់"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"គ្រប់គ្រង"</string>
@@ -767,8 +767,8 @@
<item quantity="one">%d នាទី</item>
</plurals>
<string name="battery_panel_title" msgid="5931157246673665963">"ការប្រើប្រាស់ថ្ម"</string>
- <string name="battery_detail_charging_summary" msgid="8821202155297559706">"មិនអាចប្រើមុខងារសន្សំថ្មបានទេក្នុងអំឡុងពេលសាកថ្ម"</string>
- <string name="battery_detail_switch_title" msgid="6940976502957380405">"មុខងារសន្សំថ្ម"</string>
+ <string name="battery_detail_charging_summary" msgid="8821202155297559706">"កម្មវិធីសន្សំថ្មមិនអាចប្រើបានអំឡុងពេលសាកថ្មទេ"</string>
+ <string name="battery_detail_switch_title" msgid="6940976502957380405">"កម្មវិធីសន្សំថ្ម"</string>
<string name="battery_detail_switch_summary" msgid="3668748557848025990">"កាត់បន្ថយប្រតិបត្តិការ និងទិន្នន័យផ្ទៃខាងក្រោយ"</string>
<string name="keyboard_key_button_template" msgid="8005673627272051429">"ប៊ូតុង <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
@@ -980,11 +980,11 @@
<string name="slice_permission_checkbox" msgid="4242888137592298523">"អនុញ្ញាតឱ្យ <xliff:g id="APP">%1$s</xliff:g> បង្ហាញស្ថិតិប្រើប្រាស់ពីកម្មវិធីនានា"</string>
<string name="slice_permission_allow" msgid="6340449521277951123">"អនុញ្ញាត"</string>
<string name="slice_permission_deny" msgid="6870256451658176895">"បដិសេធ"</string>
- <string name="auto_saver_title" msgid="6873691178754086596">"ចុចដើម្បីកំណត់កាលវិភាគមុខងារសន្សំថ្ម"</string>
+ <string name="auto_saver_title" msgid="6873691178754086596">"ចុចដើម្បីកំណត់កាលវិភាគកម្មវិធីសន្សំថ្ម"</string>
<string name="auto_saver_text" msgid="3214960308353838764">"បើកនៅពេលថ្មទំនងជាអស់"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"ទេ អរគុណ"</string>
- <string name="auto_saver_enabled_title" msgid="4294726198280286333">"កាលវិភាគមុខងារសន្សំថ្មបានបើកហើយ"</string>
- <string name="auto_saver_enabled_text" msgid="7889491183116752719">"មុខងារសន្សំថ្មនឹងបើកដោយស្វ័យប្រវត្តិ នៅពេលថ្មនៅសល់តិចជាង <xliff:g id="PERCENTAGE">%d</xliff:g>%%។"</string>
+ <string name="auto_saver_enabled_title" msgid="4294726198280286333">"កាលវិភាគកម្មវិធីសន្សំថ្មបានបើកហើយ"</string>
+ <string name="auto_saver_enabled_text" msgid="7889491183116752719">"កម្មវិធីសន្សំថ្មនឹងបើកដោយស្វ័យប្រវត្តិ នៅពេលថ្មនៅសល់តិចជាង <xliff:g id="PERCENTAGE">%d</xliff:g>%% ។"</string>
<string name="open_saver_setting_action" msgid="2111461909782935190">"ការកំណត់"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"យល់ហើយ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"ចម្លង SysUI Heap"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 38926cb..d545e31 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -125,7 +125,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"ಪ್ರವೇಶಿಸುವಿಕೆ"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"ಪರದೆಯನ್ನು ತಿರುಗಿಸಿ"</string>
<string name="accessibility_recent" msgid="901641734769533575">"ಸಮಗ್ರ ನೋಟ"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"Search"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"ಹುಡುಕಿ"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"ಕ್ಯಾಮರಾ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ಫೋನ್"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
@@ -389,7 +389,7 @@
<string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"ವೈ-ಫೈ ಸಂಪರ್ಕಗೊಂಡಿಲ್ಲ"</string>
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ಪ್ರಕಾಶಮಾನ"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"ಸ್ವಯಂ"</string>
- <string name="quick_settings_inversion_label" msgid="5078769633069667698">"ಬಣ್ಣಗಳನ್ನು ಇನ್ವರ್ಟ್ ಮಾಡಿ"</string>
+ <string name="quick_settings_inversion_label" msgid="5078769633069667698">"ಬಣ್ಣಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"ಬಣ್ಣ ತಿದ್ದುಪಡಿ ಮೋಡ್"</string>
<string name="quick_settings_more_settings" msgid="2878235926753776694">"ಹೆಚ್ಚಿನ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"ಮುಗಿದಿದೆ"</string>
@@ -441,7 +441,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"<xliff:g id="CHARGING_TIME">%s</xliff:g> ಪೂರ್ಣಗೊಳ್ಳುವವರೆಗೆ"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"ನೆಟ್ವರ್ಕ್\n ವೀಕ್ಷಿಸಬಹುದಾಗಿರುತ್ತದೆ"</string>
- <string name="description_target_search" msgid="3875069993128855865">"Search"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"ಹುಡುಕಿ"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ಗಾಗಿ ಮೇಲಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ."</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ಗಾಗಿ ಎಡಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ."</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"ಅಲಾರಾಂಗಳು, ಜ್ಞಾಪನೆಗಳು, ಈವೆಂಟ್ಗಳು ಹಾಗೂ ನೀವು ಸೂಚಿಸಿರುವ ಕರೆದಾರರನ್ನು ಹೊರತುಪಡಿಸಿ ಬೇರಾವುದೇ ಸದ್ದುಗಳು ಅಥವಾ ವೈಬ್ರೇಶನ್ಗಳು ನಿಮಗೆ ತೊಂದರೆ ನೀಡುವುದಿಲ್ಲ. ಹಾಗಿದ್ದರೂ, ನೀವು ಪ್ಲೇ ಮಾಡುವ ಸಂಗೀತ, ವೀಡಿಯೊಗಳು ಮತ್ತು ಆಟಗಳ ಆಡಿಯೊವನ್ನು ನೀವು ಕೇಳಿಸಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
@@ -502,10 +502,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಆನ್ ಆಗಿದೆ"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಆಫ್ ಮಾಡಿ"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"ರೆಕಾರ್ಡ್ ಮಾಡುವಾಗ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಕಾಣಿಸುವ ಸಕಲ ಮಾಹಿತಿಗೂ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಪ್ರವೇಶ ಹೊಂದಿರುತ್ತದೆ. ಇದು ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೊ ಪ್ಲೇಬ್ಯಾಕ್ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಕೂಡ ಒಳಗೊಂಡಿರುತ್ತದೆ."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಗೋಚರಿಸುವ ಅಥವಾ ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಆಗುವ ಎಲ್ಲಾ ಮಾಹಿತಿಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೊ ಪ್ಲೇಬ್ಯಾಕ್ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಇದು ಒಳಗೊಂಡಿದೆ."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"ಈ ವೈಶಿಷ್ಟ್ಯವು ಒದಗಿಸುವ ಸೇವೆಗಳು, ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಗೋಚರಿಸುವ ಅಥವಾ ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಆಗುವ ಎಲ್ಲಾ ಮಾಹಿತಿಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೊ ಪ್ಲೇಬ್ಯಾಕ್ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಇದು ಒಳಗೊಂಡಿದೆ."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಿಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಬೇಕೆ?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಮೂಲಕ ರೆಕಾರ್ಡಿಂಗ್, ಬಿತ್ತರಿಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸುವುದೇ?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಬಳಸಿಕೊಂಡು ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸುವುದೇ?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"ಮತ್ತೊಮ್ಮೆ ತೋರಿಸದಿರು"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ನಿರ್ವಹಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 959cbbc..a858576 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -373,7 +373,7 @@
<string name="quick_settings_time_label" msgid="3352680970557509303">"시간"</string>
<string name="quick_settings_user_label" msgid="1253515509432672496">"나"</string>
<string name="quick_settings_user_title" msgid="8673045967216204537">"사용자"</string>
- <string name="quick_settings_user_new_user" msgid="3347905871336069666">"신규 사용자"</string>
+ <string name="quick_settings_user_new_user" msgid="3347905871336069666">"새 사용자"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
<string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"연결되어 있지 않음"</string>
<string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"네트워크가 연결되지 않음"</string>
@@ -475,7 +475,7 @@
<string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"현재 사용자: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"프로필 표시"</string>
<string name="user_add_user" msgid="4336657383006913022">"사용자 추가"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"신규 사용자"</string>
+ <string name="user_new_user_name" msgid="2019166282704195789">"새 사용자"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"게스트를 삭제하시겠습니까?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"삭제"</string>
@@ -502,10 +502,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"절전 모드 사용 중"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"성능 및 백그라운드 데이터를 줄입니다."</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"절전 모드 사용 중지"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>이 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>이(가) 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"이 기능을 제공하는 서비스는 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"녹화 또는 전송을 시작하시겠습니까?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>으로 녹화 또는 전송을 시작하시겠습니까?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>(으)로 녹화 또는 전송을 시작하시겠습니까?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"다시 표시 안함"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"모두 지우기"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"관리"</string>
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"휴대전화 설정에 따라 벨소리나 진동이 울릴 수 있음"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"휴대전화 설정에 따라 벨소리나 진동이 울릴 수 있습니다. 기본적으로 <xliff:g id="APP_NAME">%1$s</xliff:g>의 대화는 대화창으로 표시됩니다."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"이 콘텐츠로 연결되는 플로팅 바로가기로 사용자의 주의를 끕니다."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"대화 섹션 상단에 표시, 플로팅 대화창으로 표시, 그리고 잠금 화면에 프로필 사진이 표시됨"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"대화 섹션 상단에 표시, 플로팅 대화창으로 표시, 그리고 잠금 화면에 프로필 사진이 표시됩니다."</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"설정"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"우선순위"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱은 대화 기능을 지원하지 않습니다."</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index e7c9789..1d5e9dd 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -502,10 +502,10 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Батареяны үнөмдөгүч режими күйүк"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Иштин майнаптуулугун начарлатып, фондук дайын-даректерди чектейт"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Батареяны үнөмдөгүчтү өчүрүү"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"Жаздырып же тышкы экранга чыгарып жатканда, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу экраныңыздагы бардык маалыматты же түзмөктө ойнолуп жаткан бардык нерселерди (сырсөздөрдү, төлөмдүн чоо-жайын, сүрөттөрдү, билдирүүлөрдү жана угуп жаткан аудиофайлдарды) көрө алат."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Жаздырып же тышкы экранга чыгарып жатканда, бул колдонмо экраныңыздагы бардык маалыматты же түзмөктө ойнолуп жаткан бардык нерселерди (сырсөздөрдү, төлөмдүн чоо-жайын, сүрөттөрдү, билдирүүлөрдү жана угуп жаткан аудиофайлдарды) көрө алат."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"Бул функцияны аткарган <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> кызматы экраныңызда көрүнүп турган бардык маалыматты же жаздыруу жана тышкы экранга чыгаруу учурунда түзмөгүңүздө ойнотулган маалыматты колдоно алат. Буга сырсөздөр, төлөмдүн чоо-жайы, сүрөттөр, билдирүүлөр жана ойнотулган аудио кирет."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Бул функцияны аткарган кызматка экраныңыздагы бардык маалымат же түзмөктө ойнотулуп жаткан нерсе, сырсөздөр, төлөмдөрдүн чоо-жайы, сүрөттөр, билдирүүлөр жана аудио файлдар жеткиликтүү болот."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Жаздырып же тышкы экранга чыгарып баштайсызбы?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу аркылуу жаздырып же тышкы экранга чыгарып баштайсызбы?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> менен жаздырылып же тышкы экранга чыгарылып башталсынбы?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Экинчи көрүнбөсүн"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Баарын тазалап салуу"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Башкаруу"</string>
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Телефондун жөндөөлөрүнө жараша шыңгырап же дирилдеши мүмкүн"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Телефондун жөндөөлөрүнө жараша шыңгырап же дирилдеши мүмкүн. <xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосундагы жазышуулар демейки жөндөө боюнча калкып чыкма билдирмелер түрүндө көрүнөт."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Калкыма ыкчам баскыч менен көңүлүңүздү бул мазмунга буруп турат."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Жазышуулар тизмесинин өйдө жагында калкып чыкма билдирме түрүндө көрүнүп, профиль сүрөтү кулпуланган экрандан чагылдырылат"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Жазышуу бөлүмүнүн жогорку жагында калкып чыкма билдирме түрүндө көрүнүп, профиль сүрөтү кулпуланган экрандан чагылдырылат"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Жөндөөлөр"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Маанилүүлүгү"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> жазышуу функцияларын колдоого албайт"</string>
@@ -856,7 +856,7 @@
<string name="left_icon" msgid="5036278531966897006">"¨Солго¨ сүрөтчөсү"</string>
<string name="right_icon" msgid="1103955040645237425">"¨Оңго¨ сүрөтчөсү"</string>
<string name="drag_to_add_tiles" msgid="8933270127508303672">"Керектүү элементтерди сүйрөп келиңиз"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Элементтердин иретин өзгөртүү үчүн кармап туруп, сүйрөңүз"</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Элементтердин иретин өзгөртүү үчүн, кармап туруп, сүйрөңүз"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Алып салуу үчүн бул жерге сүйрөңүз"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Сизге жок дегенде <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> мозаика керек"</string>
<string name="qs_edit" msgid="5583565172803472437">"Түзөтүү"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 24a68ab..83d0134 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -508,7 +508,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Akumuliatoriaus tausojimo priemonė įjungta"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Sumažinamas našumas ir foninių duomenų naudojimas"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Išjungti Akumuliatoriaus tausojimo priemonę"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> galės pasiekti visą informaciją, matomą ekrane ir leidžiamą iš įrenginio įrašant ar perduodant turinį. Tai apima įvairią informaciją, pvz., slaptažodžius, išsamią mokėjimo informaciją, nuotraukas, pranešimus ir leidžiamus garso įrašus."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"„<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ galės pasiekti visą informaciją, matomą ekrane ir leidžiamą iš įrenginio įrašant ar perduodant turinį. Tai apima įvairią informaciją, pvz., slaptažodžius, išsamią mokėjimo informaciją, nuotraukas, pranešimus ir leidžiamus garso įrašus."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Šią funkcija teikianti paslauga galės pasiekti visą informaciją, matomą ekrane ir leidžiamą iš įrenginio įrašant ar perduodant turinį. Tai apima įvairią informaciją, pvz., slaptažodžius, išsamią mokėjimo informaciją, nuotraukas, pranešimus ir leidžiamus garso įrašus."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Pradėti įrašyti ar perduoti turinį?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Pradėti įrašyti ar perduoti turinį naudojant „<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“?"</string>
@@ -778,7 +778,7 @@
</plurals>
<string name="battery_panel_title" msgid="5931157246673665963">"Akum. energ. vartoj."</string>
<string name="battery_detail_charging_summary" msgid="8821202155297559706">"Akumuliatoriaus tausojimo priemonė nepasiekiama įkraunant"</string>
- <string name="battery_detail_switch_title" msgid="6940976502957380405">"Akum. taus. pr."</string>
+ <string name="battery_detail_switch_title" msgid="6940976502957380405">"Akumuliat. taus. pr."</string>
<string name="battery_detail_switch_summary" msgid="3668748557848025990">"Sumažinamas našumas ir foninių duomenų naudojimas"</string>
<string name="keyboard_key_button_template" msgid="8005673627272051429">"Mygtukas <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_key_home" msgid="3734400625170020657">"Pagrindinis"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 5b53b08..70250b2 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -715,7 +715,7 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Noklusējums"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"Burbulis"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Nav skaņas signāla vai vibrācijas"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nav skaņas signāla vai vibrācijas, kā arī atrodas tālāk sarunu sadaļā"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nav skaņas signāla vai vibrācijas, kā arī atrodas zemāk sarunu sadaļā"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Atkarībā no tālruņa iestatījumiem var zvanīt vai vibrēt"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Atkarībā no tālruņa iestatījumiem var zvanīt vai vibrēt. Sarunas no lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> pēc noklusējuma tiek parādītas burbulī."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Piesaista jūsu uzmanību, rādot peldošu saīsni uz šo saturu."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index d63f99c..0ac73cf8 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -502,8 +502,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Штедачот на батерија е вклучен"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Ја намалува изведбата и податоците во заднина"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Исклучете го штедачот на батерија"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ќе има пристап до сите податоци што се видливи на екранот или пуштени од вашиот уред додека се снима или емитува. Ова вклучува податоци како лозинки, детали за плаќање, фотографии, пораки, аудио што го пуштате итн."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Услугата што ја обезбедува функцијава ќе има пристап до сите податоци што се видливи на екранот или пуштени од вашиот уред додека се снима или емитува. Ова вклучува информации како лозинки, детали за плаќање, фотографии, пораки, аудио што го пуштате итн."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ќе има пристап до сите информации што се видливи на екранот или пуштени од вашиот уред додека се снима или емитува. Ова вклучува информации како, на пример, лозинки, детали на исплатата, фотографии, пораки и аудио што го пуштате."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Услугата што ја обезбедува функцијава ќе има пристап до сите информации што се видливи на екранот или пуштени од вашиот уред додека се снима или емитува. Ова вклучува информации како, на пример, лозинки, детали на исплатата, фотографии, пораки и аудио што го пуштате."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Да почне снимање или емитување?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Да почне снимање или емитување со <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Не покажувај повторно"</string>
@@ -667,7 +667,7 @@
<string name="tuner_warning_title" msgid="7721976098452135267">"Забава за некои, но не за сите"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Адаптерот на УИ на системот ви дава дополнителни начини за дотерување и приспособување на корисничкиот интерфејс на Android. Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string>
<string name="tuner_persistent_warning" msgid="230466285569307806">"Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string>
- <string name="got_it" msgid="477119182261892069">"Сфатив"</string>
+ <string name="got_it" msgid="477119182261892069">"Разбрав"</string>
<string name="tuner_toast" msgid="3812684836514766951">"Честито! Го додадовте Адаптерот на УИ на системот на Поставки"</string>
<string name="remove_from_settings" msgid="633775561782209994">"Отстрани од поставки"</string>
<string name="remove_from_settings_prompt" msgid="551565437265615426">"Да се отстрани Адаптерот на УИ на системот од Поставки и да престанат да се користат сите негови функции?"</string>
@@ -712,13 +712,13 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Стандардно"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"Балонче"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звук или вибрации"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звук или вибрации и се појавува подолу во делот со разговори"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звук или вибрации и се појавува под делот за разговор"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Може да ѕвони или вибрира во зависност од поставките на телефонот"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Може да ѕвони или вибрира во зависност од поставките на телефонот Стандардно, разговорите од <xliff:g id="APP_NAME">%1$s</xliff:g> се во балончиња."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Ви го задржува вниманието со лебдечка кратенка на содржинава."</string>
<string name="notification_channel_summary_priority" msgid="7952654515769021553">"Се појавува на горниот дел од секцијата на разговорот во вид на лебдечко меурче, покажувајќи ја профилната слика на заклучениот екран"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Поставки"</string>
- <string name="notification_priority_title" msgid="2079708866333537093">"Приоритетно"</string>
+ <string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддржува функции за разговор"</string>
<string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Нема неодамнешни балончиња"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Неодамнешните и отфрлените балончиња ќе се појавуваат тука"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index bf15091..2a3ce74 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -125,7 +125,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"ഉപയോഗസഹായി"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"സ്ക്രീൻ തിരിക്കുക"</string>
<string name="accessibility_recent" msgid="901641734769533575">"അവലോകനം"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"Search"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"തിരയൽ"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"ക്യാമറ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ഫോണ്"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"വോയ്സ് സഹായം"</string>
@@ -389,7 +389,7 @@
<string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"വൈഫൈ കണക്റ്റ് ചെയ്തിട്ടില്ല"</string>
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"തെളിച്ചം"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"യാന്ത്രികം"</string>
- <string name="quick_settings_inversion_label" msgid="5078769633069667698">"നെഗറ്റീവ് ലുക്ക്"</string>
+ <string name="quick_settings_inversion_label" msgid="5078769633069667698">"നിറം മാറ്റുക"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"വർണ്ണം ശരിയാക്കൽ മോഡ്"</string>
<string name="quick_settings_more_settings" msgid="2878235926753776694">"കൂടുതൽ ക്രമീകരണങ്ങൾ"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"പൂർത്തിയാക്കി"</string>
@@ -441,7 +441,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"ഫുൾ ചാർജാകാൻ, <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"നെറ്റ്വർക്ക്\nനിരീക്ഷിക്കപ്പെടാം"</string>
- <string name="description_target_search" msgid="3875069993128855865">"Search"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"തിരയൽ"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> എന്നതിനായി മുകളിലേയ്ക്ക് സ്ലൈഡുചെയ്യുക."</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> എന്നതിനായി ഇടത്തേയ്ക്ക് സ്ലൈഡുചെയ്യുക."</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"നിങ്ങൾ സജ്ജീകരിച്ച അലാറങ്ങൾ, റിമൈൻഡറുകൾ, ഇവന്റുകൾ, കോളർമാർ എന്നിവയിൽ നിന്നുള്ള ശബ്ദങ്ങളും വൈബ്രേഷനുകളുമൊഴികെ മറ്റൊന്നും നിങ്ങളെ ശല്യപ്പെടുത്തുകയില്ല. സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയുൾപ്പെടെ പ്ലേ ചെയ്യുന്നതെന്തും നിങ്ങൾക്ക് തുടർന്നും കേൾക്കാൻ കഴിയും."</string>
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"ബാറ്ററി ലാഭിക്കൽ ഓണാണ്"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്ക്കുന്നു"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ബാറ്ററി ലാഭിക്കൽ ഓഫാക്കുക"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"റെക്കോർഡ് ചെയ്യുമ്പോഴോ കാസ്റ്റ് ചെയ്യുമ്പോഴോ നിങ്ങളുടെ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്യുന്നതോ നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ആയ എല്ലാ വിവരങ്ങളിലേക്കും <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ന് ആക്സസ് ഉണ്ടായിരിക്കും. നിങ്ങൾ പ്ലേ ചെയ്യുന്ന ഒഡിയോ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, പാസ്വേഡുകൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഇതിൽ ഉൾപ്പെടുന്നു."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"റെക്കോർഡ് ചെയ്യുമ്പോഴോ കാസ്റ്റ് ചെയ്യുമ്പോഴോ നിങ്ങളുടെ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്യുന്നതോ നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ആയ എല്ലാ വിവരങ്ങളിലേക്കും <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> എന്നതിന് ആക്സസ് ഉണ്ടായിരിക്കും. നിങ്ങൾ പ്ലേ ചെയ്യുന്ന ഒഡിയോ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, പാസ്വേഡുകൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഇതിൽ ഉൾപ്പെടുന്നു."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"റെക്കോർഡ് ചെയ്യുമ്പോഴോ കാസ്റ്റ് ചെയ്യുമ്പോഴോ നിങ്ങളുടെ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്യുന്നതോ നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ആയ എല്ലാ വിവരങ്ങളിലേക്കും ഈ ഫംഗ്ഷൻ ലഭ്യമാക്കുന്ന സേവനത്തിന് ആക്സസ് ഉണ്ടായിരിക്കും. നിങ്ങൾ പ്ലേ ചെയ്യുന്ന ഓഡിയോ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, പാസ്വേഡുകൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഇതിൽ ഉൾപ്പെടുന്നു."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"റെക്കോർഡ് ചെയ്യൽ അല്ലെങ്കിൽ കാസ്റ്റ് ചെയ്യൽ ആരംഭിക്കണോ?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ഉപയോഗിച്ച് റെക്കോർഡ് ചെയ്യൽ അല്ലെങ്കിൽ കാസ്റ്റ് ചെയ്യൽ ആരംഭിക്കണോ?"</string>
@@ -767,7 +767,7 @@
<item quantity="one">%d മിനിറ്റ്</item>
</plurals>
<string name="battery_panel_title" msgid="5931157246673665963">"ബാറ്ററി ഉപയോഗം"</string>
- <string name="battery_detail_charging_summary" msgid="8821202155297559706">"ചാർജ് ചെയ്യുമ്പോൾ ബാറ്ററി ലാഭിക്കൽ സാധ്യമല്ല"</string>
+ <string name="battery_detail_charging_summary" msgid="8821202155297559706">"ചാർജുചെയ്യുന്ന സമയത്ത് ബാറ്ററി ലാഭിക്കൽ നടക്കില്ല"</string>
<string name="battery_detail_switch_title" msgid="6940976502957380405">"ബാറ്ററി ലാഭിക്കൽ"</string>
<string name="battery_detail_switch_summary" msgid="3668748557848025990">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്ക്കുന്നു"</string>
<string name="keyboard_key_button_template" msgid="8005673627272051429">"ബട്ടൺ <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -984,7 +984,7 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ബാറ്ററി ചാർജ് തീരാൻ സാധ്യതയുണ്ടെങ്കിൽ ഓണാക്കുക"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"വേണ്ട"</string>
<string name="auto_saver_enabled_title" msgid="4294726198280286333">"ബാറ്ററി ലാഭിക്കൽ ഷെഡ്യൂൾ ഓണാക്കുക"</string>
- <string name="auto_saver_enabled_text" msgid="7889491183116752719">"ബാറ്ററി <xliff:g id="PERCENTAGE">%d</xliff:g>%% ൽ താഴെയാകുമ്പോൾ, ബാറ്ററി ലാഭിക്കൽ സ്വയമേവ ഓണാകും."</string>
+ <string name="auto_saver_enabled_text" msgid="7889491183116752719">"ബാറ്ററി <xliff:g id="PERCENTAGE">%d</xliff:g>%% ൽ താഴെയാകുമ്പോൾ, ബാറ്ററി ലാഭിക്കൽ സ്വമേധയാ ഓണാകും."</string>
<string name="open_saver_setting_action" msgid="2111461909782935190">"ക്രമീകരണം"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"മനസ്സിലായി"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ഹീപ്പ് ഡമ്പ് ചെയ്യുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 717389e4..f27e885 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -551,29 +551,29 @@
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Таны байгууллага таны ажлын профайлд сертификатын зөвшөөрөл суулгасан байна. Таны аюулгүй сүлжээний ачааллыг өөрчлөх эсвэл хянах боломжтой."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Сертификатын зөвшөөрлийг энэ төхөөрөмжид суулгасан байна. Таны аюулгүй сүлжээний ачааллыг өөрчлөх эсвэл хянах боломжтой."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Таны админ төхөөрөмжийн ачааллыг хянадаг сүлжээний логийг асаасан байна."</string>
- <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"Та имэйл, апп, веб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна."</string>
- <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"Та имэйл, апп, веб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="VPN_APP_0">%1$s</xliff:g>, <xliff:g id="VPN_APP_1">%2$s</xliff:g>-д холбогдсон байна."</string>
- <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"Таны ажлын профайл <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна. Энэ нь таны имэйл, апп, веб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой."</string>
- <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"Таны хувийн профайлыг имэйл, апп, веб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбосон байна."</string>
+ <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"Та имэйл, апп, вэб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"Та имэйл, апп, вэб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="VPN_APP_0">%1$s</xliff:g>, <xliff:g id="VPN_APP_1">%2$s</xliff:g>-д холбогдсон байна."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"Таны ажлын профайл <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна. Энэ нь таны имэйл, апп, вэб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"Таны хувийн профайлыг имэйл, апп, вэб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбосон байна."</string>
<string name="monitoring_description_do_header_generic" msgid="6130190408164834986">"Таны төхөөрөмжийг <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> удирддаг."</string>
<string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> таны төхөөрөмжийг удирдахын тулд <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g>-г ашигладаг."</string>
<string name="monitoring_description_do_body" msgid="7700878065625769970">"Таны админ тохиргоо, байгууллагын хандалт, апп, төхөөрөмжтэй холбоотой өгөгдөл болон таны төхөөрөмжийн байршлын мэдээллийг хянах, удирдах боломжтой."</string>
<string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
<string name="monitoring_description_do_learn_more" msgid="645149183455573790">"Дэлгэрэнгүй үзэх"</string>
- <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"Таны имэйл, апп, веб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна."</string>
+ <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"Таны имэйл, апп, вэб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN тохиргоог нээх"</string>
<string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string>
<string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"Итгэмжлэгдсэн мандат үнэмлэхийг нээх"</string>
<string name="monitoring_description_network_logging" msgid="577305979174002252">"Таны админ төхөөрөмжийн ачааллыг хянадаг сүлжээний логийг асаасан байна.\n\nДэлгэрэнгүй мэдээлэл авах бол админтайгаа холбогдоно уу."</string>
- <string name="monitoring_description_vpn" msgid="1685428000684586870">"Та апп-д VPN холболт хийхийг зөвшөөрсөн байна.\n\nЭнэхүү апп нь таны имэйл, апп, вебсайт зэрэг төхөөрөмж болон сүлжээний үйл ажиллагааг хянах боломжтой."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> таны ажлын профайлыг удирддаг.\n\nТаны админ имэйл, апп болон веб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой.\n\nДэлгэрэнгүй мэдээлэл авах бол админтайгаа холбогдоно уу.\n\nТа сүлжээний үйл ажиллагааг хянах боломжтой VPN-д холбогдсон байна."</string>
+ <string name="monitoring_description_vpn" msgid="1685428000684586870">"Та апп-д VPN холболт хийхийг зөвшөөрсөн байна.\n\nЭнэхүү апп нь таны имэйл, апп, вэбсайт зэрэг төхөөрөмж болон сүлжээний үйл ажиллагааг хянах боломжтой."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> таны ажлын профайлыг удирддаг.\n\nТаны админ имэйл, апп болон вэб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой.\n\nДэлгэрэнгүй мэдээлэл авах бол админтайгаа холбогдоно уу.\n\nТа сүлжээний үйл ажиллагааг хянах боломжтой VPN-д холбогдсон байна."</string>
<string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
- <string name="monitoring_description_app" msgid="376868879287922929">"Та <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон бөгөөд энэ нь таны имэйл, апп, вебсайт зэрэг сүлжээний үйл ажиллагааг хянах боломжтой."</string>
- <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Та <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон бөгөөд энэ нь таны имэйл, апп, вебсайт зэрэг сүлжээний хувийн үйл ажиллагааг хянах боломжтой."</string>
- <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"Та имэйл, апп, веб хуудас зэрэг хувийн сүлжээнийхээ үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон байна."</string>
- <string name="monitoring_description_app_work" msgid="3713084153786663662">"Таны ажлын профайлыг <xliff:g id="ORGANIZATION">%1$s</xliff:g> удирддаг. Энэ нь таны имэйл, апп, веб хуудас зэрэг ажлын сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION">%2$s</xliff:g>-д холбогдсон. \n\nДэлгэрэнгүй мэдээллийг авахын тулд админтай холбогдоно уу."</string>
- <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"Таны ажлын профайлыг <xliff:g id="ORGANIZATION">%1$s</xliff:g> удирддаг. Энэ нь таны имэйл, апп, веб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>-тай холбогдсон. \n\nМөн таны сүлжээний хувийн үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>-д холбогдсон байна."</string>
+ <string name="monitoring_description_app" msgid="376868879287922929">"Та <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон бөгөөд энэ нь таны имэйл, апп, вэбсайт зэрэг сүлжээний үйл ажиллагааг хянах боломжтой."</string>
+ <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Та <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон бөгөөд энэ нь таны имэйл, апп, вэбсайт зэрэг сүлжээний хувийн үйл ажиллагааг хянах боломжтой."</string>
+ <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"Та имэйл, апп, вэб хуудас зэрэг хувийн сүлжээнийхээ үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон байна."</string>
+ <string name="monitoring_description_app_work" msgid="3713084153786663662">"Таны ажлын профайлыг <xliff:g id="ORGANIZATION">%1$s</xliff:g> удирддаг. Энэ нь таны имэйл, апп, вэб хуудас зэрэг ажлын сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION">%2$s</xliff:g>-д холбогдсон. \n\nДэлгэрэнгүй мэдээллийг авахын тулд админтай холбогдоно уу."</string>
+ <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"Таны ажлын профайлыг <xliff:g id="ORGANIZATION">%1$s</xliff:g> удирддаг. Энэ нь таны имэйл, апп, вэб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>-тай холбогдсон. \n\nМөн таны сүлжээний хувийн үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>-д холбогдсон байна."</string>
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent-р түгжээгүй байлгасан"</string>
<string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"Таныг гараар нээх хүртэл төхөөрөмж түгжээтэй байх болно"</string>
<string name="keyguard_indication_trust_unlocked_plugged_in" msgid="2323452175329362855">"<xliff:g id="KEYGUARD_INDICATION">%1$s</xliff:g>\n<xliff:g id="POWER_INDICATION">%2$s</xliff:g>"</string>
@@ -655,8 +655,8 @@
<string name="status_bar_alarm" msgid="87160847643623352">"Сэрүүлэг"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Ажлын профайл"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Нислэгийн горим"</string>
- <string name="add_tile" msgid="6239678623873086686">"Вебсайтын цонх нэмэх"</string>
- <string name="broadcast_tile" msgid="5224010633596487481">"Вебсайтын цонх дамжуулах"</string>
+ <string name="add_tile" msgid="6239678623873086686">"Вэбсайтын цонх нэмэх"</string>
+ <string name="broadcast_tile" msgid="5224010633596487481">"Вэбсайтын цонх дамжуулах"</string>
<string name="zen_alarm_warning_indef" msgid="5252866591716504287">"Та өмнө нь унтраагаагүй тохиолдолд <xliff:g id="WHEN">%1$s</xliff:g>-т сэрүүлгээ сонсохгүй"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g>-т та дараагийн сэрүүлгээ сонсохгүй"</string>
<string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> цагт"</string>
@@ -712,7 +712,7 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Өгөгдмөл"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"Бөмбөлөг"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Дуу эсвэл чичиргээ байхгүй"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Дуу эсвэл чичиргээ байхгүй бөгөөд харилцан ярианы хэсгийн доод талд харагдана"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Дуу эсвэл чичиргээ байхгүй бөгөөд харицан ярианы хэсгийн доод талд харагдана"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Утасны тохиргоонд тулгуурлан хонх дуугаргах эсвэл чичирхийлж болзошгүй"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Утасны тохиргоонд тулгуурлан хонх дуугаргах эсвэл чичирхийлж болзошгүй. <xliff:g id="APP_NAME">%1$s</xliff:g>-н харилцан яриаг өгөгдмөл тохиргооны дагуу бөмбөлөг болгоно."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Энэ контентын хөвөн гарч ирэх товчлолтойгоор таны анхаарлыг татдаг."</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index f6bd5fa..850ef28 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -115,17 +115,17 @@
<string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रेकॉर्डिंग हटवताना एरर आली"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"परवानग्या मिळवता आल्या नाहीत"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन रेकॉर्डिंग सुरू करताना एरर आली"</string>
- <string name="usb_preference_title" msgid="1439924437558480718">"USB फाइल स्थानांतरण पर्याय"</string>
+ <string name="usb_preference_title" msgid="1439924437558480718">"USB फाईल स्थानांतरण पर्याय"</string>
<string name="use_mtp_button_title" msgid="5036082897886518086">"मीडिया प्लेअर म्हणून माउंट करा (MTP)"</string>
<string name="use_ptp_button_title" msgid="7676427598943446826">"कॅमेरा म्हणून माउंट करा (PTP)"</string>
- <string name="installer_cd_button_title" msgid="5499998592841984743">"Mac साठी Android फाइल स्थानांतर अॅप इंस्टॉल करा"</string>
+ <string name="installer_cd_button_title" msgid="5499998592841984743">"Mac साठी Android फाईल स्थानांतर अॅप इंस्टॉल करा"</string>
<string name="accessibility_back" msgid="6530104400086152611">"मागे"</string>
<string name="accessibility_home" msgid="5430449841237966217">"होम"</string>
<string name="accessibility_menu" msgid="2701163794470513040">"मेनू"</string>
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"अॅक्सेसिबिलिटी"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"स्क्रीन फिरवा"</string>
<string name="accessibility_recent" msgid="901641734769533575">"अवलोकन"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"Search"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"शोधा"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"कॅमेरा"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"फोन"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"व्हॉइस सहाय्य"</string>
@@ -267,7 +267,7 @@
<string name="accessibility_quick_settings_wifi" msgid="167707325133803052">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi_changed_off" msgid="2230487165558877262">"Wifi बंद झाले."</string>
<string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"Wifi सुरू झाले."</string>
- <string name="accessibility_quick_settings_mobile" msgid="1817825313718492906">"मोबाइल <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_mobile" msgid="1817825313718492906">"मोबाईल <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="533594896310663853">"बॅटरी <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"विमान मोड बंद."</string>
<string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"विमान मोड सुरू."</string>
@@ -290,7 +290,7 @@
<string name="accessibility_quick_settings_location_changed_off" msgid="5132776369388699133">"स्थान अहवाल बंद केला."</string>
<string name="accessibility_quick_settings_location_changed_on" msgid="7159115433070112154">"स्थान अहवाल सुरू केला."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> साठी अलार्म सेट केला."</string>
- <string name="accessibility_quick_settings_close" msgid="2974895537860082341">"पॅनल बंद करा."</string>
+ <string name="accessibility_quick_settings_close" msgid="2974895537860082341">"पॅनेल बंद करा."</string>
<string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"अधिक वेळ."</string>
<string name="accessibility_quick_settings_less_time" msgid="9110364286464977870">"कमी वेळ."</string>
<string name="accessibility_quick_settings_flashlight_off" msgid="7606563260714825190">"फ्लॅशलाइट बंद."</string>
@@ -300,8 +300,8 @@
<string name="accessibility_quick_settings_flashlight_changed_on" msgid="4747870681508334200">"फ्लॅशलाइट सुरू केला."</string>
<string name="accessibility_quick_settings_color_inversion_changed_off" msgid="7548045840282925393">"रंग उत्क्रमण बंद केले."</string>
<string name="accessibility_quick_settings_color_inversion_changed_on" msgid="4711141858364404084">"रंग उत्क्रमण सुरू केले."</string>
- <string name="accessibility_quick_settings_hotspot_changed_off" msgid="7002061268910095176">"मोबाइल हॉटस्पॉट बंद केला."</string>
- <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"मोबाइल हॉटस्पॉट सुरू केला."</string>
+ <string name="accessibility_quick_settings_hotspot_changed_off" msgid="7002061268910095176">"मोबाईल हॉटस्पॉट बंद केला."</string>
+ <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"मोबाईल हॉटस्पॉट सुरू केला."</string>
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"स्क्रीन कास्ट करणे थांबले."</string>
<string name="accessibility_quick_settings_work_mode_off" msgid="562749867895549696">"कार्य मोड बंद."</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"कार्य मोड सुरू."</string>
@@ -441,7 +441,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"<xliff:g id="CHARGING_TIME">%s</xliff:g> पूर्ण होईपर्यंत"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"चार्ज होत नाही"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"नेटवर्कचे परीक्षण\nकेले जाऊ शकते"</string>
- <string name="description_target_search" msgid="3875069993128855865">"Search"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"शोध"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> साठी वर स्लाइड करा."</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> साठी डावीकडे स्लाइड करा."</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"अलार्म, रिमाइंडर, इव्हेंट आणि तुम्ही निश्चित केलेल्या कॉलर व्यतिरिक्त तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्त्यय आणला जाणार नाही. तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज ऐकू शकतात."</string>
@@ -504,8 +504,8 @@
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"बॅटरी सेव्हर बंद करा"</string>
<string name="media_projection_dialog_text" msgid="1755705274910034772">"तुमच्या स्क्रीनवर दृश्यमान असलेल्या किंवा रेकॉर्ड किंवा कास्ट करताना तुमच्या डिव्हाइसमधून प्ले केलेल्या सर्व माहितीचा अॅक्सेस <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ला असेल. यामध्ये पासवर्ड, पेमेंट तपशील, फोटो, मेसेज आणि तुम्ही प्ले केलेला ऑडिओ यासारख्या माहितीचा समावेश असतो."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"हे कार्य पुरवठा करणाऱ्या सेवेस तुमच्या स्क्रीनवर दृश्यमान असलेल्या किंवा रेकॉर्ड किंवा कास्ट करताना तुमच्या डिव्हाइसमधून प्ले केलेल्या सर्व माहितीचा अॅक्सेस असेल. यामध्ये पासवर्ड, पेमेंट तपशील, फोटो, मेसेज आणि तुम्ही प्ले केलेला ऑडिओ यासारख्या माहितीचा समावेश असतो."</string>
- <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"रेकॉर्ड करणे किंवा कास्ट करणे सुरू करायचे का ?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ने रेकॉर्ड करणे किंवा कास्ट करणे सुरू करायचे का?"</string>
+ <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"रेकॉर्ड किंवा कास्ट करणे सुरू करायचे आहे का ?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ने रेकॉर्ड करणे किंवा कास्ट करणे सुरू करा?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"पुन्हा दर्शवू नका"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"सर्व साफ करा"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थापित करा"</string>
@@ -626,10 +626,10 @@
<string name="qs_status_phone_vibrate" msgid="7055409506885541979">"फोन व्हायब्रेटवर आहे"</string>
<string name="qs_status_phone_muted" msgid="3763664791309544103">"फोन म्यूट केला"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. सशब्द करण्यासाठी टॅप करा."</string>
- <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. व्हायब्रेट सेट करण्यासाठी टॅप करा. प्रवेशयोग्यता सेवा म्यूट केल्या जाऊ शकतात."</string>
- <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. म्यूट करण्यासाठी टॅप करा. प्रवेशक्षमता सेवा म्यूट केल्या जाऊ शकतात."</string>
+ <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. व्हायब्रेट सेट करण्यासाठी टॅप करा. प्रवेशयोग्यता सेवा नि:शब्द केल्या जाऊ शकतात."</string>
+ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. नि:शब्द करण्यासाठी टॅप करा. प्रवेशक्षमता सेवा नि:शब्द केल्या जाऊ शकतात."</string>
<string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. व्हायब्रेट सेट करण्यासाठी टॅप करा."</string>
- <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. म्यूट करण्यासाठी टॅप करा."</string>
+ <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. नि:शब्द करण्यासाठी टॅप करा."</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करा"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"म्यूट काढून टाका"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"व्हायब्रेट करा"</string>
@@ -723,7 +723,7 @@
<string name="bubble_overflow_empty_title" msgid="3120029421991510842">"अलीकडील कोणतेही बबल नाहीत"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"अलीकडील बबल आणि डिसमिस केलेले बबल येथे दिसतील"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"या सूचनांमध्ये सुधारणा केली जाऊ शकत नाही."</string>
- <string name="notification_multichannel_desc" msgid="7414593090056236179">"या सूचनांचा संच येथे कॉंफिगर केला जाऊ शकत नाही"</string>
+ <string name="notification_multichannel_desc" msgid="7414593090056236179">"या सूचनांचा संच येथे कॉन्फिगर केला जाऊ शकत नाही"</string>
<string name="notification_delegate_header" msgid="1264510071031479920">"प्रॉक्सी केलेल्या सूचना"</string>
<string name="notification_channel_dialog_title" msgid="6856514143093200019">"सर्व <xliff:g id="APP_NAME">%1$s</xliff:g> वरील सूचना"</string>
<string name="see_more_title" msgid="7409317011708185729">"आणखी पाहा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 84da74b..4b467c3 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -405,7 +405,7 @@
<item quantity="one">%d peranti</item>
</plurals>
<string name="quick_settings_notifications_label" msgid="3379631363952582758">"Pemberitahuan"</string>
- <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampu Suluh"</string>
+ <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampu suluh"</string>
<string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera sedang digunakan"</string>
<string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Data mudah alih"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Penggunaan data"</string>
@@ -987,7 +987,7 @@
<string name="auto_saver_enabled_text" msgid="7889491183116752719">"Penjimat Bateri akan dihidupkan secara automatik setelah kuasa bateri kurang daripada <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
<string name="open_saver_setting_action" msgid="2111461909782935190">"Tetapan"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
- <string name="heap_dump_tile_name" msgid="2464189856478823046">"DumpSys"</string>
+ <string name="heap_dump_tile_name" msgid="2464189856478823046">"Longgok Tmbunn SysUI"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Penderia dimatikan"</string>
<string name="device_services" msgid="1549944177856658705">"Perkhidmatan Peranti"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Tiada tajuk"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 75d05d4..68e0f3e8 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -502,8 +502,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"ဘက်ထရီ အားထိန်းကို ဖွင့်ထားခြင်း"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"လုပ်ကိုင်မှုကို လျှော့ချလျက် နောက်ခံ ဒေတာကို ကန့်သတ်သည်"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ဘက်ထရီ အားထိန်းကို ပိတ်ရန်"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် သင့်ဖန်သားပြင်တွင် မြင်ရသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အချက်အလက်မှန်သမျှကို သုံးနိုင်နိုင်ပါမည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှုအသေးစိတ်များ၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် သင်ဖွင့်သည့်အသံကဲ့သို့သော အချက်အလက်များ ပါဝင်သည်။"</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ဤလုပ်ရပ်အတွက် ဝန်ဆောင်မှုသည် အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် သင့်ဖန်သားပြင်တွင် မြင်ရသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အချက်အလက်မှန်သမျှကို သုံးနိုင်ပြီး သင့်စက်မှ ဖွင့်နိုင်ပါမည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှုအသေးစိတ်များ၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် သင်ဖွင့်သည့်အသံကဲ့သို့သော အချက်အလက်များ ပါဝင်သည်။"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် သင့်မျက်နှာပြင်တွင် မြင်ရသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အချက်အလက်မှန်သမျှကို သုံးနိုင်ပါမည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှုအသေးစိတ်များ၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် သင်ဖွင့်သည့်အသံကဲ့သို့သော အချက်အလက်များ ပါဝင်သည်။"</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ဤလုပ်ရပ်အတွက် ဝန်ဆောင်မှုသည် အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် သင့်မျက်နှာပြင်တွင် မြင်ရသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အချက်အလက်မှန်သမျှကို သုံးနိုင်ပါမည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှုအသေးစိတ်များ၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် သင်ဖွင့်သည့်အသံကဲ့သို့သော အချက်အလက်များ ပါဝင်သည်။"</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ဖမ်းယူခြင်း သို့မဟုတ် ကာစ်လုပ်ခြင်း စတင်မလား။"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> နှင့် ဖမ်းယူခြင်း သို့မဟုတ် ကာစ်လုပ်ခြင်း စတင်မလား။"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"နောက်ထပ် မပြပါနှင့်"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 758d2be..daa5f36 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -43,7 +43,7 @@
<string name="status_bar_settings_mute_label" msgid="914392730086057522">"म्युट गर्नुहोस्"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="2151934479226017725">"स्वतः"</string>
<string name="status_bar_settings_notifications" msgid="5285316949980621438">"सूचनाहरू"</string>
- <string name="bluetooth_tethered" msgid="4171071193052799041">"ब्लुटुथ टेदर भयो"</string>
+ <string name="bluetooth_tethered" msgid="4171071193052799041">"ब्लुटुथ टेथर भयो"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="2972273031043777851">"इनपुट विधिहरू सेटअप गर्नुहोस्"</string>
<string name="status_bar_use_physical_keyboard" msgid="4849251850931213371">"वास्तविक किबोर्ड"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_DEVICE">%2$s</xliff:g> माथि पहुँच राख्ने अनुमति दिने हो?"</string>
@@ -341,7 +341,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"स्क्रिन सेभर"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
- <string name="quick_settings_header_onboarding_text" msgid="1918085351115504765">"थप विकल्पहरूका लागि आइकनहरूमा टच एण्ड होल्ड गर्नुहोस्"</string>
+ <string name="quick_settings_header_onboarding_text" msgid="1918085351115504765">"थप विकल्पहरूका लागि आइकनहरूमा छोइराख्नुहोस्"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"बाधा नपुऱ्याउनुहोस्"</string>
<string name="quick_settings_dnd_priority_label" msgid="6251076422352664571">"प्राथमिकता मात्र"</string>
<string name="quick_settings_dnd_alarms_label" msgid="1241780970469630835">"अलार्महरू मात्र"</string>
@@ -368,7 +368,7 @@
<string name="quick_settings_location_off_label" msgid="7923929131443915919">"स्थान बन्द छ"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"मिडिया उपकरण"</string>
<string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
- <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"आपत्कालीन कल मात्र"</string>
+ <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"आपतकालीन कल मात्र"</string>
<string name="quick_settings_settings_label" msgid="2214639529565474534">"सेटिङहरू"</string>
<string name="quick_settings_time_label" msgid="3352680970557509303">"समय"</string>
<string name="quick_settings_user_label" msgid="1253515509432672496">"मलाई"</string>
@@ -502,8 +502,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"ब्याट्री सेभर अन छ"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"प्रदर्शन र पृष्ठभूमि डेटा घटाउँनुहोस्"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ब्याट्री सेभर अफ गर्नुहोस्"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, फोटो, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।"</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"यो कार्य प्रदान गर्ने सेवाले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, फोटो, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, तस्बिर, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।"</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"यो कार्य प्रदान गर्ने सेवाले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, तस्बिर, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।"</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"रेकर्ड गर्न वा cast गर्न थाल्ने हो?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> मार्फत रेकर्ड गर्न वा cast गर्न थाल्ने हो?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"फेरि नदेखाउनुहोस्"</string>
@@ -593,16 +593,16 @@
<string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"असक्षम पार्नुहोस्"</string>
<string name="accessibility_output_chooser" msgid="7807898688967194183">"आउटपुट यन्त्र बदल्नुहोस्"</string>
<string name="screen_pinning_title" msgid="9058007390337841305">"एप पिन गरिएको छ"</string>
- <string name="screen_pinning_description" msgid="8699395373875667743">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न पछाडि र परिदृश्य बटनलाई टच एण्ड होल्ड गर्नुहोस्।"</string>
- <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न पछाडि र गृह नामक बटनहरूलाई टच एण्ड होल्ड गर्नुहोस्।"</string>
+ <string name="screen_pinning_description" msgid="8699395373875667743">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न पछाडि र परिदृश्य बटनलाई छोइराख्नुहोस्।"</string>
+ <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न पछाडि र गृह नामक बटनहरूलाई छोइराख्नुहोस्।"</string>
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"तपाईंले यो एप अनपिन नगरेसम्म यो एप यहाँ देखिइरहने छ। अनपिन गर्न माथितिर स्वाइप गरी होल्ड गर्नुहोस्।"</string>
- <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न परिदृश्य बटनलाई टच एण्ड होल्ड गर्नुहोस्।"</string>
- <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न गृह नामक बटनलाई टच एण्ड होल्ड गर्नुहोस्।"</string>
+ <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न परिदृश्य बटनलाई छोइराख्नुहोस्।"</string>
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न गृह नामक बटनलाई छोइराख्नुहोस्।"</string>
<string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"स्क्रिनमा व्यक्तिगत डेटा (जस्तै सम्पर्क ठेगाना र इमेलको सामग्री) देखिन सक्छ।"</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"पिन गरिएको एपले अन्य एप खोल्न सक्छ।"</string>
- <string name="screen_pinning_toast" msgid="8177286912533744328">"यो एप अनपनि गर्न पछाडि र विवरण नामक बटनहरूलाई टच एण्ड होल्ड गर्नुहोस्"</string>
- <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"यो एप अनपनि गर्न पछाडि र होम बटनलाई टच एण्ड होल्ड गर्नुहोस्"</string>
- <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"यो एप अनपिन गर्न माथितिर स्वाइप गरी स्क्रिनमा टच एण्ड होल्ड गर्नुहोस्"</string>
+ <string name="screen_pinning_toast" msgid="8177286912533744328">"यो एप अनपनि गर्न पछाडि र विवरण नामक बटनहरूलाई छोइराख्नुहोस्"</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"यो एप अनपनि गर्न पछाडि र होम बटनलाई छोइराख्नुहोस्"</string>
+ <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"यो एप अनपिन गर्न माथितिर स्वाइप गरी स्क्रिनमा छोइराख्नुहोस्"</string>
<string name="screen_pinning_positive" msgid="3285785989665266984">"बुझेँ"</string>
<string name="screen_pinning_negative" msgid="6882816864569211666">"धन्यवाद पर्दैन"</string>
<string name="screen_pinning_start" msgid="7483998671383371313">"एप पिन गरियो"</string>
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"फोनको सेटिङका आधारमा घन्टी बज्न वा कम्पन हुन सक्छ"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"फोनको सेटिङका आधारमा घन्टी बज्न वा कम्पन हुन सक्छ। <xliff:g id="APP_NAME">%1$s</xliff:g> का वार्तालापहरू पूर्वनिर्धारित रूपमा बबलमा देखाइन्छन्।"</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"फ्लोटिङ सर्टकटमार्फत यो सामग्रीतर्फ तपाईंको ध्यान आकर्षित गर्दछ।"</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"वार्तालाप खण्डको सिरानमा देखा पर्छ, तैरने बबलका रूपमा देखा पर्छ, लक स्क्रिनमा प्रोफाइल फोटो देखाइन्छ"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"वार्तालाप खण्डको सिरानमा देखा पर्छ, तैरने बबलका रूपमा देखा पर्छ, लक स्क्रिनमा प्रोफाइल तस्बिर देखाइन्छ"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"सेटिङ"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा वार्तालापसम्बन्धी सुविधा प्रयोग गर्न मिल्दैन"</string>
@@ -729,11 +729,11 @@
<string name="see_more_title" msgid="7409317011708185729">"थप हेर्नुहोस्"</string>
<string name="appops_camera" msgid="5215967620896725715">"यो अनुप्रयोगले क्यामेराको प्रयोग गर्दै छ।"</string>
<string name="appops_microphone" msgid="8805468338613070149">"यो अनुप्रयोगले माइक्रोफोनको प्रयोग गर्दै छ।"</string>
- <string name="appops_overlay" msgid="4822261562576558490">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य एपमाथि प्रदर्शन गर्दै छ।"</string>
+ <string name="appops_overlay" msgid="4822261562576558490">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमाथि प्रदर्शन गर्दै छ।"</string>
<string name="appops_camera_mic" msgid="7032239823944420431">"यो अनुप्रयोगले माइक्रोफोन र क्यामेराको प्रयोग गर्दै छ।"</string>
- <string name="appops_camera_overlay" msgid="6466845606058816484">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य एपमाथि प्रदर्शन गर्नुका साथै क्यामेराको प्रयोग गर्दै छ।"</string>
- <string name="appops_mic_overlay" msgid="4609326508944233061">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य एपमाथि प्रदर्शन गर्नुका साथै माइक्रोफोनको प्रयोग गर्दै छ।"</string>
- <string name="appops_camera_mic_overlay" msgid="5584311236445644095">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य एपमाथि प्रदर्शन गर्नुका साथै माइक्रोफोन र क्यामेराको प्रयोग गर्दै छ।"</string>
+ <string name="appops_camera_overlay" msgid="6466845606058816484">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमाथि प्रदर्शन गर्नुका साथै क्यामेराको प्रयोग गर्दै छ।"</string>
+ <string name="appops_mic_overlay" msgid="4609326508944233061">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमाथि प्रदर्शन गर्नुका साथै माइक्रोफोनको प्रयोग गर्दै छ।"</string>
+ <string name="appops_camera_mic_overlay" msgid="5584311236445644095">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमाथि प्रदर्शन गर्नुका साथै माइक्रोफोन र क्यामेराको प्रयोग गर्दै छ।"</string>
<string name="notification_appops_settings" msgid="5208974858340445174">"सेटिङहरू"</string>
<string name="notification_appops_ok" msgid="2177609375872784124">"ठिक छ"</string>
<string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> का सूचना सम्बन्धी नियन्त्रणहरूलाई खोलियो"</string>
@@ -1017,7 +1017,7 @@
<string name="priority_onboarding_title" msgid="2893070698479227616">"वार्तालापको प्राथमिकता निर्धारण गरी \"महत्त्वपूर्ण\" बनाइयो"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"महत्वपूर्ण वार्तालापहरू:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"वार्तालाप खण्डको सिरानमा देखिने छन्"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लक स्क्रिनमा प्रोफाइल फोटो देखाउने छन्"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लक स्क्रिनमा प्रोफाइल तस्बिर देखाउने छन्"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"एपहरूमाथि तैरिने बबलका रूपमा देखाइयोस्"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"बाधा नपुऱ्याउनुहोस् मोडलाई बेवास्ता गरियोस्"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"बुझेँ"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index a65794b..4e30fc5 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -354,7 +354,7 @@
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Invoer"</string>
- <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hoortoestellen"</string>
+ <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Gehoorapparaten"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Inschakelen..."</string>
<string name="quick_settings_brightness_label" msgid="680259653088849563">"Helderheid"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatisch draaien"</string>
@@ -392,7 +392,7 @@
<string name="quick_settings_inversion_label" msgid="5078769633069667698">"Kleuren omkeren"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"Modus voor kleurcorrectie"</string>
<string name="quick_settings_more_settings" msgid="2878235926753776694">"Meer instellingen"</string>
- <string name="quick_settings_done" msgid="2163641301648855793">"Klaar"</string>
+ <string name="quick_settings_done" msgid="2163641301648855793">"Gereed"</string>
<string name="quick_settings_connected" msgid="3873605509184830379">"Verbonden"</string>
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Verbonden, batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="quick_settings_connecting" msgid="2381969772953268809">"Verbinding maken…"</string>
@@ -694,7 +694,7 @@
<string name="notification_channel_silenced" msgid="1995937493874511359">"Deze meldingen worden zonder geluid weergegeven"</string>
<string name="notification_channel_unsilenced" msgid="94878840742161152">"Deze meldingen stellen je op de hoogte"</string>
<string name="inline_blocking_helper" msgid="2891486013649543452">"Meestal sluit je deze meldingen. \nWil je ze blijven weergeven?"</string>
- <string name="inline_done_button" msgid="6043094985588909584">"Klaar"</string>
+ <string name="inline_done_button" msgid="6043094985588909584">"Gereed"</string>
<string name="inline_ok_button" msgid="603075490581280343">"Toepassen"</string>
<string name="inline_keep_showing" msgid="8736001253507073497">"Deze meldingen blijven weergeven?"</string>
<string name="inline_stop_button" msgid="2453460935438696090">"Meldingen stoppen"</string>
@@ -712,11 +712,11 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Standaard"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"Bubbel"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Geen geluid of trilling"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Geen geluid of trilling en wordt lager in het gedeelte met gesprekken weergegeven"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Geen geluid of trilling en wordt op een lagere positie in het gedeelte met gesprekken weergegeven"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Kan overgaan of trillen op basis van de telefooninstellingen"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Kan overgaan of trillen op basis van de telefooninstellingen. Gesprekken uit <xliff:g id="APP_NAME">%1$s</xliff:g> worden standaard als bubbels weergegeven."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Trekt de aandacht met een zwevende snelkoppeling naar deze content."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Wordt bovenaan het gespreksgedeelte weergegeven, verschijnt als zwevende bubbel, geeft profielfoto weer op vergrendelscherm"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Wordt bovenaan het gedeelte met gesprekken weergegeven, verschijnt als zwevende bubbel, geeft de profielfoto weer op het vergrendelscherm"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Instellingen"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ondersteunt geen gespreksfuncties"</string>
@@ -741,7 +741,7 @@
<string name="notification_channel_switch_accessibility" msgid="8979885820432540252">"Meldingen van dit kanaal toestaan"</string>
<string name="notification_more_settings" msgid="4936228656989201793">"Meer instellingen"</string>
<string name="notification_app_settings" msgid="8963648463858039377">"Aanpassen"</string>
- <string name="notification_done" msgid="6215117625922713976">"Klaar"</string>
+ <string name="notification_done" msgid="6215117625922713976">"Gereed"</string>
<string name="inline_undo" msgid="9026953267645116526">"Ongedaan maken"</string>
<string name="demote" msgid="6225813324237153980">"Deze melding markeren als geen gesprek"</string>
<string name="notification_conversation_favorite" msgid="1905240206975921907">"Belangrijk gesprek"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 9527c3f..c35b22a 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -125,7 +125,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"ଆକ୍ସେସିବିଲିଟୀ"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"ସ୍କ୍ରୀନ୍କୁ ଘୁରାନ୍ତୁ"</string>
<string name="accessibility_recent" msgid="901641734769533575">"ଓଭରଭିଉ"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"Search"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"କ୍ୟାମେରା"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ଫୋନ୍"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ଭଏସ୍ ସହାୟକ"</string>
@@ -441,7 +441,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବାକୁ ଆଉ <xliff:g id="CHARGING_TIME">%s</xliff:g> ଅଛି"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"ଚାର୍ଜ ହେଉନାହିଁ"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"ନେଟ୍ୱର୍କ\nମନିଟର୍ କରାଯାଇପାରେ"</string>
- <string name="description_target_search" msgid="3875069993128855865">"Search"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"ସର୍ଚ୍ଚ"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ପାଇଁ ଉପରକୁ ସ୍ଲାଇଡ୍ କରନ୍ତୁ।"</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ପାଇଁ ବାମକୁ ସ୍ଲାଇଡ୍ କରନ୍ତୁ"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"ଆଲାର୍ମ, ରିମାଇଣ୍ଡର୍, ଇଭେଣ୍ଟ ଏବଂ ଆପଣ ନିର୍ଦ୍ଦିଷ୍ଟ କରିଥିବା କଲର୍ଙ୍କ ବ୍ୟତୀତ ଆପଣଙ୍କ ଧ୍ୟାନ ଅନ୍ୟ କୌଣସି ଧ୍ୱନୀ ଏବଂ ଭାଇବ୍ରେଶନ୍ରେ ଆକର୍ଷଣ କରାଯିବନାହିଁ। ମ୍ୟୁଜିକ୍, ଭିଡିଓ ଏବଂ ଗେମ୍ ସମେତ ନିଜେ ଚଲାଇବାକୁ ବାଛିଥିବା ଅନ୍ୟ ସବୁକିଛି ଆପଣ ଶୁଣିପାରିବେ।"</string>
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"ଫୋନ୍ ସେଟିଂସ୍ ଆଧାରରେ ରିଙ୍ଗ କିମ୍ବା ଭାଇବ୍ରେଟ୍ ହୋଇପାରେ"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"ଫୋନ୍ ସେଟିଂସ୍ ଆଧାରରେ ରିଙ୍ଗ କିମ୍ବା ଭାଇବ୍ରେଟ୍ ହୋଇପାରେ। <xliff:g id="APP_NAME">%1$s</xliff:g>ରୁ ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ଡିଫଲ୍ଟ ଭାବରେ ବବଲ୍ ହୁଏ।"</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ଏହି ବିଷୟବସ୍ତୁ ପାଇଁ ଏକ ଭାସମାନ ସର୍ଟକଟ୍ ସହ ଆପଣଙ୍କର ଧ୍ୟାନ ଦିଅନ୍ତୁ।"</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"ବାର୍ତ୍ତାଳାପ ବିଭାଗର ଶୀର୍ଷରେ ଦେଖାଏ, ଫ୍ଲୋଟିଂ ବବଲ୍ ଭାବେ ଦେଖାଯାଏ, ଲକ୍ ସ୍କ୍ରିନରେ ପ୍ରୋଫାଇଲ୍ ଛବି ଡିସପ୍ଲେ କରେ"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"ବାର୍ତ୍ତାଳାପ ବିଭାଗର ଶୀର୍ଷରେ ଦେଖାଏ, ଭାସମାନ ବବଲ୍ ଭାବେ ଦେଖାଯାଏ, ଲକ୍ ସ୍କ୍ରିନରେ ପ୍ରୋଫାଇଲ୍ ଛବି ଡିସପ୍ଲେ କରେ"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ସେଟିଂସ୍"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ପ୍ରାଥମିକତା"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବାର୍ତ୍ତାଳାପ ଫିଚରଗୁଡ଼ିକୁ ସମର୍ଥନ କରେ ନାହିଁ"</string>
@@ -855,7 +855,7 @@
<string name="right_keycode" msgid="2480715509844798438">"ଡାହାଣ କୀ\'କୋଡ୍"</string>
<string name="left_icon" msgid="5036278531966897006">"ବାମ ଆଇକନ୍"</string>
<string name="right_icon" msgid="1103955040645237425">"ଡାହାଣ ଆଇକନ୍"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"ଟାଇଲ୍ ଯୋଗ କରିବା ପାଇଁ ଦାବିଧରି ଟାଣନ୍ତୁ"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"ଟାଇଲ୍ ଯୋଡ଼ିବା ପାଇଁ ଦାବିଧରି ଟାଣନ୍ତୁ"</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"ଟାଇଲ୍ ପୁଣି ସଜାଇବାକୁ ଦାବିଧରି ଟାଣନ୍ତୁ"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ବାହାର କରିବାକୁ ଏଠାକୁ ଡ୍ରାଗ୍ କରନ୍ତୁ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"ଆପଣଙ୍କର ଅତିକମ୍ରେ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>ଟି ଟାଇଲ୍ ଆବଶ୍ୟକ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index badaf47..4449ca7 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -1014,7 +1014,7 @@
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Przenieś w lewy dolny róg"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Przenieś w prawy dolny róg"</string>
<string name="bubble_dismiss_text" msgid="1314082410868930066">"Zamknij dymek"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nie wyświetlaj rozmowy jako dymka"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nie wyświetlaj rozmowy jako dymku"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Czatuj, korzystając z dymków"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Nowe rozmowy będą wyświetlane jako pływające ikony lub dymki. Kliknij, by otworzyć dymek. Przeciągnij, by go przenieść."</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Zarządzaj dymkami w dowolnym momencie"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index aa92135..b0c8e76 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Economia de bateria ativada"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduz o desempenho e os dados em segundo plano"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Desativar a Economia de bateria"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"O app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> terá acesso a todas as informações visíveis na tela ou tocadas no dispositivo, como gravação ou transmissão. Isso inclui informações como senhas, detalhes de pagamento, fotos, mensagens e o áudio que você tocar."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"O app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> terá acesso a todas as informações visíveis na tela ou tocadas no dispositivo, como gravação ou transmissão Isso inclui informações como senhas, detalhes de pagamento, fotos, mensagens e áudio que você toca."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"O serviço que oferece essa função terá acesso a todas as informações visíveis na tela ou reproduzidas durante uma gravação ou transmissão. Isso inclui senhas, detalhes de pagamento, fotos, mensagens e áudio."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Iniciar gravação ou transmissão?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Iniciar gravação ou transmissão com o app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -713,12 +713,12 @@
<string name="notification_bubble_title" msgid="8330481035191903164">"Bolha"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Som e vibração desativados"</string>
<string name="notification_conversation_summary_low" msgid="1734433426085468009">"O som e a vibração estão desativados, e o balão aparece na parte inferior da seção de conversa"</string>
- <string name="notification_channel_summary_default" msgid="3282930979307248890">"Podem vibrar ou tocar com base nas configurações do smartphone"</string>
+ <string name="notification_channel_summary_default" msgid="3282930979307248890">"Pode vibrar ou tocar com base nas configurações do smartphone"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Pode vibrar ou tocar com base nas configurações do smartphone. As conversas do app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem em balões por padrão."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantém sua atenção com um atalho flutuante para esse conteúdo."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Aparecem na parte superior de uma seção de conversa, em forma de balões, mostrando a foto do perfil na tela de bloqueio"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Aparece na parte superior de uma seção de conversa, em forma de balão, mostrando a foto do perfil na tela de bloqueio"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configurações"</string>
- <string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
+ <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
<string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
<string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nenhum balão recente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Os balões recentes e dispensados aparecerão aqui"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 8ea6d45..fcd12c6 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Pode tocar ou vibrar com base nas definições do telemóvel."</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Pode tocar ou vibrar com base nas definições do telemóvel. As conversas da app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem como um balão por predefinição."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantém a sua atenção com um atalho flutuante para este conteúdo."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Aparece no topo da secção de conversas, surge como balão flutuante e apresenta a imagem do perfil no ecrã de bloqueio."</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Aparece na parte superior da secção de conversas, surge como um balão flutuante e apresenta a imagem do perfil no ecrã de bloqueio."</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Definições"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
<string name="no_shortcut" msgid="8257177117568230126">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> não suporta funcionalidades de conversa."</string>
@@ -855,7 +855,7 @@
<string name="right_keycode" msgid="2480715509844798438">"Código de tecla direito"</string>
<string name="left_icon" msgid="5036278531966897006">"Ícone esquerdo"</string>
<string name="right_icon" msgid="1103955040645237425">"Ícone direito"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Tocar sem soltar e arrastar para adicionar mosaicos"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Toque sem soltar e arraste para adicionar mosaicos."</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Tocar sem soltar e arrastar para reorganizar os mosaicos"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastar para aqui para remover"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Necessita de, pelo menos, <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> cartões"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index aa92135..b0c8e76 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Economia de bateria ativada"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Reduz o desempenho e os dados em segundo plano"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Desativar a Economia de bateria"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"O app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> terá acesso a todas as informações visíveis na tela ou tocadas no dispositivo, como gravação ou transmissão. Isso inclui informações como senhas, detalhes de pagamento, fotos, mensagens e o áudio que você tocar."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"O app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> terá acesso a todas as informações visíveis na tela ou tocadas no dispositivo, como gravação ou transmissão Isso inclui informações como senhas, detalhes de pagamento, fotos, mensagens e áudio que você toca."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"O serviço que oferece essa função terá acesso a todas as informações visíveis na tela ou reproduzidas durante uma gravação ou transmissão. Isso inclui senhas, detalhes de pagamento, fotos, mensagens e áudio."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Iniciar gravação ou transmissão?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Iniciar gravação ou transmissão com o app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -713,12 +713,12 @@
<string name="notification_bubble_title" msgid="8330481035191903164">"Bolha"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Som e vibração desativados"</string>
<string name="notification_conversation_summary_low" msgid="1734433426085468009">"O som e a vibração estão desativados, e o balão aparece na parte inferior da seção de conversa"</string>
- <string name="notification_channel_summary_default" msgid="3282930979307248890">"Podem vibrar ou tocar com base nas configurações do smartphone"</string>
+ <string name="notification_channel_summary_default" msgid="3282930979307248890">"Pode vibrar ou tocar com base nas configurações do smartphone"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Pode vibrar ou tocar com base nas configurações do smartphone. As conversas do app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem em balões por padrão."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantém sua atenção com um atalho flutuante para esse conteúdo."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Aparecem na parte superior de uma seção de conversa, em forma de balões, mostrando a foto do perfil na tela de bloqueio"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Aparece na parte superior de uma seção de conversa, em forma de balão, mostrando a foto do perfil na tela de bloqueio"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configurações"</string>
- <string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
+ <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
<string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
<string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nenhum balão recente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Os balões recentes e dispensados aparecerão aqui"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index d2e8886..0a34500 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -722,7 +722,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Звонок или вибрация в зависимости от настроек телефона"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Звонок или вибрация в зависимости от настроек телефона. Разговоры из приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" по умолчанию появляются в виде всплывающего чата."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Привлекает ваше внимание к контенту с помощью плавающего ярлыка"</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Появляется в верхней части списка разговоров и как всплывающий чат, фото профиля показывается на заблок. экране"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Появляется в верхней части списка разговоров и как всплывающий чат, а также показывает фото профиля на заблокированном экране"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Настройки"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" не поддерживает функции разговоров."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index e1f6fc7..2d01f93 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -95,7 +95,7 @@
<string name="screenrecord_description" msgid="1123231719680353736">"Med snemanjem lahko sistem Android zajame morebitne občutljive podatke, ki so prikazani na zaslonu ali se predvajajo v napravi. To vključuje gesla, podatke za plačilo, fotografije, sporočila in zvok."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Snemanje zvoka"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvok v napravi"</string>
- <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvoki v napravi, kot so glasba, klici in toni zvonjenja"</string>
+ <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvok v napravi, kot so glasba, klici in toni zvonjenja"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Zvok v napravi in mikrofon"</string>
<string name="screenrecord_start" msgid="330991441575775004">"Začni"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 1f4b7cd..6a87793 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Marrja e lejeve dështoi"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Gabim gjatë nisjes së regjistrimit të ekranit"</string>
<string name="usb_preference_title" msgid="1439924437558480718">"Opsionet e transferimit të dosjeve të USB-së"</string>
- <string name="use_mtp_button_title" msgid="5036082897886518086">"Lidh si një luajtës të medias (MTP)"</string>
+ <string name="use_mtp_button_title" msgid="5036082897886518086">"Lidh si një lexues \"media\" (MTP)"</string>
<string name="use_ptp_button_title" msgid="7676427598943446826">"Montoje si kamerë (PTP)"</string>
<string name="installer_cd_button_title" msgid="5499998592841984743">"Instalo \"Transferimi i skedarëve të Android\" për Mac"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Prapa"</string>
@@ -248,7 +248,7 @@
<string name="accessibility_remove_notification" msgid="1641455251495815527">"Pastro njoftimin."</string>
<string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS-ja është e aktivizuar."</string>
<string name="accessibility_gps_acquiring" msgid="896207402196024040">"Po siguron GPS-në."</string>
- <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletajpi është i aktivizuar."</string>
+ <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teleprinteri është i aktivizuar."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Zile me dridhje."</string>
<string name="accessibility_ringer_silent" msgid="8994620163934249882">"Zilja është heshtur."</string>
<!-- no translation found for accessibility_casting (8708751252897282313) -->
@@ -482,7 +482,7 @@
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Mirë se erdhe, i ftuar!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string>
- <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Po, vazhdo"</string>
+ <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Po, vazhdo!"</string>
<string name="guest_notification_title" msgid="4434456703930764167">"Përdorues vizitor"</string>
<string name="guest_notification_text" msgid="4202692942089571351">"Për të fshirë aplikacionet dhe të dhënat, hiqe përdoruesin vizitor"</string>
<string name="guest_notification_remove_action" msgid="4153019027696868099">"HIQ VIZITORIN"</string>
@@ -502,8 +502,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"\"Kursyesi i baterisë\" është i aktivizuar"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Pakëson veprimtarinë dhe të dhënat në sfond"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Çaktivizo \"Kursyesin e baterisë\""</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> do të ketë qasje te të gjitha informacionet që janë të dukshme në ekran ose që luhen nga pajisja jote gjatë regjistrimit ose transmetimit. Kjo përfshin informacione, si p.sh.: fjalëkalimet, detajet e pagesave, fotografitë, mesazhet dhe audion që luan ti."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Shërbimi që e ofron këtë funksion do të ketë qasje te të gjitha informacionet që janë të dukshme në ekran ose që luhen nga pajisja jote gjatë regjistrimit ose transmetimit. Kjo përfshin informacione, si p.sh.: fjalëkalimet, detajet e pagesave, fotografitë, mesazhet dhe audion që luan ti."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> do të ketë qasje te të gjitha informacionet që janë të dukshme në ekran ose që luhen nga pajisja jote gjatë regjistrimit ose transmetimit. Kjo përfshin informacione si p.sh. fjalëkalimet, detajet e pagesave, fotografitë, mesazhet dhe audion që luan ti."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Shërbimi që e ofron këtë funksion do të ketë qasje te të gjitha informacionet që janë të dukshme në ekran ose që luhen nga pajisja jote gjatë regjistrimit ose transmetimit. Kjo përfshin informacione si p.sh. fjalëkalimet, detajet e pagesave, fotografitë, mesazhet dhe audion që luan ti."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Do të fillosh regjistrimin ose transmetimin?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Fillo regjistrimin ose transmetimin me <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Mos e shfaq sërish"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 61a2303..7091fe9 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -38,7 +38,7 @@
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Укључи"</string>
<string name="battery_saver_start_action" msgid="4553256017945469937">"Укључи Уштеду батерије"</string>
<string name="status_bar_settings_settings_button" msgid="534331565185171556">"Подешавања"</string>
- <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"WiFi"</string>
+ <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аутоматско ротирање екрана"</string>
<string name="status_bar_settings_mute_label" msgid="914392730086057522">"УГАСИ"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="2151934479226017725">"АУТОM."</string>
@@ -226,7 +226,7 @@
<string name="data_connection_cdma" msgid="7678457855627313518">"1X"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Роминг"</string>
<string name="data_connection_edge" msgid="6316755666481405762">"EDGE"</string>
- <string name="accessibility_data_connection_wifi" msgid="4422160347472742434">"WiFi"</string>
+ <string name="accessibility_data_connection_wifi" msgid="4422160347472742434">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="1140839832913084973">"Нема SIM картице."</string>
<string name="accessibility_cell_data" msgid="172950885786007392">"Мобилни подаци"</string>
<string name="accessibility_cell_data_on" msgid="691666434519443162">"Мобилни подаци су укључени"</string>
@@ -265,8 +265,8 @@
<string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Закључан екран за посао"</string>
<string name="accessibility_desc_close" msgid="8293708213442107755">"Затвори"</string>
<string name="accessibility_quick_settings_wifi" msgid="167707325133803052">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
- <string name="accessibility_quick_settings_wifi_changed_off" msgid="2230487165558877262">"WiFi је искључен."</string>
- <string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"WiFi је укључен."</string>
+ <string name="accessibility_quick_settings_wifi_changed_off" msgid="2230487165558877262">"Wi-Fi је искључен."</string>
+ <string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"Wi-Fi је укључен."</string>
<string name="accessibility_quick_settings_mobile" msgid="1817825313718492906">"Мобилна мрежа: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="533594896310663853">"Батерија: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"Режим рада у авиону је искључен."</string>
@@ -375,19 +375,19 @@
<string name="quick_settings_user_label" msgid="1253515509432672496">"Ја"</string>
<string name="quick_settings_user_title" msgid="8673045967216204537">"Корисник"</string>
<string name="quick_settings_user_new_user" msgid="3347905871336069666">"Нови корисник"</string>
- <string name="quick_settings_wifi_label" msgid="2879507532983487244">"WiFi"</string>
+ <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
<string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Веза није успостављена"</string>
<string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"Нема мреже"</string>
- <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"WiFi је искључен"</string>
- <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"WiFi је укључен"</string>
- <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Није доступна ниједна WiFi мрежа"</string>
+ <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"Wi-Fi је искључен"</string>
+ <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi је укључен"</string>
+ <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Није доступна ниједна Wi-Fi мрежа"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Укључује се..."</string>
<string name="quick_settings_cast_title" msgid="2279220930629235211">"Пребацивање екрана"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"Пребацивање"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Неименовани уређај"</string>
<string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"Спремно за пребацивање"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Није доступан ниједан уређај"</string>
- <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"WiFi није повезан"</string>
+ <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Wi-Fi није повезан"</string>
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Осветљеност"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"АУТОМАТСКА"</string>
<string name="quick_settings_inversion_label" msgid="5078769633069667698">"Обрни боје"</string>
@@ -643,8 +643,8 @@
<string name="output_none_found" msgid="5488087293120982770">"Није пронађен ниједан уређај"</string>
<string name="output_none_found_service_off" msgid="935667567681386368">"Није пронађен ниједан уређај. Пробајте да укључите услугу <xliff:g id="SERVICE">%1$s</xliff:g>"</string>
<string name="output_service_bt" msgid="4315362133973911687">"Bluetooth"</string>
- <string name="output_service_wifi" msgid="9003667810868222134">"WiFi"</string>
- <string name="output_service_bt_wifi" msgid="7186882540475524124">"Bluetooth и WiFi"</string>
+ <string name="output_service_wifi" msgid="9003667810868222134">"Wi-Fi"</string>
+ <string name="output_service_bt_wifi" msgid="7186882540475524124">"Bluetooth и Wi-Fi"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"Тјунер за кориснички интерфејс система"</string>
<string name="show_battery_percentage" msgid="6235377891802910455">"Приказуј уграђени проценат батерије"</string>
<string name="show_battery_percentage_summary" msgid="9053024758304102915">"Приказивање нивоа напуњености батерије у процентима унутар иконе на статусној траци када се батерија не пуни"</string>
@@ -964,7 +964,7 @@
<string name="mobile_data" msgid="4564407557775397216">"Мобилни подаци"</string>
<string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
- <string name="wifi_is_off" msgid="5389597396308001471">"WiFi је искључен"</string>
+ <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi је искључен"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth је искључен"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Режим Не узнемиравај је искључен"</string>
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Аутоматско правило (<xliff:g id="ID_1">%s</xliff:g>) је укључило режим Не узнемиравај."</string>
@@ -976,7 +976,7 @@
<string name="running_foreground_services_title" msgid="5137313173431186685">"Апликације покренуте у позадини"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Додирните за детаље о батерији и потрошњи података"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Желите да искључите мобилне податке?"</string>
- <string name="mobile_data_disable_message" msgid="8604966027899770415">"Нећете имати приступ подацима или интернету преко мобилног оператера <xliff:g id="CARRIER">%s</xliff:g>. Интернет ће бити доступан само преко WiFi везе."</string>
+ <string name="mobile_data_disable_message" msgid="8604966027899770415">"Нећете имати приступ подацима или интернету преко мобилног оператера <xliff:g id="CARRIER">%s</xliff:g>. Интернет ће бити доступан само преко Wi-Fi везе."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"мобилни оператер"</string>
<string name="touch_filtered_warning" msgid="8119511393338714836">"Подешавања не могу да верификују ваш одговор јер апликација скрива захтев за дозволу."</string>
<string name="slice_permission_title" msgid="3262615140094151017">"Желите ли да дозволите апликацији <xliff:g id="APP_0">%1$s</xliff:g> да приказује исечке из апликације <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index f972a68..addc1b4 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -125,7 +125,7 @@
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"యాక్సెస్ సామర్థ్యం"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"స్క్రీన్ను తిప్పండి"</string>
<string name="accessibility_recent" msgid="901641734769533575">"ఓవర్వ్యూ"</string>
- <string name="accessibility_search_light" msgid="524741790416076988">"సెర్చ్"</string>
+ <string name="accessibility_search_light" msgid="524741790416076988">"వెతుకు"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"కెమెరా"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ఫోన్"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"వాయిస్ అసిస్టెంట్"</string>
@@ -441,7 +441,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"పూర్తిగా నిండటానికి <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
<string name="expanded_header_battery_not_charging" msgid="809409140358955848">"ఛార్జ్ కావడం లేదు"</string>
<string name="ssl_ca_cert_warning" msgid="8373011375250324005">"నెట్వర్క్\nపర్యవేక్షించబడవచ్చు"</string>
- <string name="description_target_search" msgid="3875069993128855865">"సెర్చ్"</string>
+ <string name="description_target_search" msgid="3875069993128855865">"శోధించండి"</string>
<string name="description_direction_up" msgid="3632251507574121434">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> కోసం పైకి స్లైడ్ చేయండి."</string>
<string name="description_direction_left" msgid="4762708739096907741">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> కోసం ఎడమవైపుకు స్లైడ్ చేయండి."</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"మీరు పేర్కొనే అలారాలు, రిమైండర్లు, ఈవెంట్లు మరియు కాలర్ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు."</string>
@@ -695,7 +695,7 @@
<string name="notification_channel_unsilenced" msgid="94878840742161152">"ఈ నోటిఫికేషన్లు మిమ్మల్ని హెచ్చరిస్తాయి"</string>
<string name="inline_blocking_helper" msgid="2891486013649543452">"మీరు సాధారణంగా ఈ నోటిఫికేషన్లను విస్మరిస్తారు. \nవాటి ప్రదర్శనను కొనసాగించాలా?"</string>
<string name="inline_done_button" msgid="6043094985588909584">"పూర్తయింది"</string>
- <string name="inline_ok_button" msgid="603075490581280343">"అప్లయి చేయి"</string>
+ <string name="inline_ok_button" msgid="603075490581280343">"అప్లై చేయి"</string>
<string name="inline_keep_showing" msgid="8736001253507073497">"ఈ నోటిఫికేషన్లను చూపిస్తూ ఉండాలా?"</string>
<string name="inline_stop_button" msgid="2453460935438696090">"నోటిఫికేషన్లను ఆపివేయి"</string>
<string name="inline_deliver_silently_button" msgid="2714314213321223286">"నిశ్శబ్దంగా బట్వాడా చేయండి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index a1c740e..71679be 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -92,7 +92,7 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"กำลังประมวลผลการอัดหน้าจอ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการบันทึกหน้าจอ"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"เริ่มบันทึกเลยไหม"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"ขณะบันทึก ระบบ Android อาจบันทึกข้อมูลที่ละเอียดอ่อนซึ่งปรากฏบนหน้าจอหรือเล่นในอุปกรณ์ได้ ซึ่งรวมถึงรหัสผ่าน ข้อมูลการชำระเงิน รูปภาพ ข้อความ และเสียง"</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"ขณะบันทึก ระบบ Android อาจบันทึกข้อมูลที่ละเอียดอ่อนที่ปรากฏบนหน้าจอหรือเล่นในอุปกรณ์ได้ ซึ่งรวมถึงรหัสผ่าน ข้อมูลการชำระเงิน รูปภาพ ข้อความ และเสียง"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"บันทึกเสียง"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"เสียงจากอุปกรณ์"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"เสียงจากอุปกรณ์ เช่น เพลง การโทร และเสียงเรียกเข้า"</string>
@@ -339,7 +339,7 @@
<string name="accessibility_rotation_lock_on_landscape_changed" msgid="5785739044300729592">"ขณะนี้หน้าจอล็อกอยู่ในแนวนอน"</string>
<string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"ขณะนี้หน้าจอล็อกอยู่ในแนวตั้ง"</string>
<string name="dessert_case" msgid="9104973640704357717">"ชั้นแสดงของหวาน"</string>
- <string name="start_dreams" msgid="9131802557946276718">"โปรแกรมรักษาจอภาพ"</string>
+ <string name="start_dreams" msgid="9131802557946276718">"โปรแกรมรักษาหน้าจอ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"อีเทอร์เน็ต"</string>
<string name="quick_settings_header_onboarding_text" msgid="1918085351115504765">"แตะไอคอนค้างไว้เพื่อดูตัวเลือกอื่นๆ"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"ห้ามรบกวน"</string>
@@ -511,7 +511,7 @@
<string name="manage_notifications_text" msgid="6885645344647733116">"จัดการ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ประวัติ"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"ใหม่"</string>
- <string name="notification_section_header_gentle" msgid="6804099527336337197">"ปิดเสียง"</string>
+ <string name="notification_section_header_gentle" msgid="6804099527336337197">"เงียบ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"การแจ้งเตือน"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"การสนทนา"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ล้างการแจ้งเตือนแบบไม่มีเสียงทั้งหมด"</string>
@@ -708,7 +708,7 @@
<string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"แจ้งเตือนต่อไป"</string>
<string name="inline_turn_off_notifications" msgid="8543989584403106071">"ปิดการแจ้งเตือน"</string>
<string name="inline_keep_showing_app" msgid="4393429060390649757">"แสดงการแจ้งเตือนจากแอปนี้ต่อไปไหม"</string>
- <string name="notification_silence_title" msgid="8608090968400832335">"ปิดเสียง"</string>
+ <string name="notification_silence_title" msgid="8608090968400832335">"เงียบ"</string>
<string name="notification_alert_title" msgid="3656229781017543655">"ค่าเริ่มต้น"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"บับเบิล"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"ไม่มีเสียงหรือการสั่น"</string>
@@ -856,7 +856,7 @@
<string name="left_icon" msgid="5036278531966897006">"ไอคอนทางซ้าย"</string>
<string name="right_icon" msgid="1103955040645237425">"ไอคอนทางขวา"</string>
<string name="drag_to_add_tiles" msgid="8933270127508303672">"กดค้างแล้วลากเพื่อเพิ่มการ์ด"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"กดค้างแล้วลากเพื่อจัดเรียงการ์ดใหม่"</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"กดการ์ดค้างไว้แล้วลากเพื่อจัดเรียงใหม่"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ลากมาที่นี่เพื่อนำออก"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"คุณต้องมีการ์ดอย่างน้อย <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> รายการ"</string>
<string name="qs_edit" msgid="5583565172803472437">"แก้ไข"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 18891da..4e3c42b 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -227,7 +227,7 @@
<string name="data_connection_roaming" msgid="375650836665414797">"Rouming"</string>
<string name="data_connection_edge" msgid="6316755666481405762">"EDGE"</string>
<string name="accessibility_data_connection_wifi" msgid="4422160347472742434">"Wi-Fi"</string>
- <string name="accessibility_no_sim" msgid="1140839832913084973">"SIM kartasiz."</string>
+ <string name="accessibility_no_sim" msgid="1140839832913084973">"SIM karta solinmagan."</string>
<string name="accessibility_cell_data" msgid="172950885786007392">"Mobil internet"</string>
<string name="accessibility_cell_data_on" msgid="691666434519443162">"Mobil internet yoniq"</string>
<string name="cell_data_off_content_description" msgid="9165555931499878044">"Mobil internet yoqilmagan"</string>
@@ -362,7 +362,7 @@
<string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"<xliff:g id="ID_1">%s</xliff:g> rejimi"</string>
<string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"Aylanmaydigan qilingan"</string>
<string name="quick_settings_rotation_locked_portrait_label" msgid="1194988975270484482">"Tik holat"</string>
- <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"Yotiq"</string>
+ <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"Eniga"</string>
<string name="quick_settings_ime_label" msgid="3351174938144332051">"Kiritish usuli"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Joylashuv"</string>
<string name="quick_settings_location_off_label" msgid="7923929131443915919">"Joylashuvni aniqlash xizmati yoqilmagan"</string>
@@ -505,7 +505,7 @@
<string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ekranda chiqqan yoki yozib olish va translatsiya vaqtida ijro etilgan barcha axborotlarga ruxsat oladi. Bu axborotlar parollar, toʻlov tafsilotlari, rasmlar, xabarlar va ijro etilgan audiolardan iborat boʻlishi mumkin."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Bu funksiyani taʼminlovchi xizmat ekranda chiqqan yoki yozib olish va translatsiya vaqtida ijro etilgan barcha axborotlarga ruxsat oladi. Bu axborotlar parollar, toʻlov tafsilotlari, rasmlar, xabarlar va ijro etilgan audiolardan iborat boʻlishi mumkin."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Yozib olish yoki translatsiya boshlansinmi?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> orqali yozib olish yoki translatsiya boshlansinmi?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> bilan yozib olinsin yoki translatsiya qilinsinmi?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Boshqa ko‘rsatilmasin"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Hammasini tozalash"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Boshqarish"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 768bf98..13fad5a 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -502,8 +502,8 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"Trình tiết kiệm pin đang bật"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Giảm hiệu suất và dữ liệu nền"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Tắt trình tiết kiệm pin"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ có quyền truy cập vào tất cả các thông tin hiển thị trên màn hình của bạn hoặc phát trên thiết bị của bạn trong khi ghi âm/ghi hình hoặc truyền, bao gồm cả thông tin như mật khẩu, chi tiết thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Dịch vụ cung cấp chức năng này có quyền truy cập vào tất cả các thông tin hiển thị trên màn hình của bạn hoặc phát trên thiết bị của bạn trong khi ghi âm/ghi hình hoặc truyền, bao gồm cả thông tin như mật khẩu, chi tiết thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ có quyền truy cập vào tất cả các thông tin hiển thị trên màn hình của bạn hoặc phát từ thiết bị trong khi ghi âm/ghi hình hoặc truyền, bao gồm cả thông tin như mật khẩu, chi tiết thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Dịch vụ cung cấp chức năng này có quyền truy cập vào tất cả các thông tin hiển thị trên màn hình của bạn hoặc phát từ thiết bị trong khi ghi âm/ghi hình hoặc truyền, bao gồm cả thông tin như mật khẩu, chi tiết thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Bắt đầu ghi âm/ghi hình hoặc truyền?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Bắt đầu ghi âm/ghi hình hoặc truyền bằng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_remember_text" msgid="6896767327140422951">"Không hiển thị lại"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index e1d398d..dc59e78 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"可能會根據手機設定發出鈴聲或震動"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"可能會根據手機設定發出鈴聲或震動。「<xliff:g id="APP_NAME">%1$s</xliff:g>」的對話會預設以對話氣泡顯示。"</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"為此內容建立浮動捷徑以保持注意力。"</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"以浮動對話泡顯示在對話部分的頂部,並在上鎖畫面顯示個人檔案相片"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"在對話部分的頂部以浮動對話氣泡顯示,並在上鎖畫面顯示個人檔案相片"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"設定"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"重要"</string>
<string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
@@ -987,7 +987,7 @@
<string name="auto_saver_enabled_text" msgid="7889491183116752719">"省電模式將會在電量低於 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 時自動開啟。"</string>
<string name="open_saver_setting_action" msgid="2111461909782935190">"設定"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"知道了"</string>
- <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="heap_dump_tile_name" msgid="2464189856478823046">"轉儲 SysUI 堆"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"感應器已關閉"</string>
<string name="device_services" msgid="1549944177856658705">"裝置服務"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 7ecb7d2..79300ee 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -502,7 +502,7 @@
<string name="battery_saver_notification_title" msgid="8419266546034372562">"省電模式已開啟"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"降低效能並限制背景數據傳輸"</string>
<string name="battery_saver_notification_action_text" msgid="6022091913807026887">"關閉省電模式"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"在錄製或投放內容時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>可存取畫面上顯示的任何資訊或裝置播放的任何內容,包括密碼、付款詳情、相片、訊息和你播放的音訊。"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"在錄製或投放內容時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可存取畫面上顯示的任何資訊或裝置播放的任何內容,包括密碼、付款詳情、相片、訊息和你播放的音訊。"</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"在錄製或投放內容時,提供這項功能的服務可存取畫面上顯示的任何資訊或裝置播放的任何內容,包括密碼、付款詳情、相片、訊息和你播放的音訊。"</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"要開始錄製或投放內容嗎?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"要使用「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」開始錄製或投放內容嗎?"</string>
@@ -712,7 +712,7 @@
<string name="notification_alert_title" msgid="3656229781017543655">"預設"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"泡泡"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"不震動或發出聲音"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"不震動或發出聲音,並調整排序到其他對話下方"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"不震動或發出聲音,並顯示在對話部分的下方"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"根據手機的設定響鈴或震動"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"可能會根據手機的設定響鈴或震動。根據預設,來自「<xliff:g id="APP_NAME">%1$s</xliff:g>」的對話會以對話框形式顯示。"</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"利用浮動式捷徑快速存取這項內容。"</string>
@@ -987,7 +987,7 @@
<string name="auto_saver_enabled_text" msgid="7889491183116752719">"省電模式會在電量低於 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 時自動開啟。"</string>
<string name="open_saver_setting_action" msgid="2111461909782935190">"設定"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"我知道了"</string>
- <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="heap_dump_tile_name" msgid="2464189856478823046">"傾印 SysUI 記憶體快照"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"已關閉感應器"</string>
<string name="device_services" msgid="1549944177856658705">"裝置服務"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string>
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
deleted file mode 100644
index 12daa61..0000000
--- a/packages/Tethering/Android.bp
+++ /dev/null
@@ -1,134 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-java_defaults {
- name: "TetheringAndroidLibraryDefaults",
- sdk_version: "module_current",
- srcs: [
- "src/**/*.java",
- ":framework-tethering-shared-srcs",
- ":tethering-module-utils-srcs",
- ":services-tethering-shared-srcs",
- ],
- static_libs: [
- "androidx.annotation_annotation",
- "netd_aidl_interface-java",
- "netlink-client",
- "networkstack-aidl-interfaces-java",
- "android.hardware.tetheroffload.config-V1.0-java",
- "android.hardware.tetheroffload.control-V1.0-java",
- "net-utils-framework-common",
- ],
- libs: [
- "framework-statsd.stubs.module_lib",
- "framework-tethering.impl",
- "framework-wifi",
- "unsupportedappusage",
- ],
- plugins: ["java_api_finder"],
- manifest: "AndroidManifestBase.xml",
-}
-
-// Build tethering static library, used to compile both variants of the tethering.
-android_library {
- name: "TetheringApiCurrentLib",
- defaults: ["TetheringAndroidLibraryDefaults"],
-}
-
-// Due to b/143733063, APK can't access a jni lib that is in APEX (but not in the APK).
-cc_library {
- name: "libtetherutilsjni",
- sdk_version: "current",
- apex_available: [
- "//apex_available:platform", // Used by InProcessTethering
- "com.android.tethering",
- ],
- min_sdk_version: "current",
- srcs: [
- "jni/android_net_util_TetheringUtils.cpp",
- ],
- shared_libs: [
- "liblog",
- "libnativehelper_compat_libc++",
- ],
-
- // We cannot use plain "libc++" here to link libc++ dynamically because it results in:
- // java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
- // even if "libc++" is added into jni_libs below. Adding "libc++_shared" into jni_libs doesn't
- // build because soong complains of:
- // module Tethering missing dependencies: libc++_shared
- //
- // So, link libc++ statically. This means that we also need to ensure that all the C++ libraries
- // we depend on do not dynamically link libc++. This is currently the case, because liblog is
- // C-only and libnativehelper_compat_libc also uses stl: "c++_static".
- stl: "c++_static",
-
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- "-Wthread-safety",
- ],
-
- ldflags: ["-Wl,--exclude-libs=ALL,-error-limit=0"],
-}
-
-// Common defaults for compiling the actual APK.
-java_defaults {
- name: "TetheringAppDefaults",
- sdk_version: "module_current",
- privileged: true,
- jni_libs: [
- "libtetherutilsjni",
- ],
- resource_dirs: [
- "res",
- ],
- libs: [
- "framework-tethering",
- ],
- jarjar_rules: "jarjar-rules.txt",
- optimize: {
- proguard_flags_files: ["proguard.flags"],
- },
-}
-
-// Non-updatable tethering running in the system server process for devices not using the module
-android_app {
- name: "InProcessTethering",
- defaults: ["TetheringAppDefaults"],
- static_libs: ["TetheringApiCurrentLib"],
- certificate: "platform",
- manifest: "AndroidManifest_InProcess.xml",
- // InProcessTethering is a replacement for Tethering
- overrides: ["Tethering"],
- apex_available: ["com.android.tethering"],
- min_sdk_version: "current",
-}
-
-// Updatable tethering packaged as an application
-android_app {
- name: "Tethering",
- defaults: ["TetheringAppDefaults"],
- static_libs: ["TetheringApiCurrentLib"],
- certificate: "networkstack",
- manifest: "AndroidManifest.xml",
- use_embedded_native_libs: true,
- // The permission configuration *must* be included to ensure security of the device
- required: ["NetworkPermissionConfig"],
- apex_available: ["com.android.tethering"],
- min_sdk_version: "current",
-}
diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml
deleted file mode 100644
index 2b2fe45..0000000
--- a/packages/Tethering/AndroidManifest.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * 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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.networkstack.tethering"
- android:sharedUserId="android.uid.networkstack">
- <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
-
- <!-- Permissions must be defined here, and not in the base manifest, as the tethering
- running in the system server process does not need any permission, and having
- privileged permissions added would cause crashes on startup unless they are also
- added to the privileged permissions whitelist for that package. -->
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
- <uses-permission android:name="android.permission.BROADCAST_STICKY" />
- <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
- <uses-permission android:name="android.permission.MANAGE_USB" />
- <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
- <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
- <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
- <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <uses-permission android:name="android.permission.TETHER_PRIVILEGED" />
- <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
- <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-
- <protected-broadcast android:name="com.android.server.connectivity.tethering.DISABLE_TETHERING" />
-
- <application
- android:process="com.android.networkstack.process"
- android:extractNativeLibs="false"
- android:persistent="true">
- <service android:name="com.android.networkstack.tethering.TetheringService"
- android:permission="android.permission.MAINLINE_NETWORK_STACK"
- android:exported="true">
- <intent-filter>
- <action android:name="android.net.ITetheringConnector"/>
- </intent-filter>
- </service>
- </application>
-</manifest>
diff --git a/packages/Tethering/AndroidManifestBase.xml b/packages/Tethering/AndroidManifestBase.xml
deleted file mode 100644
index fa85f66..0000000
--- a/packages/Tethering/AndroidManifestBase.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * 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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.networkstack.tethering"
- android:versionCode="1"
- android:versionName="R-initial">
- <application
- android:label="Tethering"
- android:defaultToDeviceProtectedStorage="true"
- android:directBootAware="true">
- </application>
-</manifest>
diff --git a/packages/Tethering/AndroidManifest_InProcess.xml b/packages/Tethering/AndroidManifest_InProcess.xml
deleted file mode 100644
index b1f1240..0000000
--- a/packages/Tethering/AndroidManifest_InProcess.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * 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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.networkstack.tethering.inprocess"
- android:sharedUserId="android.uid.system"
- android:process="system">
- <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
- <application>
- <service android:name="com.android.networkstack.tethering.TetheringService"
- android:process="system"
- android:permission="android.permission.MAINLINE_NETWORK_STACK"
- android:exported="true">
- <intent-filter>
- <action android:name="android.net.ITetheringConnector.InProcess"/>
- </intent-filter>
- </service>
- </application>
-</manifest>
diff --git a/packages/Tethering/OWNERS b/packages/Tethering/OWNERS
deleted file mode 100644
index 5b42d49..0000000
--- a/packages/Tethering/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-include platform/packages/modules/NetworkStack/:/OWNERS
-markchien@google.com
diff --git a/packages/Tethering/TEST_MAPPING b/packages/Tethering/TEST_MAPPING
deleted file mode 100644
index 5617b0c..0000000
--- a/packages/Tethering/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "presubmit": [
- {
- "name": "TetheringTests"
- }
- ],
- "postsubmit": [
- {
- "name": "TetheringIntegrationTests"
- }
- ]
-}
diff --git a/packages/Tethering/apex/Android.bp b/packages/Tethering/apex/Android.bp
deleted file mode 100644
index 67097a7..0000000
--- a/packages/Tethering/apex/Android.bp
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-apex {
- name: "com.android.tethering",
- updatable: true,
- min_sdk_version: "current",
- java_libs: ["framework-tethering"],
- apps: ["Tethering"],
- manifest: "manifest.json",
- key: "com.android.tethering.key",
-
- androidManifest: "AndroidManifest.xml",
-}
-
-apex_key {
- name: "com.android.tethering.key",
- public_key: "com.android.tethering.avbpubkey",
- private_key: "com.android.tethering.pem",
-}
-
-android_app_certificate {
- name: "com.android.tethering.certificate",
- certificate: "com.android.tethering",
-}
-
-override_apex {
- name: "com.android.tethering.inprocess",
- base: "com.android.tethering",
- package_name: "com.android.tethering.inprocess",
- apps: [
- "InProcessTethering",
- ],
-}
diff --git a/packages/Tethering/apex/AndroidManifest.xml b/packages/Tethering/apex/AndroidManifest.xml
deleted file mode 100644
index 4aae3cc..0000000
--- a/packages/Tethering/apex/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.tethering">
- <!-- APEX does not have classes.dex -->
- <application android:hasCode="false" />
- <!-- b/145383354: Current minSdk is locked to Q for development cycle, lock it to next version
- before ship. -->
- <!-- TODO: Uncomment this when the R API level is fixed. b/148281152 -->
- <!--uses-sdk
- android:minSdkVersion="29"
- android:targetSdkVersion="29"
- />
- -->
-</manifest>
diff --git a/packages/Tethering/apex/com.android.tethering.avbpubkey b/packages/Tethering/apex/com.android.tethering.avbpubkey
deleted file mode 100644
index 9a2c017..0000000
--- a/packages/Tethering/apex/com.android.tethering.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/apex/com.android.tethering.pem b/packages/Tethering/apex/com.android.tethering.pem
deleted file mode 100644
index d4f39ab..0000000
--- a/packages/Tethering/apex/com.android.tethering.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKgIBAAKCAgEA+AWTp03PBRMGt4mVNLt5PDoFFSfmFOVTM7jt5AJXnQMIDsAM
-1cyWGWRridGIpoHAaCALVgW5aRySgi8yV5xP4w0YHcKbfh9M6I9oz4RUo4GQBZfX
-+lFIGaLjb6I3tEJxPuxps4sW26Io63ihwTnKeGyADHdHGWDUs9WU0Ml+QTvKrdjy
-qC03M0dehYXILGiA9m+UXwKoKxhWgfDUhWLhDBUtLJLPL4WeqKc9sG9h+zzVqE+8
-LzJsfrodKhTTrLpWOXi6YLRTk8dzsuPz/Nu98sJd1w3fHd20DrmkqsxVhgN1h+nk
-zcPpxyGYIP6qYVZCmIXCwZZNtPeb7y/tOs967VHoZ4Qj7p2tE0CAWFMZFGjA/pcZ
-7fi6CsIuMOYBbj4+wRlJwpG1g5zSJBCjzhv7dZp8S5oXmLShNYOMYEdsPfaZbm08
-3pVY+k8DVf7idcANXNw1lM+sPbE2hp5VuEuVpK+ca5x8hIMpTqJ84wDAjnC1kCwm
-X2xfNvYPKNF58SvqlNCPN8X7hQjoeaEb7w24vCdZMRqeGBmu1GNQvCyzbBO0huQm
-f5CQPrZjPcnoImlP879VPxY4YB6tAjsA/ZLiub9VdT108lCjb5r8criMzpMAA/AQ
-NqQLWFI3M43xPemGBTiIguTYgpRgGcdRZf7XuTgTY5qzQZZuZMVuwaqSD2cCAwEA
-AQKCAgEA0jMvw3BPTrakT7Lb8JgelKt7mUV6WyVMUZ6eh0pw5JIoJxAfEKfWYmjY
-NzKNRMjcv6LA2MP7MplTld/YI6ZHkl+Lm9VOISL39HVuV8mIThbFb+gT1INEvu1t
-IjRyT2SsQ67rmo377mLNmVtgg7mt3kfecjI44MpPGqad/CF4zmKVUKd4aI4BpYUM
-F8+dKf3bpoBEWA2RZwy2bGQmSXHW132vDoLR8y2knL04rCqJ+PrC/WWuULXEe9bS
-VtLV3yMBZq3qD4Fk/+7fILLPGvNFVdPi4htQiChYrM4rP9HzfaO63VieYMF0hR70
-pqoOznXj9Q4QVC9FZmUgFCQjQ1+KhqJw3OldIo0SnvpsLdTO/inKkhQWKC5HlPyh
-/rqvro2j3pTHWPAziuBr+oQPcdVCOlCBZ+B99L1tO7aGktVPEIVQG7G7jlFMBiJ1
-j/kRGk2RTX8RaPQJTnwUqp8mWUV2fwxHiXNadjejA5ZU3eQT2eAOhXl1w6Lv2jEl
-0wMOwPMJGcF77CcqnnWHON8fkxCbAfyy5Uo6Pm9g/Zzecn+ji2sabG7Ge5t0gzdL
-LKRcGoyakN2CrbQ8pxlCTgE4HX5oPY+VuqOf8L3AIWIJBsyLbXHVkL1mqQ/Ed2uz
-zaaSFYUZw81+m/5bl8JLPaIFNPyikZrXTD0YRer3V06XiyP/kYECggEBAP033xeF
-OhgRwkRTjd68hwRJpyHsZDWxHiUqQf6l6yFv5mEE355G2IGI7cZmR2+tUDjQdxLv
-tAZIszTK4PFCdVTeWfGVFbVF84eNWLB124pHDMM79GN/AMcuHnQPR756a8IO1hIy
-4KxIUE1a1PKN5b9IgE5Lu4TZM96HDpFcUAmCT5urdYDmg3++IWT9PYQlGS7Hhiar
-r+Hh646waM8Qx619CwXBqy+Y37+WHVbYqJClr6AcpVMrGA+6cgpskFpZAPLsoy7G
-RSsVfyV8pH2JKm/hzk7XCwIpczxeWQSfpJWZ+oOPFHu+zM60Cdj2UrQyKrNHwew8
-+WYe9eCA+MiNBcECggEBAPq/F1vdqROiLv9uzhKb8ybgdL7CmREELiqwK+MvNE9t
-W7lQz7lcWzav+b2n0M+VJBxUWB3XClgoIvA/AllgTgsYXfKAxNakhKLSBoMmvKCW
-HtWcGr/D3RcmacK+DTMWlVS/LuueAFLuH6UmBIUFKc+qA5x7oQecAFALBFupE3G4
-LtAspLBI6P8gRtRav5p2whs9H8qjYcyf2f6liWpkmFITcXvPvAxFHicR6ZJdwZ/S
-PiX2LJQnOpT7L3+2PWnYwzFStb4MkMGlFKcscU9CvS53JcP/J4Asjk0I4zDB2gri
-xzFHPlVzCr2IVVGptKCQ3sdYiMIzQKzEXQHCU8h37ycCggEBAJu8aC48Fz3Edlm1
-ldS+2L9vWSaJEBzhoSu0cMBgZVu8SdGzwKDE69XHVI4oS5lI28UFmaaA3JTc07MN
-cAmSGT2oP2NQkPhbXGsrKLfm1K6YAiZ1Ulp7OwxFth8lYreo7Wt92nV46yuqkhDx
-Y3UGhp39xkPhWiRbvgYHxJLsVqFyjumsK2mq3IeNdVZ6VgJXGsTlnAFeqJ7hZxHs
-N5natSRjeosA0PtGJ57agZLvT8Ue0gREef3LzFGoFwmIOcQHZ4kAt2BGOzZDU17H
-6Rb4bKxBEbT1l2St/5zKXi90zDHicOvG7Q8qiyY6HrBc1wLSs+ZtpLxZx/3h3tFE
-IT6fVUECggEBAMSAQm8Ey76OJ+SXUjk1K50442SnHcs/Cmr7urkEQitImUwl71Pk
-87pst/uP6szypOTqmE9yOTIS6iZ6Sn3+QcriIqWrkhZfwW3Tx7S6A7KZUrq15iSH
-+thsiw9JXxC9TvOmC8AsBzb2U6hZncsc28JZCxFztSNAduJDb/vhCVLiMxWDFuDr
-kmR1R+yc3XDQRpeQFDz6QudYEj9EPOc6xD/16sZLaqP2+oVFvVSt0tJLsdaQECle
-gMNGAdhE2eX8MCOUHMc+E6cdlozYAEhMFfO2/cqWR79jq3TlVR3dnOFRDScqHMhc
-KnuTvsELjHkUbvGsCSiff7yk+fop7vy4OJsCggEAPemJdItO2rhib8EofrZdY72I
-oifX1jhPZ1BWD2GKgcx+eVyJGbONBbJVexvvskTfZBvCcAegmgp+sngP6MO6yZkr
-cHMfAJeApYZnshsgXksHGMDtSB50/w1JLrc/nqpxdpy/aTazt0Eu1pLWpze1HFZ/
-Xyu4PcmrU+4P1vN7c396slHMktEvly6QqOn4nfBbGDJ17Ow6X1XFvGjAxQPIDTB+
-6loV14AHymwmqwMrGn84O72rzqyw+41GxW5+oXhOZ4MeXF3u89TBLWvXDpPy/YQU
-EiKpodN0YeEn6Ghzplan8rUha+7TP7AYnS5pCszsCHKd03Py0lMLkF+uAfVsDA==
------END RSA PRIVATE KEY-----
diff --git a/packages/Tethering/apex/com.android.tethering.pk8 b/packages/Tethering/apex/com.android.tethering.pk8
deleted file mode 100644
index 3b94405..0000000
--- a/packages/Tethering/apex/com.android.tethering.pk8
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/apex/com.android.tethering.x509.pem b/packages/Tethering/apex/com.android.tethering.x509.pem
deleted file mode 100644
index a1786e3..0000000
--- a/packages/Tethering/apex/com.android.tethering.x509.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGKTCCBBGgAwIBAgIUNiSs5EMqxCZ31gWWCcRJVp9HffAwDQYJKoZIhvcNAQEL
-BQAwgaIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMR4wHAYDVQQDDBVjb20uYW5kcm9pZC50ZXRoZXJpbmcxIjAgBgkqhkiG9w0B
-CQEWE2FuZHJvaWRAYW5kcm9pZC5jb20wIBcNMTkxMjE4MDcwMDQ4WhgPNDc1NzEx
-MTMwNzAwNDhaMIGiMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW
-MBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UE
-CwwHQW5kcm9pZDEeMBwGA1UEAwwVY29tLmFuZHJvaWQudGV0aGVyaW5nMSIwIAYJ
-KoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tMIICIjANBgkqhkiG9w0BAQEF
-AAOCAg8AMIICCgKCAgEAxvTUA4seblYjZLfTVNwZuJH914QVNFTj+vD94pWmt5Aq
-sH1DVTpBvpXXegc/P5HI2XF/71poSBib1WaQSuXG0fU5K75T18bOGL0qF+fhMtBO
-wUyvulcjO0h4XE/xf0txY54exUjAA4JS9ERGJOgb4GOwSbPyzekfmzIyCZ2Yawwu
-+oGwD2ZNzZRaPOoWxjwohBWQ6mySuvF9RRRb300qmxxUGFM9Ki3aqrWlYlHEOwOC
-M+gIXxYFO7S+yUzf6/gMZLOz2YqfcTOup4hAxtExR7niutxJSsRLPBL237exAJoz
-OupoXjtWAlPK4ZwZ/Nl1jdTWauJ+Kv3WqzhHGEb2gn3ZpeO3IdOjJhDgFJ6m1OT/
-kjRbW1LCuKGrKaoqsEDT2X3a7Izfripn65hSNTfR5gNLtgELaI3/vXi8Fmzw1AfH
-+qi6ulElZvSwx0qm+S0QiPyGFlxrsdnHoGJl1tzjJW8KdNZRvzRLUQtbphPp+VkL
-5i0bNKum+AwbfdUkLkNLfw9XdbujgBkZTZDQbZGsNjgrvyXcPO2KiJee0hVCZRs0
-rhDi5Pfm7BnN/I2vaTRz/W4mdct9H2RWMuqlSH90JvmKtWcND8ahmOJ3sggrvzfO
-QNs3k4JTRecamMzqIkylhlnEC4FjWc6Bx4wsEpwBMZOkF/tGGMZYf2C09a8tpP0C
-AwEAAaNTMFEwHQYDVR0OBBYEFNP5gIpNWmq0xa411M1GaRPbEijvMB8GA1UdIwQY
-MBaAFNP5gIpNWmq0xa411M1GaRPbEijvMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
-hvcNAQELBQADggIBADJGmU3QP4EGbt6eBhVPeo/efsqrHsuB2fvFzvIobJbfkSob
-cmvjbzIikOlPAgFWj8lT5SDcIWRorFf1u2JylClJ0nSDcqJMHVKmT7wseV/KtX//
-1yUyJFRQVzmjC89dp8OIc00GmItivKLer3NbJdkR3rTUjg7+bNUO27Qp3AFREmiJ
-P+M7ouvcQRvByUWbp/LOrJpMdJLysRBO562RwrtwTjltdvufyYswbBZOKEiUh1Jc
-Ged+3+SJdhwq3Wy+R3Uj7YE7mUMu1QNbANIMrwF8W93EA53eoL2+cKmuaVU6ZURL
-xgSJaY6TrunnSI9XTROLtjsFlJorYWy2tvG7Q5Hw3OkO2Xdz/mm85VTkiusg9DMB
-WWTv607YtsIO0FhKmcV4bp3q/EkRj3t/zLvL9uFJrWDGkuShZq6fQvqbCvaokOPY
-+M0ZRIwgwa9UpEE0BMklVWqR6BGyap614gOgcOjYM70WRNl59Qne+g128ZN7g9nz
-61F70i7kUngV0ZUz1/Fu/NCG+6wGF85ZbFmQl60YHPDw1FtjVUuKyBblaDzdJunx
-yQr2t9RUokzFBFK0lGW3+yf0WDQ5fqTMs5h8bz1FCq8/HzWmpdOfqePLe4zsld3b
-1nFuSohaIfbn/HDdTNtTBGQPgz8ZswQ6ejJJqTLz9D/odbqn9LeIhDZXcQTf
------END CERTIFICATE-----
diff --git a/packages/Tethering/apex/manifest.json b/packages/Tethering/apex/manifest.json
deleted file mode 100644
index 538ffb3..0000000
--- a/packages/Tethering/apex/manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.tethering",
- "version": 300000000
-}
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
deleted file mode 100644
index c8becce7..0000000
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_sdk_library {
- name: "framework-tethering",
- defaults: ["framework-module-defaults"],
-
- // Allow access to the stubs from anywhere.
- visibility: ["//visibility:public"],
-
- // Restrict access to implementation library.
- impl_library_visibility: [
- "//visibility:override", // Ignore the visibility property.
- "//frameworks/base/packages/Tethering:__subpackages__",
- ],
-
- srcs: [
- ":framework-tethering-srcs",
- ],
-
- jarjar_rules: "jarjar-rules.txt",
- installable: true,
-
- hostdex: true, // for hiddenapi check
- apex_available: ["com.android.tethering"],
- permitted_packages: ["android.net"],
-}
-
-filegroup {
- name: "framework-tethering-srcs",
- srcs: [
- "src/android/net/TetheredClient.aidl",
- "src/android/net/TetheredClient.java",
- "src/android/net/TetheringManager.java",
- "src/android/net/TetheringConstants.java",
- "src/android/net/IIntResultListener.aidl",
- "src/android/net/ITetheringEventCallback.aidl",
- "src/android/net/ITetheringConnector.aidl",
- "src/android/net/TetheringCallbackStartedParcel.aidl",
- "src/android/net/TetheringConfigurationParcel.aidl",
- "src/android/net/TetheringRequestParcel.aidl",
- "src/android/net/TetherStatesParcel.aidl",
- ],
- path: "src"
-}
diff --git a/packages/Tethering/common/TetheringLib/api/current.txt b/packages/Tethering/common/TetheringLib/api/current.txt
deleted file mode 100644
index d802177..0000000
--- a/packages/Tethering/common/TetheringLib/api/current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/api/module-lib-current.txt b/packages/Tethering/common/TetheringLib/api/module-lib-current.txt
deleted file mode 100644
index 754584e..0000000
--- a/packages/Tethering/common/TetheringLib/api/module-lib-current.txt
+++ /dev/null
@@ -1,129 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
- public final class TetheredClient implements android.os.Parcelable {
- ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int);
- method public int describeContents();
- method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses();
- method @NonNull public android.net.MacAddress getMacAddress();
- method public int getTetheringType();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR;
- }
-
- public static final class TetheredClient.AddressInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.net.LinkAddress getAddress();
- method @Nullable public String getHostname();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
- }
-
- public final class TetheringConstants {
- field public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
- field public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
- field public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
- field public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
- field public static final String EXTRA_SET_ALARM = "extraSetAlarm";
- }
-
- public class TetheringManager {
- ctor public TetheringManager(@NonNull android.content.Context, @NonNull java.util.function.Supplier<android.os.IBinder>);
- method public int getLastTetherError(@NonNull String);
- method @NonNull public String[] getTetherableBluetoothRegexs();
- method @NonNull public String[] getTetherableIfaces();
- method @NonNull public String[] getTetherableUsbRegexs();
- method @NonNull public String[] getTetherableWifiRegexs();
- method @NonNull public String[] getTetheredIfaces();
- method @NonNull public String[] getTetheringErroredIfaces();
- method public boolean isTetheringSupported();
- method public boolean isTetheringSupported(@NonNull String);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
- method public void requestLatestTetheringEntitlementResult(int, @NonNull android.os.ResultReceiver, boolean);
- method @Deprecated public int setUsbTethering(boolean);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
- method @Deprecated public int tether(@NonNull String);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
- method @Deprecated public int untether(@NonNull String);
- field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
- field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
- field public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
- field public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
- field public static final String EXTRA_ERRORED_TETHER = "erroredArray";
- field public static final int TETHERING_BLUETOOTH = 2; // 0x2
- field public static final int TETHERING_ETHERNET = 5; // 0x5
- field public static final int TETHERING_INVALID = -1; // 0xffffffff
- field public static final int TETHERING_NCM = 4; // 0x4
- field public static final int TETHERING_USB = 1; // 0x1
- field public static final int TETHERING_WIFI = 0; // 0x0
- field public static final int TETHERING_WIFI_P2P = 3; // 0x3
- field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
- field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9
- field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8
- field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
- field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
- field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5
- field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
- field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
- field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
- field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb
- field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
- field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
- field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
- field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
- field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10
- field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
- field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
- field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
- field public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; // 0x1
- field public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; // 0x0
- }
-
- public static interface TetheringManager.OnTetheringEntitlementResultListener {
- method public void onTetheringEntitlementResult(int);
- }
-
- public static interface TetheringManager.StartTetheringCallback {
- method public default void onTetheringFailed(int);
- method public default void onTetheringStarted();
- }
-
- public static interface TetheringManager.TetheringEventCallback {
- method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
- method public default void onError(@NonNull String, int);
- method public default void onOffloadStatusChanged(int);
- method public default void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
- method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
- method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
- method public default void onTetheringSupported(boolean);
- method public default void onUpstreamChanged(@Nullable android.net.Network);
- }
-
- public static class TetheringManager.TetheringInterfaceRegexps {
- method @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs();
- method @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs();
- method @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
- }
-
- public static class TetheringManager.TetheringRequest {
- method @Nullable public android.net.LinkAddress getClientStaticIpv4Address();
- method @Nullable public android.net.LinkAddress getLocalIpv4Address();
- method public boolean getShouldShowEntitlementUi();
- method public int getTetheringType();
- method public boolean isExemptFromEntitlementCheck();
- }
-
- public static class TetheringManager.TetheringRequest.Builder {
- ctor public TetheringManager.TetheringRequest.Builder(int);
- method @NonNull public android.net.TetheringManager.TetheringRequest build();
- method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
- method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean);
- method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress);
- }
-
-}
-
diff --git a/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt b/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/api/removed.txt b/packages/Tethering/common/TetheringLib/api/removed.txt
deleted file mode 100644
index d802177..0000000
--- a/packages/Tethering/common/TetheringLib/api/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/api/system-current.txt b/packages/Tethering/common/TetheringLib/api/system-current.txt
deleted file mode 100644
index edd1ebb5..0000000
--- a/packages/Tethering/common/TetheringLib/api/system-current.txt
+++ /dev/null
@@ -1,99 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
- public final class TetheredClient implements android.os.Parcelable {
- ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int);
- method public int describeContents();
- method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses();
- method @NonNull public android.net.MacAddress getMacAddress();
- method public int getTetheringType();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR;
- }
-
- public static final class TetheredClient.AddressInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.net.LinkAddress getAddress();
- method @Nullable public String getHostname();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
- }
-
- public class TetheringManager {
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
- field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
- field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
- field public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
- field public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
- field public static final String EXTRA_ERRORED_TETHER = "erroredArray";
- field public static final int TETHERING_BLUETOOTH = 2; // 0x2
- field public static final int TETHERING_ETHERNET = 5; // 0x5
- field public static final int TETHERING_INVALID = -1; // 0xffffffff
- field public static final int TETHERING_NCM = 4; // 0x4
- field public static final int TETHERING_USB = 1; // 0x1
- field public static final int TETHERING_WIFI = 0; // 0x0
- field public static final int TETHERING_WIFI_P2P = 3; // 0x3
- field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
- field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9
- field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8
- field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
- field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
- field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5
- field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
- field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
- field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
- field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb
- field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
- field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
- field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
- field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
- field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10
- field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
- field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
- field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
- field public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; // 0x1
- field public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; // 0x0
- }
-
- public static interface TetheringManager.OnTetheringEntitlementResultListener {
- method public void onTetheringEntitlementResult(int);
- }
-
- public static interface TetheringManager.StartTetheringCallback {
- method public default void onTetheringFailed(int);
- method public default void onTetheringStarted();
- }
-
- public static interface TetheringManager.TetheringEventCallback {
- method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
- method public default void onError(@NonNull String, int);
- method public default void onOffloadStatusChanged(int);
- method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
- method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
- method public default void onTetheringSupported(boolean);
- method public default void onUpstreamChanged(@Nullable android.net.Network);
- }
-
- public static class TetheringManager.TetheringRequest {
- method @Nullable public android.net.LinkAddress getClientStaticIpv4Address();
- method @Nullable public android.net.LinkAddress getLocalIpv4Address();
- method public boolean getShouldShowEntitlementUi();
- method public int getTetheringType();
- method public boolean isExemptFromEntitlementCheck();
- }
-
- public static class TetheringManager.TetheringRequest.Builder {
- ctor public TetheringManager.TetheringRequest.Builder(int);
- method @NonNull public android.net.TetheringManager.TetheringRequest build();
- method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
- method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean);
- method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress);
- }
-
-}
-
diff --git a/packages/Tethering/common/TetheringLib/api/system-removed.txt b/packages/Tethering/common/TetheringLib/api/system-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/packages/Tethering/common/TetheringLib/api/system-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/jarjar-rules.txt b/packages/Tethering/common/TetheringLib/jarjar-rules.txt
deleted file mode 100644
index e459fad..0000000
--- a/packages/Tethering/common/TetheringLib/jarjar-rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-# jarjar rules for the bootclasspath tethering framework library here
\ No newline at end of file
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/IIntResultListener.aidl b/packages/Tethering/common/TetheringLib/src/android/net/IIntResultListener.aidl
deleted file mode 100644
index c3d66ee..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/IIntResultListener.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-/**
- * Listener interface allowing objects to listen to various module event.
- * {@hide}
- */
-oneway interface IIntResultListener {
- void onResult(int resultCode);
-}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl b/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl
deleted file mode 100644
index 8be7964..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl
+++ /dev/null
@@ -1,46 +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.net;
-
-import android.net.IIntResultListener;
-import android.net.ITetheringEventCallback;
-import android.net.TetheringRequestParcel;
-import android.os.ResultReceiver;
-
-/** @hide */
-oneway interface ITetheringConnector {
- void tether(String iface, String callerPkg, IIntResultListener receiver);
-
- void untether(String iface, String callerPkg, IIntResultListener receiver);
-
- void setUsbTethering(boolean enable, String callerPkg, IIntResultListener receiver);
-
- void startTethering(in TetheringRequestParcel request, String callerPkg,
- IIntResultListener receiver);
-
- void stopTethering(int type, String callerPkg, IIntResultListener receiver);
-
- void requestLatestTetheringEntitlementResult(int type, in ResultReceiver receiver,
- boolean showEntitlementUi, String callerPkg);
-
- void registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
-
- void unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
-
- void isTetheringSupported(String callerPkg, IIntResultListener receiver);
-
- void stopAllTethering(String callerPkg, IIntResultListener receiver);
-}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/ITetheringEventCallback.aidl b/packages/Tethering/common/TetheringLib/src/android/net/ITetheringEventCallback.aidl
deleted file mode 100644
index b4e3ba4..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/ITetheringEventCallback.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.net.Network;
-import android.net.TetheredClient;
-import android.net.TetheringConfigurationParcel;
-import android.net.TetheringCallbackStartedParcel;
-import android.net.TetherStatesParcel;
-
-/**
- * Callback class for receiving tethering changed events.
- * @hide
- */
-oneway interface ITetheringEventCallback
-{
- /** Called immediately after the callbacks are registered */
- void onCallbackStarted(in TetheringCallbackStartedParcel parcel);
- void onCallbackStopped(int errorCode);
- void onUpstreamChanged(in Network network);
- void onConfigurationChanged(in TetheringConfigurationParcel config);
- void onTetherStatesChanged(in TetherStatesParcel states);
- void onTetherClientsChanged(in List<TetheredClient> clients);
- void onOffloadStatusChanged(int status);
-}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetherStatesParcel.aidl b/packages/Tethering/common/TetheringLib/src/android/net/TetherStatesParcel.aidl
deleted file mode 100644
index 3d842b3..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetherStatesParcel.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-/**
- * Status details for tethering downstream interfaces.
- * {@hide}
- */
-parcelable TetherStatesParcel {
- String[] availableList;
- String[] tetheredList;
- String[] localOnlyList;
- String[] erroredIfaceList;
- // List of Last error code corresponding to each errored iface in erroredIfaceList. */
- // TODO: Improve this as b/143122247.
- int[] lastErrorList;
-}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.aidl b/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.aidl
deleted file mode 100644
index 0b279b8..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.aidl
+++ /dev/null
@@ -1,18 +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.net;
-
-@JavaOnlyStableParcelable parcelable TetheredClient;
\ No newline at end of file
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java
deleted file mode 100644
index 48be0d9..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java
+++ /dev/null
@@ -1,244 +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.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Information on a tethered downstream client.
- * @hide
- */
-@SystemApi
-@SystemApi(client = MODULE_LIBRARIES)
-@TestApi
-public final class TetheredClient implements Parcelable {
- @NonNull
- private final MacAddress mMacAddress;
- @NonNull
- private final List<AddressInfo> mAddresses;
- // TODO: use an @IntDef here
- private final int mTetheringType;
-
- public TetheredClient(@NonNull MacAddress macAddress,
- @NonNull Collection<AddressInfo> addresses, int tetheringType) {
- mMacAddress = macAddress;
- mAddresses = new ArrayList<>(addresses);
- mTetheringType = tetheringType;
- }
-
- private TetheredClient(@NonNull Parcel in) {
- this(in.readParcelable(null), in.createTypedArrayList(AddressInfo.CREATOR), in.readInt());
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeParcelable(mMacAddress, flags);
- dest.writeTypedList(mAddresses);
- dest.writeInt(mTetheringType);
- }
-
- /**
- * Get the MAC address used to identify the client.
- */
- @NonNull
- public MacAddress getMacAddress() {
- return mMacAddress;
- }
-
- /**
- * Get information on the list of addresses that are associated with the client.
- */
- @NonNull
- public List<AddressInfo> getAddresses() {
- return new ArrayList<>(mAddresses);
- }
-
- /**
- * Get the type of tethering used by the client.
- * @return one of the {@code TetheringManager#TETHERING_*} constants.
- */
- public int getTetheringType() {
- return mTetheringType;
- }
-
- /**
- * Return a new {@link TetheredClient} that has all the attributes of this instance, plus the
- * {@link AddressInfo} of the provided {@link TetheredClient}.
- *
- * <p>Duplicate addresses are removed.
- * @hide
- */
- public TetheredClient addAddresses(@NonNull TetheredClient other) {
- final LinkedHashSet<AddressInfo> newAddresses = new LinkedHashSet<>(
- mAddresses.size() + other.mAddresses.size());
- newAddresses.addAll(mAddresses);
- newAddresses.addAll(other.mAddresses);
- return new TetheredClient(mMacAddress, newAddresses, mTetheringType);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mMacAddress, mAddresses, mTetheringType);
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof TetheredClient)) return false;
- final TetheredClient other = (TetheredClient) obj;
- return mMacAddress.equals(other.mMacAddress)
- && mAddresses.equals(other.mAddresses)
- && mTetheringType == other.mTetheringType;
- }
-
- /**
- * Information on an lease assigned to a tethered client.
- */
- public static final class AddressInfo implements Parcelable {
- @NonNull
- private final LinkAddress mAddress;
- @Nullable
- private final String mHostname;
-
- /** @hide */
- public AddressInfo(@NonNull LinkAddress address, @Nullable String hostname) {
- this.mAddress = address;
- this.mHostname = hostname;
- }
-
- private AddressInfo(Parcel in) {
- this(in.readParcelable(null), in.readString());
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeParcelable(mAddress, flags);
- dest.writeString(mHostname);
- }
-
- /**
- * Get the link address (including prefix length and lifetime) used by the client.
- *
- * This may be an IPv4 or IPv6 address.
- */
- @NonNull
- public LinkAddress getAddress() {
- return mAddress;
- }
-
- /**
- * Get the hostname that was advertised by the client when obtaining its address, if any.
- */
- @Nullable
- public String getHostname() {
- return mHostname;
- }
-
- /**
- * Get the expiration time of the address assigned to the client.
- * @hide
- */
- public long getExpirationTime() {
- return mAddress.getExpirationTime();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mAddress, mHostname);
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof AddressInfo)) return false;
- final AddressInfo other = (AddressInfo) obj;
- // Use .equals() for addresses as all changes, including address expiry changes,
- // should be included.
- return other.mAddress.equals(mAddress)
- && Objects.equals(mHostname, other.mHostname);
- }
-
- @NonNull
- public static final Creator<AddressInfo> CREATOR = new Creator<AddressInfo>() {
- @NonNull
- @Override
- public AddressInfo createFromParcel(@NonNull Parcel in) {
- return new AddressInfo(in);
- }
-
- @NonNull
- @Override
- public AddressInfo[] newArray(int size) {
- return new AddressInfo[size];
- }
- };
-
- @NonNull
- @Override
- public String toString() {
- return "AddressInfo {"
- + mAddress
- + (mHostname != null ? ", hostname " + mHostname : "")
- + "}";
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull
- public static final Creator<TetheredClient> CREATOR = new Creator<TetheredClient>() {
- @NonNull
- @Override
- public TetheredClient createFromParcel(@NonNull Parcel in) {
- return new TetheredClient(in);
- }
-
- @NonNull
- @Override
- public TetheredClient[] newArray(int size) {
- return new TetheredClient[size];
- }
- };
-
- @NonNull
- @Override
- public String toString() {
- return "TetheredClient {hwAddr " + mMacAddress
- + ", addresses " + mAddresses
- + ", tetheringType " + mTetheringType
- + "}";
- }
-}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringCallbackStartedParcel.aidl b/packages/Tethering/common/TetheringLib/src/android/net/TetheringCallbackStartedParcel.aidl
deleted file mode 100644
index 253eacb..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringCallbackStartedParcel.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.net.Network;
-import android.net.TetheredClient;
-import android.net.TetheringConfigurationParcel;
-import android.net.TetherStatesParcel;
-
-/**
- * Initial information reported by tethering upon callback registration.
- * @hide
- */
-parcelable TetheringCallbackStartedParcel {
- boolean tetheringSupported;
- Network upstreamNetwork;
- TetheringConfigurationParcel config;
- TetherStatesParcel states;
- List<TetheredClient> tetheredClients;
- int offloadStatus;
-}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl b/packages/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl
deleted file mode 100644
index 89f3813..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-/**
- * Configuration details for tethering.
- * @hide
- */
-parcelable TetheringConfigurationParcel {
- int subId;
- String[] tetherableUsbRegexs;
- String[] tetherableWifiRegexs;
- String[] tetherableBluetoothRegexs;
- boolean isDunRequired;
- boolean chooseUpstreamAutomatically;
- int[] preferredUpstreamIfaceTypes;
- String[] legacyDhcpRanges;
- String[] defaultIPv4DNS;
- boolean enableLegacyDhcpServer;
- String[] provisioningApp;
- String provisioningAppNoUi;
- int provisioningCheckPeriod;
-}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java
deleted file mode 100644
index f14def6a..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java
+++ /dev/null
@@ -1,93 +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.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-
-import android.annotation.SystemApi;
-import android.os.ResultReceiver;
-
-/**
- * Collections of constants for internal tethering usage.
- *
- * <p>These hidden constants are not in TetheringManager as they are not part of the API stubs
- * generated for TetheringManager, which prevents the tethering module from linking them at
- * build time.
- * TODO: investigate changing the tethering build rules so that Tethering can reference hidden
- * symbols from framework-tethering even when they are in a non-hidden class.
- * @hide
- */
-@SystemApi(client = MODULE_LIBRARIES)
-public final class TetheringConstants {
- /** An explicit private class to avoid exposing constructor.*/
- private TetheringConstants() { }
-
- /**
- * Extra used for communicating with the TetherService and TetherProvisioningActivity.
- * Includes the type of tethering to enable if any.
- */
- public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
- /**
- * Extra used for communicating with the TetherService. Includes the type of tethering for
- * which to cancel provisioning.
- */
- public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
- /**
- * Extra used for communicating with the TetherService. True to schedule a recheck of tether
- * provisioning.
- */
- public static final String EXTRA_SET_ALARM = "extraSetAlarm";
- /**
- * Tells the TetherService to run a provision check now.
- */
- public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
- /**
- * Extra used for communicating with the TetherService and TetherProvisioningActivity.
- * Contains the {@link ResultReceiver} which will receive provisioning results.
- * Can not be empty.
- */
- public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
-
- /**
- * Extra used for communicating with the TetherService and TetherProvisioningActivity.
- * Contains the subId of current active cellular upstream.
- * @hide
- */
- public static final String EXTRA_TETHER_SUBID = "android.net.extra.TETHER_SUBID";
-
- /**
- * Extra used for telling TetherProvisioningActivity the entitlement package name and class
- * name to start UI entitlement check.
- * @hide
- */
- public static final String EXTRA_TETHER_UI_PROVISIONING_APP_NAME =
- "android.net.extra.TETHER_UI_PROVISIONING_APP_NAME";
-
- /**
- * Extra used for telling TetherService the intent action to start silent entitlement check.
- * @hide
- */
- public static final String EXTRA_TETHER_SILENT_PROVISIONING_ACTION =
- "android.net.extra.TETHER_SILENT_PROVISIONING_ACTION";
-
- /**
- * Extra used for TetherService to receive the response of provisioning check.
- * @hide
- */
- public static final String EXTRA_TETHER_PROVISIONING_RESPONSE =
- "android.net.extra.TETHER_PROVISIONING_RESPONSE";
-}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
deleted file mode 100644
index 4f053cb..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
+++ /dev/null
@@ -1,1356 +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.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-
-import android.Manifest;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.ConditionVariable;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.function.Supplier;
-
-/**
- * This class provides the APIs to control the tethering service.
- * <p> The primary responsibilities of this class are to provide the APIs for applications to
- * start tethering, stop tethering, query configuration and query status.
- *
- * @hide
- */
-@SystemApi
-@SystemApi(client = MODULE_LIBRARIES)
-@TestApi
-public class TetheringManager {
- private static final String TAG = TetheringManager.class.getSimpleName();
- private static final int DEFAULT_TIMEOUT_MS = 60_000;
- private static final long CONNECTOR_POLL_INTERVAL_MILLIS = 200L;
-
- @GuardedBy("mConnectorWaitQueue")
- @Nullable
- private ITetheringConnector mConnector;
- @GuardedBy("mConnectorWaitQueue")
- @NonNull
- private final List<ConnectorConsumer> mConnectorWaitQueue = new ArrayList<>();
- private final Supplier<IBinder> mConnectorSupplier;
-
- private final TetheringCallbackInternal mCallback;
- private final Context mContext;
- private final ArrayMap<TetheringEventCallback, ITetheringEventCallback>
- mTetheringEventCallbacks = new ArrayMap<>();
-
- private volatile TetheringConfigurationParcel mTetheringConfiguration;
- private volatile TetherStatesParcel mTetherStatesParcel;
-
- /**
- * Broadcast Action: A tetherable connection has come or gone.
- * Uses {@code TetheringManager.EXTRA_AVAILABLE_TETHER},
- * {@code TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY},
- * {@code TetheringManager.EXTRA_ACTIVE_TETHER}, and
- * {@code TetheringManager.EXTRA_ERRORED_TETHER} to indicate
- * the current state of tethering. Each include a list of
- * interface names in that state (may be empty).
- */
- public static final String ACTION_TETHER_STATE_CHANGED =
- "android.net.conn.TETHER_STATE_CHANGED";
-
- /**
- * gives a String[] listing all the interfaces configured for
- * tethering and currently available for tethering.
- */
- public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
-
- /**
- * gives a String[] listing all the interfaces currently in local-only
- * mode (ie, has DHCPv4+IPv6-ULA support and no packet forwarding)
- */
- public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
-
- /**
- * gives a String[] listing all the interfaces currently tethered
- * (ie, has DHCPv4 support and packets potentially forwarded/NATed)
- */
- public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
-
- /**
- * gives a String[] listing all the interfaces we tried to tether and
- * failed. Use {@link #getLastTetherError} to find the error code
- * for any interfaces listed here.
- */
- public static final String EXTRA_ERRORED_TETHER = "erroredArray";
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = false, value = {
- TETHERING_WIFI,
- TETHERING_USB,
- TETHERING_BLUETOOTH,
- TETHERING_WIFI_P2P,
- TETHERING_NCM,
- TETHERING_ETHERNET,
- })
- public @interface TetheringType {
- }
-
- /**
- * Invalid tethering type.
- * @see #startTethering.
- */
- public static final int TETHERING_INVALID = -1;
-
- /**
- * Wifi tethering type.
- * @see #startTethering.
- */
- public static final int TETHERING_WIFI = 0;
-
- /**
- * USB tethering type.
- * @see #startTethering.
- */
- public static final int TETHERING_USB = 1;
-
- /**
- * Bluetooth tethering type.
- * @see #startTethering.
- */
- public static final int TETHERING_BLUETOOTH = 2;
-
- /**
- * Wifi P2p tethering type.
- * Wifi P2p tethering is set through events automatically, and don't
- * need to start from #startTethering.
- */
- public static final int TETHERING_WIFI_P2P = 3;
-
- /**
- * Ncm local tethering type.
- * @see #startTethering(TetheringRequest, Executor, StartTetheringCallback)
- */
- public static final int TETHERING_NCM = 4;
-
- /**
- * Ethernet tethering type.
- * @see #startTethering(TetheringRequest, Executor, StartTetheringCallback)
- */
- public static final int TETHERING_ETHERNET = 5;
-
- /**
- * WIGIG tethering type. Use a separate type to prevent
- * conflicts with TETHERING_WIFI
- * This type is only used internally by the tethering module
- * @hide
- */
- public static final int TETHERING_WIGIG = 6;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- TETHER_ERROR_NO_ERROR,
- TETHER_ERROR_PROVISIONING_FAILED,
- TETHER_ERROR_ENTITLEMENT_UNKNOWN,
- })
- public @interface EntitlementResult {
- }
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- TETHER_ERROR_NO_ERROR,
- TETHER_ERROR_UNKNOWN_IFACE,
- TETHER_ERROR_SERVICE_UNAVAIL,
- TETHER_ERROR_INTERNAL_ERROR,
- TETHER_ERROR_TETHER_IFACE_ERROR,
- TETHER_ERROR_ENABLE_FORWARDING_ERROR,
- TETHER_ERROR_DISABLE_FORWARDING_ERROR,
- TETHER_ERROR_IFACE_CFG_ERROR,
- TETHER_ERROR_DHCPSERVER_ERROR,
- })
- public @interface TetheringIfaceError {
- }
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- TETHER_ERROR_SERVICE_UNAVAIL,
- TETHER_ERROR_INTERNAL_ERROR,
- TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION,
- TETHER_ERROR_UNKNOWN_TYPE,
- })
- public @interface StartTetheringError {
- }
-
- public static final int TETHER_ERROR_NO_ERROR = 0;
- public static final int TETHER_ERROR_UNKNOWN_IFACE = 1;
- public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2;
- public static final int TETHER_ERROR_UNSUPPORTED = 3;
- public static final int TETHER_ERROR_UNAVAIL_IFACE = 4;
- public static final int TETHER_ERROR_INTERNAL_ERROR = 5;
- public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
- public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
- public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8;
- public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9;
- public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10;
- public static final int TETHER_ERROR_PROVISIONING_FAILED = 11;
- public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12;
- public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13;
- public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14;
- public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15;
- public static final int TETHER_ERROR_UNKNOWN_TYPE = 16;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = false, value = {
- TETHER_HARDWARE_OFFLOAD_STOPPED,
- TETHER_HARDWARE_OFFLOAD_STARTED,
- TETHER_HARDWARE_OFFLOAD_FAILED,
- })
- public @interface TetherOffloadStatus {
- }
-
- /** Tethering offload status is stopped. */
- public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0;
- /** Tethering offload status is started. */
- public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1;
- /** Fail to start tethering offload. */
- public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2;
-
- /**
- * Create a TetheringManager object for interacting with the tethering service.
- *
- * @param context Context for the manager.
- * @param connectorSupplier Supplier for the manager connector; may return null while the
- * service is not connected.
- * {@hide}
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public TetheringManager(@NonNull final Context context,
- @NonNull Supplier<IBinder> connectorSupplier) {
- mContext = context;
- mCallback = new TetheringCallbackInternal();
- mConnectorSupplier = connectorSupplier;
-
- final String pkgName = mContext.getOpPackageName();
-
- final IBinder connector = mConnectorSupplier.get();
- // If the connector is available on start, do not start a polling thread. This introduces
- // differences in the thread that sends the oneway binder calls to the service between the
- // first few seconds after boot and later, but it avoids always having differences between
- // the first usage of TetheringManager from a process and subsequent usages (so the
- // difference is only on boot). On boot binder calls may be queued until the service comes
- // up and be sent from a worker thread; later, they are always sent from the caller thread.
- // Considering that it's just oneway binder calls, and ordering is preserved, this seems
- // better than inconsistent behavior persisting after boot.
- if (connector != null) {
- mConnector = ITetheringConnector.Stub.asInterface(connector);
- } else {
- startPollingForConnector();
- }
-
- Log.i(TAG, "registerTetheringEventCallback:" + pkgName);
- getConnector(c -> c.registerTetheringEventCallback(mCallback, pkgName));
- }
-
- private void startPollingForConnector() {
- new Thread(() -> {
- while (true) {
- try {
- Thread.sleep(CONNECTOR_POLL_INTERVAL_MILLIS);
- } catch (InterruptedException e) {
- // Not much to do here, the system needs to wait for the connector
- }
-
- final IBinder connector = mConnectorSupplier.get();
- if (connector != null) {
- onTetheringConnected(ITetheringConnector.Stub.asInterface(connector));
- return;
- }
- }
- }).start();
- }
-
- private interface ConnectorConsumer {
- void onConnectorAvailable(ITetheringConnector connector) throws RemoteException;
- }
-
- private void onTetheringConnected(ITetheringConnector connector) {
- // Process the connector wait queue in order, including any items that are added
- // while processing.
- //
- // 1. Copy the queue to a local variable under lock.
- // 2. Drain the local queue with the lock released (otherwise, enqueuing future commands
- // would block on the lock).
- // 3. Acquire the lock again. If any new tasks were queued during step 2, goto 1.
- // If not, set mConnector to non-null so future tasks are run immediately, not queued.
- //
- // For this to work, all calls to the tethering service must use getConnector(), which
- // ensures that tasks are added to the queue with the lock held.
- //
- // Once mConnector is set to non-null, it will never be null again. If the network stack
- // process crashes, no recovery is possible.
- // TODO: evaluate whether it is possible to recover from network stack process crashes
- // (though in most cases the system will have crashed when the network stack process
- // crashes).
- do {
- final List<ConnectorConsumer> localWaitQueue;
- synchronized (mConnectorWaitQueue) {
- localWaitQueue = new ArrayList<>(mConnectorWaitQueue);
- mConnectorWaitQueue.clear();
- }
-
- // Allow more tasks to be added at the end without blocking while draining the queue.
- for (ConnectorConsumer task : localWaitQueue) {
- try {
- task.onConnectorAvailable(connector);
- } catch (RemoteException e) {
- // Most likely the network stack process crashed, which is likely to crash the
- // system. Keep processing other requests but report the error loudly.
- Log.wtf(TAG, "Error processing request for the tethering connector", e);
- }
- }
-
- synchronized (mConnectorWaitQueue) {
- if (mConnectorWaitQueue.size() == 0) {
- mConnector = connector;
- return;
- }
- }
- } while (true);
- }
-
- /**
- * Asynchronously get the ITetheringConnector to execute some operation.
- *
- * <p>If the connector is already available, the operation will be executed on the caller's
- * thread. Otherwise it will be queued and executed on a worker thread. The operation should be
- * limited to performing oneway binder calls to minimize differences due to threading.
- */
- private void getConnector(ConnectorConsumer consumer) {
- final ITetheringConnector connector;
- synchronized (mConnectorWaitQueue) {
- connector = mConnector;
- if (connector == null) {
- mConnectorWaitQueue.add(consumer);
- return;
- }
- }
-
- try {
- consumer.onConnectorAvailable(connector);
- } catch (RemoteException e) {
- throw new IllegalStateException(e);
- }
- }
-
- private interface RequestHelper {
- void runRequest(ITetheringConnector connector, IIntResultListener listener);
- }
-
- // Used to dispatch legacy ConnectivityManager methods that expect tethering to be able to
- // return results and perform operations synchronously.
- // TODO: remove once there are no callers of these legacy methods.
- private class RequestDispatcher {
- private final ConditionVariable mWaiting;
- public volatile int mRemoteResult;
-
- private final IIntResultListener mListener = new IIntResultListener.Stub() {
- @Override
- public void onResult(final int resultCode) {
- mRemoteResult = resultCode;
- mWaiting.open();
- }
- };
-
- RequestDispatcher() {
- mWaiting = new ConditionVariable();
- }
-
- int waitForResult(final RequestHelper request) {
- getConnector(c -> request.runRequest(c, mListener));
- if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
- throw new IllegalStateException("Callback timeout");
- }
-
- throwIfPermissionFailure(mRemoteResult);
-
- return mRemoteResult;
- }
- }
-
- private void throwIfPermissionFailure(final int errorCode) {
- switch (errorCode) {
- case TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION:
- throw new SecurityException("No android.permission.TETHER_PRIVILEGED"
- + " or android.permission.WRITE_SETTINGS permission");
- case TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION:
- throw new SecurityException(
- "No android.permission.ACCESS_NETWORK_STATE permission");
- }
- }
-
- private class TetheringCallbackInternal extends ITetheringEventCallback.Stub {
- private volatile int mError = TETHER_ERROR_NO_ERROR;
- private final ConditionVariable mWaitForCallback = new ConditionVariable();
-
- @Override
- public void onCallbackStarted(TetheringCallbackStartedParcel parcel) {
- mTetheringConfiguration = parcel.config;
- mTetherStatesParcel = parcel.states;
- mWaitForCallback.open();
- }
-
- @Override
- public void onCallbackStopped(int errorCode) {
- mError = errorCode;
- mWaitForCallback.open();
- }
-
- @Override
- public void onUpstreamChanged(Network network) { }
-
- @Override
- public void onConfigurationChanged(TetheringConfigurationParcel config) {
- mTetheringConfiguration = config;
- }
-
- @Override
- public void onTetherStatesChanged(TetherStatesParcel states) {
- mTetherStatesParcel = states;
- }
-
- @Override
- public void onTetherClientsChanged(List<TetheredClient> clients) { }
-
- @Override
- public void onOffloadStatusChanged(int status) { }
-
- public void waitForStarted() {
- mWaitForCallback.block(DEFAULT_TIMEOUT_MS);
- throwIfPermissionFailure(mError);
- }
- }
-
- /**
- * Attempt to tether the named interface. This will setup a dhcp server
- * on the interface, forward and NAT IP v4 packets and forward DNS requests
- * to the best active upstream network interface. Note that if no upstream
- * IP network interface is available, dhcp will still run and traffic will be
- * allowed between the tethered devices and this device, though upstream net
- * access will of course fail until an upstream network interface becomes
- * active.
- *
- * @deprecated The only usages is PanService. It uses this for legacy reasons
- * and will migrate away as soon as possible.
- *
- * @param iface the interface name to tether.
- * @return error a {@code TETHER_ERROR} value indicating success or failure type
- *
- * {@hide}
- */
- @Deprecated
- @SystemApi(client = MODULE_LIBRARIES)
- public int tether(@NonNull final String iface) {
- final String callerPkg = mContext.getOpPackageName();
- Log.i(TAG, "tether caller:" + callerPkg);
- final RequestDispatcher dispatcher = new RequestDispatcher();
-
- return dispatcher.waitForResult((connector, listener) -> {
- try {
- connector.tether(iface, callerPkg, listener);
- } catch (RemoteException e) {
- throw new IllegalStateException(e);
- }
- });
- }
-
- /**
- * Stop tethering the named interface.
- *
- * @deprecated The only usages is PanService. It uses this for legacy reasons
- * and will migrate away as soon as possible.
- *
- * {@hide}
- */
- @Deprecated
- @SystemApi(client = MODULE_LIBRARIES)
- public int untether(@NonNull final String iface) {
- final String callerPkg = mContext.getOpPackageName();
- Log.i(TAG, "untether caller:" + callerPkg);
-
- final RequestDispatcher dispatcher = new RequestDispatcher();
-
- return dispatcher.waitForResult((connector, listener) -> {
- try {
- connector.untether(iface, callerPkg, listener);
- } catch (RemoteException e) {
- throw new IllegalStateException(e);
- }
- });
- }
-
- /**
- * Attempt to both alter the mode of USB and Tethering of USB.
- *
- * @deprecated New client should not use this API anymore. All clients should use
- * #startTethering or #stopTethering which encapsulate proper entitlement logic. If the API is
- * used and an entitlement check is needed, downstream USB tethering will be enabled but will
- * not have any upstream.
- *
- * {@hide}
- */
- @Deprecated
- @SystemApi(client = MODULE_LIBRARIES)
- public int setUsbTethering(final boolean enable) {
- final String callerPkg = mContext.getOpPackageName();
- Log.i(TAG, "setUsbTethering caller:" + callerPkg);
-
- final RequestDispatcher dispatcher = new RequestDispatcher();
-
- return dispatcher.waitForResult((connector, listener) -> {
- try {
- connector.setUsbTethering(enable, callerPkg, listener);
- } catch (RemoteException e) {
- throw new IllegalStateException(e);
- }
- });
- }
-
- /**
- * Use with {@link #startTethering} to specify additional parameters when starting tethering.
- */
- public static class TetheringRequest {
- /** A configuration set for TetheringRequest. */
- private final TetheringRequestParcel mRequestParcel;
-
- private TetheringRequest(final TetheringRequestParcel request) {
- mRequestParcel = request;
- }
-
- /** Builder used to create TetheringRequest. */
- public static class Builder {
- private final TetheringRequestParcel mBuilderParcel;
-
- /** Default constructor of Builder. */
- public Builder(@TetheringType final int type) {
- mBuilderParcel = new TetheringRequestParcel();
- mBuilderParcel.tetheringType = type;
- mBuilderParcel.localIPv4Address = null;
- mBuilderParcel.staticClientAddress = null;
- mBuilderParcel.exemptFromEntitlementCheck = false;
- mBuilderParcel.showProvisioningUi = true;
- }
-
- /**
- * Configure tethering with static IPv4 assignment.
- *
- * A DHCP server will be started, but will only be able to offer the client address.
- * The two addresses must be in the same prefix.
- *
- * @param localIPv4Address The preferred local IPv4 link address to use.
- * @param clientAddress The static client address.
- */
- @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
- @NonNull
- public Builder setStaticIpv4Addresses(@NonNull final LinkAddress localIPv4Address,
- @NonNull final LinkAddress clientAddress) {
- Objects.requireNonNull(localIPv4Address);
- Objects.requireNonNull(clientAddress);
- if (!checkStaticAddressConfiguration(localIPv4Address, clientAddress)) {
- throw new IllegalArgumentException("Invalid server or client addresses");
- }
-
- mBuilderParcel.localIPv4Address = localIPv4Address;
- mBuilderParcel.staticClientAddress = clientAddress;
- return this;
- }
-
- /** Start tethering without entitlement checks. */
- @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
- @NonNull
- public Builder setExemptFromEntitlementCheck(boolean exempt) {
- mBuilderParcel.exemptFromEntitlementCheck = exempt;
- return this;
- }
-
- /**
- * If an entitlement check is needed, sets whether to show the entitlement UI or to
- * perform a silent entitlement check. By default, the entitlement UI is shown.
- */
- @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
- @NonNull
- public Builder setShouldShowEntitlementUi(boolean showUi) {
- mBuilderParcel.showProvisioningUi = showUi;
- return this;
- }
-
- /** Build {@link TetheringRequest] with the currently set configuration. */
- @NonNull
- public TetheringRequest build() {
- return new TetheringRequest(mBuilderParcel);
- }
- }
-
- /**
- * Get the local IPv4 address, if one was configured with
- * {@link Builder#setStaticIpv4Addresses}.
- */
- @Nullable
- public LinkAddress getLocalIpv4Address() {
- return mRequestParcel.localIPv4Address;
- }
-
- /**
- * Get the static IPv4 address of the client, if one was configured with
- * {@link Builder#setStaticIpv4Addresses}.
- */
- @Nullable
- public LinkAddress getClientStaticIpv4Address() {
- return mRequestParcel.staticClientAddress;
- }
-
- /** Get tethering type. */
- @TetheringType
- public int getTetheringType() {
- return mRequestParcel.tetheringType;
- }
-
- /** Check if exempt from entitlement check. */
- public boolean isExemptFromEntitlementCheck() {
- return mRequestParcel.exemptFromEntitlementCheck;
- }
-
- /** Check if show entitlement ui. */
- public boolean getShouldShowEntitlementUi() {
- return mRequestParcel.showProvisioningUi;
- }
-
- /**
- * Check whether the two addresses are ipv4 and in the same prefix.
- * @hide
- */
- public static boolean checkStaticAddressConfiguration(
- @NonNull final LinkAddress localIPv4Address,
- @NonNull final LinkAddress clientAddress) {
- return localIPv4Address.getPrefixLength() == clientAddress.getPrefixLength()
- && localIPv4Address.isIpv4() && clientAddress.isIpv4()
- && new IpPrefix(localIPv4Address.toString()).equals(
- new IpPrefix(clientAddress.toString()));
- }
-
- /**
- * Get a TetheringRequestParcel from the configuration
- * @hide
- */
- public TetheringRequestParcel getParcel() {
- return mRequestParcel;
- }
-
- /** String of TetheringRequest detail. */
- public String toString() {
- return "TetheringRequest [ type= " + mRequestParcel.tetheringType
- + ", localIPv4Address= " + mRequestParcel.localIPv4Address
- + ", staticClientAddress= " + mRequestParcel.staticClientAddress
- + ", exemptFromEntitlementCheck= "
- + mRequestParcel.exemptFromEntitlementCheck + ", showProvisioningUi= "
- + mRequestParcel.showProvisioningUi + " ]";
- }
- }
-
- /**
- * Callback for use with {@link #startTethering} to find out whether tethering succeeded.
- */
- public interface StartTetheringCallback {
- /**
- * Called when tethering has been successfully started.
- */
- default void onTetheringStarted() {}
-
- /**
- * Called when starting tethering failed.
- *
- * @param error The error that caused the failure.
- */
- default void onTetheringFailed(@StartTetheringError final int error) {}
- }
-
- /**
- * Starts tethering and runs tether provisioning for the given type if needed. If provisioning
- * fails, stopTethering will be called automatically.
- *
- * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
- * fail if a tethering entitlement check is required.
- *
- * @param request a {@link TetheringRequest} which can specify the preferred configuration.
- * @param executor {@link Executor} to specify the thread upon which the callback of
- * TetheringRequest will be invoked.
- * @param callback A callback that will be called to indicate the success status of the
- * tethering start request.
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.TETHER_PRIVILEGED,
- android.Manifest.permission.WRITE_SETTINGS
- })
- public void startTethering(@NonNull final TetheringRequest request,
- @NonNull final Executor executor, @NonNull final StartTetheringCallback callback) {
- final String callerPkg = mContext.getOpPackageName();
- Log.i(TAG, "startTethering caller:" + callerPkg);
-
- final IIntResultListener listener = new IIntResultListener.Stub() {
- @Override
- public void onResult(final int resultCode) {
- executor.execute(() -> {
- if (resultCode == TETHER_ERROR_NO_ERROR) {
- callback.onTetheringStarted();
- } else {
- callback.onTetheringFailed(resultCode);
- }
- });
- }
- };
- getConnector(c -> c.startTethering(request.getParcel(), callerPkg, listener));
- }
-
- /**
- * Starts tethering and runs tether provisioning for the given type if needed. If provisioning
- * fails, stopTethering will be called automatically.
- *
- * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
- * fail if a tethering entitlement check is required.
- *
- * @param type The tethering type, on of the {@code TetheringManager#TETHERING_*} constants.
- * @param executor {@link Executor} to specify the thread upon which the callback of
- * TetheringRequest will be invoked.
- * @hide
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.TETHER_PRIVILEGED,
- android.Manifest.permission.WRITE_SETTINGS
- })
- @SystemApi(client = MODULE_LIBRARIES)
- public void startTethering(int type, @NonNull final Executor executor,
- @NonNull final StartTetheringCallback callback) {
- startTethering(new TetheringRequest.Builder(type).build(), executor, callback);
- }
-
- /**
- * Stops tethering for the given type. Also cancels any provisioning rechecks for that type if
- * applicable.
- *
- * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
- * fail if a tethering entitlement check is required.
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.TETHER_PRIVILEGED,
- android.Manifest.permission.WRITE_SETTINGS
- })
- public void stopTethering(@TetheringType final int type) {
- final String callerPkg = mContext.getOpPackageName();
- Log.i(TAG, "stopTethering caller:" + callerPkg);
-
- getConnector(c -> c.stopTethering(type, callerPkg, new IIntResultListener.Stub() {
- @Override
- public void onResult(int resultCode) {
- // TODO: provide an API to obtain result
- // This has never been possible as stopTethering has always been void and never
- // taken a callback object. The only indication that callers have is if the call
- // results in a TETHER_STATE_CHANGE broadcast.
- }
- }));
- }
-
- /**
- * Callback for use with {@link #getLatestTetheringEntitlementResult} to find out whether
- * entitlement succeeded.
- */
- public interface OnTetheringEntitlementResultListener {
- /**
- * Called to notify entitlement result.
- *
- * @param resultCode an int value of entitlement result. It may be one of
- * {@link #TETHER_ERROR_NO_ERROR},
- * {@link #TETHER_ERROR_PROVISIONING_FAILED}, or
- * {@link #TETHER_ERROR_ENTITLEMENT_UNKNOWN}.
- */
- void onTetheringEntitlementResult(@EntitlementResult int result);
- }
-
- /**
- * Request the latest value of the tethering entitlement check.
- *
- * <p>This method will only return the latest entitlement result if it is available. If no
- * cached entitlement result is available, and {@code showEntitlementUi} is false,
- * {@link #TETHER_ERROR_ENTITLEMENT_UNKNOWN} will be returned. If {@code showEntitlementUi} is
- * true, entitlement will be run.
- *
- * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
- * fail if a tethering entitlement check is required.
- *
- * @param type the downstream type of tethering. Must be one of {@code #TETHERING_*} constants.
- * @param showEntitlementUi a boolean indicating whether to check result for the UI-based
- * entitlement check or the silent entitlement check.
- * @param executor the executor on which callback will be invoked.
- * @param listener an {@link OnTetheringEntitlementResultListener} which will be called to
- * notify the caller of the result of entitlement check. The listener may be called zero
- * or one time.
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.TETHER_PRIVILEGED,
- android.Manifest.permission.WRITE_SETTINGS
- })
- public void requestLatestTetheringEntitlementResult(@TetheringType int type,
- boolean showEntitlementUi,
- @NonNull Executor executor,
- @NonNull final OnTetheringEntitlementResultListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException(
- "OnTetheringEntitlementResultListener cannot be null.");
- }
-
- ResultReceiver wrappedListener = new ResultReceiver(null /* handler */) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- executor.execute(() -> {
- listener.onTetheringEntitlementResult(resultCode);
- });
- }
- };
-
- requestLatestTetheringEntitlementResult(type, wrappedListener,
- showEntitlementUi);
- }
-
- /**
- * Helper function of #requestLatestTetheringEntitlementResult to remain backwards compatible
- * with ConnectivityManager#getLatestTetheringEntitlementResult
- *
- * {@hide}
- */
- // TODO: improve the usage of ResultReceiver, b/145096122
- @SystemApi(client = MODULE_LIBRARIES)
- public void requestLatestTetheringEntitlementResult(@TetheringType final int type,
- @NonNull final ResultReceiver receiver, final boolean showEntitlementUi) {
- final String callerPkg = mContext.getOpPackageName();
- Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg);
-
- getConnector(c -> c.requestLatestTetheringEntitlementResult(
- type, receiver, showEntitlementUi, callerPkg));
- }
-
- /**
- * Callback for use with {@link registerTetheringEventCallback} to find out tethering
- * upstream status.
- */
- public interface TetheringEventCallback {
- /**
- * Called when tethering supported status changed.
- *
- * <p>This will be called immediately after the callback is registered, and may be called
- * multiple times later upon changes.
- *
- * <p>Tethering may be disabled via system properties, device configuration, or device
- * policy restrictions.
- *
- * @param supported The new supported status
- */
- default void onTetheringSupported(boolean supported) {}
-
- /**
- * Called when tethering upstream changed.
- *
- * <p>This will be called immediately after the callback is registered, and may be called
- * multiple times later upon changes.
- *
- * @param network the {@link Network} of tethering upstream. Null means tethering doesn't
- * have any upstream.
- */
- default void onUpstreamChanged(@Nullable Network network) {}
-
- /**
- * Called when there was a change in tethering interface regular expressions.
- *
- * <p>This will be called immediately after the callback is registered, and may be called
- * multiple times later upon changes.
- * @param reg The new regular expressions.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- default void onTetherableInterfaceRegexpsChanged(@NonNull TetheringInterfaceRegexps reg) {}
-
- /**
- * Called when there was a change in the list of tetherable interfaces. Tetherable
- * interface means this interface is available and can be used for tethering.
- *
- * <p>This will be called immediately after the callback is registered, and may be called
- * multiple times later upon changes.
- * @param interfaces The list of tetherable interface names.
- */
- default void onTetherableInterfacesChanged(@NonNull List<String> interfaces) {}
-
- /**
- * Called when there was a change in the list of tethered interfaces.
- *
- * <p>This will be called immediately after the callback is registered, and may be called
- * multiple times later upon changes.
- * @param interfaces The list of 0 or more String of currently tethered interface names.
- */
- default void onTetheredInterfacesChanged(@NonNull List<String> interfaces) {}
-
- /**
- * Called when an error occurred configuring tethering.
- *
- * <p>This will be called immediately after the callback is registered if the latest status
- * on the interface is an error, and may be called multiple times later upon changes.
- * @param ifName Name of the interface.
- * @param error One of {@code TetheringManager#TETHER_ERROR_*}.
- */
- default void onError(@NonNull String ifName, @TetheringIfaceError int error) {}
-
- /**
- * Called when the list of tethered clients changes.
- *
- * <p>This callback provides best-effort information on connected clients based on state
- * known to the system, however the list cannot be completely accurate (and should not be
- * used for security purposes). For example, clients behind a bridge and using static IP
- * assignments are not visible to the tethering device; or even when using DHCP, such
- * clients may still be reported by this callback after disconnection as the system cannot
- * determine if they are still connected.
- * @param clients The new set of tethered clients; the collection is not ordered.
- */
- default void onClientsChanged(@NonNull Collection<TetheredClient> clients) {}
-
- /**
- * Called when tethering offload status changes.
- *
- * <p>This will be called immediately after the callback is registered.
- * @param status The offload status.
- */
- default void onOffloadStatusChanged(@TetherOffloadStatus int status) {}
- }
-
- /**
- * Regular expressions used to identify tethering interfaces.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static class TetheringInterfaceRegexps {
- private final String[] mTetherableBluetoothRegexs;
- private final String[] mTetherableUsbRegexs;
- private final String[] mTetherableWifiRegexs;
-
- /** @hide */
- public TetheringInterfaceRegexps(@NonNull String[] tetherableBluetoothRegexs,
- @NonNull String[] tetherableUsbRegexs, @NonNull String[] tetherableWifiRegexs) {
- mTetherableBluetoothRegexs = tetherableBluetoothRegexs.clone();
- mTetherableUsbRegexs = tetherableUsbRegexs.clone();
- mTetherableWifiRegexs = tetherableWifiRegexs.clone();
- }
-
- @NonNull
- public List<String> getTetherableBluetoothRegexs() {
- return Collections.unmodifiableList(Arrays.asList(mTetherableBluetoothRegexs));
- }
-
- @NonNull
- public List<String> getTetherableUsbRegexs() {
- return Collections.unmodifiableList(Arrays.asList(mTetherableUsbRegexs));
- }
-
- @NonNull
- public List<String> getTetherableWifiRegexs() {
- return Collections.unmodifiableList(Arrays.asList(mTetherableWifiRegexs));
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mTetherableBluetoothRegexs, mTetherableUsbRegexs,
- mTetherableWifiRegexs);
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof TetheringInterfaceRegexps)) return false;
- final TetheringInterfaceRegexps other = (TetheringInterfaceRegexps) obj;
- return Arrays.equals(mTetherableBluetoothRegexs, other.mTetherableBluetoothRegexs)
- && Arrays.equals(mTetherableUsbRegexs, other.mTetherableUsbRegexs)
- && Arrays.equals(mTetherableWifiRegexs, other.mTetherableWifiRegexs);
- }
- }
-
- /**
- * Start listening to tethering change events. Any new added callback will receive the last
- * tethering status right away. If callback is registered,
- * {@link TetheringEventCallback#onUpstreamChanged} will immediately be called. If tethering
- * has no upstream or disabled, the argument of callback will be null. The same callback object
- * cannot be registered twice.
- *
- * @param executor the executor on which callback will be invoked.
- * @param callback the callback to be called when tethering has change events.
- */
- @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
- public void registerTetheringEventCallback(@NonNull Executor executor,
- @NonNull TetheringEventCallback callback) {
- final String callerPkg = mContext.getOpPackageName();
- Log.i(TAG, "registerTetheringEventCallback caller:" + callerPkg);
-
- synchronized (mTetheringEventCallbacks) {
- if (mTetheringEventCallbacks.containsKey(callback)) {
- throw new IllegalArgumentException("callback was already registered.");
- }
- final ITetheringEventCallback remoteCallback = new ITetheringEventCallback.Stub() {
- // Only accessed with a lock on this object
- private final HashMap<String, Integer> mErrorStates = new HashMap<>();
- private String[] mLastTetherableInterfaces = null;
- private String[] mLastTetheredInterfaces = null;
-
- @Override
- public void onUpstreamChanged(Network network) throws RemoteException {
- executor.execute(() -> {
- callback.onUpstreamChanged(network);
- });
- }
-
- private synchronized void sendErrorCallbacks(final TetherStatesParcel newStates) {
- for (int i = 0; i < newStates.erroredIfaceList.length; i++) {
- final String iface = newStates.erroredIfaceList[i];
- final Integer lastError = mErrorStates.get(iface);
- final int newError = newStates.lastErrorList[i];
- if (newError != TETHER_ERROR_NO_ERROR
- && !Objects.equals(lastError, newError)) {
- callback.onError(iface, newError);
- }
- mErrorStates.put(iface, newError);
- }
- }
-
- private synchronized void maybeSendTetherableIfacesChangedCallback(
- final TetherStatesParcel newStates) {
- if (Arrays.equals(mLastTetherableInterfaces, newStates.availableList)) return;
- mLastTetherableInterfaces = newStates.availableList.clone();
- callback.onTetherableInterfacesChanged(
- Collections.unmodifiableList(Arrays.asList(mLastTetherableInterfaces)));
- }
-
- private synchronized void maybeSendTetheredIfacesChangedCallback(
- final TetherStatesParcel newStates) {
- if (Arrays.equals(mLastTetheredInterfaces, newStates.tetheredList)) return;
- mLastTetheredInterfaces = newStates.tetheredList.clone();
- callback.onTetheredInterfacesChanged(
- Collections.unmodifiableList(Arrays.asList(mLastTetheredInterfaces)));
- }
-
- // Called immediately after the callbacks are registered.
- @Override
- public void onCallbackStarted(TetheringCallbackStartedParcel parcel) {
- executor.execute(() -> {
- callback.onTetheringSupported(parcel.tetheringSupported);
- callback.onUpstreamChanged(parcel.upstreamNetwork);
- sendErrorCallbacks(parcel.states);
- sendRegexpsChanged(parcel.config);
- maybeSendTetherableIfacesChangedCallback(parcel.states);
- maybeSendTetheredIfacesChangedCallback(parcel.states);
- callback.onClientsChanged(parcel.tetheredClients);
- callback.onOffloadStatusChanged(parcel.offloadStatus);
- });
- }
-
- @Override
- public void onCallbackStopped(int errorCode) {
- executor.execute(() -> {
- throwIfPermissionFailure(errorCode);
- });
- }
-
- private void sendRegexpsChanged(TetheringConfigurationParcel parcel) {
- callback.onTetherableInterfaceRegexpsChanged(new TetheringInterfaceRegexps(
- parcel.tetherableBluetoothRegexs,
- parcel.tetherableUsbRegexs,
- parcel.tetherableWifiRegexs));
- }
-
- @Override
- public void onConfigurationChanged(TetheringConfigurationParcel config) {
- executor.execute(() -> sendRegexpsChanged(config));
- }
-
- @Override
- public void onTetherStatesChanged(TetherStatesParcel states) {
- executor.execute(() -> {
- sendErrorCallbacks(states);
- maybeSendTetherableIfacesChangedCallback(states);
- maybeSendTetheredIfacesChangedCallback(states);
- });
- }
-
- @Override
- public void onTetherClientsChanged(final List<TetheredClient> clients) {
- executor.execute(() -> callback.onClientsChanged(clients));
- }
-
- @Override
- public void onOffloadStatusChanged(final int status) {
- executor.execute(() -> callback.onOffloadStatusChanged(status));
- }
- };
- getConnector(c -> c.registerTetheringEventCallback(remoteCallback, callerPkg));
- mTetheringEventCallbacks.put(callback, remoteCallback);
- }
- }
-
- /**
- * Remove tethering event callback previously registered with
- * {@link #registerTetheringEventCallback}.
- *
- * @param callback previously registered callback.
- */
- @RequiresPermission(anyOf = {
- Manifest.permission.TETHER_PRIVILEGED,
- Manifest.permission.ACCESS_NETWORK_STATE
- })
- public void unregisterTetheringEventCallback(@NonNull final TetheringEventCallback callback) {
- final String callerPkg = mContext.getOpPackageName();
- Log.i(TAG, "unregisterTetheringEventCallback caller:" + callerPkg);
-
- synchronized (mTetheringEventCallbacks) {
- ITetheringEventCallback remoteCallback = mTetheringEventCallbacks.remove(callback);
- if (remoteCallback == null) {
- throw new IllegalArgumentException("callback was not registered.");
- }
-
- getConnector(c -> c.unregisterTetheringEventCallback(remoteCallback, callerPkg));
- }
- }
-
- /**
- * Get a more detailed error code after a Tethering or Untethering
- * request asynchronously failed.
- *
- * @param iface The name of the interface of interest
- * @return error The error code of the last error tethering or untethering the named
- * interface
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public int getLastTetherError(@NonNull final String iface) {
- mCallback.waitForStarted();
- if (mTetherStatesParcel == null) return TETHER_ERROR_NO_ERROR;
-
- int i = 0;
- for (String errored : mTetherStatesParcel.erroredIfaceList) {
- if (iface.equals(errored)) return mTetherStatesParcel.lastErrorList[i];
-
- i++;
- }
- return TETHER_ERROR_NO_ERROR;
- }
-
- /**
- * Get the list of regular expressions that define any tetherable
- * USB network interfaces. If USB tethering is not supported by the
- * device, this list should be empty.
- *
- * @return an array of 0 or more regular expression Strings defining
- * what interfaces are considered tetherable usb interfaces.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public @NonNull String[] getTetherableUsbRegexs() {
- mCallback.waitForStarted();
- return mTetheringConfiguration.tetherableUsbRegexs;
- }
-
- /**
- * Get the list of regular expressions that define any tetherable
- * Wifi network interfaces. If Wifi tethering is not supported by the
- * device, this list should be empty.
- *
- * @return an array of 0 or more regular expression Strings defining
- * what interfaces are considered tetherable wifi interfaces.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public @NonNull String[] getTetherableWifiRegexs() {
- mCallback.waitForStarted();
- return mTetheringConfiguration.tetherableWifiRegexs;
- }
-
- /**
- * Get the list of regular expressions that define any tetherable
- * Bluetooth network interfaces. If Bluetooth tethering is not supported by the
- * device, this list should be empty.
- *
- * @return an array of 0 or more regular expression Strings defining
- * what interfaces are considered tetherable bluetooth interfaces.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public @NonNull String[] getTetherableBluetoothRegexs() {
- mCallback.waitForStarted();
- return mTetheringConfiguration.tetherableBluetoothRegexs;
- }
-
- /**
- * Get the set of tetherable, available interfaces. This list is limited by
- * device configuration and current interface existence.
- *
- * @return an array of 0 or more Strings of tetherable interface names.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public @NonNull String[] getTetherableIfaces() {
- mCallback.waitForStarted();
- if (mTetherStatesParcel == null) return new String[0];
-
- return mTetherStatesParcel.availableList;
- }
-
- /**
- * Get the set of tethered interfaces.
- *
- * @return an array of 0 or more String of currently tethered interface names.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public @NonNull String[] getTetheredIfaces() {
- mCallback.waitForStarted();
- if (mTetherStatesParcel == null) return new String[0];
-
- return mTetherStatesParcel.tetheredList;
- }
-
- /**
- * Get the set of interface names which attempted to tether but
- * failed. Re-attempting to tether may cause them to reset to the Tethered
- * state. Alternatively, causing the interface to be destroyed and recreated
- * may cause them to reset to the available state.
- * {@link TetheringManager#getLastTetherError} can be used to get more
- * information on the cause of the errors.
- *
- * @return an array of 0 or more String indicating the interface names
- * which failed to tether.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public @NonNull String[] getTetheringErroredIfaces() {
- mCallback.waitForStarted();
- if (mTetherStatesParcel == null) return new String[0];
-
- return mTetherStatesParcel.erroredIfaceList;
- }
-
- /**
- * Get the set of tethered dhcp ranges.
- *
- * @deprecated This API just return the default value which is not used in DhcpServer.
- * @hide
- */
- @Deprecated
- public @NonNull String[] getTetheredDhcpRanges() {
- mCallback.waitForStarted();
- return mTetheringConfiguration.legacyDhcpRanges;
- }
-
- /**
- * Check if the device allows for tethering. It may be disabled via
- * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
- * due to device configuration.
- *
- * @return a boolean - {@code true} indicating Tethering is supported.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public boolean isTetheringSupported() {
- final String callerPkg = mContext.getOpPackageName();
-
- return isTetheringSupported(callerPkg);
- }
-
- /**
- * Check if the device allows for tethering. It may be disabled via {@code ro.tether.denied}
- * system property, Settings.TETHER_SUPPORTED or due to device configuration. This is useful
- * for system components that query this API on behalf of an app. In particular, Bluetooth
- * has @UnsupportedAppUsage calls that will let apps turn on bluetooth tethering if they have
- * the right permissions, but such an app needs to know whether it can (permissions as well
- * as support from the device) turn on tethering in the first place to show the appropriate UI.
- *
- * @param callerPkg The caller package name, if it is not matching the calling uid,
- * SecurityException would be thrown.
- * @return a boolean - {@code true} indicating Tethering is supported.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public boolean isTetheringSupported(@NonNull final String callerPkg) {
-
- final RequestDispatcher dispatcher = new RequestDispatcher();
- final int ret = dispatcher.waitForResult((connector, listener) -> {
- try {
- connector.isTetheringSupported(callerPkg, listener);
- } catch (RemoteException e) {
- throw new IllegalStateException(e);
- }
- });
-
- return ret == TETHER_ERROR_NO_ERROR;
- }
-
- /**
- * Stop all active tethering.
- *
- * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
- * fail if a tethering entitlement check is required.
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.TETHER_PRIVILEGED,
- android.Manifest.permission.WRITE_SETTINGS
- })
- public void stopAllTethering() {
- final String callerPkg = mContext.getOpPackageName();
- Log.i(TAG, "stopAllTethering caller:" + callerPkg);
-
- getConnector(c -> c.stopAllTethering(callerPkg, new IIntResultListener.Stub() {
- @Override
- public void onResult(int resultCode) {
- // TODO: add an API parameter to send result to caller.
- // This has never been possible as stopAllTethering has always been void and never
- // taken a callback object. The only indication that callers have is if the call
- // results in a TETHER_STATE_CHANGE broadcast.
- }
- }));
- }
-}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl b/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl
deleted file mode 100644
index c0280d3..0000000
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl
+++ /dev/null
@@ -1,31 +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.net;
-
-import android.net.LinkAddress;
-
-/**
- * Configuration details for requesting tethering.
- * @hide
- */
-parcelable TetheringRequestParcel {
- int tetheringType;
- LinkAddress localIPv4Address;
- LinkAddress staticClientAddress;
- boolean exemptFromEntitlementCheck;
- boolean showProvisioningUi;
-}
diff --git a/packages/Tethering/jarjar-rules.txt b/packages/Tethering/jarjar-rules.txt
deleted file mode 100644
index 591861f..0000000
--- a/packages/Tethering/jarjar-rules.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-# These must be kept in sync with the framework-tethering-shared-srcs filegroup.
-# Classes from the framework-tethering-shared-srcs filegroup.
-# If there are files in that filegroup that are not covered below, the classes in the
-# module will be overwritten by the ones in the framework.
-rule com.android.internal.util.** com.android.networkstack.tethering.util.@1
-rule android.util.LocalLog* com.android.networkstack.tethering.util.LocalLog@1
-
-rule android.net.shared.Inet4AddressUtils* com.android.networkstack.tethering.shared.Inet4AddressUtils@1
-
-# Classes from net-utils-framework-common
-rule com.android.net.module.util.** com.android.networkstack.tethering.util.@1
\ No newline at end of file
diff --git a/packages/Tethering/jni/android_net_util_TetheringUtils.cpp b/packages/Tethering/jni/android_net_util_TetheringUtils.cpp
deleted file mode 100644
index 54934406..0000000
--- a/packages/Tethering/jni/android_net_util_TetheringUtils.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <error.h>
-#include <jni.h>
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedUtfChars.h>
-#include <net/if.h>
-#include <netinet/icmp6.h>
-#include <sys/socket.h>
-
-#define LOG_TAG "TetheringUtils"
-#include <android/log.h>
-
-namespace android {
-
-static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject javaFd,
- jint ifIndex)
-{
- static const int kLinkLocalHopLimit = 255;
-
- int fd = jniGetFDFromFileDescriptor(env, javaFd);
-
- // Set an ICMPv6 filter that only passes Router Solicitations.
- struct icmp6_filter rs_only;
- ICMP6_FILTER_SETBLOCKALL(&rs_only);
- ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &rs_only);
- socklen_t len = sizeof(rs_only);
- if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &rs_only, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(ICMP6_FILTER): %s", strerror(errno));
- return;
- }
-
- // Most/all of the rest of these options can be set via Java code, but
- // because we're here on account of setting an icmp6_filter go ahead
- // and do it all natively for now.
-
- // Set the multicast hoplimit to 255 (link-local only).
- int hops = kLinkLocalHopLimit;
- len = sizeof(hops);
- if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(IPV6_MULTICAST_HOPS): %s", strerror(errno));
- return;
- }
-
- // Set the unicast hoplimit to 255 (link-local only).
- hops = kLinkLocalHopLimit;
- len = sizeof(hops);
- if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(IPV6_UNICAST_HOPS): %s", strerror(errno));
- return;
- }
-
- // Explicitly disable multicast loopback.
- int off = 0;
- len = sizeof(off);
- if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(IPV6_MULTICAST_LOOP): %s", strerror(errno));
- return;
- }
-
- // Specify the IPv6 interface to use for outbound multicast.
- len = sizeof(ifIndex);
- if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifIndex, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(IPV6_MULTICAST_IF): %s", strerror(errno));
- return;
- }
-
- // Additional options to be considered:
- // - IPV6_TCLASS
- // - IPV6_RECVPKTINFO
- // - IPV6_RECVHOPLIMIT
-
- // Bind to [::].
- const struct sockaddr_in6 sin6 = {
- .sin6_family = AF_INET6,
- .sin6_port = 0,
- .sin6_flowinfo = 0,
- .sin6_addr = IN6ADDR_ANY_INIT,
- .sin6_scope_id = 0,
- };
- auto sa = reinterpret_cast<const struct sockaddr *>(&sin6);
- len = sizeof(sin6);
- if (bind(fd, sa, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "bind(IN6ADDR_ANY): %s", strerror(errno));
- return;
- }
-
- // Join the all-routers multicast group, ff02::2%index.
- struct ipv6_mreq all_rtrs = {
- .ipv6mr_multiaddr = {{{0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2}}},
- .ipv6mr_interface = ifIndex,
- };
- len = sizeof(all_rtrs);
- if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &all_rtrs, len) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(IPV6_JOIN_GROUP): %s", strerror(errno));
- return;
- }
-}
-
-/*
- * JNI registration.
- */
-static const JNINativeMethod gMethods[] = {
- /* name, signature, funcPtr */
- { "setupRaSocket", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_util_setupRaSocket },
-};
-
-int register_android_net_util_TetheringUtils(JNIEnv* env) {
- return jniRegisterNativeMethods(env,
- "android/net/util/TetheringUtils",
- gMethods, NELEM(gMethods));
-}
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
- JNIEnv *env;
- if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
- __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
- return JNI_ERR;
- }
-
- if (register_android_net_util_TetheringUtils(env) < 0) {
- return JNI_ERR;
- }
-
- return JNI_VERSION_1_6;
-}
-
-}; // namespace android
diff --git a/packages/Tethering/proguard.flags b/packages/Tethering/proguard.flags
deleted file mode 100644
index 051fbd1..0000000
--- a/packages/Tethering/proguard.flags
+++ /dev/null
@@ -1,9 +0,0 @@
-# Keep class's integer static field for MessageUtils to parsing their name.
--keep class com.android.networkstack.tethering.Tethering$TetherMasterSM {
- static final int CMD_*;
- static final int EVENT_*;
-}
-
--keepclassmembers class android.net.ip.IpServer {
- static final int CMD_*;
-}
diff --git a/packages/Tethering/res/drawable-hdpi/stat_sys_tether_bluetooth.png b/packages/Tethering/res/drawable-hdpi/stat_sys_tether_bluetooth.png
deleted file mode 100644
index 9451174..0000000
--- a/packages/Tethering/res/drawable-hdpi/stat_sys_tether_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-hdpi/stat_sys_tether_general.png b/packages/Tethering/res/drawable-hdpi/stat_sys_tether_general.png
deleted file mode 100644
index 79d5756..0000000
--- a/packages/Tethering/res/drawable-hdpi/stat_sys_tether_general.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-hdpi/stat_sys_tether_usb.png b/packages/Tethering/res/drawable-hdpi/stat_sys_tether_usb.png
deleted file mode 100644
index cae1bd1..0000000
--- a/packages/Tethering/res/drawable-hdpi/stat_sys_tether_usb.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-ldpi/stat_sys_tether_bluetooth.png b/packages/Tethering/res/drawable-ldpi/stat_sys_tether_bluetooth.png
deleted file mode 100644
index ffe8e8c..0000000
--- a/packages/Tethering/res/drawable-ldpi/stat_sys_tether_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-ldpi/stat_sys_tether_general.png b/packages/Tethering/res/drawable-ldpi/stat_sys_tether_general.png
deleted file mode 100644
index ca20f73..0000000
--- a/packages/Tethering/res/drawable-ldpi/stat_sys_tether_general.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-ldpi/stat_sys_tether_usb.png b/packages/Tethering/res/drawable-ldpi/stat_sys_tether_usb.png
deleted file mode 100644
index 65e9075..0000000
--- a/packages/Tethering/res/drawable-ldpi/stat_sys_tether_usb.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-mdpi/stat_sys_tether_bluetooth.png b/packages/Tethering/res/drawable-mdpi/stat_sys_tether_bluetooth.png
deleted file mode 100644
index f42dae0..0000000
--- a/packages/Tethering/res/drawable-mdpi/stat_sys_tether_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-mdpi/stat_sys_tether_general.png b/packages/Tethering/res/drawable-mdpi/stat_sys_tether_general.png
deleted file mode 100644
index 0655161..0000000
--- a/packages/Tethering/res/drawable-mdpi/stat_sys_tether_general.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-mdpi/stat_sys_tether_usb.png b/packages/Tethering/res/drawable-mdpi/stat_sys_tether_usb.png
deleted file mode 100644
index 2e2b8ca..0000000
--- a/packages/Tethering/res/drawable-mdpi/stat_sys_tether_usb.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-xhdpi/stat_sys_tether_bluetooth.png b/packages/Tethering/res/drawable-xhdpi/stat_sys_tether_bluetooth.png
deleted file mode 100644
index 3f57d1c..0000000
--- a/packages/Tethering/res/drawable-xhdpi/stat_sys_tether_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-xhdpi/stat_sys_tether_general.png b/packages/Tethering/res/drawable-xhdpi/stat_sys_tether_general.png
deleted file mode 100644
index 34b0cb3..0000000
--- a/packages/Tethering/res/drawable-xhdpi/stat_sys_tether_general.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-xhdpi/stat_sys_tether_usb.png b/packages/Tethering/res/drawable-xhdpi/stat_sys_tether_usb.png
deleted file mode 100644
index 36afe48..0000000
--- a/packages/Tethering/res/drawable-xhdpi/stat_sys_tether_usb.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-xxhdpi/stat_sys_tether_bluetooth.png b/packages/Tethering/res/drawable-xxhdpi/stat_sys_tether_bluetooth.png
deleted file mode 100644
index 25acfbb..0000000
--- a/packages/Tethering/res/drawable-xxhdpi/stat_sys_tether_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-xxhdpi/stat_sys_tether_general.png b/packages/Tethering/res/drawable-xxhdpi/stat_sys_tether_general.png
deleted file mode 100644
index 5c65601..0000000
--- a/packages/Tethering/res/drawable-xxhdpi/stat_sys_tether_general.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/drawable-xxhdpi/stat_sys_tether_usb.png b/packages/Tethering/res/drawable-xxhdpi/stat_sys_tether_usb.png
deleted file mode 100644
index 28b4b54..0000000
--- a/packages/Tethering/res/drawable-xxhdpi/stat_sys_tether_usb.png
+++ /dev/null
Binary files differ
diff --git a/packages/Tethering/res/values-af/strings.xml b/packages/Tethering/res/values-af/strings.xml
deleted file mode 100644
index 056168b..0000000
--- a/packages/Tethering/res/values-af/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Verbinding of warmkol is aktief"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Tik om op te stel."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Verbinding is gedeaktiveer"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontak jou administrateur vir besonderhede"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Warmkol- en verbindingstatus"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-am/strings.xml b/packages/Tethering/res/values-am/strings.xml
deleted file mode 100644
index ac468dd..0000000
--- a/packages/Tethering/res/values-am/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"እንደ ሞደም መሰካት ወይም መገናኛ ነጥብ ገባሪ"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"ለማዋቀር መታ ያድርጉ።"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"እንደ ሞደም መሰካት ተሰናክሏል"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"መገናኛ ነጥብ እና እንደ ሞደም የመሰካት ሁኔታ"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ar/strings.xml b/packages/Tethering/res/values-ar/strings.xml
deleted file mode 100644
index 7d5bad3..0000000
--- a/packages/Tethering/res/values-ar/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"النطاق نشط أو نقطة الاتصال نشطة"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"انقر للإعداد."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"التوصيل متوقف."</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"تواصَل مع المشرف للحصول على التفاصيل."</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"حالة نقطة الاتصال والتوصيل"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-as/strings.xml b/packages/Tethering/res/values-as/strings.xml
deleted file mode 100644
index 0913504..0000000
--- a/packages/Tethering/res/values-as/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"টে\'ডাৰিং অথবা হ\'টস্প\'ট সক্ৰিয় অৱস্থাত আছে"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"ছেট আপ কৰিবলৈ টিপক।"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"টে\'ডাৰিঙৰ সুবিধাটো অক্ষম কৰি থোৱা হৈছে"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"সবিশেষ জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"হ’টস্প\'ট আৰু টে\'ডাৰিঙৰ স্থিতি"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-az/strings.xml b/packages/Tethering/res/values-az/strings.xml
deleted file mode 100644
index dce70da..0000000
--- a/packages/Tethering/res/values-az/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Birləşmə və ya hotspot aktivdir"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamaq üçün toxunun."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Birləşmə deaktivdir"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Detallar üçün adminlə əlaqə saxlayın"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot & birləşmə statusu"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-b+sr+Latn/strings.xml b/packages/Tethering/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index b0774ec..0000000
--- a/packages/Tethering/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Privezivanje ili hotspot je aktivan"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste podesili."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Privezivanje je onemogućeno"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Potražite detalje od administratora"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspota i privezivanja"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-be/strings.xml b/packages/Tethering/res/values-be/strings.xml
deleted file mode 100644
index a8acebe..0000000
--- a/packages/Tethering/res/values-be/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Мадэм або хот-спот актыўныя"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Дакраніцеся, каб наладзіць."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Рэжым мадэма выключаны"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Стан \"Хот-спот і мадэм\""</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-bg/strings.xml b/packages/Tethering/res/values-bg/strings.xml
deleted file mode 100644
index 94fb2d8..0000000
--- a/packages/Tethering/res/values-bg/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Има активна споделена връзка или точка за достъп"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Докоснете, за да настроите."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Функцията за тетъринг е деактивирана"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Свържете се с администратора си за подробности"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Състояние на функцията за точка за достъп и тетъринг"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-bn/strings.xml b/packages/Tethering/res/values-bn/strings.xml
deleted file mode 100644
index aea02b9..0000000
--- a/packages/Tethering/res/values-bn/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"টিথারিং বা হটস্পট চালু আছে"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"সেট-আপ করতে ট্যাপ করুন।"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"টিথারিং বন্ধ করা আছে"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"বিশদে জানতে অ্যাডমিনের সাথে যোগাযোগ করুন"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"হটস্পট ও টিথারিং স্ট্যাটাস"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-bs/strings.xml b/packages/Tethering/res/values-bs/strings.xml
deleted file mode 100644
index de23272..0000000
--- a/packages/Tethering/res/values-bs/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Aktivno je povezivanje putem mobitela ili pristupna tačka"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da postavite."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezivanje putem mobitela je onemogućeno"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontaktirajte svog administratora za detalje"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status pristupne tačke i povezivanja putem mobitela"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ca/strings.xml b/packages/Tethering/res/values-ca/strings.xml
deleted file mode 100644
index 88b795c..0000000
--- a/packages/Tethering/res/values-ca/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Compartició de xarxa o punt d\'accés Wi‑Fi actius"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Toca per configurar."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"La compartició de xarxa està desactivada"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta amb el teu administrador per obtenir més informació"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estat del punt d\'accés Wi‑Fi i de la compartició de xarxa"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-cs/strings.xml b/packages/Tethering/res/values-cs/strings.xml
deleted file mode 100644
index 8c1b83b..0000000
--- a/packages/Tethering/res/values-cs/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering nebo hotspot je aktivní"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím zahájíte nastavení."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je zakázán"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požádejte administrátora"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-da/strings.xml b/packages/Tethering/res/values-da/strings.xml
deleted file mode 100644
index f413e70..0000000
--- a/packages/Tethering/res/values-da/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Netdeling eller hotspot er aktivt"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Tryk for at konfigurere."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Netdeling er deaktiveret"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakt din administrator for at få oplysninger"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for hotspot og netdeling"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-de/strings.xml b/packages/Tethering/res/values-de/strings.xml
deleted file mode 100644
index f057d78..0000000
--- a/packages/Tethering/res/values-de/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering oder Hotspot aktiv"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Zum Einrichten tippen."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering ist deaktiviert"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Bitte wende dich für weitere Informationen an den Administrator"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot- und Tethering-Status"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-el/strings.xml b/packages/Tethering/res/values-el/strings.xml
deleted file mode 100644
index b3c986b..0000000
--- a/packages/Tethering/res/values-el/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Πατήστε για ρύθμιση."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Η σύνδεση είναι απενεργοποιημένη"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Κατάσταση σημείου πρόσβασης Wi-Fi και σύνδεσης"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-en-rAU/strings.xml b/packages/Tethering/res/values-en-rAU/strings.xml
deleted file mode 100644
index 769e0120..0000000
--- a/packages/Tethering/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-en-rCA/strings.xml b/packages/Tethering/res/values-en-rCA/strings.xml
deleted file mode 100644
index 769e0120..0000000
--- a/packages/Tethering/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-en-rGB/strings.xml b/packages/Tethering/res/values-en-rGB/strings.xml
deleted file mode 100644
index 769e0120..0000000
--- a/packages/Tethering/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-en-rIN/strings.xml b/packages/Tethering/res/values-en-rIN/strings.xml
deleted file mode 100644
index 769e0120..0000000
--- a/packages/Tethering/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-en-rXC/strings.xml b/packages/Tethering/res/values-en-rXC/strings.xml
deleted file mode 100644
index f1674be..0000000
--- a/packages/Tethering/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot & tethering status"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-es-rUS/strings.xml b/packages/Tethering/res/values-es-rUS/strings.xml
deleted file mode 100644
index 63689f4..0000000
--- a/packages/Tethering/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión a red o hotspot conectados"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Presiona para configurar esta opción."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Se inhabilitó la conexión mediante dispositivo portátil"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Para obtener más información, comunícate con el administrador"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del hotspot y la conexión mediante dispositivo portátil"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-es/strings.xml b/packages/Tethering/res/values-es/strings.xml
deleted file mode 100644
index 9a34ed5..0000000
--- a/packages/Tethering/res/values-es/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida o punto de acceso activos"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"La conexión compartida está inhabilitada"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Solicita más información a tu administrador"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del punto de acceso y de la conexión compartida"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-et/strings.xml b/packages/Tethering/res/values-et/strings.xml
deleted file mode 100644
index 0970341..0000000
--- a/packages/Tethering/res/values-et/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Jagamine või kuumkoht on aktiivne"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Puudutage seadistamiseks."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Jagamine on keelatud"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Kuumkoha ja jagamise olek"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-eu/strings.xml b/packages/Tethering/res/values-eu/strings.xml
deleted file mode 100644
index 632019e..0000000
--- a/packages/Tethering/res/values-eu/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Konexioa partekatzea edo wifi-gunea aktibo dago"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Sakatu konfiguratzeko."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Desgaituta dago konexioa partekatzeko aukera"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Wifi-gunearen eta konexioa partekatzeko eginbidearen egoera"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-fa/strings.xml b/packages/Tethering/res/values-fa/strings.xml
deleted file mode 100644
index 2e21c85..0000000
--- a/packages/Tethering/res/values-fa/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"اشتراکگذاری اینترنت یا نقطه اتصال فعال"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"برای راهاندازی ضربه بزنید."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"اشتراکگذاری اینترنت غیرفعال است"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"برای جزئیات، با سرپرستتان تماس بگیرید"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"وضعیت نقطه اتصال و اشتراکگذاری اینترنت"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-fi/strings.xml b/packages/Tethering/res/values-fi/strings.xml
deleted file mode 100644
index 413db3f..0000000
--- a/packages/Tethering/res/values-fi/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Yhteyden jakaminen tai hotspot käytössä"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Ota käyttöön napauttamalla."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Yhteyden jakaminen on poistettu käytöstä"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pyydä lisätietoja järjestelmänvalvojalta"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspotin ja yhteyden jakamisen tila"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-fr-rCA/strings.xml b/packages/Tethering/res/values-fr-rCA/strings.xml
deleted file mode 100644
index eb2e4ba..0000000
--- a/packages/Tethering/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès sans fil activé"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Touchez pour configurer."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Communiquez avec votre administrateur pour obtenir plus de détails"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Point d\'accès et partage de connexion"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-fr/strings.xml b/packages/Tethering/res/values-fr/strings.xml
deleted file mode 100644
index 22259c5..0000000
--- a/packages/Tethering/res/values-fr/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès activé"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Appuyez pour effectuer la configuration."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pour en savoir plus, contactez votre administrateur"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"État du point d\'accès et du partage de connexion"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-gl/strings.xml b/packages/Tethering/res/values-gl/strings.xml
deleted file mode 100644
index ded82fc..0000000
--- a/packages/Tethering/res/values-gl/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida ou zona wifi activada"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"A conexión compartida está desactivada"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta co administrador para obter información"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona wifi e da conexión compartida"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-gu/strings.xml b/packages/Tethering/res/values-gu/strings.xml
deleted file mode 100644
index 7cbbc2d..0000000
--- a/packages/Tethering/res/values-gu/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"ઇન્ટરનેટ શેર કરવાની સુવિધા અથવા હૉટસ્પૉટ સક્રિય છે"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"સેટઅપ કરવા માટે ટૅપ કરો."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરી છે"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"હૉટસ્પૉટ અને ઇન્ટરનેટ શેર કરવાની સુવિધાનું સ્ટેટસ"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-hi/strings.xml b/packages/Tethering/res/values-hi/strings.xml
deleted file mode 100644
index 08af81b..0000000
--- a/packages/Tethering/res/values-hi/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिंग या हॉटस्पॉट चालू है"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"सेट अप करने के लिए टैप करें."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिंग बंद है"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"जानकारी के लिए अपने एडमिन से संपर्क करें"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हॉटस्पॉट और टेदरिंग की स्थिति"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-hr/strings.xml b/packages/Tethering/res/values-hr/strings.xml
deleted file mode 100644
index 827c135..0000000
--- a/packages/Tethering/res/values-hr/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Modemsko povezivanje ili žarišna točka aktivni"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste postavili."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modemsko je povezivanje onemogućeno"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Obratite se administratoru da biste saznali pojedinosti"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status žarišne točke i modemskog povezivanja"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-hu/strings.xml b/packages/Tethering/res/values-hu/strings.xml
deleted file mode 100644
index eb68d6b..0000000
--- a/packages/Tethering/res/values-hu/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Megosztás vagy aktív hotspot"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Koppintson a beállításhoz."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Az internetmegosztás le van tiltva"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"A részletekért forduljon rendszergazdájához"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot és internetmegosztás állapota"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-hy/strings.xml b/packages/Tethering/res/values-hy/strings.xml
deleted file mode 100644
index 912941e..0000000
--- a/packages/Tethering/res/values-hy/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Մոդեմի ռեժիմը միացված է"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Հպեք՝ կարգավորելու համար։"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Մոդեմի ռեժիմն անջատված է"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Թեժ կետի և մոդեմի ռեժիմի կարգավիճակը"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-in/strings.xml b/packages/Tethering/res/values-in/strings.xml
deleted file mode 100644
index a4e175a..0000000
--- a/packages/Tethering/res/values-in/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering atau hotspot aktif"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Ketuk untuk menyiapkan."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering dinonaktifkan"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi admin untuk mengetahui detailnya"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspot & tethering"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-is/strings.xml b/packages/Tethering/res/values-is/strings.xml
deleted file mode 100644
index e9f6670..0000000
--- a/packages/Tethering/res/values-is/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Kveikt á tjóðrun eða aðgangsstað"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Ýttu til að setja upp."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Slökkt er á tjóðrun"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Staða heits reits og tjóðrunar"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-it/strings.xml b/packages/Tethering/res/values-it/strings.xml
deleted file mode 100644
index ffb9196..0000000
--- a/packages/Tethering/res/values-it/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Hotspot o tethering attivo"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Tocca per impostare."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering disattivato"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contatta il tuo amministratore per avere informazioni dettagliate"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stato hotspot e tethering"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-iw/strings.xml b/packages/Tethering/res/values-iw/strings.xml
deleted file mode 100644
index 7adcb47..0000000
--- a/packages/Tethering/res/values-iw/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"נקודה לשיתוף אינטרנט או שיתוף אינטרנט בין מכשירים: בסטטוס פעיל"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"יש להקיש כדי להגדיר."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"שיתוף האינטרנט בין מכשירים מושבת"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"לפרטים, יש לפנות למנהל המערכת"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"סטטוס של נקודה לשיתוף אינטרנט ושיתוף אינטרנט בין מכשירים"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ja/strings.xml b/packages/Tethering/res/values-ja/strings.xml
deleted file mode 100644
index f68a730..0000000
--- a/packages/Tethering/res/values-ja/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"テザリングまたはアクセス ポイントが有効です"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"タップしてセットアップします。"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"テザリングは無効に設定されています"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳しくは、管理者にお問い合わせください"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"アクセス ポイントとテザリングのステータス"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ka/strings.xml b/packages/Tethering/res/values-ka/strings.xml
deleted file mode 100644
index 7c22e82..0000000
--- a/packages/Tethering/res/values-ka/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"შეეხეთ დასაყენებლად."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ტეტერინგი გათიშულია"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"უსადენო ქსელის და ტეტერინგის სტატუსი"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-kk/strings.xml b/packages/Tethering/res/values-kk/strings.xml
deleted file mode 100644
index 0857d06..0000000
--- a/packages/Tethering/res/values-kk/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Тетеринг немесе хотспот қосулы"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Реттеу үшін түртіңіз."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Тетеринг өшірілді."</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Мәліметтерді әкімшіден алыңыз."</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Хотспот және тетеринг күйі"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-km/strings.xml b/packages/Tethering/res/values-km/strings.xml
deleted file mode 100644
index 536e3d1..0000000
--- a/packages/Tethering/res/values-km/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"ការភ្ជាប់ ឬហតស្ប៉តកំពុងដំណើរការ"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"ចុចដើម្បីរៀបចំ។"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ការភ្ជាប់ត្រូវបានបិទ"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"ទាក់ទងអ្នកគ្រប់គ្រងរបស់អ្នក ដើម្បីទទួលបានព័ត៌មានលម្អិត"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ស្ថានភាពនៃការភ្ជាប់ និងហតស្ប៉ត"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-kn/strings.xml b/packages/Tethering/res/values-kn/strings.xml
deleted file mode 100644
index 32f5492..0000000
--- a/packages/Tethering/res/values-kn/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"ಸೆಟಪ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ಹಾಟ್ಸ್ಪಾಟ್ ಮತ್ತು ಟೆಥರಿಂಗ್ ಸ್ಥಿತಿ"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ko/strings.xml b/packages/Tethering/res/values-ko/strings.xml
deleted file mode 100644
index 156b247..0000000
--- a/packages/Tethering/res/values-ko/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"테더링 또는 핫스팟 사용"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"설정하려면 탭하세요."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"테더링이 사용 중지됨"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"자세한 정보는 관리자에게 문의하세요."</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"핫스팟 및 테더링 상태"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ky/strings.xml b/packages/Tethering/res/values-ky/strings.xml
deleted file mode 100644
index 18ee5fd..0000000
--- a/packages/Tethering/res/values-ky/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Модем режими күйүп турат"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Жөндөө үчүн таптап коюңуз."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Телефонду модем катары колдонууга болбойт"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Байланыш түйүнүнүн жана модем режиминин статусу"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-lo/strings.xml b/packages/Tethering/res/values-lo/strings.xml
deleted file mode 100644
index b127670..0000000
--- a/packages/Tethering/res/values-lo/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"ເປີດການປ່ອຍສັນຍານ ຫຼື ຮັອດສະປອດແລ້ວ"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"ແຕະເພື່ອຕັ້ງຄ່າ."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ສະຖານະຮັອດສະປອດ ແລະ ການປ່ອຍສັນຍານ"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-lt/strings.xml b/packages/Tethering/res/values-lt/strings.xml
deleted file mode 100644
index 8427baf..0000000
--- a/packages/Tethering/res/values-lt/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Įrenginys naudojamas kaip modemas arba įjungtas viešosios interneto prieigos taškas"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Palieskite, kad nustatytumėte."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Įrenginio kaip modemo naudojimas išjungtas"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Viešosios interneto prieigos taško ir įrenginio kaip modemo naudojimo būsena"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-lv/strings.xml b/packages/Tethering/res/values-lv/strings.xml
deleted file mode 100644
index aa2d699..0000000
--- a/packages/Tethering/res/values-lv/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Piesaiste vai tīklājs ir aktīvs."</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Pieskarieties, lai to iestatītu."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Piesaiste ir atspējota"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Tīklāja un piesaistes statuss"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-af/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-af/strings.xml
deleted file mode 100644
index 19d659c..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-af/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Verbinding het nie internet nie"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Toestelle kan nie koppel nie"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Skakel verbinding af"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Warmkol of verbinding is aan"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Bykomende heffings kan geld terwyl jy swerf"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-am/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-am/strings.xml
deleted file mode 100644
index 8995430..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-am/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ማስተሳሰር ምንም በይነመረብ የለውም"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"መሣሪያዎችን ማገናኘት አይቻልም"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ማስተሳሰርን አጥፋ"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"መገናኛ ነጥብ ወይም ማስተሳሰር በርቷል"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"በሚያንዣብብበት ጊዜ ተጨማሪ ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ar/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ar/strings.xml
deleted file mode 100644
index 54f3b53..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ar/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ما مِن اتصال بالإنترنت خلال التوصيل"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"تعذّر اتصال الأجهزة"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"إيقاف التوصيل"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"نقطة الاتصال أو التوصيل مفعّلان"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"قد يتم تطبيق رسوم إضافية أثناء التجوال."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-as/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-as/strings.xml
deleted file mode 100644
index e215141c..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-as/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"টে\'ডাৰিঙৰ ইণ্টাৰনেট নাই"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"ডিভাইচসমূহ সংযোগ কৰিব নোৱাৰি"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"টে\'ডাৰিং অফ কৰক"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"হটস্পট অথবা টে\'ডাৰিং অন আছে"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ৰ\'মিঙত থাকিলে অতিৰিক্ত মাচুল প্ৰযোজ্য হ’ব পাৰে"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-az/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-az/strings.xml
deleted file mode 100644
index 1fd8e4c..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-az/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modemin internetə girişi yoxdur"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Cihazları qoşmaq mümkün deyil"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Modemi deaktiv edin"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot və ya modem aktivdir"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rouminq zamanı əlavə ödənişlər tətbiq edilə bilər"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml
deleted file mode 100644
index 1abe4f3..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Privezivanje nema pristup internetu"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Povezivanje uređaja nije uspelo"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključi privezivanje"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Uključen je hotspot ili privezivanje"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Možda važe dodatni troškovi u romingu"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-be/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-be/strings.xml
deleted file mode 100644
index 38dbd1e..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-be/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Рэжым мадэма выкарыстоўваецца без доступу да інтэрнэту"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Не ўдалося падключыць прылады"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Выключыць рэжым мадэма"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Хот-спот або рэжым мадэма ўключаны"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Пры выкарыстанні роўмінгу можа спаганяцца дадатковая плата"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-bg/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-bg/strings.xml
deleted file mode 100644
index 04b44db..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-bg/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Тетърингът няма връзка с интернет"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Устройствата не могат да установят връзка"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Изключване на тетъринга"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Точката за достъп или тетърингът са включени"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Възможно е да ви бъдат начислени допълнителни такси при роуминг"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-bn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-bn/strings.xml
deleted file mode 100644
index 579d1be..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-bn/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"টিথারিং করার জন্য কোনও ইন্টারনেট কানেকশন নেই"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"ডিভাইস কানেক্ট করতে পারছে না"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"টিথারিং বন্ধ করুন"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"হটস্পট বা টিথারিং চালু আছে"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"রোমিংয়ের সময় অতিরিক্ত চার্জ করা হতে পারে"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-bs/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-bs/strings.xml
deleted file mode 100644
index 9ce3efe..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-bs/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Povezivanje putem mobitela nema internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Uređaji se ne mogu povezati"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključi povezivanje putem mobitela"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Pristupna tačka ili povezivanje putem mobitela je uključeno"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Mogu nastati dodatni troškovi u romingu"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ca/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ca/strings.xml
deleted file mode 100644
index 46d4c35..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ca/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"La compartició de xarxa no té accés a Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"No es poden connectar els dispositius"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactiva la compartició de xarxa"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"S\'ha activat el punt d\'accés Wi‑Fi o la compartició de xarxa"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"És possible que s\'apliquin costos addicionals en itinerància"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-cs/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-cs/strings.xml
deleted file mode 100644
index cc13860..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-cs/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nemá připojení k internetu"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Zařízení se nemůžou připojit"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vypnout tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Je zapnutý hotspot nebo tethering"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Při roamingu mohou být účtovány dodatečné poplatky"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-da/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-da/strings.xml
deleted file mode 100644
index 92c3ae1..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-da/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Netdeling har ingen internetforbindelse"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enheder kan ikke oprette forbindelse"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Deaktiver netdeling"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot eller netdeling er aktiveret"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Der opkræves muligvis yderligere gebyrer ved roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-de/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-de/strings.xml
deleted file mode 100644
index 967eb4d..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-de/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering hat keinen Internetzugriff"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Geräte können sich nicht verbinden"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering deaktivieren"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot oder Tethering ist aktiviert"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Für das Roaming können zusätzliche Gebühren anfallen"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-el/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-el/strings.xml
deleted file mode 100644
index 5fb4974..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-el/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Η σύνδεση δεν έχει πρόσβαση στο διαδίκτυο"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Δεν είναι δυνατή η σύνδεση των συσκευών"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Απενεργοποιήστε τη σύνδεση"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ενεργό σημείο πρόσβασης Wi-Fi ή ενεργή σύνδεση"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ενδέχεται να ισχύουν επιπλέον χρεώσεις κατά την περιαγωγή."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml
deleted file mode 100644
index 45647f9..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml
deleted file mode 100644
index 45647f9..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml
deleted file mode 100644
index 45647f9..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml
deleted file mode 100644
index 45647f9..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml
deleted file mode 100644
index 7877074..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml
deleted file mode 100644
index 08edd81..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"La conexión mediante dispositivo móvil no tiene Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"No se pueden conectar los dispositivos"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión mediante dispositivo móvil"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Se activó el hotspot o la conexión mediante dispositivo móvil"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Es posible que se apliquen cargos adicionales por roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-es/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-es/strings.xml
deleted file mode 100644
index 79f51d0..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-es/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"La conexión no se puede compartir, porque no hay acceso a Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Los dispositivos no se pueden conectar"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión compartida"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Punto de acceso o conexión compartida activados"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Puede que se apliquen cargos adicionales en itinerancia"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-et/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-et/strings.xml
deleted file mode 100644
index 2da5f8a..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-et/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Jagamisel puudub internetiühendus"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Seadmed ei saa ühendust luua"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Lülita jagamine välja"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Kuumkoht või jagamine on sisse lülitatud"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rändluse kasutamisega võivad kaasneda lisatasud"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-eu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-eu/strings.xml
deleted file mode 100644
index 2073f28..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-eu/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Konexioa partekatzeko aukerak ez du Interneteko konexiorik"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Ezin dira konektatu gailuak"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desaktibatu konexioa partekatzeko aukera"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Wifi-gunea edo konexioa partekatzeko aukera aktibatuta dago"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Baliteke kostu gehigarriak ordaindu behar izatea ibiltaritzan"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-fa/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fa/strings.xml
deleted file mode 100644
index e21b2a0..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-fa/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"«اشتراکگذاری اینترنت» به اینترنت دسترسی ندارد"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"دستگاهها متصل نمیشوند"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"خاموش کردن «اشتراکگذاری اینترنت»"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"«نقطه اتصال» یا «اشتراکگذاری اینترنت» روشن است"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ممکن است درحین فراگردی تغییرات دیگر اعمال شود"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-fi/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fi/strings.xml
deleted file mode 100644
index 88b0b13..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-fi/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ei jaettavaa internetyhteyttä"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Laitteet eivät voi muodostaa yhteyttä"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Laita yhteyden jakaminen pois päältä"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot tai yhteyden jakaminen on päällä"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Roaming voi aiheuttaa lisämaksuja"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml
deleted file mode 100644
index 3b781bc..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Le partage de connexion n\'est pas connecté à Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossible de connecter les appareils"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Désactiver le partage de connexion"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Le point d\'accès ou le partage de connexion est activé"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-fr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fr/strings.xml
deleted file mode 100644
index 51d7203..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-fr/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Aucune connexion à Internet n\'est disponible pour le partage de connexion"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossible de connecter les appareils"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Désactiver le partage de connexion"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Le point d\'accès ou le partage de connexion est activé"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-gl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-gl/strings.xml
deleted file mode 100644
index 008ccb4..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-gl/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"A conexión compartida non ten Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Non se puideron conectar os dispositivos"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión compartida"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Está activada a zona wifi ou a conexión compartida"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pódense aplicar cargos adicionais en itinerancia"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-gu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-gu/strings.xml
deleted file mode 100644
index f2e3b4d..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-gu/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ઇન્ટરનેટ શેર કરવાની સુવિધામાં ઇન્ટરનેટ નથી"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"ડિવાઇસ કનેક્ટ કરી શકાતા નથી"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરો"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"હૉટસ્પૉટ અથવા ઇન્ટરનેટ શેર કરવાની સુવિધા ચાલુ છે"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"રોમિંગમાં વધારાના શુલ્ક લાગી શકે છે"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-hi/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hi/strings.xml
deleted file mode 100644
index b11839d..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-hi/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिंग से इंटरनेट नहीं चल रहा"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"डिवाइस कनेक्ट नहीं हो पा रहे"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिंग बंद करें"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हॉटस्पॉट या टेदरिंग चालू है"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिंग के दौरान अतिरिक्त शुल्क लग सकता है"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-hr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hr/strings.xml
deleted file mode 100644
index 0a5aca2..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-hr/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modemsko povezivanje nema internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Uređaji se ne mogu povezati"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključivanje modemskog povezivanja"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Uključena je žarišna točka ili modemsko povezivanje"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"U roamingu su mogući dodatni troškovi"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-hu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hu/strings.xml
deleted file mode 100644
index 21c689a4..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-hu/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nincs internetkapcsolat az internet megosztásához"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Az eszközök nem tudnak csatlakozni"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Internetmegosztás kikapcsolása"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"A hotspot vagy az internetmegosztás be van kapcsolva"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Roaming során további díjak léphetnek fel"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-hy/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hy/strings.xml
deleted file mode 100644
index 689d9287..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-hy/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Մոդեմի ռեժիմի կապը բացակայում է"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Չհաջողվեց միացնել սարքը"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Անջատել մոդեմի ռեժիմը"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Թեժ կետը կամ մոդեմի ռեժիմը միացված է"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ռոումինգում կարող են լրացուցիչ վճարներ գանձվել"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-in/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-in/strings.xml
deleted file mode 100644
index a5f4d19..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-in/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tidak ada koneksi internet di tethering"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Perangkat tidak dapat terhubung"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Nonaktifkan tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot atau tethering aktif"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Biaya tambahan mungkin berlaku saat roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-is/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-is/strings.xml
deleted file mode 100644
index fc7e8aa..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-is/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tjóðrun er ekki með internettengingu"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Tæki geta ekki tengst"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Slökkva á tjóðrun"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Kveikt er á heitum reit eða tjóðrun"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Viðbótargjöld kunna að eiga við í reiki"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-it/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-it/strings.xml
deleted file mode 100644
index 6456dd1..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-it/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nessuna connessione a Internet per il tethering"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossibile connettere i dispositivi"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Disattiva il tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot o tethering attivi"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Potrebbero essere applicati costi aggiuntivi durante il roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-iw/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-iw/strings.xml
deleted file mode 100644
index 46b24bd..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-iw/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"אי אפשר להפעיל את תכונת שיתוף האינטרנט בין מכשירים כי אין חיבור לאינטרנט"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"למכשירים אין אפשרות להתחבר"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"השבתה של שיתוף האינטרנט בין מכשירים"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"תכונת הנקודה לשיתוף אינטרנט או תכונת שיתוף האינטרנט בין מכשירים פועלת"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ייתכנו חיובים נוספים בעת נדידה"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ja/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ja/strings.xml
deleted file mode 100644
index e6eb277..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ja/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"テザリングがインターネットに接続されていません"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"デバイスを接続できません"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"テザリングを OFF にする"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"アクセス ポイントまたはテザリングが ON です"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ローミング時に追加料金が発生することがあります"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ka/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ka/strings.xml
deleted file mode 100644
index aeddd71..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ka/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ტეტერინგს არ აქვს ინტერნეტზე წვდომა"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"მოწყობილობები ვერ ახერხებენ დაკავშირებას"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ტეტერინგის გამორთვა"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ჩართულია უსადენო ქსელი ან ტეტერინგი"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"როუმინგის გამოყენებისას შეიძლება ჩამოგეჭრათ დამატებითი საფასური"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-kk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-kk/strings.xml
deleted file mode 100644
index 255f0a2..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-kk/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Тетеринг режимі интернет байланысынсыз пайдаланылуда"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Құрылғыларды байланыстыру мүмкін емес"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Тетерингіні өшіру"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Хотспот немесе тетеринг қосулы"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роуминг кезінде қосымша ақы алынуы мүмкін."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-km/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-km/strings.xml
deleted file mode 100644
index 2bceb1c..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-km/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ការភ្ជាប់មិនមានអ៊ីនធឺណិតទេ"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"មិនអាចភ្ជាប់ឧបករណ៍បានទេ"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"បិទការភ្ជាប់"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ហតស្ប៉ត ឬការភ្ជាប់ត្រូវបានបើក"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"អាចមានការគិតថ្លៃបន្ថែម នៅពេលរ៉ូមីង"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-kn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-kn/strings.xml
deleted file mode 100644
index ed76930..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-kn/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ಟೆಥರಿಂಗ್ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಕನೆಕ್ಷನ್ ಹೊಂದಿಲ್ಲ"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"ಸಾಧನಗಳನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ಟೆಥರಿಂಗ್ ಆಫ್ ಮಾಡಿ"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ಹಾಟ್ಸ್ಪಾಟ್ ಅಥವಾ ಟೆಥರಿಂಗ್ ಆನ್ ಆಗಿದೆ"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ರೋಮಿಂಗ್ನಲ್ಲಿರುವಾಗ ಹೆಚ್ಚುವರಿ ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ko/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ko/strings.xml
deleted file mode 100644
index 6e50494..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ko/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"테더링으로 인터넷을 사용할 수 없음"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"기기에서 연결할 수 없음"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"테더링 사용 중지"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"핫스팟 또는 테더링 켜짐"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"로밍 중에는 추가 요금이 발생할 수 있습니다."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ky/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ky/strings.xml
deleted file mode 100644
index d68128b..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ky/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Модем режими Интернети жок колдонулууда"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Түзмөктөр туташпай жатат"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Модем режимин өчүрүү"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Байланыш түйүнү же модем режими күйүк"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роумингде кошумча акы алынышы мүмкүн"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-lo/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-lo/strings.xml
deleted file mode 100644
index 03e134a..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-lo/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ການປ່ອຍສັນຍານບໍ່ມີອິນເຕີເນັດ"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"ອຸປະກອນບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ປິດການປ່ອຍສັນຍານ"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ເປີດໃຊ້ຮັອດສະປອດ ຫຼື ການປ່ອຍສັນຍານຢູ່"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ອາດມີຄ່າໃຊ້ຈ່າຍເພີ່ມເຕີມໃນລະຫວ່າງການໂຣມມິງ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-lt/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-lt/strings.xml
deleted file mode 100644
index 652cedc..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-lt/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nėra įrenginio kaip modemo naudojimo interneto ryšio"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Nepavyko susieti įrenginių"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Išjungti įrenginio kaip modemo naudojimą"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Įjungtas viešosios interneto prieigos taškas arba įrenginio kaip modemo naudojimas"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Veikiant tarptinkliniam ryšiui gali būti taikomi papildomi mokesčiai"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-lv/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-lv/strings.xml
deleted file mode 100644
index 2219722..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-lv/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Piesaistei nav interneta savienojuma"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Nevar savienot ierīces"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Izslēgt piesaisti"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ir ieslēgts tīklājs vai piesaiste"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Viesabonēšanas laikā var tikt piemērota papildu samaksa"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-mk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-mk/strings.xml
deleted file mode 100644
index 227f9e3..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-mk/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Нема интернет преку мобилен"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Уредите не може да се поврзат"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Исклучи интернет преку мобилен"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Точката на пристап или интернетот преку мобилен е вклучен"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"При роаминг може да се наплатат дополнителни трошоци"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ml/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ml/strings.xml
deleted file mode 100644
index ec43885..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ml/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ടെതറിംഗിന് ഇന്റർനെറ്റ് ഇല്ല"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"ഉപകരണങ്ങൾ കണക്റ്റ് ചെയ്യാനാവില്ല"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ടെതറിംഗ് ഓഫാക്കുക"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ഹോട്ട്സ്പോട്ട് അല്ലെങ്കിൽ ടെതറിംഗ് ഓണാണ്"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"റോമിംഗ് ചെയ്യുമ്പോൾ അധിക നിരക്കുകൾ ബാധകമായേക്കാം"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-mn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-mn/strings.xml
deleted file mode 100644
index e263573..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-mn/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Модемд интернэт алга байна"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Төхөөрөмжүүд холбогдох боломжгүй байна"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Модем болгохыг унтраах"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Сүлжээний цэг эсвэл модем болгох асаалттай байна"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роумингийн үеэр нэмэлт төлбөр нэхэмжилж болзошгүй"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-mr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-mr/strings.xml
deleted file mode 100644
index adf845d..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-mr/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिंगला इंटरनेट नाही"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"डिव्हाइस कनेक्ट होऊ शकत नाहीत"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिंग बंद करा"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हॉटस्पॉट किंवा टेदरिंग सुरू आहे"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिंगदरम्यान अतिरिक्त शुल्क लागू होऊ शकतात"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ms/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ms/strings.xml
deleted file mode 100644
index f65c451..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ms/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Penambatan tiada Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Peranti tidak dapat disambungkan"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Matikan penambatan"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Tempat liputan atau penambatan dihidupkan"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Caj tambahan mungkin digunakan semasa perayauan"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-my/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-my/strings.xml
deleted file mode 100644
index 4118e77..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-my/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းတွင် အင်တာနက် မရှိပါ"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"စက်များ ချိတ်ဆက်၍ မရပါ"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ပိတ်ရန်"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ဟော့စပေါ့ (သို့) မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ဖွင့်ထားသည်"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ပြင်ပကွန်ရက်နှင့် ချိတ်ဆက်သည့်အခါ နောက်ထပ်ကျသင့်မှုများ ရှိနိုင်သည်"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-nb/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-nb/strings.xml
deleted file mode 100644
index 3685358..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-nb/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Internettdeling har ikke internettilgang"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enhetene kan ikke koble til"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Slå av internettdeling"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Wi-Fi-sone eller internettdeling er på"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ytterligere kostnader kan påløpe under roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
deleted file mode 100644
index d074f15..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिङमार्फत इन्टरनेट कनेक्सन प्राप्त हुन सकेन"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिङ निष्क्रिय पार्नुहोस्"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हटस्पट वा टेदरिङ सक्रिय छ"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-nl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-nl/strings.xml
deleted file mode 100644
index 1d88894..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-nl/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering heeft geen internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Apparaten kunnen niet worden verbonden"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering uitschakelen"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot of tethering is ingeschakeld"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Er kunnen extra kosten voor roaming in rekening worden gebracht."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-or/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-or/strings.xml
deleted file mode 100644
index 8038815..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-or/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ଟିଥରିଂ ପାଇଁ କୌଣସି ଇଣ୍ଟର୍ନେଟ୍ ସଂଯୋଗ ନାହିଁ"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"ଡିଭାଇସଗୁଡ଼ିକ ସଂଯୋଗ କରାଯାଇପାରିବ ନାହିଁ"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ଟିଥରିଂ ବନ୍ଦ କରନ୍ତୁ"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ହଟସ୍ପଟ୍ କିମ୍ବା ଟିଥରିଂ ଚାଲୁ ଅଛି"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ରୋମିଂରେ ଥିବା ସମୟରେ ଅତିରିକ୍ତ ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-pa/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pa/strings.xml
deleted file mode 100644
index 819833e..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-pa/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ਟੈਦਰਿੰਗ ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"ਡੀਵਾਈਸ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ਟੈਦਰਿੰਗ ਬੰਦ ਕਰੋ"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ਹੌਟਸਪੌਟ ਜਾਂ ਟੈਦਰਿੰਗ ਚਾਲੂ ਹੈ"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ਰੋਮਿੰਗ ਦੌਰਾਨ ਵਧੀਕ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-pl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pl/strings.xml
deleted file mode 100644
index 65e4380..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-pl/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nie ma internetu"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Urządzenia nie mogą się połączyć"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Wyłącz tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot lub tethering jest włączony"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Podczas korzystania z roamingu mogą zostać naliczone dodatkowe opłaty"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml
deleted file mode 100644
index d886617..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"O tethering não tem Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível conectar os dispositivos"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar o tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ponto de acesso ou tethering ativado"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pode haver cobranças extras durante o roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml
deleted file mode 100644
index bfd45ca..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"A ligação (à Internet) via telemóvel não tem Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível ligar os dispositivos"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar ligação (à Internet) via telemóvel"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"A zona Wi-Fi ou a ligação (à Internet) via telemóvel está ativada"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Podem aplicar-se custos adicionais em roaming."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-pt/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pt/strings.xml
deleted file mode 100644
index d886617..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-pt/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"O tethering não tem Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível conectar os dispositivos"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar o tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ponto de acesso ou tethering ativado"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pode haver cobranças extras durante o roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ro/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ro/strings.xml
deleted file mode 100644
index 8d87a9e5..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ro/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Procesul de tethering nu are internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Dispozitivele nu se pot conecta"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Dezactivați procesul de tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"S-a activat hotspotul sau tethering"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Se pot aplica taxe suplimentare pentru roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ru/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ru/strings.xml
deleted file mode 100644
index dbdb9eb..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ru/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Режим модема используется без доступа к Интернету"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Невозможно подключить устройства."</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Отключить режим модема"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Включены точка доступа или режим модема"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"За использование услуг связи в роуминге может взиматься дополнительная плата."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-si/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-si/strings.xml
deleted file mode 100644
index d8301e4..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-si/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ටෙදරින් හට අන්තර්ජාලය නැත"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"උපාංගවලට සම්බන්ධ විය නොහැකිය"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ටෙදරින් ක්රියාවිරහිත කරන්න"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"හොට්ස්පොට් හෝ ටෙදරින් ක්රියාත්මකයි"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"රෝමිං අතරතුර අමතර ගාස්තු අදාළ විය හැකිය"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sk/strings.xml
deleted file mode 100644
index bef7136..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-sk/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nemá internetové pripojenie"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Zariadenia sa nemôžu pripojiť"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vypnúť tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Je zapnutý hotspot alebo tethering"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Počas roamingu vám môžu byť účtované ďalšie poplatky"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sl/strings.xml
deleted file mode 100644
index 3202c62..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-sl/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Internetna povezava prek mobilnega telefona ni vzpostavljena"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Napravi se ne moreta povezati"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Izklopi internetno povezavo prek mobilnega telefona"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Dostopna točka ali internetna povezava prek mobilnega telefona je vklopljena"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Med gostovanjem lahko nastanejo dodatni stroški"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sq/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sq/strings.xml
deleted file mode 100644
index 37f6ad2..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-sq/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ndarja e internetit nuk ka internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Pajisjet nuk mund të lidhen"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Çaktivizo ndarjen e internetit"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Zona e qasjes për internet ose ndarja e internetit është aktive"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Mund të zbatohen tarifime shtesë kur je në roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sr/strings.xml
deleted file mode 100644
index 5566d03..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-sr/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Привезивање нема приступ интернету"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Повезивање уређаја није успело"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Искључи привезивање"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Укључен је хотспот или привезивање"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Можда важе додатни трошкови у ромингу"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sv/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sv/strings.xml
deleted file mode 100644
index 9765acd..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-sv/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Det finns ingen internetanslutning för internetdelningen"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enheterna kan inte anslutas"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Inaktivera internetdelning"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Surfzon eller internetdelning har aktiverats"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ytterligare avgifter kan tillkomma vid roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sw/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sw/strings.xml
deleted file mode 100644
index cf850c9..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-sw/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Kipengele cha kusambaza mtandao hakina intaneti"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Imeshindwa kuunganisha vifaa"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Zima kipengele cha kusambaza mtandao"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Umewasha kipengele cha kusambaza mtandao au mtandao pepe"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Huenda ukatozwa gharama za ziada ukitumia mitandao ya ng\'ambo"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
deleted file mode 100644
index f4b15aa..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"சாதனங்களால் இணைய முடியவில்லை"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"இணைப்பு முறையை ஆஃப் செய்"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-te/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-te/strings.xml
deleted file mode 100644
index 937d34d..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-te/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"టెథరింగ్ చేయడానికి ఇంటర్నెట్ కనెక్షన్ లేదు"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"పరికరాలు కనెక్ట్ అవ్వడం లేదు"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"టెథరింగ్ను ఆఫ్ చేయండి"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"హాట్స్పాట్ లేదా టెథరింగ్ ఆన్లో ఉంది"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"రోమింగ్లో ఉన్నప్పుడు అదనపు ఛార్జీలు వర్తించవచ్చు"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-th/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-th/strings.xml
deleted file mode 100644
index f781fae..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-th/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือไม่มีอินเทอร์เน็ต"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"อุปกรณ์เชื่อมต่อไม่ได้"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ปิดการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ฮอตสปอตหรือการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือเปิดอยู่"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"อาจมีค่าใช้จ่ายเพิ่มเติมขณะโรมมิ่ง"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-tl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-tl/strings.xml
deleted file mode 100644
index 8d5d4653..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-tl/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Walang internet ang pag-tether"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Hindi makakonekta ang mga device"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"I-off ang pag-tether"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Naka-on ang Hotspot o pag-tether"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Posibleng magkaroon ng mga karagdagang singil habang nagro-roam"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-tr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-tr/strings.xml
deleted file mode 100644
index 80cab33..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-tr/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering\'in internet bağlantısı yok"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Cihazlar bağlanamıyor"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering\'i kapat"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot veya tethering açık"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Dolaşım sırasında ek ücretler uygulanabilir"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-uk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-uk/strings.xml
deleted file mode 100644
index c05932a..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-uk/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Телефон, який використовується як модем, не підключений до Інтернету"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Не вдається підключити пристрої"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Вимкнути використання телефона як модема"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Увімкнено точку доступу або використання телефона як модема"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"У роумінгу може стягуватися додаткова плата"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ur/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ur/strings.xml
deleted file mode 100644
index d820eee..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-ur/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"ٹیدرنگ میں انٹرنیٹ نہیں ہے"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"آلات منسلک نہیں ہو سکتے"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ٹیدرنگ آف کریں"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ہاٹ اسپاٹ یا ٹیدرنگ آن ہے"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"رومنگ کے دوران اضافی چارجز لاگو ہو سکتے ہیں"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-uz/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-uz/strings.xml
deleted file mode 100644
index 726148a..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-uz/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modem internetga ulanmagan"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Qurilmalar ulanmadi"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Modem rejimini faolsizlantirish"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot yoki modem rejimi yoniq"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rouming vaqtida qoʻshimcha haq olinishi mumkin"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-vi/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-vi/strings.xml
deleted file mode 100644
index b7cb045..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-vi/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Không có Internet để chia sẻ kết Internet"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Các thiết bị không thể kết nối"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tắt tính năng chia sẻ Internet"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Điểm phát sóng hoặc tính năng chia sẻ Internet đang bật"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Bạn có thể mất thêm phí dữ liệu khi chuyển vùng"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml
deleted file mode 100644
index af91aff..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"共享网络未连接到互联网"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"设备无法连接"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"关闭网络共享"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"热点或网络共享已开启"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"漫游时可能会产生额外的费用"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml
deleted file mode 100644
index 28e6b80..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過網絡共享連線至互聯網"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"裝置無法連接"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉網絡共享"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"熱點或網絡共享已開啟"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"漫遊時可能需要支付額外費用"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
deleted file mode 100644
index 528a1e5..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過網路共用連上網際網路"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"裝置無法連線"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉網路共用"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"無線基地台或網路共用已開啟"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"使用漫遊服務可能須支付額外費用"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-zu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zu/strings.xml
deleted file mode 100644
index 11eb666..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004-zu/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ukusebenzisa ifoni njengemodemu akunayo i-inthanethi"</string>
- <string name="no_upstream_notification_message" msgid="3843613362272973447">"Amadivayisi awakwazi ukuxhumeka"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vala ukusebenzisa ifoni njengemodemu"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"I-hotspot noma ukusebenzisa ifoni njengemodemu kuvuliwe"</string>
- <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Kungaba nezinkokhelo ezengeziwe uma uzula"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004/config.xml b/packages/Tethering/res/values-mcc310-mnc004/config.xml
deleted file mode 100644
index 5c5be04..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004/config.xml
+++ /dev/null
@@ -1,23 +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.
--->
-<resources>
- <!-- Delay(millisecond) to show no upstream notification after there's no Backhaul. Set delay to
- "0" for disable this feature. -->
- <integer name="delay_to_show_no_upstream_after_no_backhaul">5000</integer>
-
- <!-- Config for showing upstream roaming notification. -->
- <bool name="config_upstream_roaming_notification">true</bool>
-</resources>
\ No newline at end of file
diff --git a/packages/Tethering/res/values-mcc310-mnc004/strings.xml b/packages/Tethering/res/values-mcc310-mnc004/strings.xml
deleted file mode 100644
index ce9ff60..0000000
--- a/packages/Tethering/res/values-mcc310-mnc004/strings.xml
+++ /dev/null
@@ -1,28 +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.
--->
-<resources>
- <!-- String for no upstream notification title [CHAR LIMIT=200] -->
- <string name="no_upstream_notification_title">Tethering has no internet</string>
- <!-- String for no upstream notification title [CHAR LIMIT=200] -->
- <string name="no_upstream_notification_message">Devices can\u2019t connect</string>
- <!-- String for no upstream notification disable button [CHAR LIMIT=200] -->
- <string name="no_upstream_notification_disable_button">Turn off tethering</string>
-
- <!-- String for cellular roaming notification title [CHAR LIMIT=200] -->
- <string name="upstream_roaming_notification_title">Hotspot or tethering is on</string>
- <!-- String for cellular roaming notification message [CHAR LIMIT=500] -->
- <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-af/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-af/strings.xml
deleted file mode 100644
index 9bfa531..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-af/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Verbinding het nie internet nie"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Toestelle kan nie koppel nie"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Skakel verbinding af"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Warmkol of verbinding is aan"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Bykomende heffings kan geld terwyl jy swerf"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-am/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-am/strings.xml
deleted file mode 100644
index 5949dfa..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-am/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ማስተሳሰር ምንም በይነመረብ የለውም"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"መሣሪያዎችን ማገናኘት አይቻልም"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ማስተሳሰርን አጥፋ"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"መገናኛ ነጥብ ወይም ማስተሳሰር በርቷል"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"በሚያንዣብብበት ጊዜ ተጨማሪ ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ar/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ar/strings.xml
deleted file mode 100644
index 8467f9b..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ar/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ما مِن اتصال بالإنترنت خلال التوصيل"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"تعذّر اتصال الأجهزة"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"إيقاف التوصيل"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"نقطة الاتصال أو التوصيل مفعّلان"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"قد يتم تطبيق رسوم إضافية أثناء التجوال."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-as/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-as/strings.xml
deleted file mode 100644
index 9776bd8..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-as/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"টে\'ডাৰিঙৰ ইণ্টাৰনেট নাই"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"ডিভাইচসমূহ সংযোগ কৰিব নোৱাৰি"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"টে\'ডাৰিং অফ কৰক"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"হটস্পট অথবা টে\'ডাৰিং অন আছে"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ৰ\'মিঙত থাকিলে অতিৰিক্ত মাচুল প্ৰযোজ্য হ’ব পাৰে"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-az/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-az/strings.xml
deleted file mode 100644
index e6d3eaf..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-az/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Modemin internetə girişi yoxdur"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Cihazları qoşmaq mümkün deyil"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Modemi deaktiv edin"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot və ya modem aktivdir"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rouminq zamanı əlavə ödənişlər tətbiq edilə bilər"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml
deleted file mode 100644
index 4c8a1df..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Privezivanje nema pristup internetu"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Povezivanje uređaja nije uspelo"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključi privezivanje"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Uključen je hotspot ili privezivanje"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Možda važe dodatni troškovi u romingu"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-be/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-be/strings.xml
deleted file mode 100644
index edfa41e..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-be/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Рэжым мадэма выкарыстоўваецца без доступу да інтэрнэту"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Не ўдалося падключыць прылады"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Выключыць рэжым мадэма"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Хот-спот або рэжым мадэма ўключаны"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Пры выкарыстанні роўмінгу можа спаганяцца дадатковая плата"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-bg/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-bg/strings.xml
deleted file mode 100644
index f563981..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-bg/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Тетърингът няма връзка с интернет"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Устройствата не могат да установят връзка"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Изключване на тетъринга"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Точката за достъп или тетърингът са включени"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Възможно е да ви бъдат начислени допълнителни такси при роуминг"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-bn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-bn/strings.xml
deleted file mode 100644
index d8ecd2e..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-bn/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"টিথারিং করার জন্য কোনও ইন্টারনেট কানেকশন নেই"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"ডিভাইস কানেক্ট করতে পারছে না"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"টিথারিং বন্ধ করুন"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"হটস্পট বা টিথারিং চালু আছে"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"রোমিংয়ের সময় অতিরিক্ত চার্জ করা হতে পারে"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-bs/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-bs/strings.xml
deleted file mode 100644
index b85fd5e..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-bs/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Povezivanje putem mobitela nema internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Uređaji se ne mogu povezati"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključi povezivanje putem mobitela"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Pristupna tačka ili povezivanje putem mobitela je uključeno"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Mogu nastati dodatni troškovi u romingu"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ca/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ca/strings.xml
deleted file mode 100644
index a357215..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ca/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"La compartició de xarxa no té accés a Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"No es poden connectar els dispositius"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactiva la compartició de xarxa"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"S\'ha activat el punt d\'accés Wi‑Fi o la compartició de xarxa"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"És possible que s\'apliquin costos addicionals en itinerància"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-cs/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-cs/strings.xml
deleted file mode 100644
index 91196be..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-cs/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nemá připojení k internetu"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Zařízení se nemůžou připojit"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vypnout tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Je zapnutý hotspot nebo tethering"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Při roamingu mohou být účtovány dodatečné poplatky"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-da/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-da/strings.xml
deleted file mode 100644
index 1968900..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-da/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Netdeling har ingen internetforbindelse"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enheder kan ikke oprette forbindelse"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Deaktiver netdeling"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot eller netdeling er aktiveret"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Der opkræves muligvis yderligere gebyrer ved roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-de/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-de/strings.xml
deleted file mode 100644
index eb3f8c5..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-de/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering hat keinen Internetzugriff"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Geräte können sich nicht verbinden"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering deaktivieren"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot oder Tethering ist aktiviert"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Für das Roaming können zusätzliche Gebühren anfallen"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-el/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-el/strings.xml
deleted file mode 100644
index 56c3d81..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-el/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Η σύνδεση δεν έχει πρόσβαση στο διαδίκτυο"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Δεν είναι δυνατή η σύνδεση των συσκευών"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Απενεργοποιήστε τη σύνδεση"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ενεργό σημείο πρόσβασης Wi-Fi ή ενεργή σύνδεση"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ενδέχεται να ισχύουν επιπλέον χρεώσεις κατά την περιαγωγή."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml
deleted file mode 100644
index dd1a197..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml
deleted file mode 100644
index dd1a197..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml
deleted file mode 100644
index dd1a197..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml
deleted file mode 100644
index dd1a197..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml
deleted file mode 100644
index d3347aa..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml
deleted file mode 100644
index 2f0504f..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"La conexión mediante dispositivo móvil no tiene Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"No se pueden conectar los dispositivos"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión mediante dispositivo móvil"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Se activó el hotspot o la conexión mediante dispositivo móvil"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Es posible que se apliquen cargos adicionales por roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-es/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-es/strings.xml
deleted file mode 100644
index 2d8f882..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-es/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"La conexión no se puede compartir, porque no hay acceso a Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Los dispositivos no se pueden conectar"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión compartida"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Punto de acceso o conexión compartida activados"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Puede que se apliquen cargos adicionales en itinerancia"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-et/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-et/strings.xml
deleted file mode 100644
index 8493c470..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-et/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Jagamisel puudub internetiühendus"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Seadmed ei saa ühendust luua"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Lülita jagamine välja"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Kuumkoht või jagamine on sisse lülitatud"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rändluse kasutamisega võivad kaasneda lisatasud"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-eu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-eu/strings.xml
deleted file mode 100644
index 33bccab..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-eu/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Konexioa partekatzeko aukerak ez du Interneteko konexiorik"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Ezin dira konektatu gailuak"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desaktibatu konexioa partekatzeko aukera"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Wifi-gunea edo konexioa partekatzeko aukera aktibatuta dago"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Baliteke kostu gehigarriak ordaindu behar izatea ibiltaritzan"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-fa/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fa/strings.xml
deleted file mode 100644
index cf8a0cc..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-fa/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"«اشتراکگذاری اینترنت» به اینترنت دسترسی ندارد"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"دستگاهها متصل نمیشوند"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"خاموش کردن «اشتراکگذاری اینترنت»"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"«نقطه اتصال» یا «اشتراکگذاری اینترنت» روشن است"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ممکن است درحین فراگردی تغییرات دیگر اعمال شود"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-fi/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fi/strings.xml
deleted file mode 100644
index 6a3ab80..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-fi/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Ei jaettavaa internetyhteyttä"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Laitteet eivät voi muodostaa yhteyttä"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Laita yhteyden jakaminen pois päältä"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot tai yhteyden jakaminen on päällä"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Roaming voi aiheuttaa lisämaksuja"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml
deleted file mode 100644
index ffb9bf6..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Le partage de connexion n\'est pas connecté à Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossible de connecter les appareils"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Désactiver le partage de connexion"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Le point d\'accès ou le partage de connexion est activé"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-fr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fr/strings.xml
deleted file mode 100644
index 768bce3..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-fr/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Aucune connexion à Internet n\'est disponible pour le partage de connexion"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossible de connecter les appareils"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Désactiver le partage de connexion"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Le point d\'accès ou le partage de connexion est activé"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-gl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-gl/strings.xml
deleted file mode 100644
index 0c4195a..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-gl/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"A conexión compartida non ten Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Non se puideron conectar os dispositivos"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión compartida"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Está activada a zona wifi ou a conexión compartida"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pódense aplicar cargos adicionais en itinerancia"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-gu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-gu/strings.xml
deleted file mode 100644
index e9d33a7..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-gu/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ઇન્ટરનેટ શેર કરવાની સુવિધામાં ઇન્ટરનેટ નથી"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"ડિવાઇસ કનેક્ટ કરી શકાતા નથી"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરો"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"હૉટસ્પૉટ અથવા ઇન્ટરનેટ શેર કરવાની સુવિધા ચાલુ છે"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"રોમિંગમાં વધારાના શુલ્ક લાગી શકે છે"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-hi/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hi/strings.xml
deleted file mode 100644
index aa418ac..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-hi/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिंग से इंटरनेट नहीं चल रहा"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"डिवाइस कनेक्ट नहीं हो पा रहे"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिंग बंद करें"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हॉटस्पॉट या टेदरिंग चालू है"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिंग के दौरान अतिरिक्त शुल्क लग सकता है"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-hr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hr/strings.xml
deleted file mode 100644
index 51c524a..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-hr/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Modemsko povezivanje nema internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Uređaji se ne mogu povezati"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključivanje modemskog povezivanja"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Uključena je žarišna točka ili modemsko povezivanje"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"U roamingu su mogući dodatni troškovi"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-hu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hu/strings.xml
deleted file mode 100644
index 164e45e..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-hu/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Nincs internetkapcsolat az internet megosztásához"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Az eszközök nem tudnak csatlakozni"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Internetmegosztás kikapcsolása"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"A hotspot vagy az internetmegosztás be van kapcsolva"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Roaming során további díjak léphetnek fel"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-hy/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hy/strings.xml
deleted file mode 100644
index e76c0a4..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-hy/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Մոդեմի ռեժիմի կապը բացակայում է"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Չհաջողվեց միացնել սարքը"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Անջատել մոդեմի ռեժիմը"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Թեժ կետը կամ մոդեմի ռեժիմը միացված է"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ռոումինգում կարող են լրացուցիչ վճարներ գանձվել"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-in/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-in/strings.xml
deleted file mode 100644
index 2b817f8..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-in/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tidak ada koneksi internet di tethering"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Perangkat tidak dapat terhubung"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Nonaktifkan tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot atau tethering aktif"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Biaya tambahan mungkin berlaku saat roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-is/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-is/strings.xml
deleted file mode 100644
index a338d9c..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-is/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tjóðrun er ekki með internettengingu"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Tæki geta ekki tengst"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Slökkva á tjóðrun"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Kveikt er á heitum reit eða tjóðrun"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Viðbótargjöld kunna að eiga við í reiki"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-it/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-it/strings.xml
deleted file mode 100644
index 77769c2..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-it/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Nessuna connessione a Internet per il tethering"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossibile connettere i dispositivi"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Disattiva il tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot o tethering attivi"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Potrebbero essere applicati costi aggiuntivi durante il roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-iw/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-iw/strings.xml
deleted file mode 100644
index 5267b51..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-iw/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"אי אפשר להפעיל את תכונת שיתוף האינטרנט בין מכשירים כי אין חיבור לאינטרנט"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"למכשירים אין אפשרות להתחבר"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"השבתה של שיתוף האינטרנט בין מכשירים"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"תכונת הנקודה לשיתוף אינטרנט או תכונת שיתוף האינטרנט בין מכשירים פועלת"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ייתכנו חיובים נוספים בעת נדידה"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ja/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ja/strings.xml
deleted file mode 100644
index 66a9a6d..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ja/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"テザリングがインターネットに接続されていません"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"デバイスを接続できません"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"テザリングを OFF にする"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"アクセス ポイントまたはテザリングが ON です"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ローミング時に追加料金が発生することがあります"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ka/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ka/strings.xml
deleted file mode 100644
index d8ad880..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ka/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ტეტერინგს არ აქვს ინტერნეტზე წვდომა"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"მოწყობილობები ვერ ახერხებენ დაკავშირებას"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ტეტერინგის გამორთვა"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ჩართულია უსადენო ქსელი ან ტეტერინგი"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"როუმინგის გამოყენებისას შეიძლება ჩამოგეჭრათ დამატებითი საფასური"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-kk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-kk/strings.xml
deleted file mode 100644
index 1ddd6b4..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-kk/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Тетеринг режимі интернет байланысынсыз пайдаланылуда"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Құрылғыларды байланыстыру мүмкін емес"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Тетерингіні өшіру"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Хотспот немесе тетеринг қосулы"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роуминг кезінде қосымша ақы алынуы мүмкін."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-km/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-km/strings.xml
deleted file mode 100644
index cf5a137..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-km/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ការភ្ជាប់មិនមានអ៊ីនធឺណិតទេ"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"មិនអាចភ្ជាប់ឧបករណ៍បានទេ"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"បិទការភ្ជាប់"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ហតស្ប៉ត ឬការភ្ជាប់ត្រូវបានបើក"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"អាចមានការគិតថ្លៃបន្ថែម នៅពេលរ៉ូមីង"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-kn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-kn/strings.xml
deleted file mode 100644
index 68ae68b..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-kn/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ಟೆಥರಿಂಗ್ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಕನೆಕ್ಷನ್ ಹೊಂದಿಲ್ಲ"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"ಸಾಧನಗಳನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ಟೆಥರಿಂಗ್ ಆಫ್ ಮಾಡಿ"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ಹಾಟ್ಸ್ಪಾಟ್ ಅಥವಾ ಟೆಥರಿಂಗ್ ಆನ್ ಆಗಿದೆ"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ರೋಮಿಂಗ್ನಲ್ಲಿರುವಾಗ ಹೆಚ್ಚುವರಿ ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ko/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ko/strings.xml
deleted file mode 100644
index 17185ba..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ko/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"테더링으로 인터넷을 사용할 수 없음"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"기기에서 연결할 수 없음"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"테더링 사용 중지"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"핫스팟 또는 테더링 켜짐"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"로밍 중에는 추가 요금이 발생할 수 있습니다."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ky/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ky/strings.xml
deleted file mode 100644
index 6a9fb98..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ky/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Модем режими Интернети жок колдонулууда"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Түзмөктөр туташпай жатат"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Модем режимин өчүрүү"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Байланыш түйүнү же модем режими күйүк"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роумингде кошумча акы алынышы мүмкүн"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-lo/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-lo/strings.xml
deleted file mode 100644
index bcc4b57..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-lo/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ການປ່ອຍສັນຍານບໍ່ມີອິນເຕີເນັດ"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"ອຸປະກອນບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ປິດການປ່ອຍສັນຍານ"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ເປີດໃຊ້ຮັອດສະປອດ ຫຼື ການປ່ອຍສັນຍານຢູ່"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ອາດມີຄ່າໃຊ້ຈ່າຍເພີ່ມເຕີມໃນລະຫວ່າງການໂຣມມິງ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-lt/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-lt/strings.xml
deleted file mode 100644
index 011c2c1..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-lt/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Nėra įrenginio kaip modemo naudojimo interneto ryšio"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Nepavyko susieti įrenginių"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Išjungti įrenginio kaip modemo naudojimą"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Įjungtas viešosios interneto prieigos taškas arba įrenginio kaip modemo naudojimas"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Veikiant tarptinkliniam ryšiui gali būti taikomi papildomi mokesčiai"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-lv/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-lv/strings.xml
deleted file mode 100644
index 5cb2f3b..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-lv/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Piesaistei nav interneta savienojuma"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Nevar savienot ierīces"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Izslēgt piesaisti"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ir ieslēgts tīklājs vai piesaiste"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Viesabonēšanas laikā var tikt piemērota papildu samaksa"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-mk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-mk/strings.xml
deleted file mode 100644
index 4cbfd88..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-mk/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Нема интернет преку мобилен"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Уредите не може да се поврзат"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Исклучи интернет преку мобилен"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Точката на пристап или интернетот преку мобилен е вклучен"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"При роаминг може да се наплатат дополнителни трошоци"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ml/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ml/strings.xml
deleted file mode 100644
index 9cf4eaf..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ml/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ടെതറിംഗിന് ഇന്റർനെറ്റ് ഇല്ല"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"ഉപകരണങ്ങൾ കണക്റ്റ് ചെയ്യാനാവില്ല"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ടെതറിംഗ് ഓഫാക്കുക"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ഹോട്ട്സ്പോട്ട് അല്ലെങ്കിൽ ടെതറിംഗ് ഓണാണ്"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"റോമിംഗ് ചെയ്യുമ്പോൾ അധിക നിരക്കുകൾ ബാധകമായേക്കാം"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-mn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-mn/strings.xml
deleted file mode 100644
index 47c82c1..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-mn/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Модемд интернэт алга байна"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Төхөөрөмжүүд холбогдох боломжгүй байна"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Модем болгохыг унтраах"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Сүлжээний цэг эсвэл модем болгох асаалттай байна"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роумингийн үеэр нэмэлт төлбөр нэхэмжилж болзошгүй"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-mr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-mr/strings.xml
deleted file mode 100644
index ad9e809..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-mr/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिंगला इंटरनेट नाही"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"डिव्हाइस कनेक्ट होऊ शकत नाहीत"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिंग बंद करा"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हॉटस्पॉट किंवा टेदरिंग सुरू आहे"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिंगदरम्यान अतिरिक्त शुल्क लागू होऊ शकतात"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ms/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ms/strings.xml
deleted file mode 100644
index e708cb8..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ms/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Penambatan tiada Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Peranti tidak dapat disambungkan"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Matikan penambatan"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Tempat liputan atau penambatan dihidupkan"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Caj tambahan mungkin digunakan semasa perayauan"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-my/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-my/strings.xml
deleted file mode 100644
index ba54622..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-my/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းတွင် အင်တာနက် မရှိပါ"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"စက်များ ချိတ်ဆက်၍ မရပါ"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ပိတ်ရန်"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ဟော့စပေါ့ (သို့) မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ဖွင့်ထားသည်"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ပြင်ပကွန်ရက်နှင့် ချိတ်ဆက်သည့်အခါ နောက်ထပ်ကျသင့်မှုများ ရှိနိုင်သည်"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-nb/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-nb/strings.xml
deleted file mode 100644
index 57db484a2..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-nb/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Internettdeling har ikke internettilgang"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enhetene kan ikke koble til"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Slå av internettdeling"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Wi-Fi-sone eller internettdeling er på"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ytterligere kostnader kan påløpe under roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
deleted file mode 100644
index 1503244..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिङमार्फत इन्टरनेट कनेक्सन प्राप्त हुन सकेन"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिङ निष्क्रिय पार्नुहोस्"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हटस्पट वा टेदरिङ सक्रिय छ"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-nl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-nl/strings.xml
deleted file mode 100644
index b08133f..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-nl/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering heeft geen internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Apparaten kunnen niet worden verbonden"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering uitschakelen"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot of tethering is ingeschakeld"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Er kunnen extra kosten voor roaming in rekening worden gebracht."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-or/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-or/strings.xml
deleted file mode 100644
index 1ad4ca3..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-or/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ଟିଥରିଂ ପାଇଁ କୌଣସି ଇଣ୍ଟର୍ନେଟ୍ ସଂଯୋଗ ନାହିଁ"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"ଡିଭାଇସଗୁଡ଼ିକ ସଂଯୋଗ କରାଯାଇପାରିବ ନାହିଁ"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ଟିଥରିଂ ବନ୍ଦ କରନ୍ତୁ"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ହଟସ୍ପଟ୍ କିମ୍ବା ଟିଥରିଂ ଚାଲୁ ଅଛି"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ରୋମିଂରେ ଥିବା ସମୟରେ ଅତିରିକ୍ତ ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-pa/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pa/strings.xml
deleted file mode 100644
index 88def56..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-pa/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ਟੈਦਰਿੰਗ ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"ਡੀਵਾਈਸ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ਟੈਦਰਿੰਗ ਬੰਦ ਕਰੋ"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ਹੌਟਸਪੌਟ ਜਾਂ ਟੈਦਰਿੰਗ ਚਾਲੂ ਹੈ"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ਰੋਮਿੰਗ ਦੌਰਾਨ ਵਧੀਕ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-pl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pl/strings.xml
deleted file mode 100644
index f9890ab..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-pl/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nie ma internetu"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Urządzenia nie mogą się połączyć"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Wyłącz tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot lub tethering jest włączony"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Podczas korzystania z roamingu mogą zostać naliczone dodatkowe opłaty"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml
deleted file mode 100644
index ce3b884..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"O tethering não tem Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível conectar os dispositivos"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar o tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ponto de acesso ou tethering ativado"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pode haver cobranças extras durante o roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml
deleted file mode 100644
index 7e883ea..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"A ligação (à Internet) via telemóvel não tem Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível ligar os dispositivos"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar ligação (à Internet) via telemóvel"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"A zona Wi-Fi ou a ligação (à Internet) via telemóvel está ativada"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Podem aplicar-se custos adicionais em roaming."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-pt/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pt/strings.xml
deleted file mode 100644
index ce3b884..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-pt/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"O tethering não tem Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível conectar os dispositivos"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar o tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ponto de acesso ou tethering ativado"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pode haver cobranças extras durante o roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ro/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ro/strings.xml
deleted file mode 100644
index 1009417..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ro/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Procesul de tethering nu are internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Dispozitivele nu se pot conecta"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Dezactivați procesul de tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"S-a activat hotspotul sau tethering"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Se pot aplica taxe suplimentare pentru roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ru/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ru/strings.xml
deleted file mode 100644
index 88683be..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ru/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Режим модема используется без доступа к Интернету"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Невозможно подключить устройства."</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Отключить режим модема"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Включены точка доступа или режим модема"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"За использование услуг связи в роуминге может взиматься дополнительная плата."</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-si/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-si/strings.xml
deleted file mode 100644
index 176bcdb..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-si/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ටෙදරින් හට අන්තර්ජාලය නැත"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"උපාංගවලට සම්බන්ධ විය නොහැකිය"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ටෙදරින් ක්රියාවිරහිත කරන්න"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"හොට්ස්පොට් හෝ ටෙදරින් ක්රියාත්මකයි"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"රෝමිං අතරතුර අමතර ගාස්තු අදාළ විය හැකිය"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sk/strings.xml
deleted file mode 100644
index b9e2127..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-sk/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nemá internetové pripojenie"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Zariadenia sa nemôžu pripojiť"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vypnúť tethering"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Je zapnutý hotspot alebo tethering"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Počas roamingu vám môžu byť účtované ďalšie poplatky"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sl/strings.xml
deleted file mode 100644
index e8140e6..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-sl/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Internetna povezava prek mobilnega telefona ni vzpostavljena"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Napravi se ne moreta povezati"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Izklopi internetno povezavo prek mobilnega telefona"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Dostopna točka ali internetna povezava prek mobilnega telefona je vklopljena"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Med gostovanjem lahko nastanejo dodatni stroški"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sq/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sq/strings.xml
deleted file mode 100644
index 61e698d..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-sq/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Ndarja e internetit nuk ka internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Pajisjet nuk mund të lidhen"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Çaktivizo ndarjen e internetit"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Zona e qasjes për internet ose ndarja e internetit është aktive"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Mund të zbatohen tarifime shtesë kur je në roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sr/strings.xml
deleted file mode 100644
index b4c411c..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-sr/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Привезивање нема приступ интернету"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Повезивање уређаја није успело"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Искључи привезивање"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Укључен је хотспот или привезивање"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Можда важе додатни трошкови у ромингу"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sv/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sv/strings.xml
deleted file mode 100644
index 4f543e4..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-sv/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Det finns ingen internetanslutning för internetdelningen"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enheterna kan inte anslutas"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Inaktivera internetdelning"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Surfzon eller internetdelning har aktiverats"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ytterligare avgifter kan tillkomma vid roaming"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sw/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sw/strings.xml
deleted file mode 100644
index ac347ab..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-sw/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Kipengele cha kusambaza mtandao hakina intaneti"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Imeshindwa kuunganisha vifaa"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Zima kipengele cha kusambaza mtandao"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Umewasha kipengele cha kusambaza mtandao au mtandao pepe"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Huenda ukatozwa gharama za ziada ukitumia mitandao ya ng\'ambo"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
deleted file mode 100644
index 2ea2467..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"சாதனங்களால் இணைய முடியவில்லை"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"இணைப்பு முறையை ஆஃப் செய்"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-te/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-te/strings.xml
deleted file mode 100644
index 9360297..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-te/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"టెథరింగ్ చేయడానికి ఇంటర్నెట్ కనెక్షన్ లేదు"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"పరికరాలు కనెక్ట్ అవ్వడం లేదు"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"టెథరింగ్ను ఆఫ్ చేయండి"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"హాట్స్పాట్ లేదా టెథరింగ్ ఆన్లో ఉంది"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"రోమింగ్లో ఉన్నప్పుడు అదనపు ఛార్జీలు వర్తించవచ్చు"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-th/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-th/strings.xml
deleted file mode 100644
index 9c4d7e0..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-th/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือไม่มีอินเทอร์เน็ต"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"อุปกรณ์เชื่อมต่อไม่ได้"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ปิดการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ฮอตสปอตหรือการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือเปิดอยู่"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"อาจมีค่าใช้จ่ายเพิ่มเติมขณะโรมมิ่ง"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-tl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-tl/strings.xml
deleted file mode 100644
index a7c78a5..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-tl/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Walang internet ang pag-tether"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Hindi makakonekta ang mga device"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"I-off ang pag-tether"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Naka-on ang Hotspot o pag-tether"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Posibleng magkaroon ng mga karagdagang singil habang nagro-roam"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-tr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-tr/strings.xml
deleted file mode 100644
index 93da2c3..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-tr/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering\'in internet bağlantısı yok"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Cihazlar bağlanamıyor"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering\'i kapat"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot veya tethering açık"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Dolaşım sırasında ek ücretler uygulanabilir"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-uk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-uk/strings.xml
deleted file mode 100644
index ee0dcd2..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-uk/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Телефон, який використовується як модем, не підключений до Інтернету"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Не вдається підключити пристрої"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Вимкнути використання телефона як модема"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Увімкнено точку доступу або використання телефона як модема"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"У роумінгу може стягуватися додаткова плата"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ur/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ur/strings.xml
deleted file mode 100644
index 41cd28e..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-ur/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"ٹیدرنگ میں انٹرنیٹ نہیں ہے"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"آلات منسلک نہیں ہو سکتے"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ٹیدرنگ آف کریں"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ہاٹ اسپاٹ یا ٹیدرنگ آن ہے"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"رومنگ کے دوران اضافی چارجز لاگو ہو سکتے ہیں"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-uz/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-uz/strings.xml
deleted file mode 100644
index c847bc9..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-uz/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Modem internetga ulanmagan"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Qurilmalar ulanmadi"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Modem rejimini faolsizlantirish"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot yoki modem rejimi yoniq"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rouming vaqtida qoʻshimcha haq olinishi mumkin"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-vi/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-vi/strings.xml
deleted file mode 100644
index a74326f..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-vi/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Không có Internet để chia sẻ kết Internet"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Các thiết bị không thể kết nối"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tắt tính năng chia sẻ Internet"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Điểm phát sóng hoặc tính năng chia sẻ Internet đang bật"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Bạn có thể mất thêm phí dữ liệu khi chuyển vùng"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml
deleted file mode 100644
index d737003..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"共享网络未连接到互联网"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"设备无法连接"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"关闭网络共享"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"热点或网络共享已开启"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"漫游时可能会产生额外的费用"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml
deleted file mode 100644
index f378a9d..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過網絡共享連線至互聯網"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"裝置無法連接"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉網絡共享"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"熱點或網絡共享已開啟"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"漫遊時可能需要支付額外費用"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
deleted file mode 100644
index cd653df..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過網路共用連上網際網路"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"裝置無法連線"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉網路共用"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"無線基地台或網路共用已開啟"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"使用漫遊服務可能須支付額外費用"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-zu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zu/strings.xml
deleted file mode 100644
index 32f6df5..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480-zu/strings.xml
+++ /dev/null
@@ -1,24 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"Ukusebenzisa ifoni njengemodemu akunayo i-inthanethi"</string>
- <string name="no_upstream_notification_message" msgid="6508394877641864863">"Amadivayisi awakwazi ukuxhumeka"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vala ukusebenzisa ifoni njengemodemu"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"I-hotspot noma ukusebenzisa ifoni njengemodemu kuvuliwe"</string>
- <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Kungaba nezinkokhelo ezengeziwe uma uzula"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480/config.xml b/packages/Tethering/res/values-mcc311-mnc480/config.xml
deleted file mode 100644
index 5c5be04..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480/config.xml
+++ /dev/null
@@ -1,23 +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.
--->
-<resources>
- <!-- Delay(millisecond) to show no upstream notification after there's no Backhaul. Set delay to
- "0" for disable this feature. -->
- <integer name="delay_to_show_no_upstream_after_no_backhaul">5000</integer>
-
- <!-- Config for showing upstream roaming notification. -->
- <bool name="config_upstream_roaming_notification">true</bool>
-</resources>
\ No newline at end of file
diff --git a/packages/Tethering/res/values-mcc311-mnc480/strings.xml b/packages/Tethering/res/values-mcc311-mnc480/strings.xml
deleted file mode 100644
index ce9ff60..0000000
--- a/packages/Tethering/res/values-mcc311-mnc480/strings.xml
+++ /dev/null
@@ -1,28 +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.
--->
-<resources>
- <!-- String for no upstream notification title [CHAR LIMIT=200] -->
- <string name="no_upstream_notification_title">Tethering has no internet</string>
- <!-- String for no upstream notification title [CHAR LIMIT=200] -->
- <string name="no_upstream_notification_message">Devices can\u2019t connect</string>
- <!-- String for no upstream notification disable button [CHAR LIMIT=200] -->
- <string name="no_upstream_notification_disable_button">Turn off tethering</string>
-
- <!-- String for cellular roaming notification title [CHAR LIMIT=200] -->
- <string name="upstream_roaming_notification_title">Hotspot or tethering is on</string>
- <!-- String for cellular roaming notification message [CHAR LIMIT=500] -->
- <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string>
-</resources>
diff --git a/packages/Tethering/res/values-mk/strings.xml b/packages/Tethering/res/values-mk/strings.xml
deleted file mode 100644
index 9ad9b9a..0000000
--- a/packages/Tethering/res/values-mk/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Активно е врзување или точка на пристап"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Допрете за поставување."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Врзувањето е оневозможено"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Контактирајте со администраторот за детали"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус на точката на пристап и врзувањето"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ml/strings.xml b/packages/Tethering/res/values-ml/strings.xml
deleted file mode 100644
index 9db79ce..0000000
--- a/packages/Tethering/res/values-ml/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്പോട്ട് സജീവമാണ്"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"സജ്ജീകരിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"വിശദാംശങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ഹോട്ട്സ്പോട്ടിന്റെയും ടെതറിംഗിന്റെയും നില"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-mn/strings.xml b/packages/Tethering/res/values-mn/strings.xml
deleted file mode 100644
index 42d1edb..0000000
--- a/packages/Tethering/res/values-mn/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Модем болгох эсвэл сүлжээний цэг идэвхтэй байна"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Тохируулахын тулд товшино уу."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Модем болгохыг идэвхгүй болгосон"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Сүлжээний цэг болон модем болгох төлөв"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-mr/strings.xml b/packages/Tethering/res/values-mr/strings.xml
deleted file mode 100644
index 13995b6..0000000
--- a/packages/Tethering/res/values-mr/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिंग किंवा हॉटस्पॉट अॅक्टिव्ह आहे"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"सेट करण्यासाठी टॅप करा."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिंग बंद केले आहे"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"तपशीलांसाठी तुमच्या ॲडमिनशी संपर्क साधा"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हॉटस्पॉट आणि टेदरिंगची स्थिती"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ms/strings.xml b/packages/Tethering/res/values-ms/strings.xml
deleted file mode 100644
index d6a67f3..0000000
--- a/packages/Tethering/res/values-ms/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Penambatan atau tempat liputan aktif"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Ketik untuk membuat persediaan."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Penambatan dilumpuhkan"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi pentadbir anda untuk mendapatkan maklumat lanjut"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status tempat liputan & penambatan"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-my/strings.xml b/packages/Tethering/res/values-my/strings.xml
deleted file mode 100644
index 49f6b88..0000000
--- a/packages/Tethering/res/values-my/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းကို ပိတ်ထားသည်"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"အသေးစိတ်အတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ဟော့စပေါ့နှင့် မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း အခြေအနေ"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-nb/strings.xml b/packages/Tethering/res/values-nb/strings.xml
deleted file mode 100644
index 9594e0a..0000000
--- a/packages/Tethering/res/values-nb/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Internettdeling eller Wi-Fi-sone er aktiv"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Trykk for å konfigurere."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internettdeling er slått av"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ta kontakt med administratoren din for å få mer informasjon"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for Wi-Fi-sone og internettdeling"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ne/strings.xml b/packages/Tethering/res/values-ne/strings.xml
deleted file mode 100644
index 72ae3a8..0000000
--- a/packages/Tethering/res/values-ne/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिङ वा हटस्पट सक्रिय छ"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"सेटअप गर्न ट्याप गर्नुहोस्।"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिङ सुविधा असक्षम पारिएको छ"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हटस्पट तथा टेदरिङको स्थिति"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-nl/strings.xml b/packages/Tethering/res/values-nl/strings.xml
deleted file mode 100644
index 18b2bbf..0000000
--- a/packages/Tethering/res/values-nl/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering of hotspot actief"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Tik om in te stellen."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is uitgeschakeld"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Neem contact op met je beheerder voor meer informatie"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status van hotspot en tethering"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-or/strings.xml b/packages/Tethering/res/values-or/strings.xml
deleted file mode 100644
index a15a6db..0000000
--- a/packages/Tethering/res/values-or/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"ଟିଥେରିଂ କିମ୍ୱା ହଟସ୍ପଟ୍ ସକ୍ରିୟ ଅଛି"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"ସେଟ୍ ଅପ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ଟିଥେରିଂ ଅକ୍ଷମ କରାଯାଇଛି"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"ବିବରଣୀଗୁଡ଼ିକ ପାଇଁ ଆପଣଙ୍କ ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ହଟସ୍ପଟ୍ ଓ ଟିଥେରିଂ ସ୍ଥିତି"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-pa/strings.xml b/packages/Tethering/res/values-pa/strings.xml
deleted file mode 100644
index a8235e4..0000000
--- a/packages/Tethering/res/values-pa/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"ਟੈਦਰਿੰਗ ਜਾਂ ਹੌਟਸਪੌਟ ਕਿਰਿਆਸ਼ੀਲ"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ਟੈਦਰਿੰਗ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ਹੌਟਸਪੌਟ ਅਤੇ ਟੈਦਰਿੰਗ ਦੀ ਸਥਿਤੀ"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-pl/strings.xml b/packages/Tethering/res/values-pl/strings.xml
deleted file mode 100644
index ccb017d..0000000
--- a/packages/Tethering/res/values-pl/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Aktywny tethering lub punkt dostępu"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Kliknij, by skonfigurować"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering został wyłączony"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot i tethering – stan"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-pt-rBR/strings.xml b/packages/Tethering/res/values-pt-rBR/strings.xml
deleted file mode 100644
index a0a4745..0000000
--- a/packages/Tethering/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-pt-rPT/strings.xml b/packages/Tethering/res/values-pt-rPT/strings.xml
deleted file mode 100644
index e3f03fc..0000000
--- a/packages/Tethering/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Ligação (à Internet) via telemóvel ou zona Wi-Fi ativas"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"A ligação (à Internet) via telemóvel está desativada."</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacte o administrador para obter detalhes."</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona Wi-Fi e da ligação (à Internet) via telemóvel"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-pt/strings.xml b/packages/Tethering/res/values-pt/strings.xml
deleted file mode 100644
index a0a4745..0000000
--- a/packages/Tethering/res/values-pt/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ro/strings.xml b/packages/Tethering/res/values-ro/strings.xml
deleted file mode 100644
index 5706a4a..0000000
--- a/packages/Tethering/res/values-ro/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering sau hotspot activ"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Atingeți ca să configurați."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tetheringul este dezactivat"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contactați administratorul pentru detalii"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Starea hotspotului și a tetheringului"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ru/strings.xml b/packages/Tethering/res/values-ru/strings.xml
deleted file mode 100644
index 7cb6f7d..0000000
--- a/packages/Tethering/res/values-ru/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Включен режим модема или точка доступа"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Нажмите, чтобы настроить."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Использование телефона в качестве модема запрещено"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Чтобы узнать подробности, обратитесь к администратору."</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хот-спота и режима модема"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-si/strings.xml b/packages/Tethering/res/values-si/strings.xml
deleted file mode 100644
index ec34c22..0000000
--- a/packages/Tethering/res/values-si/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"ටෙදරින් හෝ හොට්ස්පොට් සක්රීයයි"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"පිහිටුවීමට තට්ටු කරන්න."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ටෙදරින් අබල කර ඇත"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"හොට්ස්පොට් & ටෙදරින් තත්ත්වය"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-sk/strings.xml b/packages/Tethering/res/values-sk/strings.xml
deleted file mode 100644
index 43e787c..0000000
--- a/packages/Tethering/res/values-sk/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering alebo prístupový bod je aktívny"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím prejdete na nastavenie."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je deaktivovaný"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požiadajte svojho správcu"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-sl/strings.xml b/packages/Tethering/res/values-sl/strings.xml
deleted file mode 100644
index 5943362..0000000
--- a/packages/Tethering/res/values-sl/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Povezava z internetom prek mobilnega telefona ali dostopna točka je aktivna"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Dotaknite se, če želite nastaviti."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezava z internetom prek mobilnega telefona je onemogočena"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Za podrobnosti se obrnite na skrbnika"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stanje dostopne točke in povezave z internetom prek mobilnega telefona"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-sq/strings.xml b/packages/Tethering/res/values-sq/strings.xml
deleted file mode 100644
index 21e1155..0000000
--- a/packages/Tethering/res/values-sq/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Ndarja e internetit ose zona e qasjes së internetit është aktive"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Trokit për ta konfiguruar."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ndarja e internetit është çaktivizuar"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakto me administratorin për detaje"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Statusi i zonës së qasjes dhe ndarjes së internetit"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-sr/strings.xml b/packages/Tethering/res/values-sr/strings.xml
deleted file mode 100644
index e2e4dc6..0000000
--- a/packages/Tethering/res/values-sr/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Привезивање или хотспот је активан"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Додирните да бисте подесили."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Привезивање је онемогућено"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Потражите детаље од администратора"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хотспота и привезивања"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-sv/strings.xml b/packages/Tethering/res/values-sv/strings.xml
deleted file mode 100644
index 72702c2..0000000
--- a/packages/Tethering/res/values-sv/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Internetdelning eller surfzon har aktiverats"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Tryck om du vill konfigurera."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internetdelning har inaktiverats"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakta administratören om du vill veta mer"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trådlös surfzon och internetdelning har inaktiverats"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-sw/strings.xml b/packages/Tethering/res/values-sw/strings.xml
deleted file mode 100644
index 65e4aa8ce..0000000
--- a/packages/Tethering/res/values-sw/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Kusambaza mtandao au mtandaopepe umewashwa"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Gusa ili uweke mipangilio."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Umezima kipengele cha kusambaza mtandao"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Mtandaopepe na hali ya kusambaza mtandao"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ta/strings.xml b/packages/Tethering/res/values-ta/strings.xml
deleted file mode 100644
index 4aba62d..0000000
--- a/packages/Tethering/res/values-ta/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"டெதெரிங் அல்லது ஹாட்ஸ்பாட் இயங்குகிறது"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"அமைக்க, தட்டவும்."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"டெதெரிங் முடக்கப்பட்டுள்ளது"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"விவரங்களுக்கு உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ஹாட்ஸ்பாட் & டெதெரிங் நிலை"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-te/strings.xml b/packages/Tethering/res/values-te/strings.xml
deleted file mode 100644
index 1f91791..0000000
--- a/packages/Tethering/res/values-te/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"టెథరింగ్ లేదా హాట్స్పాట్ యాక్టివ్గా ఉంది"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"సెటప్ చేయడానికి ట్యాప్ చేయండి."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"టెథరింగ్ డిజేబుల్ చేయబడింది"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"వివరాల కోసం మీ అడ్మిన్ని సంప్రదించండి"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"హాట్స్పాట్ & టెథరింగ్ స్థితి"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-th/strings.xml b/packages/Tethering/res/values-th/strings.xml
deleted file mode 100644
index 44171c0..0000000
--- a/packages/Tethering/res/values-th/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือหรือฮอตสปอตทำงานอยู่"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"แตะเพื่อตั้งค่า"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"สถานะฮอตสปอตและการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-tl/strings.xml b/packages/Tethering/res/values-tl/strings.xml
deleted file mode 100644
index 7347dd3..0000000
--- a/packages/Tethering/res/values-tl/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Aktibo ang pag-tether o hotspot"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"I-tap para i-set up."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Naka-disable ang pag-tether"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status ng hotspot at pag-tether"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-tr/strings.xml b/packages/Tethering/res/values-tr/strings.xml
deleted file mode 100644
index 32030f1..0000000
--- a/packages/Tethering/res/values-tr/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering veya hotspot etkin"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamak için dokunun."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering devre dışı bırakıldı"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ayrıntılı bilgi için yöneticinize başvurun"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot ve tethering durumu"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-uk/strings.xml b/packages/Tethering/res/values-uk/strings.xml
deleted file mode 100644
index 1ca89b3..0000000
--- a/packages/Tethering/res/values-uk/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Модем чи точка доступу активні"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Натисніть, щоб налаштувати."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Використання телефона як модема вимкнено"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Щоб дізнатися більше, зв\'яжіться з адміністратором"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус точки доступу та модема"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-ur/strings.xml b/packages/Tethering/res/values-ur/strings.xml
deleted file mode 100644
index d72c7d4..0000000
--- a/packages/Tethering/res/values-ur/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"ٹیدرنگ یا ہاٹ اسپاٹ فعال"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"ٹیدرنگ غیر فعال ہے"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ہاٹ اسپاٹ اور ٹیتھرنگ کا اسٹیٹس"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-uz/strings.xml b/packages/Tethering/res/values-uz/strings.xml
deleted file mode 100644
index af3b2eb..0000000
--- a/packages/Tethering/res/values-uz/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Modem rejimi yoki hotspot yoniq"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Sozlash uchun bosing."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modem rejimi faolsizlantirildi"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Tafsilotlari uchun administratoringizga murojaat qiling"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot va modem rejimi holati"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-vi/strings.xml b/packages/Tethering/res/values-vi/strings.xml
deleted file mode 100644
index 21a0735..0000000
--- a/packages/Tethering/res/values-vi/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Tính năng chia sẻ Internet hoặc điểm phát sóng đang hoạt động"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Hãy nhấn để thiết lập."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Đã tắt tính năng chia sẻ Internet"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trạng thái điểm phát sóng và chia sẻ Internet"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-zh-rCN/strings.xml b/packages/Tethering/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 98e3b4b..0000000
--- a/packages/Tethering/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"网络共享或热点已启用"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"点按即可设置。"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"网络共享已停用"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"如需了解详情,请与您的管理员联系"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"热点和网络共享状态"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-zh-rHK/strings.xml b/packages/Tethering/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 9cafd42..0000000
--- a/packages/Tethering/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"網絡共享或熱點已啟用"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"輕按即可設定。"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"網絡共享已停用"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"請聯絡您的管理員以瞭解詳情"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"熱點和網絡共享狀態"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-zh-rTW/strings.xml b/packages/Tethering/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 50a50bf..0000000
--- a/packages/Tethering/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"網路共用或無線基地台已啟用"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"輕觸即可進行設定。"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"網路共用已停用"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳情請洽你的管理員"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"無線基地台與網路共用狀態"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values-zu/strings.xml b/packages/Tethering/res/values-zu/strings.xml
deleted file mode 100644
index f210f87..0000000
--- a/packages/Tethering/res/values-zu/strings.xml
+++ /dev/null
@@ -1,29 +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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string>
- <string name="tethered_notification_message" msgid="64800879503420696">"Thepha ukuze usethe."</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string>
- <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"I-Hotspot nesimo sokusebenzisa ifoni njengemodemu"</string>
- <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
- <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
- <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
- <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
- <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
-</resources>
diff --git a/packages/Tethering/res/values/config.xml b/packages/Tethering/res/values/config.xml
deleted file mode 100644
index 9b9dcde..0000000
--- a/packages/Tethering/res/values/config.xml
+++ /dev/null
@@ -1,191 +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.
--->
-<resources>
- <!--
- OEMs that wish to change the below settings must do so via a runtime resource overlay package
- and *NOT* by changing this file. This file is part of the tethering mainline module.
- TODO: define two resources for each config item: a default_* resource and a config_* resource,
- config_* is empty by default but may be overridden by RROs.
- -->
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- USB interfaces. If the device doesn't want to support tethering over USB this should
- be empty. An example would be "usb.*" -->
- <string-array translatable="false" name="config_tether_usb_regexs">
- <item>"usb\\d"</item>
- <item>"rndis\\d"</item>
- </string-array>
-
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- NCM interfaces. If the device doesn't want to support tethering over NCM this should
- be empty. -->
- <string-array translatable="false" name="config_tether_ncm_regexs">
- </string-array>
-
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- Wifi interfaces. If the device doesn't want to support tethering over Wifi this
- should be empty. An example would be "softap.*" -->
- <string-array translatable="false" name="config_tether_wifi_regexs">
- <item>"wlan\\d"</item>
- <item>"softap\\d"</item>
- </string-array>
-
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- WiGig interfaces. If the device doesn't want to support tethering over WiGig this
- should be empty. An example would be "wigig\\d" -->
- <string-array translatable="false" name="config_tether_wigig_regexs">
- <item>"wigig\\d"</item>
- </string-array>
-
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- Wifi P2P interfaces. If the device doesn't want to support tethering over Wifi P2p this
- should be empty. An example would be "p2p-p2p\\d-.*" -->
- <string-array translatable="false" name="config_tether_wifi_p2p_regexs">
- <item>"p2p-p2p\\d-.*"</item>
- <item>"p2p\\d"</item>
- </string-array>
-
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- bluetooth interfaces. If the device doesn't want to support tethering over bluetooth this
- should be empty. -->
- <string-array translatable="false" name="config_tether_bluetooth_regexs">
- <item>"bt-pan"</item>
- </string-array>
-
- <!-- Use the BPF offload for tethering when the kernel has support. True by default.
- If the device doesn't want to support tether BPF offload, this should be false.
- Note that this setting could be overridden by device config.
- -->
- <bool translatable="false" name="config_tether_enable_bpf_offload">true</bool>
-
- <!-- Use the old dnsmasq DHCP server for tethering instead of the framework implementation. -->
- <bool translatable="false" name="config_tether_enable_legacy_dhcp_server">false</bool>
-
- <!-- Dhcp range (min, max) to use for tethering purposes -->
- <string-array translatable="false" name="config_tether_dhcp_range">
- </string-array>
-
- <!-- Used to config periodic polls tether offload stats from tethering offload HAL to make the
- data warnings work. 5000(ms) by default. If the device doesn't want to poll tether
- offload stats, this should be -1. Note that this setting could be override by
- runtime resource overlays.
- -->
- <integer translatable="false" name="config_tether_offload_poll_interval">5000</integer>
-
- <!-- Array of ConnectivityManager.TYPE_{BLUETOOTH, ETHERNET, MOBILE, MOBILE_DUN, MOBILE_HIPRI,
- WIFI} values allowable for tethering.
-
- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
- [1,7,0] for TYPE_WIFI, TYPE_BLUETOOTH, and TYPE_MOBILE.
-
- This list is also modified by code within the framework, including:
-
- - TYPE_ETHERNET (9) is prepended to this list, and
-
- - the return value of TelephonyManager.isTetheringApnRequired()
- determines how the array is further modified:
-
- * TRUE (DUN REQUIRED).
- TYPE_MOBILE is removed (if present).
- TYPE_MOBILE_HIPRI is removed (if present).
- TYPE_MOBILE_DUN is appended (if not already present).
-
- * FALSE (DUN NOT REQUIRED).
- TYPE_MOBILE_DUN is removed (if present).
- If both of TYPE_MOBILE{,_HIPRI} are not present:
- TYPE_MOBILE is appended.
- TYPE_MOBILE_HIPRI is appended.
-
- For other changes applied to this list, now and in the future, see
- com.android.networkstack.tethering.TetheringConfiguration.
-
- Note also: the order of this is important. The first upstream type
- for which a satisfying network exists is used.
- -->
- <integer-array translatable="false" name="config_tether_upstream_types">
- </integer-array>
-
- <!-- When true, the tethering upstream network follows the current default
- Internet network (except when the current default network is mobile,
- in which case a DUN network will be used if required).
-
- When true, overrides the config_tether_upstream_types setting above.
- -->
- <bool translatable="false" name="config_tether_upstream_automatic">true</bool>
-
-
- <!-- If the mobile hotspot feature requires provisioning, a package name and class name
- can be provided to launch a supported application that provisions the devices.
- EntitlementManager will send an intent to Settings with the specified package name and
- class name in extras to launch provision app.
- TODO: note what extras here.
-
- See EntitlementManager#runUiTetherProvisioning and
- packages/apps/Settings/src/com/android/settings/network/TetherProvisioningActivity.java
- for more details.
-
- For ui-less/periodic recheck support see config_mobile_hotspot_provision_app_no_ui
- -->
- <!-- The first element is the package name and the second element is the class name
- of the provisioning app -->
- <string-array translatable="false" name="config_mobile_hotspot_provision_app">
- <!--
- <item>com.example.provisioning</item>
- <item>com.example.provisioning.Activity</item>
- -->
- </string-array>
-
- <!-- If the mobile hotspot feature requires provisioning, an action can be provided
- that will be broadcast in non-ui cases for checking the provisioning status.
- EntitlementManager will pass the specified name to Settings and Settings would
- launch provisioning app by sending an intent with the package name.
-
- A second broadcast, action defined by config_mobile_hotspot_provision_response,
- will be sent back to notify if provisioning succeeded or not. The response will
- match that of the activity in config_mobile_hotspot_provision_app, but instead
- contained within the int extra "EntitlementResult".
- TODO: provide the system api for "EntitlementResult" extra and note it here.
-
- See EntitlementManager#runSilentTetherProvisioning and
- packages/apps/Settings/src/com/android/settings/wifi/tether/TetherService.java for more
- details.
- -->
- <string translatable="false" name="config_mobile_hotspot_provision_app_no_ui"></string>
-
- <!-- Sent in response to a provisioning check. The caller must hold the
- permission android.permission.TETHER_PRIVILEGED for Settings to
- receive this response.
-
- See config_mobile_hotspot_provision_response
- -->
- <string translatable="false" name="config_mobile_hotspot_provision_response"></string>
-
- <!-- Number of hours between each background provisioning call -->
- <integer translatable="false" name="config_mobile_hotspot_provision_check_period">24</integer>
-
- <!-- ComponentName of the service used to run no ui tether provisioning. -->
- <string translatable="false" name="config_wifi_tether_enable">com.android.settings/.wifi.tether.TetherService</string>
-
- <!-- No upstream notification is shown when there is a downstream but no upstream that is able
- to do the tethering. -->
- <!-- Delay(millisecond) to show no upstream notification after there's no Backhaul. Set delay to
- "-1" for disable this feature. -->
- <integer name="delay_to_show_no_upstream_after_no_backhaul">-1</integer>
-
- <!-- Cellular roaming notification is shown when upstream is cellular network and in roaming
- state. -->
- <!-- Config for showing upstream roaming notification. -->
- <bool name="config_upstream_roaming_notification">false</bool>
-</resources>
diff --git a/packages/Tethering/res/values/overlayable.xml b/packages/Tethering/res/values/overlayable.xml
deleted file mode 100644
index 6a33d55..0000000
--- a/packages/Tethering/res/values/overlayable.xml
+++ /dev/null
@@ -1,45 +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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <overlayable name="TetheringConfig">
- <policy type="product|system|vendor">
- <!-- Params from config.xml that can be overlaid -->
- <item type="array" name="config_tether_usb_regexs"/>
- <item type="array" name="config_tether_ncm_regexs" />
- <item type="array" name="config_tether_wifi_regexs"/>
- <item type="array" name="config_tether_wigig_regexs"/>
- <item type="array" name="config_tether_wifi_p2p_regexs"/>
- <item type="array" name="config_tether_bluetooth_regexs"/>
- <item type="array" name="config_tether_dhcp_range"/>
- <!-- Use the BPF offload for tethering when the kernel has support. True by default.
- If the device doesn't want to support tether BPF offload, this should be false.
- Note that this setting could be overridden by device config.
- -->
- <item type="bool" name="config_tether_enable_bpf_offload"/>
- <item type="bool" name="config_tether_enable_legacy_dhcp_server"/>
- <item type="integer" name="config_tether_offload_poll_interval"/>
- <item type="array" name="config_tether_upstream_types"/>
- <item type="bool" name="config_tether_upstream_automatic"/>
- <!-- Configuration values for tethering entitlement check -->
- <item type="array" name="config_mobile_hotspot_provision_app"/>
- <item type="string" name="config_mobile_hotspot_provision_app_no_ui"/>
- <item type="string" name="config_mobile_hotspot_provision_response"/>
- <item type="integer" name="config_mobile_hotspot_provision_check_period"/>
- <item type="string" name="config_wifi_tether_enable"/>
- <!-- Params from config.xml that can be overlaid -->
- </policy>
- </overlayable>
-</resources>
diff --git a/packages/Tethering/res/values/strings.xml b/packages/Tethering/res/values/strings.xml
deleted file mode 100644
index d63c7c5..0000000
--- a/packages/Tethering/res/values/strings.xml
+++ /dev/null
@@ -1,47 +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.
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Shown when the device is tethered -->
- <!-- String for tethered notification title [CHAR LIMIT=200] -->
- <string name="tethered_notification_title">Tethering or hotspot active</string>
- <!-- String for tethered notification message [CHAR LIMIT=200] -->
- <string name="tethered_notification_message">Tap to set up.</string>
-
- <!-- This notification is shown when tethering has been disabled on a user's device.
- The device is managed by the user's employer. Tethering can't be turned on unless the
- IT administrator allows it. The noun "admin" is another reference for "IT administrator." -->
- <!-- String for tether disabling notification title [CHAR LIMIT=200] -->
- <string name="disable_tether_notification_title">Tethering is disabled</string>
- <!-- String for tether disabling notification message [CHAR LIMIT=200] -->
- <string name="disable_tether_notification_message">Contact your admin for details</string>
-
- <!-- This string should be consistent with the "Hotspot & tethering" text in the "Network and
- Internet" settings page. That is currently the tether_settings_title_all string. -->
- <!-- String for tether notification channel name [CHAR LIMIT=200] -->
- <string name="notification_channel_tethering_status">Hotspot & tethering status</string>
-
- <!-- String for no upstream notification title [CHAR LIMIT=200] -->
- <string name="no_upstream_notification_title"></string>
- <!-- String for no upstream notification message [CHAR LIMIT=200] -->
- <string name="no_upstream_notification_message"></string>
- <!-- String for no upstream notification disable button [CHAR LIMIT=200] -->
- <string name="no_upstream_notification_disable_button"></string>
-
- <!-- String for cellular roaming notification title [CHAR LIMIT=200] -->
- <string name="upstream_roaming_notification_title"></string>
- <!-- String for cellular roaming notification message [CHAR LIMIT=500] -->
- <string name="upstream_roaming_notification_message"></string>
-</resources>
diff --git a/packages/Tethering/src/android/net/dhcp/DhcpServerCallbacks.java b/packages/Tethering/src/android/net/dhcp/DhcpServerCallbacks.java
deleted file mode 100644
index 9fda125..0000000
--- a/packages/Tethering/src/android/net/dhcp/DhcpServerCallbacks.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 android.net.dhcp;
-
-/**
- * Convenience wrapper around IDhcpServerCallbacks.Stub that implements getInterfaceVersion().
- * @hide
- */
-public abstract class DhcpServerCallbacks extends IDhcpServerCallbacks.Stub {
- /**
- * Get the version of the aidl interface implemented by the callbacks.
- */
- @Override
- public int getInterfaceVersion() {
- return IDhcpServerCallbacks.VERSION;
- }
-
- @Override
- public String getInterfaceHash() {
- return IDhcpServerCallbacks.HASH;
- }
-}
diff --git a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
deleted file mode 100644
index aaaec17..0000000
--- a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
-
-import android.net.LinkAddress;
-import android.util.ArraySet;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.net.Inet4Address;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * Subclass of {@link DhcpServingParamsParcel} with additional utility methods for building.
- *
- * <p>This utility class does not check for validity of the parameters: invalid parameters are
- * reported by the receiving module when unparceling the parcel.
- *
- * @see DhcpServingParams
- * @hide
- */
-public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel {
- public static final int MTU_UNSET = 0;
-
- /**
- * Set the server address and served prefix for the DHCP server.
- *
- * <p>This parameter is required.
- */
- public DhcpServingParamsParcelExt setServerAddr(@NonNull LinkAddress serverAddr) {
- this.serverAddr = inet4AddressToIntHTH((Inet4Address) serverAddr.getAddress());
- this.serverAddrPrefixLength = serverAddr.getPrefixLength();
- return this;
- }
-
- /**
- * Set the default routers to be advertised to DHCP clients.
- *
- * <p>Each router must be inside the served prefix. This may be an empty set, but it must
- * always be set explicitly.
- */
- public DhcpServingParamsParcelExt setDefaultRouters(@NonNull Set<Inet4Address> defaultRouters) {
- this.defaultRouters = toIntArray(defaultRouters);
- return this;
- }
-
- /**
- * Set the default routers to be advertised to DHCP clients.
- *
- * <p>Each router must be inside the served prefix. This may be an empty list of routers,
- * but it must always be set explicitly.
- */
- public DhcpServingParamsParcelExt setDefaultRouters(@NonNull Inet4Address... defaultRouters) {
- return setDefaultRouters(newArraySet(defaultRouters));
- }
-
- /**
- * Convenience method to build the parameters with no default router.
- *
- * <p>Equivalent to calling {@link #setDefaultRouters(Inet4Address...)} with no address.
- */
- public DhcpServingParamsParcelExt setNoDefaultRouter() {
- return setDefaultRouters();
- }
-
- /**
- * Set the DNS servers to be advertised to DHCP clients.
- *
- * <p>This may be an empty set, but it must always be set explicitly.
- */
- public DhcpServingParamsParcelExt setDnsServers(@NonNull Set<Inet4Address> dnsServers) {
- this.dnsServers = toIntArray(dnsServers);
- return this;
- }
-
- /**
- * Set the DNS servers to be advertised to DHCP clients.
- *
- * <p>This may be an empty list of servers, but it must always be set explicitly.
- */
- public DhcpServingParamsParcelExt setDnsServers(@NonNull Inet4Address... dnsServers) {
- return setDnsServers(newArraySet(dnsServers));
- }
-
- /**
- * Convenience method to build the parameters with no DNS server.
- *
- * <p>Equivalent to calling {@link #setDnsServers(Inet4Address...)} with no address.
- */
- public DhcpServingParamsParcelExt setNoDnsServer() {
- return setDnsServers();
- }
-
- /**
- * Set excluded addresses that the DHCP server is not allowed to assign to clients.
- *
- * <p>This parameter is optional. DNS servers and default routers are always excluded
- * and do not need to be set here.
- */
- public DhcpServingParamsParcelExt setExcludedAddrs(@NonNull Set<Inet4Address> excludedAddrs) {
- this.excludedAddrs = toIntArray(excludedAddrs);
- return this;
- }
-
- /**
- * Set excluded addresses that the DHCP server is not allowed to assign to clients.
- *
- * <p>This parameter is optional. DNS servers and default routers are always excluded
- * and do not need to be set here.
- */
- public DhcpServingParamsParcelExt setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) {
- return setExcludedAddrs(newArraySet(excludedAddrs));
- }
-
- /**
- * Set the lease time for leases assigned by the DHCP server.
- *
- * <p>This parameter is required.
- */
- public DhcpServingParamsParcelExt setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs) {
- this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
- return this;
- }
-
- /**
- * Set the link MTU to be advertised to DHCP clients.
- *
- * <p>If set to {@link #MTU_UNSET}, no MTU will be advertised to clients. This parameter
- * is optional and defaults to {@link #MTU_UNSET}.
- */
- public DhcpServingParamsParcelExt setLinkMtu(int linkMtu) {
- this.linkMtu = linkMtu;
- return this;
- }
-
- /**
- * Set whether the DHCP server should send the ANDROID_METERED vendor-specific option.
- *
- * <p>If not set, the default value is false.
- */
- public DhcpServingParamsParcelExt setMetered(boolean metered) {
- this.metered = metered;
- return this;
- }
-
- /**
- * Set the client address to tell DHCP server only offer this address.
- * The client's prefix length is the same as server's.
- *
- * <p>If not set, the default value is null.
- */
- public DhcpServingParamsParcelExt setSingleClientAddr(@Nullable Inet4Address clientAddr) {
- this.singleClientAddr = clientAddr == null ? 0 : inet4AddressToIntHTH(clientAddr);
- return this;
- }
-
- /**
- * Set whether the DHCP server should request a new prefix from IpServer when receiving
- * DHCPDECLINE message in certain particular link (e.g. there is only one downstream USB
- * tethering client). If it's false, process DHCPDECLINE message as RFC2131#4.3.3 suggests.
- *
- * <p>If not set, the default value is false.
- */
- public DhcpServingParamsParcelExt setChangePrefixOnDecline(boolean changePrefixOnDecline) {
- this.changePrefixOnDecline = changePrefixOnDecline;
- return this;
- }
-
- private static int[] toIntArray(@NonNull Collection<Inet4Address> addrs) {
- int[] res = new int[addrs.size()];
- int i = 0;
- for (Inet4Address addr : addrs) {
- res[i] = inet4AddressToIntHTH(addr);
- i++;
- }
- return res;
- }
-
- private static ArraySet<Inet4Address> newArraySet(Inet4Address... addrs) {
- ArraySet<Inet4Address> addrSet = new ArraySet<>(addrs.length);
- Collections.addAll(addrSet, addrs);
- return addrSet;
- }
-}
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
deleted file mode 100644
index 8af1797..0000000
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ /dev/null
@@ -1,1385 +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.net.ip;
-
-import static android.net.RouteInfo.RTN_UNICAST;
-import static android.net.TetheringManager.TetheringRequest.checkStaticAddressConfiguration;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
-import static android.net.util.NetworkConstants.asByte;
-import static android.net.util.PrefixUtils.asIpPrefix;
-import static android.net.util.TetheringMessageBase.BASE_IPSERVER;
-import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
-
-import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
-
-import android.net.INetd;
-import android.net.INetworkStackStatusCallback;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.MacAddress;
-import android.net.RouteInfo;
-import android.net.TetheredClient;
-import android.net.TetheringManager;
-import android.net.TetheringRequestParcel;
-import android.net.dhcp.DhcpLeaseParcelable;
-import android.net.dhcp.DhcpServerCallbacks;
-import android.net.dhcp.DhcpServingParamsParcel;
-import android.net.dhcp.DhcpServingParamsParcelExt;
-import android.net.dhcp.IDhcpEventCallbacks;
-import android.net.dhcp.IDhcpServer;
-import android.net.ip.IpNeighborMonitor.NeighborEvent;
-import android.net.ip.RouterAdvertisementDaemon.RaParams;
-import android.net.shared.NetdUtils;
-import android.net.shared.RouteUtils;
-import android.net.util.InterfaceParams;
-import android.net.util.InterfaceSet;
-import android.net.util.PrefixUtils;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.util.Log;
-import android.util.SparseArray;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.networkstack.tethering.BpfCoordinator;
-import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
-import com.android.networkstack.tethering.PrivateAddressCoordinator;
-
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.NetworkInterface;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Random;
-import java.util.Set;
-
-/**
- * Provides the interface to IP-layer serving functionality for a given network
- * interface, e.g. for tethering or "local-only hotspot" mode.
- *
- * @hide
- */
-public class IpServer extends StateMachine {
- public static final int STATE_UNAVAILABLE = 0;
- public static final int STATE_AVAILABLE = 1;
- public static final int STATE_TETHERED = 2;
- public static final int STATE_LOCAL_ONLY = 3;
-
- /** Get string name of |state|.*/
- public static String getStateString(int state) {
- switch (state) {
- case STATE_UNAVAILABLE: return "UNAVAILABLE";
- case STATE_AVAILABLE: return "AVAILABLE";
- case STATE_TETHERED: return "TETHERED";
- case STATE_LOCAL_ONLY: return "LOCAL_ONLY";
- }
- return "UNKNOWN: " + state;
- }
-
- private static final byte DOUG_ADAMS = (byte) 42;
-
- // TODO: have PanService use some visible version of this constant
- private static final String BLUETOOTH_IFACE_ADDR = "192.168.44.1/24";
-
- // TODO: have this configurable
- private static final int DHCP_LEASE_TIME_SECS = 3600;
-
- private static final MacAddress NULL_MAC_ADDRESS = MacAddress.fromString("00:00:00:00:00:00");
-
- private static final String TAG = "IpServer";
- private static final boolean DBG = false;
- private static final boolean VDBG = false;
- private static final Class[] sMessageClasses = {
- IpServer.class
- };
- private static final SparseArray<String> sMagicDecoderRing =
- MessageUtils.findMessageNames(sMessageClasses);
-
- /** IpServer callback. */
- public static class Callback {
- /**
- * Notify that |who| has changed its tethering state.
- *
- * @param who the calling instance of IpServer
- * @param state one of STATE_*
- * @param lastError one of TetheringManager.TETHER_ERROR_*
- */
- public void updateInterfaceState(IpServer who, int state, int lastError) { }
-
- /**
- * Notify that |who| has new LinkProperties.
- *
- * @param who the calling instance of IpServer
- * @param newLp the new LinkProperties to report
- */
- public void updateLinkProperties(IpServer who, LinkProperties newLp) { }
-
- /**
- * Notify that the DHCP leases changed in one of the IpServers.
- */
- public void dhcpLeasesChanged() { }
-
- /**
- * Request Tethering change.
- *
- * @param tetheringType the downstream type of this IpServer.
- * @param enabled enable or disable tethering.
- */
- public void requestEnableTethering(int tetheringType, boolean enabled) { }
- }
-
- /** Capture IpServer dependencies, for injection. */
- public abstract static class Dependencies {
- /** Create an IpNeighborMonitor to be used by this IpServer */
- public IpNeighborMonitor getIpNeighborMonitor(Handler handler, SharedLog log,
- IpNeighborMonitor.NeighborEventConsumer consumer) {
- return new IpNeighborMonitor(handler, log, consumer);
- }
-
- /** Create a RouterAdvertisementDaemon instance to be used by IpServer.*/
- public RouterAdvertisementDaemon getRouterAdvertisementDaemon(InterfaceParams ifParams) {
- return new RouterAdvertisementDaemon(ifParams);
- }
-
- /** Get |ifName|'s interface information.*/
- public InterfaceParams getInterfaceParams(String ifName) {
- return InterfaceParams.getByName(ifName);
- }
-
- /** Get |ifName|'s interface index. */
- public int getIfindex(String ifName) {
- try {
- return NetworkInterface.getByName(ifName).getIndex();
- } catch (IOException | NullPointerException e) {
- Log.e(TAG, "Can't determine interface index for interface " + ifName);
- return 0;
- }
- }
-
- /** Create a DhcpServer instance to be used by IpServer. */
- public abstract void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
- DhcpServerCallbacks cb);
- }
-
- // request from the user that it wants to tether
- public static final int CMD_TETHER_REQUESTED = BASE_IPSERVER + 1;
- // request from the user that it wants to untether
- public static final int CMD_TETHER_UNREQUESTED = BASE_IPSERVER + 2;
- // notification that this interface is down
- public static final int CMD_INTERFACE_DOWN = BASE_IPSERVER + 3;
- // notification from the master SM that it had trouble enabling IP Forwarding
- public static final int CMD_IP_FORWARDING_ENABLE_ERROR = BASE_IPSERVER + 4;
- // notification from the master SM that it had trouble disabling IP Forwarding
- public static final int CMD_IP_FORWARDING_DISABLE_ERROR = BASE_IPSERVER + 5;
- // notification from the master SM that it had trouble starting tethering
- public static final int CMD_START_TETHERING_ERROR = BASE_IPSERVER + 6;
- // notification from the master SM that it had trouble stopping tethering
- public static final int CMD_STOP_TETHERING_ERROR = BASE_IPSERVER + 7;
- // notification from the master SM that it had trouble setting the DNS forwarders
- public static final int CMD_SET_DNS_FORWARDERS_ERROR = BASE_IPSERVER + 8;
- // the upstream connection has changed
- public static final int CMD_TETHER_CONNECTION_CHANGED = BASE_IPSERVER + 9;
- // new IPv6 tethering parameters need to be processed
- public static final int CMD_IPV6_TETHER_UPDATE = BASE_IPSERVER + 10;
- // new neighbor cache entry on our interface
- public static final int CMD_NEIGHBOR_EVENT = BASE_IPSERVER + 11;
- // request from DHCP server that it wants to have a new prefix
- public static final int CMD_NEW_PREFIX_REQUEST = BASE_IPSERVER + 12;
- // request from PrivateAddressCoordinator to restart tethering.
- public static final int CMD_NOTIFY_PREFIX_CONFLICT = BASE_IPSERVER + 13;
-
- private final State mInitialState;
- private final State mLocalHotspotState;
- private final State mTetheredState;
- private final State mUnavailableState;
- private final State mWaitingForRestartState;
-
- private final SharedLog mLog;
- private final INetd mNetd;
- @NonNull
- private final BpfCoordinator mBpfCoordinator;
- private final Callback mCallback;
- private final InterfaceController mInterfaceCtrl;
- private final PrivateAddressCoordinator mPrivateAddressCoordinator;
-
- private final String mIfaceName;
- private final int mInterfaceType;
- private final LinkProperties mLinkProperties;
- private final boolean mUsingLegacyDhcp;
- private final boolean mUsingBpfOffload;
-
- private final Dependencies mDeps;
-
- private int mLastError;
- private int mServingMode;
- private InterfaceSet mUpstreamIfaceSet; // may change over time
- private InterfaceParams mInterfaceParams;
- // TODO: De-duplicate this with mLinkProperties above. Currently, these link
- // properties are those selected by the IPv6TetheringCoordinator and relayed
- // to us. By comparison, mLinkProperties contains the addresses and directly
- // connected routes that have been formed from these properties iff. we have
- // succeeded in configuring them and are able to announce them within Router
- // Advertisements (otherwise, we do not add them to mLinkProperties at all).
- private LinkProperties mLastIPv6LinkProperties;
- private RouterAdvertisementDaemon mRaDaemon;
-
- // To be accessed only on the handler thread
- private int mDhcpServerStartIndex = 0;
- private IDhcpServer mDhcpServer;
- private RaParams mLastRaParams;
-
- private LinkAddress mStaticIpv4ServerAddr;
- private LinkAddress mStaticIpv4ClientAddr;
-
- @NonNull
- private List<TetheredClient> mDhcpLeases = Collections.emptyList();
-
- private int mLastIPv6UpstreamIfindex = 0;
-
- private class MyNeighborEventConsumer implements IpNeighborMonitor.NeighborEventConsumer {
- public void accept(NeighborEvent e) {
- sendMessage(CMD_NEIGHBOR_EVENT, e);
- }
- }
-
- private final IpNeighborMonitor mIpNeighborMonitor;
-
- private LinkAddress mIpv4Address;
-
- // TODO: Add a dependency object to pass the data members or variables from the tethering
- // object. It helps to reduce the arguments of the constructor.
- public IpServer(
- String ifaceName, Looper looper, int interfaceType, SharedLog log,
- INetd netd, @NonNull BpfCoordinator coordinator, Callback callback,
- boolean usingLegacyDhcp, boolean usingBpfOffload,
- PrivateAddressCoordinator addressCoordinator, Dependencies deps) {
- super(ifaceName, looper);
- mLog = log.forSubComponent(ifaceName);
- mNetd = netd;
- mBpfCoordinator = coordinator;
- mCallback = callback;
- mInterfaceCtrl = new InterfaceController(ifaceName, mNetd, mLog);
- mIfaceName = ifaceName;
- mInterfaceType = interfaceType;
- mLinkProperties = new LinkProperties();
- mUsingLegacyDhcp = usingLegacyDhcp;
- mUsingBpfOffload = usingBpfOffload;
- mPrivateAddressCoordinator = addressCoordinator;
- mDeps = deps;
- resetLinkProperties();
- mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
- mServingMode = STATE_AVAILABLE;
-
- mIpNeighborMonitor = mDeps.getIpNeighborMonitor(getHandler(), mLog,
- new MyNeighborEventConsumer());
-
- // IP neighbor monitor monitors the neighbor events for adding/removing offload
- // forwarding rules per client. If BPF offload is not supported, don't start listening
- // for neighbor events. See updateIpv6ForwardingRules, addIpv6ForwardingRule,
- // removeIpv6ForwardingRule.
- if (mUsingBpfOffload && !mIpNeighborMonitor.start()) {
- mLog.e("Failed to create IpNeighborMonitor on " + mIfaceName);
- }
-
- mInitialState = new InitialState();
- mLocalHotspotState = new LocalHotspotState();
- mTetheredState = new TetheredState();
- mUnavailableState = new UnavailableState();
- mWaitingForRestartState = new WaitingForRestartState();
- addState(mInitialState);
- addState(mLocalHotspotState);
- addState(mTetheredState);
- addState(mWaitingForRestartState, mTetheredState);
- addState(mUnavailableState);
-
- setInitialState(mInitialState);
- }
-
- /** Interface name which IpServer served.*/
- public String interfaceName() {
- return mIfaceName;
- }
-
- /**
- * Tethering downstream type. It would be one of TetheringManager#TETHERING_*.
- */
- public int interfaceType() {
- return mInterfaceType;
- }
-
- /** Last error from this IpServer. */
- public int lastError() {
- return mLastError;
- }
-
- /** Serving mode is the current state of IpServer state machine. */
- public int servingMode() {
- return mServingMode;
- }
-
- /** The properties of the network link which IpServer is serving. */
- public LinkProperties linkProperties() {
- return new LinkProperties(mLinkProperties);
- }
-
- /** The address which IpServer is using. */
- public LinkAddress getAddress() {
- return mIpv4Address;
- }
-
- /**
- * Get the latest list of DHCP leases that was reported. Must be called on the IpServer looper
- * thread.
- */
- public List<TetheredClient> getAllLeases() {
- return Collections.unmodifiableList(mDhcpLeases);
- }
-
- /** Stop this IpServer. After this is called this IpServer should not be used any more. */
- public void stop() {
- sendMessage(CMD_INTERFACE_DOWN);
- }
-
- /**
- * Tethering is canceled. IpServer state machine will be available and wait for
- * next tethering request.
- */
- public void unwanted() {
- sendMessage(CMD_TETHER_UNREQUESTED);
- }
-
- /** Internals. */
-
- private boolean startIPv4() {
- return configureIPv4(true);
- }
-
- /**
- * Convenience wrapper around INetworkStackStatusCallback to run callbacks on the IpServer
- * handler.
- *
- * <p>Different instances of this class can be created for each call to IDhcpServer methods,
- * with different implementations of the callback, to differentiate handling of success/error in
- * each call.
- */
- private abstract class OnHandlerStatusCallback extends INetworkStackStatusCallback.Stub {
- @Override
- public void onStatusAvailable(int statusCode) {
- getHandler().post(() -> callback(statusCode));
- }
-
- public abstract void callback(int statusCode);
-
- @Override
- public int getInterfaceVersion() {
- return this.VERSION;
- }
-
- @Override
- public String getInterfaceHash() {
- return this.HASH;
- }
- }
-
- private class DhcpServerCallbacksImpl extends DhcpServerCallbacks {
- private final int mStartIndex;
-
- private DhcpServerCallbacksImpl(int startIndex) {
- mStartIndex = startIndex;
- }
-
- @Override
- public void onDhcpServerCreated(int statusCode, IDhcpServer server) throws RemoteException {
- getHandler().post(() -> {
- // We are on the handler thread: mDhcpServerStartIndex can be read safely.
- if (mStartIndex != mDhcpServerStartIndex) {
- // This start request is obsolete. When the |server| binder token goes out of
- // scope, the garbage collector will finalize it, which causes the network stack
- // process garbage collector to collect the server itself.
- return;
- }
-
- if (statusCode != STATUS_SUCCESS) {
- mLog.e("Error obtaining DHCP server: " + statusCode);
- handleError();
- return;
- }
-
- mDhcpServer = server;
- try {
- mDhcpServer.startWithCallbacks(new OnHandlerStatusCallback() {
- @Override
- public void callback(int startStatusCode) {
- if (startStatusCode != STATUS_SUCCESS) {
- mLog.e("Error starting DHCP server: " + startStatusCode);
- handleError();
- }
- }
- }, new DhcpEventCallback());
- } catch (RemoteException e) {
- throw new IllegalStateException(e);
- }
- });
- }
-
- private void handleError() {
- mLastError = TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR;
- transitionTo(mInitialState);
- }
- }
-
- private class DhcpEventCallback extends IDhcpEventCallbacks.Stub {
- @Override
- public void onLeasesChanged(List<DhcpLeaseParcelable> leaseParcelables) {
- final ArrayList<TetheredClient> leases = new ArrayList<>();
- for (DhcpLeaseParcelable lease : leaseParcelables) {
- final LinkAddress address = new LinkAddress(
- intToInet4AddressHTH(lease.netAddr), lease.prefixLength,
- 0 /* flags */, RT_SCOPE_UNIVERSE /* as per RFC6724#3.2 */,
- lease.expTime /* deprecationTime */, lease.expTime /* expirationTime */);
-
- final MacAddress macAddress;
- try {
- macAddress = MacAddress.fromBytes(lease.hwAddr);
- } catch (IllegalArgumentException e) {
- Log.wtf(TAG, "Invalid address received from DhcpServer: "
- + Arrays.toString(lease.hwAddr));
- return;
- }
-
- final TetheredClient.AddressInfo addressInfo = new TetheredClient.AddressInfo(
- address, lease.hostname);
- leases.add(new TetheredClient(
- macAddress,
- Collections.singletonList(addressInfo),
- mInterfaceType));
- }
-
- getHandler().post(() -> {
- mDhcpLeases = leases;
- mCallback.dhcpLeasesChanged();
- });
- }
-
- @Override
- public void onNewPrefixRequest(@NonNull final IpPrefix currentPrefix) {
- Objects.requireNonNull(currentPrefix);
- sendMessage(CMD_NEW_PREFIX_REQUEST, currentPrefix);
- }
-
- @Override
- public int getInterfaceVersion() {
- return this.VERSION;
- }
-
- @Override
- public String getInterfaceHash() throws RemoteException {
- return this.HASH;
- }
- }
-
- private RouteInfo getDirectConnectedRoute(@NonNull final LinkAddress ipv4Address) {
- Objects.requireNonNull(ipv4Address);
- return new RouteInfo(PrefixUtils.asIpPrefix(ipv4Address), null, mIfaceName, RTN_UNICAST);
- }
-
- private DhcpServingParamsParcel makeServingParams(@NonNull final Inet4Address defaultRouter,
- @NonNull final Inet4Address dnsServer, @NonNull LinkAddress serverAddr,
- @Nullable Inet4Address clientAddr) {
- final boolean changePrefixOnDecline =
- (mInterfaceType == TetheringManager.TETHERING_NCM && clientAddr == null);
- return new DhcpServingParamsParcelExt()
- .setDefaultRouters(defaultRouter)
- .setDhcpLeaseTimeSecs(DHCP_LEASE_TIME_SECS)
- .setDnsServers(dnsServer)
- .setServerAddr(serverAddr)
- .setMetered(true)
- .setSingleClientAddr(clientAddr)
- .setChangePrefixOnDecline(changePrefixOnDecline);
- // TODO: also advertise link MTU
- }
-
- private boolean startDhcp(final LinkAddress serverLinkAddr, final LinkAddress clientLinkAddr) {
- if (mUsingLegacyDhcp) {
- return true;
- }
-
- final Inet4Address addr = (Inet4Address) serverLinkAddr.getAddress();
- final Inet4Address clientAddr = clientLinkAddr == null ? null :
- (Inet4Address) clientLinkAddr.getAddress();
-
- final DhcpServingParamsParcel params = makeServingParams(addr /* defaultRouter */,
- addr /* dnsServer */, serverLinkAddr, clientAddr);
- mDhcpServerStartIndex++;
- mDeps.makeDhcpServer(
- mIfaceName, params, new DhcpServerCallbacksImpl(mDhcpServerStartIndex));
- return true;
- }
-
- private void stopDhcp() {
- // Make all previous start requests obsolete so servers are not started later
- mDhcpServerStartIndex++;
-
- if (mDhcpServer != null) {
- try {
- mDhcpServer.stop(new OnHandlerStatusCallback() {
- @Override
- public void callback(int statusCode) {
- if (statusCode != STATUS_SUCCESS) {
- mLog.e("Error stopping DHCP server: " + statusCode);
- mLastError = TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR;
- // Not much more we can do here
- }
- mDhcpLeases.clear();
- getHandler().post(mCallback::dhcpLeasesChanged);
- }
- });
- mDhcpServer = null;
- } catch (RemoteException e) {
- mLog.e("Error stopping DHCP server", e);
- // Not much more we can do here
- }
- }
- }
-
- private boolean configureDhcp(boolean enable, final LinkAddress serverAddr,
- final LinkAddress clientAddr) {
- if (enable) {
- return startDhcp(serverAddr, clientAddr);
- } else {
- stopDhcp();
- return true;
- }
- }
-
- private void stopIPv4() {
- configureIPv4(false);
- // NOTE: All of configureIPv4() will be refactored out of existence
- // into calls to InterfaceController, shared with startIPv4().
- mInterfaceCtrl.clearIPv4Address();
- mPrivateAddressCoordinator.releaseDownstream(this);
- mIpv4Address = null;
- mStaticIpv4ServerAddr = null;
- mStaticIpv4ClientAddr = null;
- }
-
- private boolean configureIPv4(boolean enabled) {
- if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")");
-
- if (enabled) {
- mIpv4Address = requestIpv4Address();
- }
-
- if (mIpv4Address == null) {
- mLog.e("No available ipv4 address");
- return false;
- }
-
- if (mInterfaceType == TetheringManager.TETHERING_BLUETOOTH) {
- // BT configures the interface elsewhere: only start DHCP.
- // TODO: make all tethering types behave the same way, and delete the bluetooth
- // code that calls into NetworkManagementService directly.
- return configureDhcp(enabled, mIpv4Address, null /* clientAddress */);
- }
-
- final IpPrefix ipv4Prefix = asIpPrefix(mIpv4Address);
-
- final Boolean setIfaceUp;
- if (mInterfaceType == TetheringManager.TETHERING_WIFI
- || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P
- || mInterfaceType == TetheringManager.TETHERING_ETHERNET
- || mInterfaceType == TetheringManager.TETHERING_WIGIG) {
- // The WiFi and Ethernet stack has ownership of the interface up/down state.
- // It is unclear whether the Bluetooth or USB stacks will manage their own
- // state.
- setIfaceUp = null;
- } else {
- setIfaceUp = enabled;
- }
- if (!mInterfaceCtrl.setInterfaceConfiguration(mIpv4Address, setIfaceUp)) {
- mLog.e("Error configuring interface");
- if (!enabled) stopDhcp();
- return false;
- }
-
- if (enabled) {
- mLinkProperties.addLinkAddress(mIpv4Address);
- mLinkProperties.addRoute(getDirectConnectedRoute(mIpv4Address));
- } else {
- mLinkProperties.removeLinkAddress(mIpv4Address);
- mLinkProperties.removeRoute(getDirectConnectedRoute(mIpv4Address));
- }
- return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr);
- }
-
- private LinkAddress requestIpv4Address() {
- if (mStaticIpv4ServerAddr != null) return mStaticIpv4ServerAddr;
-
- if (mInterfaceType == TetheringManager.TETHERING_BLUETOOTH) {
- return new LinkAddress(BLUETOOTH_IFACE_ADDR);
- }
-
- return mPrivateAddressCoordinator.requestDownstreamAddress(this);
- }
-
- private boolean startIPv6() {
- mInterfaceParams = mDeps.getInterfaceParams(mIfaceName);
- if (mInterfaceParams == null) {
- mLog.e("Failed to find InterfaceParams");
- stopIPv6();
- return false;
- }
-
- mRaDaemon = mDeps.getRouterAdvertisementDaemon(mInterfaceParams);
- if (!mRaDaemon.start()) {
- stopIPv6();
- return false;
- }
-
- return true;
- }
-
- private void stopIPv6() {
- mInterfaceParams = null;
- setRaParams(null);
-
- if (mRaDaemon != null) {
- mRaDaemon.stop();
- mRaDaemon = null;
- }
- }
-
- // IPv6TetheringCoordinator sends updates with carefully curated IPv6-only
- // LinkProperties. These have extraneous data filtered out and only the
- // necessary prefixes included (per its prefix distribution policy).
- //
- // TODO: Evaluate using a data structure than is more directly suited to
- // communicating only the relevant information.
- private void updateUpstreamIPv6LinkProperties(LinkProperties v6only, int ttlAdjustment) {
- if (mRaDaemon == null) return;
-
- // Avoid unnecessary work on spurious updates.
- if (Objects.equals(mLastIPv6LinkProperties, v6only)) {
- return;
- }
-
- RaParams params = null;
- int upstreamIfindex = 0;
-
- if (v6only != null) {
- final String upstreamIface = v6only.getInterfaceName();
-
- params = new RaParams();
- params.mtu = v6only.getMtu();
- params.hasDefaultRoute = v6only.hasIpv6DefaultRoute();
-
- if (params.hasDefaultRoute) params.hopLimit = getHopLimit(upstreamIface, ttlAdjustment);
-
- for (LinkAddress linkAddr : v6only.getLinkAddresses()) {
- if (linkAddr.getPrefixLength() != RFC7421_PREFIX_LENGTH) continue;
-
- final IpPrefix prefix = new IpPrefix(
- linkAddr.getAddress(), linkAddr.getPrefixLength());
- params.prefixes.add(prefix);
-
- final Inet6Address dnsServer = getLocalDnsIpFor(prefix);
- if (dnsServer != null) {
- params.dnses.add(dnsServer);
- }
- }
-
- upstreamIfindex = mDeps.getIfindex(upstreamIface);
-
- // Add upstream index to name mapping for the tether stats usage in the coordinator.
- // Although this mapping could be added by both class Tethering and IpServer, adding
- // mapping from IpServer guarantees that the mapping is added before the adding
- // forwarding rules. That is because there are different state machines in both
- // classes. It is hard to guarantee the link property update order between multiple
- // state machines.
- mBpfCoordinator.addUpstreamNameToLookupTable(upstreamIfindex, upstreamIface);
- }
-
- // If v6only is null, we pass in null to setRaParams(), which handles
- // deprecation of any existing RA data.
-
- setRaParams(params);
- mLastIPv6LinkProperties = v6only;
-
- updateIpv6ForwardingRules(mLastIPv6UpstreamIfindex, upstreamIfindex, null);
- mLastIPv6UpstreamIfindex = upstreamIfindex;
- }
-
- private void removeRoutesFromLocalNetwork(@NonNull final List<RouteInfo> toBeRemoved) {
- final int removalFailures = RouteUtils.removeRoutesFromLocalNetwork(
- mNetd, toBeRemoved);
- if (removalFailures > 0) {
- mLog.e(String.format("Failed to remove %d IPv6 routes from local table.",
- removalFailures));
- }
-
- for (RouteInfo route : toBeRemoved) mLinkProperties.removeRoute(route);
- }
-
- private void addRoutesToLocalNetwork(@NonNull final List<RouteInfo> toBeAdded) {
- try {
- // It's safe to call networkAddInterface() even if
- // the interface is already in the local_network.
- mNetd.networkAddInterface(INetd.LOCAL_NET_ID, mIfaceName);
- try {
- // Add routes from local network. Note that adding routes that
- // already exist does not cause an error (EEXIST is silently ignored).
- RouteUtils.addRoutesToLocalNetwork(mNetd, mIfaceName, toBeAdded);
- } catch (IllegalStateException e) {
- mLog.e("Failed to add IPv4/v6 routes to local table: " + e);
- return;
- }
- } catch (ServiceSpecificException | RemoteException e) {
- mLog.e("Failed to add " + mIfaceName + " to local table: ", e);
- return;
- }
-
- for (RouteInfo route : toBeAdded) mLinkProperties.addRoute(route);
- }
-
- private void configureLocalIPv6Routes(
- HashSet<IpPrefix> deprecatedPrefixes, HashSet<IpPrefix> newPrefixes) {
- // [1] Remove the routes that are deprecated.
- if (!deprecatedPrefixes.isEmpty()) {
- removeRoutesFromLocalNetwork(getLocalRoutesFor(mIfaceName, deprecatedPrefixes));
- }
-
- // [2] Add only the routes that have not previously been added.
- if (newPrefixes != null && !newPrefixes.isEmpty()) {
- HashSet<IpPrefix> addedPrefixes = (HashSet) newPrefixes.clone();
- if (mLastRaParams != null) {
- addedPrefixes.removeAll(mLastRaParams.prefixes);
- }
-
- if (!addedPrefixes.isEmpty()) {
- addRoutesToLocalNetwork(getLocalRoutesFor(mIfaceName, addedPrefixes));
- }
- }
- }
-
- private void configureLocalIPv6Dns(
- HashSet<Inet6Address> deprecatedDnses, HashSet<Inet6Address> newDnses) {
- // TODO: Is this really necessary? Can we not fail earlier if INetd cannot be located?
- if (mNetd == null) {
- if (newDnses != null) newDnses.clear();
- mLog.e("No netd service instance available; not setting local IPv6 addresses");
- return;
- }
-
- // [1] Remove deprecated local DNS IP addresses.
- if (!deprecatedDnses.isEmpty()) {
- for (Inet6Address dns : deprecatedDnses) {
- if (!mInterfaceCtrl.removeAddress(dns, RFC7421_PREFIX_LENGTH)) {
- mLog.e("Failed to remove local dns IP " + dns);
- }
-
- mLinkProperties.removeLinkAddress(new LinkAddress(dns, RFC7421_PREFIX_LENGTH));
- }
- }
-
- // [2] Add only the local DNS IP addresses that have not previously been added.
- if (newDnses != null && !newDnses.isEmpty()) {
- final HashSet<Inet6Address> addedDnses = (HashSet) newDnses.clone();
- if (mLastRaParams != null) {
- addedDnses.removeAll(mLastRaParams.dnses);
- }
-
- for (Inet6Address dns : addedDnses) {
- if (!mInterfaceCtrl.addAddress(dns, RFC7421_PREFIX_LENGTH)) {
- mLog.e("Failed to add local dns IP " + dns);
- newDnses.remove(dns);
- }
-
- mLinkProperties.addLinkAddress(new LinkAddress(dns, RFC7421_PREFIX_LENGTH));
- }
- }
-
- try {
- mNetd.tetherApplyDnsInterfaces();
- } catch (ServiceSpecificException | RemoteException e) {
- mLog.e("Failed to update local DNS caching server");
- if (newDnses != null) newDnses.clear();
- }
- }
-
- private void addIpv6ForwardingRule(Ipv6ForwardingRule rule) {
- // Theoretically, we don't need this check because IP neighbor monitor doesn't start if BPF
- // offload is disabled. Add this check just in case.
- // TODO: Perhaps remove this protection check.
- if (!mUsingBpfOffload) return;
-
- mBpfCoordinator.tetherOffloadRuleAdd(this, rule);
- }
-
- private void removeIpv6ForwardingRule(Ipv6ForwardingRule rule) {
- // TODO: Perhaps remove this protection check.
- // See the related comment in #addIpv6ForwardingRule.
- if (!mUsingBpfOffload) return;
-
- mBpfCoordinator.tetherOffloadRuleRemove(this, rule);
- }
-
- private void clearIpv6ForwardingRules() {
- if (!mUsingBpfOffload) return;
-
- mBpfCoordinator.tetherOffloadRuleClear(this);
- }
-
- private void updateIpv6ForwardingRule(int newIfindex) {
- // TODO: Perhaps remove this protection check.
- // See the related comment in #addIpv6ForwardingRule.
- if (!mUsingBpfOffload) return;
-
- mBpfCoordinator.tetherOffloadRuleUpdate(this, newIfindex);
- }
-
- // Handles all updates to IPv6 forwarding rules. These can currently change only if the upstream
- // changes or if a neighbor event is received.
- private void updateIpv6ForwardingRules(int prevUpstreamIfindex, int upstreamIfindex,
- NeighborEvent e) {
- // If we no longer have an upstream, clear forwarding rules and do nothing else.
- if (upstreamIfindex == 0) {
- clearIpv6ForwardingRules();
- return;
- }
-
- // If the upstream interface has changed, remove all rules and re-add them with the new
- // upstream interface.
- if (prevUpstreamIfindex != upstreamIfindex) {
- updateIpv6ForwardingRule(upstreamIfindex);
- }
-
- // If we're here to process a NeighborEvent, do so now.
- // mInterfaceParams must be non-null or the event would not have arrived.
- if (e == null) return;
- if (!(e.ip instanceof Inet6Address) || e.ip.isMulticastAddress()
- || e.ip.isLoopbackAddress() || e.ip.isLinkLocalAddress()) {
- return;
- }
-
- // When deleting rules, we still need to pass a non-null MAC, even though it's ignored.
- // Do this here instead of in the Ipv6ForwardingRule constructor to ensure that we never
- // add rules with a null MAC, only delete them.
- MacAddress dstMac = e.isValid() ? e.macAddr : NULL_MAC_ADDRESS;
- Ipv6ForwardingRule rule = new Ipv6ForwardingRule(upstreamIfindex,
- mInterfaceParams.index, (Inet6Address) e.ip, mInterfaceParams.macAddr, dstMac);
- if (e.isValid()) {
- addIpv6ForwardingRule(rule);
- } else {
- removeIpv6ForwardingRule(rule);
- }
- }
-
- private void handleNeighborEvent(NeighborEvent e) {
- if (mInterfaceParams != null
- && mInterfaceParams.index == e.ifindex
- && mInterfaceParams.hasMacAddress) {
- updateIpv6ForwardingRules(mLastIPv6UpstreamIfindex, mLastIPv6UpstreamIfindex, e);
- }
- }
-
- private void handleNewPrefixRequest(@NonNull final IpPrefix currentPrefix) {
- if (!currentPrefix.contains(mIpv4Address.getAddress())
- || currentPrefix.getPrefixLength() != mIpv4Address.getPrefixLength()) {
- Log.e(TAG, "Invalid prefix: " + currentPrefix);
- return;
- }
-
- final LinkAddress deprecatedLinkAddress = mIpv4Address;
- mIpv4Address = requestIpv4Address();
- if (mIpv4Address == null) {
- mLog.e("Fail to request a new downstream prefix");
- return;
- }
- final Inet4Address srvAddr = (Inet4Address) mIpv4Address.getAddress();
-
- // Add new IPv4 address on the interface.
- if (!mInterfaceCtrl.addAddress(srvAddr, currentPrefix.getPrefixLength())) {
- mLog.e("Failed to add new IP " + srvAddr);
- return;
- }
-
- // Remove deprecated routes from local network.
- removeRoutesFromLocalNetwork(
- Collections.singletonList(getDirectConnectedRoute(deprecatedLinkAddress)));
- mLinkProperties.removeLinkAddress(deprecatedLinkAddress);
-
- // Add new routes to local network.
- addRoutesToLocalNetwork(
- Collections.singletonList(getDirectConnectedRoute(mIpv4Address)));
- mLinkProperties.addLinkAddress(mIpv4Address);
-
- // Update local DNS caching server with new IPv4 address, otherwise, dnsmasq doesn't
- // listen on the interface configured with new IPv4 address, that results DNS validation
- // failure of downstream client even if appropriate routes have been configured.
- try {
- mNetd.tetherApplyDnsInterfaces();
- } catch (ServiceSpecificException | RemoteException e) {
- mLog.e("Failed to update local DNS caching server");
- return;
- }
- sendLinkProperties();
-
- // Notify DHCP server that new prefix/route has been applied on IpServer.
- final Inet4Address clientAddr = mStaticIpv4ClientAddr == null ? null :
- (Inet4Address) mStaticIpv4ClientAddr.getAddress();
- final DhcpServingParamsParcel params = makeServingParams(srvAddr /* defaultRouter */,
- srvAddr /* dnsServer */, mIpv4Address /* serverLinkAddress */, clientAddr);
- try {
- mDhcpServer.updateParams(params, new OnHandlerStatusCallback() {
- @Override
- public void callback(int statusCode) {
- if (statusCode != STATUS_SUCCESS) {
- mLog.e("Error updating DHCP serving params: " + statusCode);
- }
- }
- });
- } catch (RemoteException e) {
- mLog.e("Error updating DHCP serving params", e);
- }
- }
-
- private byte getHopLimit(String upstreamIface, int adjustTTL) {
- try {
- int upstreamHopLimit = Integer.parseUnsignedInt(
- mNetd.getProcSysNet(INetd.IPV6, INetd.CONF, upstreamIface, "hop_limit"));
- upstreamHopLimit = upstreamHopLimit + adjustTTL;
- // Cap the hop limit to 255.
- return (byte) Integer.min(upstreamHopLimit, 255);
- } catch (Exception e) {
- mLog.e("Failed to find upstream interface hop limit", e);
- }
- return RaParams.DEFAULT_HOPLIMIT;
- }
-
- private void setRaParams(RaParams newParams) {
- if (mRaDaemon != null) {
- final RaParams deprecatedParams =
- RaParams.getDeprecatedRaParams(mLastRaParams, newParams);
-
- configureLocalIPv6Routes(deprecatedParams.prefixes,
- (newParams != null) ? newParams.prefixes : null);
-
- configureLocalIPv6Dns(deprecatedParams.dnses,
- (newParams != null) ? newParams.dnses : null);
-
- mRaDaemon.buildNewRa(deprecatedParams, newParams);
- }
-
- mLastRaParams = newParams;
- }
-
- private void logMessage(State state, int what) {
- mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
- }
-
- private void sendInterfaceState(int newInterfaceState) {
- mServingMode = newInterfaceState;
- mCallback.updateInterfaceState(this, newInterfaceState, mLastError);
- sendLinkProperties();
- }
-
- private void sendLinkProperties() {
- mCallback.updateLinkProperties(this, new LinkProperties(mLinkProperties));
- }
-
- private void resetLinkProperties() {
- mLinkProperties.clear();
- mLinkProperties.setInterfaceName(mIfaceName);
- }
-
- private void maybeConfigureStaticIp(final TetheringRequestParcel request) {
- // Ignore static address configuration if they are invalid or null. In theory, static
- // addresses should not be invalid here because TetheringManager do not allow caller to
- // specify invalid static address configuration.
- if (request == null || request.localIPv4Address == null
- || request.staticClientAddress == null || !checkStaticAddressConfiguration(
- request.localIPv4Address, request.staticClientAddress)) {
- return;
- }
-
- mStaticIpv4ServerAddr = request.localIPv4Address;
- mStaticIpv4ClientAddr = request.staticClientAddress;
- }
-
- class InitialState extends State {
- @Override
- public void enter() {
- sendInterfaceState(STATE_AVAILABLE);
- }
-
- @Override
- public boolean processMessage(Message message) {
- logMessage(this, message.what);
- switch (message.what) {
- case CMD_TETHER_REQUESTED:
- mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
- switch (message.arg1) {
- case STATE_LOCAL_ONLY:
- maybeConfigureStaticIp((TetheringRequestParcel) message.obj);
- transitionTo(mLocalHotspotState);
- break;
- case STATE_TETHERED:
- maybeConfigureStaticIp((TetheringRequestParcel) message.obj);
- transitionTo(mTetheredState);
- break;
- default:
- mLog.e("Invalid tethering interface serving state specified.");
- }
- break;
- case CMD_INTERFACE_DOWN:
- transitionTo(mUnavailableState);
- break;
- case CMD_IPV6_TETHER_UPDATE:
- updateUpstreamIPv6LinkProperties((LinkProperties) message.obj, message.arg1);
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
- }
-
- class BaseServingState extends State {
- @Override
- public void enter() {
- if (!startIPv4()) {
- mLastError = TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
- return;
- }
-
- try {
- NetdUtils.tetherInterface(mNetd, mIfaceName, asIpPrefix(mIpv4Address));
- } catch (RemoteException | ServiceSpecificException | IllegalStateException e) {
- mLog.e("Error Tethering", e);
- mLastError = TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
- return;
- }
-
- if (!startIPv6()) {
- mLog.e("Failed to startIPv6");
- // TODO: Make this a fatal error once Bluetooth IPv6 is sorted.
- return;
- }
- }
-
- @Override
- public void exit() {
- // Note that at this point, we're leaving the tethered state. We can fail any
- // of these operations, but it doesn't really change that we have to try them
- // all in sequence.
- stopIPv6();
-
- try {
- NetdUtils.untetherInterface(mNetd, mIfaceName);
- } catch (RemoteException | ServiceSpecificException e) {
- mLastError = TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
- mLog.e("Failed to untether interface: " + e);
- }
-
- stopIPv4();
-
- resetLinkProperties();
- }
-
- @Override
- public boolean processMessage(Message message) {
- logMessage(this, message.what);
- switch (message.what) {
- case CMD_TETHER_UNREQUESTED:
- transitionTo(mInitialState);
- if (DBG) Log.d(TAG, "Untethered (unrequested)" + mIfaceName);
- break;
- case CMD_INTERFACE_DOWN:
- transitionTo(mUnavailableState);
- if (DBG) Log.d(TAG, "Untethered (ifdown)" + mIfaceName);
- break;
- case CMD_IPV6_TETHER_UPDATE:
- updateUpstreamIPv6LinkProperties((LinkProperties) message.obj, message.arg1);
- sendLinkProperties();
- break;
- case CMD_IP_FORWARDING_ENABLE_ERROR:
- case CMD_IP_FORWARDING_DISABLE_ERROR:
- case CMD_START_TETHERING_ERROR:
- case CMD_STOP_TETHERING_ERROR:
- case CMD_SET_DNS_FORWARDERS_ERROR:
- mLastError = TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
- transitionTo(mInitialState);
- break;
- case CMD_NEW_PREFIX_REQUEST:
- handleNewPrefixRequest((IpPrefix) message.obj);
- break;
- case CMD_NOTIFY_PREFIX_CONFLICT:
- mLog.i("restart tethering: " + mInterfaceType);
- mCallback.requestEnableTethering(mInterfaceType, false /* enabled */);
- transitionTo(mWaitingForRestartState);
- break;
- default:
- return false;
- }
- return true;
- }
- }
-
- // Handling errors in BaseServingState.enter() by transitioning is
- // problematic because transitioning during a multi-state jump yields
- // a Log.wtf(). Ultimately, there should be only one ServingState,
- // and forwarding and NAT rules should be handled by a coordinating
- // functional element outside of IpServer.
- class LocalHotspotState extends BaseServingState {
- @Override
- public void enter() {
- super.enter();
- if (mLastError != TetheringManager.TETHER_ERROR_NO_ERROR) {
- transitionTo(mInitialState);
- }
-
- if (DBG) Log.d(TAG, "Local hotspot " + mIfaceName);
- sendInterfaceState(STATE_LOCAL_ONLY);
- }
-
- @Override
- public boolean processMessage(Message message) {
- if (super.processMessage(message)) return true;
-
- logMessage(this, message.what);
- switch (message.what) {
- case CMD_TETHER_REQUESTED:
- mLog.e("CMD_TETHER_REQUESTED while in local-only hotspot mode.");
- break;
- case CMD_TETHER_CONNECTION_CHANGED:
- // Ignored in local hotspot state.
- break;
- default:
- return false;
- }
- return true;
- }
- }
-
- // Handling errors in BaseServingState.enter() by transitioning is
- // problematic because transitioning during a multi-state jump yields
- // a Log.wtf(). Ultimately, there should be only one ServingState,
- // and forwarding and NAT rules should be handled by a coordinating
- // functional element outside of IpServer.
- class TetheredState extends BaseServingState {
- @Override
- public void enter() {
- super.enter();
- if (mLastError != TetheringManager.TETHER_ERROR_NO_ERROR) {
- transitionTo(mInitialState);
- }
-
- if (DBG) Log.d(TAG, "Tethered " + mIfaceName);
- sendInterfaceState(STATE_TETHERED);
- }
-
- @Override
- public void exit() {
- cleanupUpstream();
- super.exit();
- }
-
- private void cleanupUpstream() {
- if (mUpstreamIfaceSet == null) return;
-
- for (String ifname : mUpstreamIfaceSet.ifnames) cleanupUpstreamInterface(ifname);
- mUpstreamIfaceSet = null;
- clearIpv6ForwardingRules();
- }
-
- private void cleanupUpstreamInterface(String upstreamIface) {
- // Note that we don't care about errors here.
- // Sometimes interfaces are gone before we get
- // to remove their rules, which generates errors.
- // Just do the best we can.
- try {
- mNetd.ipfwdRemoveInterfaceForward(mIfaceName, upstreamIface);
- } catch (RemoteException | ServiceSpecificException e) {
- mLog.e("Exception in ipfwdRemoveInterfaceForward: " + e.toString());
- }
- try {
- mNetd.tetherRemoveForward(mIfaceName, upstreamIface);
- } catch (RemoteException | ServiceSpecificException e) {
- mLog.e("Exception in disableNat: " + e.toString());
- }
- }
-
- @Override
- public boolean processMessage(Message message) {
- if (super.processMessage(message)) return true;
-
- logMessage(this, message.what);
- switch (message.what) {
- case CMD_TETHER_REQUESTED:
- mLog.e("CMD_TETHER_REQUESTED while already tethering.");
- break;
- case CMD_TETHER_CONNECTION_CHANGED:
- final InterfaceSet newUpstreamIfaceSet = (InterfaceSet) message.obj;
- if (noChangeInUpstreamIfaceSet(newUpstreamIfaceSet)) {
- if (VDBG) Log.d(TAG, "Connection changed noop - dropping");
- break;
- }
-
- if (newUpstreamIfaceSet == null) {
- cleanupUpstream();
- break;
- }
-
- for (String removed : upstreamInterfacesRemoved(newUpstreamIfaceSet)) {
- cleanupUpstreamInterface(removed);
- }
-
- final Set<String> added = upstreamInterfacesAdd(newUpstreamIfaceSet);
- // This makes the call to cleanupUpstream() in the error
- // path for any interface neatly cleanup all the interfaces.
- mUpstreamIfaceSet = newUpstreamIfaceSet;
-
- for (String ifname : added) {
- try {
- mNetd.tetherAddForward(mIfaceName, ifname);
- mNetd.ipfwdAddInterfaceForward(mIfaceName, ifname);
- } catch (RemoteException | ServiceSpecificException e) {
- mLog.e("Exception enabling NAT: " + e.toString());
- cleanupUpstream();
- mLastError = TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR;
- transitionTo(mInitialState);
- return true;
- }
- }
- break;
- case CMD_NEIGHBOR_EVENT:
- handleNeighborEvent((NeighborEvent) message.obj);
- break;
- default:
- return false;
- }
- return true;
- }
-
- private boolean noChangeInUpstreamIfaceSet(InterfaceSet newIfaces) {
- if (mUpstreamIfaceSet == null && newIfaces == null) return true;
- if (mUpstreamIfaceSet != null && newIfaces != null) {
- return mUpstreamIfaceSet.equals(newIfaces);
- }
- return false;
- }
-
- private Set<String> upstreamInterfacesRemoved(InterfaceSet newIfaces) {
- if (mUpstreamIfaceSet == null) return new HashSet<>();
-
- final HashSet<String> removed = new HashSet<>(mUpstreamIfaceSet.ifnames);
- removed.removeAll(newIfaces.ifnames);
- return removed;
- }
-
- private Set<String> upstreamInterfacesAdd(InterfaceSet newIfaces) {
- final HashSet<String> added = new HashSet<>(newIfaces.ifnames);
- if (mUpstreamIfaceSet != null) added.removeAll(mUpstreamIfaceSet.ifnames);
- return added;
- }
- }
-
- /**
- * This state is terminal for the per interface state machine. At this
- * point, the master state machine should have removed this interface
- * specific state machine from its list of possible recipients of
- * tethering requests. The state machine itself will hang around until
- * the garbage collector finds it.
- */
- class UnavailableState extends State {
- @Override
- public void enter() {
- mIpNeighborMonitor.stop();
- mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
- sendInterfaceState(STATE_UNAVAILABLE);
- }
- }
-
- class WaitingForRestartState extends State {
- @Override
- public boolean processMessage(Message message) {
- logMessage(this, message.what);
- switch (message.what) {
- case CMD_TETHER_UNREQUESTED:
- transitionTo(mInitialState);
- mLog.i("Untethered (unrequested) and restarting " + mIfaceName);
- mCallback.requestEnableTethering(mInterfaceType, true /* enabled */);
- break;
- case CMD_INTERFACE_DOWN:
- transitionTo(mUnavailableState);
- mLog.i("Untethered (interface down) and restarting" + mIfaceName);
- mCallback.requestEnableTethering(mInterfaceType, true /* enabled */);
- break;
- default:
- return false;
- }
- return true;
- }
- }
-
- // Accumulate routes representing "prefixes to be assigned to the local
- // interface", for subsequent modification of local_network routing.
- private static ArrayList<RouteInfo> getLocalRoutesFor(
- String ifname, HashSet<IpPrefix> prefixes) {
- final ArrayList<RouteInfo> localRoutes = new ArrayList<RouteInfo>();
- for (IpPrefix ipp : prefixes) {
- localRoutes.add(new RouteInfo(ipp, null, ifname, RTN_UNICAST));
- }
- return localRoutes;
- }
-
- // Given a prefix like 2001:db8::/64 return an address like 2001:db8::1.
- private static Inet6Address getLocalDnsIpFor(IpPrefix localPrefix) {
- final byte[] dnsBytes = localPrefix.getRawAddress();
- dnsBytes[dnsBytes.length - 1] = getRandomSanitizedByte(DOUG_ADAMS, asByte(0), asByte(1));
- try {
- return Inet6Address.getByAddress(null, dnsBytes, 0);
- } catch (UnknownHostException e) {
- Log.wtf(TAG, "Failed to construct Inet6Address from: " + localPrefix);
- return null;
- }
- }
-
- private static byte getRandomSanitizedByte(byte dflt, byte... excluded) {
- final byte random = (byte) (new Random()).nextInt();
- for (int value : excluded) {
- if (random == value) return dflt;
- }
- return random;
- }
-}
diff --git a/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java b/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java
deleted file mode 100644
index 6f017dc..0000000
--- a/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java
+++ /dev/null
@@ -1,758 +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.net.ip;
-
-import static android.net.util.NetworkConstants.IPV6_MIN_MTU;
-import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.IPPROTO_ICMPV6;
-import static android.system.OsConstants.SOCK_RAW;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_SNDTIMEO;
-
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.TrafficStats;
-import android.net.util.InterfaceParams;
-import android.net.util.SocketUtils;
-import android.net.util.TetheringUtils;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.StructTimeval;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.TrafficStatsConstants;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-
-/**
- * Basic IPv6 Router Advertisement Daemon.
- *
- * TODO:
- *
- * - Rewrite using Handler (and friends) so that AlarmManager can deliver
- * "kick" messages when it's time to send a multicast RA.
- *
- * @hide
- */
-public class RouterAdvertisementDaemon {
- private static final String TAG = RouterAdvertisementDaemon.class.getSimpleName();
- private static final byte ICMPV6_ND_ROUTER_SOLICIT = asByte(133);
- private static final byte ICMPV6_ND_ROUTER_ADVERT = asByte(134);
- private static final int MIN_RA_HEADER_SIZE = 16;
-
- // Summary of various timers and lifetimes.
- private static final int MIN_RTR_ADV_INTERVAL_SEC = 300;
- private static final int MAX_RTR_ADV_INTERVAL_SEC = 600;
- // In general, router, prefix, and DNS lifetimes are all advised to be
- // greater than or equal to 3 * MAX_RTR_ADV_INTERVAL. Here, we double
- // that to allow for multicast packet loss.
- //
- // This MAX_RTR_ADV_INTERVAL_SEC and DEFAULT_LIFETIME are also consistent
- // with the https://tools.ietf.org/html/rfc7772#section-4 discussion of
- // "approximately 7 RAs per hour".
- private static final int DEFAULT_LIFETIME = 6 * MAX_RTR_ADV_INTERVAL_SEC;
- // From https://tools.ietf.org/html/rfc4861#section-10 .
- private static final int MIN_DELAY_BETWEEN_RAS_SEC = 3;
- // Both initial and final RAs, but also for changes in RA contents.
- // From https://tools.ietf.org/html/rfc4861#section-10 .
- private static final int MAX_URGENT_RTR_ADVERTISEMENTS = 5;
-
- private static final int DAY_IN_SECONDS = 86_400;
-
- private static final byte[] ALL_NODES = new byte[] {
- (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
- };
-
- private final InterfaceParams mInterface;
- private final InetSocketAddress mAllNodes;
-
- // This lock is to protect the RA from being updated while being
- // transmitted on another thread (multicast or unicast).
- //
- // TODO: This should be handled with a more RCU-like approach.
- private final Object mLock = new Object();
- @GuardedBy("mLock")
- private final byte[] mRA = new byte[IPV6_MIN_MTU];
- @GuardedBy("mLock")
- private int mRaLength;
- @GuardedBy("mLock")
- private final DeprecatedInfoTracker mDeprecatedInfoTracker;
- @GuardedBy("mLock")
- private RaParams mRaParams;
-
- private volatile FileDescriptor mSocket;
- private volatile MulticastTransmitter mMulticastTransmitter;
- private volatile UnicastResponder mUnicastResponder;
-
- /** Encapsulate the RA parameters for RouterAdvertisementDaemon.*/
- public static class RaParams {
- // Tethered traffic will have the hop limit properly decremented.
- // Consequently, set the hoplimit greater by one than the upstream
- // unicast hop limit.
- //
- // TODO: Dynamically pass down the IPV6_UNICAST_HOPS value from the
- // upstream interface for more correct behaviour.
- static final byte DEFAULT_HOPLIMIT = 65;
-
- public boolean hasDefaultRoute;
- public byte hopLimit;
- public int mtu;
- public HashSet<IpPrefix> prefixes;
- public HashSet<Inet6Address> dnses;
-
- public RaParams() {
- hasDefaultRoute = false;
- hopLimit = DEFAULT_HOPLIMIT;
- mtu = IPV6_MIN_MTU;
- prefixes = new HashSet<IpPrefix>();
- dnses = new HashSet<Inet6Address>();
- }
-
- public RaParams(RaParams other) {
- hasDefaultRoute = other.hasDefaultRoute;
- hopLimit = other.hopLimit;
- mtu = other.mtu;
- prefixes = (HashSet) other.prefixes.clone();
- dnses = (HashSet) other.dnses.clone();
- }
-
- /**
- * Returns the subset of RA parameters that become deprecated when
- * moving from announcing oldRa to announcing newRa.
- *
- * Currently only tracks differences in |prefixes| and |dnses|.
- */
- public static RaParams getDeprecatedRaParams(RaParams oldRa, RaParams newRa) {
- RaParams newlyDeprecated = new RaParams();
-
- if (oldRa != null) {
- for (IpPrefix ipp : oldRa.prefixes) {
- if (newRa == null || !newRa.prefixes.contains(ipp)) {
- newlyDeprecated.prefixes.add(ipp);
- }
- }
-
- for (Inet6Address dns : oldRa.dnses) {
- if (newRa == null || !newRa.dnses.contains(dns)) {
- newlyDeprecated.dnses.add(dns);
- }
- }
- }
-
- return newlyDeprecated;
- }
- }
-
- private static class DeprecatedInfoTracker {
- private final HashMap<IpPrefix, Integer> mPrefixes = new HashMap<>();
- private final HashMap<Inet6Address, Integer> mDnses = new HashMap<>();
-
- Set<IpPrefix> getPrefixes() {
- return mPrefixes.keySet();
- }
-
- void putPrefixes(Set<IpPrefix> prefixes) {
- for (IpPrefix ipp : prefixes) {
- mPrefixes.put(ipp, MAX_URGENT_RTR_ADVERTISEMENTS);
- }
- }
-
- void removePrefixes(Set<IpPrefix> prefixes) {
- for (IpPrefix ipp : prefixes) {
- mPrefixes.remove(ipp);
- }
- }
-
- Set<Inet6Address> getDnses() {
- return mDnses.keySet();
- }
-
- void putDnses(Set<Inet6Address> dnses) {
- for (Inet6Address dns : dnses) {
- mDnses.put(dns, MAX_URGENT_RTR_ADVERTISEMENTS);
- }
- }
-
- void removeDnses(Set<Inet6Address> dnses) {
- for (Inet6Address dns : dnses) {
- mDnses.remove(dns);
- }
- }
-
- boolean isEmpty() {
- return mPrefixes.isEmpty() && mDnses.isEmpty();
- }
-
- private boolean decrementCounters() {
- boolean removed = decrementCounter(mPrefixes);
- removed |= decrementCounter(mDnses);
- return removed;
- }
-
- private <T> boolean decrementCounter(HashMap<T, Integer> map) {
- boolean removed = false;
-
- for (Iterator<Map.Entry<T, Integer>> it = map.entrySet().iterator();
- it.hasNext();) {
- Map.Entry<T, Integer> kv = it.next();
- if (kv.getValue() == 0) {
- it.remove();
- removed = true;
- } else {
- kv.setValue(kv.getValue() - 1);
- }
- }
-
- return removed;
- }
- }
-
-
- public RouterAdvertisementDaemon(InterfaceParams ifParams) {
- mInterface = ifParams;
- mAllNodes = new InetSocketAddress(getAllNodesForScopeId(mInterface.index), 0);
- mDeprecatedInfoTracker = new DeprecatedInfoTracker();
- }
-
- /** Build new RA.*/
- public void buildNewRa(RaParams deprecatedParams, RaParams newParams) {
- synchronized (mLock) {
- if (deprecatedParams != null) {
- mDeprecatedInfoTracker.putPrefixes(deprecatedParams.prefixes);
- mDeprecatedInfoTracker.putDnses(deprecatedParams.dnses);
- }
-
- if (newParams != null) {
- // Process information that is no longer deprecated.
- mDeprecatedInfoTracker.removePrefixes(newParams.prefixes);
- mDeprecatedInfoTracker.removeDnses(newParams.dnses);
- }
-
- mRaParams = newParams;
- assembleRaLocked();
- }
-
- maybeNotifyMulticastTransmitter();
- }
-
- /** Start router advertisement daemon. */
- public boolean start() {
- if (!createSocket()) {
- return false;
- }
-
- mMulticastTransmitter = new MulticastTransmitter();
- mMulticastTransmitter.start();
-
- mUnicastResponder = new UnicastResponder();
- mUnicastResponder.start();
-
- return true;
- }
-
- /** Stop router advertisement daemon. */
- public void stop() {
- closeSocket();
- // Wake up mMulticastTransmitter thread to interrupt a potential 1 day sleep before
- // the thread's termination.
- maybeNotifyMulticastTransmitter();
- mMulticastTransmitter = null;
- mUnicastResponder = null;
- }
-
- @GuardedBy("mLock")
- private void assembleRaLocked() {
- final ByteBuffer ra = ByteBuffer.wrap(mRA);
- ra.order(ByteOrder.BIG_ENDIAN);
-
- final boolean haveRaParams = (mRaParams != null);
- boolean shouldSendRA = false;
-
- try {
- putHeader(ra, haveRaParams && mRaParams.hasDefaultRoute,
- haveRaParams ? mRaParams.hopLimit : RaParams.DEFAULT_HOPLIMIT);
- putSlla(ra, mInterface.macAddr.toByteArray());
- mRaLength = ra.position();
-
- // https://tools.ietf.org/html/rfc5175#section-4 says:
- //
- // "MUST NOT be added to a Router Advertisement message
- // if no flags in the option are set."
- //
- // putExpandedFlagsOption(ra);
-
- if (haveRaParams) {
- putMtu(ra, mRaParams.mtu);
- mRaLength = ra.position();
-
- for (IpPrefix ipp : mRaParams.prefixes) {
- putPio(ra, ipp, DEFAULT_LIFETIME, DEFAULT_LIFETIME);
- mRaLength = ra.position();
- shouldSendRA = true;
- }
-
- if (mRaParams.dnses.size() > 0) {
- putRdnss(ra, mRaParams.dnses, DEFAULT_LIFETIME);
- mRaLength = ra.position();
- shouldSendRA = true;
- }
- }
-
- for (IpPrefix ipp : mDeprecatedInfoTracker.getPrefixes()) {
- putPio(ra, ipp, 0, 0);
- mRaLength = ra.position();
- shouldSendRA = true;
- }
-
- final Set<Inet6Address> deprecatedDnses = mDeprecatedInfoTracker.getDnses();
- if (!deprecatedDnses.isEmpty()) {
- putRdnss(ra, deprecatedDnses, 0);
- mRaLength = ra.position();
- shouldSendRA = true;
- }
- } catch (BufferOverflowException e) {
- // The packet up to mRaLength is valid, since it has been updated
- // progressively as the RA was built. Log an error, and continue
- // on as best as possible.
- Log.e(TAG, "Could not construct new RA: " + e);
- }
-
- // We have nothing worth announcing; indicate as much to maybeSendRA().
- if (!shouldSendRA) {
- mRaLength = 0;
- }
- }
-
- private void maybeNotifyMulticastTransmitter() {
- final MulticastTransmitter m = mMulticastTransmitter;
- if (m != null) {
- m.hup();
- }
- }
-
- private static Inet6Address getAllNodesForScopeId(int scopeId) {
- try {
- return Inet6Address.getByAddress("ff02::1", ALL_NODES, scopeId);
- } catch (UnknownHostException uhe) {
- Log.wtf(TAG, "Failed to construct ff02::1 InetAddress: " + uhe);
- return null;
- }
- }
-
- private static byte asByte(int value) {
- return (byte) value;
- }
- private static short asShort(int value) {
- return (short) value;
- }
-
- private static void putHeader(ByteBuffer ra, boolean hasDefaultRoute, byte hopLimit) {
- /**
- Router Advertisement Message Format
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Code | Checksum |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Cur Hop Limit |M|O|H|Prf|P|R|R| Router Lifetime |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Reachable Time |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Retrans Timer |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Options ...
- +-+-+-+-+-+-+-+-+-+-+-+-
- */
- ra.put(ICMPV6_ND_ROUTER_ADVERT)
- .put(asByte(0))
- .putShort(asShort(0))
- .put(hopLimit)
- // RFC 4191 "high" preference, iff. advertising a default route.
- .put(hasDefaultRoute ? asByte(0x08) : asByte(0))
- .putShort(hasDefaultRoute ? asShort(DEFAULT_LIFETIME) : asShort(0))
- .putInt(0)
- .putInt(0);
- }
-
- private static void putSlla(ByteBuffer ra, byte[] slla) {
- /**
- Source/Target Link-layer Address
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Length | Link-Layer Address ...
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- if (slla == null || slla.length != 6) {
- // Only IEEE 802.3 6-byte addresses are supported.
- return;
- }
-
- final byte nd_option_slla = 1;
- final byte slla_num_8octets = 1;
- ra.put(nd_option_slla)
- .put(slla_num_8octets)
- .put(slla);
- }
-
- private static void putExpandedFlagsOption(ByteBuffer ra) {
- /**
- Router Advertisement Expanded Flags Option
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Length | Bit fields available ..
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ... for assignment |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
- final byte nd_option__efo = 26;
- final byte efo_num_8octets = 1;
-
- ra.put(nd_option__efo)
- .put(efo_num_8octets)
- .putShort(asShort(0))
- .putInt(0);
- }
-
- private static void putMtu(ByteBuffer ra, int mtu) {
- /**
- MTU
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Length | Reserved |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | MTU |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- final byte nd_option_mtu = 5;
- final byte mtu_num_8octs = 1;
- ra.put(nd_option_mtu)
- .put(mtu_num_8octs)
- .putShort(asShort(0))
- .putInt((mtu < IPV6_MIN_MTU) ? IPV6_MIN_MTU : mtu);
- }
-
- private static void putPio(ByteBuffer ra, IpPrefix ipp,
- int validTime, int preferredTime) {
- /**
- Prefix Information
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Length | Prefix Length |L|A| Reserved1 |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Valid Lifetime |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Preferred Lifetime |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Reserved2 |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | |
- + +
- | |
- + Prefix +
- | |
- + +
- | |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- final int prefixLength = ipp.getPrefixLength();
- if (prefixLength != 64) {
- return;
- }
- final byte nd_option_pio = 3;
- final byte pio_num_8octets = 4;
-
- if (validTime < 0) validTime = 0;
- if (preferredTime < 0) preferredTime = 0;
- if (preferredTime > validTime) preferredTime = validTime;
-
- final byte[] addr = ipp.getAddress().getAddress();
- ra.put(nd_option_pio)
- .put(pio_num_8octets)
- .put(asByte(prefixLength))
- .put(asByte(0xc0)) /* L & A set */
- .putInt(validTime)
- .putInt(preferredTime)
- .putInt(0)
- .put(addr);
- }
-
- private static void putRio(ByteBuffer ra, IpPrefix ipp) {
- /**
- Route Information Option
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Length | Prefix Length |Resvd|Prf|Resvd|
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Route Lifetime |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Prefix (Variable Length) |
- . .
- . .
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- final int prefixLength = ipp.getPrefixLength();
- if (prefixLength > 64) {
- return;
- }
- final byte nd_option_rio = 24;
- final byte rio_num_8octets = asByte(
- (prefixLength == 0) ? 1 : (prefixLength <= 8) ? 2 : 3);
-
- final byte[] addr = ipp.getAddress().getAddress();
- ra.put(nd_option_rio)
- .put(rio_num_8octets)
- .put(asByte(prefixLength))
- .put(asByte(0x18))
- .putInt(DEFAULT_LIFETIME);
-
- // Rely upon an IpPrefix's address being properly zeroed.
- if (prefixLength > 0) {
- ra.put(addr, 0, (prefixLength <= 64) ? 8 : 16);
- }
- }
-
- private static void putRdnss(ByteBuffer ra, Set<Inet6Address> dnses, int lifetime) {
- /**
- Recursive DNS Server (RDNSS) Option
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Length | Reserved |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Lifetime |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | |
- : Addresses of IPv6 Recursive DNS Servers :
- | |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
- final HashSet<Inet6Address> filteredDnses = new HashSet<>();
- for (Inet6Address dns : dnses) {
- if ((new LinkAddress(dns, RFC7421_PREFIX_LENGTH)).isGlobalPreferred()) {
- filteredDnses.add(dns);
- }
- }
- if (filteredDnses.isEmpty()) return;
-
- final byte nd_option_rdnss = 25;
- final byte rdnss_num_8octets = asByte(dnses.size() * 2 + 1);
- ra.put(nd_option_rdnss)
- .put(rdnss_num_8octets)
- .putShort(asShort(0))
- .putInt(lifetime);
-
- for (Inet6Address dns : filteredDnses) {
- // NOTE: If the full of list DNS servers doesn't fit in the packet,
- // this code will cause a buffer overflow and the RA won't include
- // this instance of the option at all.
- //
- // TODO: Consider looking at ra.remaining() to determine how many
- // DNS servers will fit, and adding only those.
- ra.put(dns.getAddress());
- }
- }
-
- private boolean createSocket() {
- final int send_timout_ms = 300;
-
- final int oldTag = TrafficStats.getAndSetThreadStatsTag(
- TrafficStatsConstants.TAG_SYSTEM_NEIGHBOR);
- try {
- mSocket = Os.socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
- // Setting SNDTIMEO is purely for defensive purposes.
- Os.setsockoptTimeval(
- mSocket, SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(send_timout_ms));
- SocketUtils.bindSocketToInterface(mSocket, mInterface.name);
- TetheringUtils.setupRaSocket(mSocket, mInterface.index);
- } catch (ErrnoException | IOException e) {
- Log.e(TAG, "Failed to create RA daemon socket: " + e);
- return false;
- } finally {
- TrafficStats.setThreadStatsTag(oldTag);
- }
-
- return true;
- }
-
- private void closeSocket() {
- if (mSocket != null) {
- try {
- SocketUtils.closeSocket(mSocket);
- } catch (IOException ignored) { }
- }
- mSocket = null;
- }
-
- private boolean isSocketValid() {
- final FileDescriptor s = mSocket;
- return (s != null) && s.valid();
- }
-
- private boolean isSuitableDestination(InetSocketAddress dest) {
- if (mAllNodes.equals(dest)) {
- return true;
- }
-
- final InetAddress destip = dest.getAddress();
- return (destip instanceof Inet6Address)
- && destip.isLinkLocalAddress()
- && (((Inet6Address) destip).getScopeId() == mInterface.index);
- }
-
- private void maybeSendRA(InetSocketAddress dest) {
- if (dest == null || !isSuitableDestination(dest)) {
- dest = mAllNodes;
- }
-
- try {
- synchronized (mLock) {
- if (mRaLength < MIN_RA_HEADER_SIZE) {
- // No actual RA to send.
- return;
- }
- Os.sendto(mSocket, mRA, 0, mRaLength, 0, dest);
- }
- Log.d(TAG, "RA sendto " + dest.getAddress().getHostAddress());
- } catch (ErrnoException | SocketException e) {
- if (isSocketValid()) {
- Log.e(TAG, "sendto error: " + e);
- }
- }
- }
-
- private final class UnicastResponder extends Thread {
- private final InetSocketAddress mSolicitor = new InetSocketAddress(0);
- // The recycled buffer for receiving Router Solicitations from clients.
- // If the RS is larger than IPV6_MIN_MTU the packets are truncated.
- // This is fine since currently only byte 0 is examined anyway.
- private final byte[] mSolicitation = new byte[IPV6_MIN_MTU];
-
- @Override
- public void run() {
- while (isSocketValid()) {
- try {
- // Blocking receive.
- final int rval = Os.recvfrom(
- mSocket, mSolicitation, 0, mSolicitation.length, 0, mSolicitor);
- // Do the least possible amount of validation.
- if (rval < 1 || mSolicitation[0] != ICMPV6_ND_ROUTER_SOLICIT) {
- continue;
- }
- } catch (ErrnoException | SocketException e) {
- if (isSocketValid()) {
- Log.e(TAG, "recvfrom error: " + e);
- }
- continue;
- }
-
- maybeSendRA(mSolicitor);
- }
- }
- }
-
- // TODO: Consider moving this to run on a provided Looper as a Handler,
- // with WakeupMessage-style messages providing the timer driven input.
- private final class MulticastTransmitter extends Thread {
- private final Random mRandom = new Random();
- private final AtomicInteger mUrgentAnnouncements = new AtomicInteger(0);
-
- @Override
- public void run() {
- while (isSocketValid()) {
- try {
- Thread.sleep(getNextMulticastTransmitDelayMs());
- } catch (InterruptedException ignored) {
- // Stop sleeping, immediately send an RA, and continue.
- }
-
- maybeSendRA(mAllNodes);
- synchronized (mLock) {
- if (mDeprecatedInfoTracker.decrementCounters()) {
- // At least one deprecated PIO has been removed;
- // reassemble the RA.
- assembleRaLocked();
- }
- }
- }
- }
-
- public void hup() {
- // Set to one fewer that the desired number, because as soon as
- // the thread interrupt is processed we immediately send an RA
- // and mUrgentAnnouncements is not examined until the subsequent
- // sleep interval computation (i.e. this way we send 3 and not 4).
- mUrgentAnnouncements.set(MAX_URGENT_RTR_ADVERTISEMENTS - 1);
- interrupt();
- }
-
- private int getNextMulticastTransmitDelaySec() {
- boolean deprecationInProgress = false;
- synchronized (mLock) {
- if (mRaLength < MIN_RA_HEADER_SIZE) {
- // No actual RA to send; just sleep for 1 day.
- return DAY_IN_SECONDS;
- }
- deprecationInProgress = !mDeprecatedInfoTracker.isEmpty();
- }
-
- final int urgentPending = mUrgentAnnouncements.getAndDecrement();
- if ((urgentPending > 0) || deprecationInProgress) {
- return MIN_DELAY_BETWEEN_RAS_SEC;
- }
-
- return MIN_RTR_ADV_INTERVAL_SEC + mRandom.nextInt(
- MAX_RTR_ADV_INTERVAL_SEC - MIN_RTR_ADV_INTERVAL_SEC);
- }
-
- private long getNextMulticastTransmitDelayMs() {
- return 1000 * (long) getNextMulticastTransmitDelaySec();
- }
- }
-}
diff --git a/packages/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java b/packages/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java
deleted file mode 100644
index b1ffdb0..0000000
--- a/packages/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java
+++ /dev/null
@@ -1,75 +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.net.util;
-
-import android.net.INetdUnsolicitedEventListener;
-
-import androidx.annotation.NonNull;
-
-/**
- * Base {@link INetdUnsolicitedEventListener} that provides no-op implementations which can be
- * overridden.
- */
-public class BaseNetdUnsolicitedEventListener extends INetdUnsolicitedEventListener.Stub {
-
- @Override
- public void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs,
- int uid) { }
-
- @Override
- public void onQuotaLimitReached(@NonNull String alertName, @NonNull String ifName) { }
-
- @Override
- public void onInterfaceDnsServerInfo(@NonNull String ifName, long lifetimeS,
- @NonNull String[] servers) { }
-
- @Override
- public void onInterfaceAddressUpdated(@NonNull String addr, String ifName, int flags,
- int scope) { }
-
- @Override
- public void onInterfaceAddressRemoved(@NonNull String addr, @NonNull String ifName, int flags,
- int scope) { }
-
- @Override
- public void onInterfaceAdded(@NonNull String ifName) { }
-
- @Override
- public void onInterfaceRemoved(@NonNull String ifName) { }
-
- @Override
- public void onInterfaceChanged(@NonNull String ifName, boolean up) { }
-
- @Override
- public void onInterfaceLinkStateChanged(@NonNull String ifName, boolean up) { }
-
- @Override
- public void onRouteChanged(boolean updated, @NonNull String route, @NonNull String gateway,
- @NonNull String ifName) { }
-
- @Override
- public void onStrictCleartextDetected(int uid, @NonNull String hex) { }
-
- @Override
- public int getInterfaceVersion() {
- return INetdUnsolicitedEventListener.VERSION;
- }
-
- @Override
- public String getInterfaceHash() {
- return INetdUnsolicitedEventListener.HASH;
- }
-}
diff --git a/packages/Tethering/src/android/net/util/InterfaceSet.java b/packages/Tethering/src/android/net/util/InterfaceSet.java
deleted file mode 100644
index 7589787..0000000
--- a/packages/Tethering/src/android/net/util/InterfaceSet.java
+++ /dev/null
@@ -1,52 +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.net.util;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.StringJoiner;
-
-
-/**
- * @hide
- */
-public class InterfaceSet {
- public final Set<String> ifnames;
-
- public InterfaceSet(String... names) {
- final Set<String> nameSet = new HashSet<>();
- for (String name : names) {
- if (name != null) nameSet.add(name);
- }
- ifnames = Collections.unmodifiableSet(nameSet);
- }
-
- @Override
- public String toString() {
- final StringJoiner sj = new StringJoiner(",", "[", "]");
- for (String ifname : ifnames) sj.add(ifname);
- return sj.toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj != null
- && obj instanceof InterfaceSet
- && ifnames.equals(((InterfaceSet) obj).ifnames);
- }
-}
diff --git a/packages/Tethering/src/android/net/util/PrefixUtils.java b/packages/Tethering/src/android/net/util/PrefixUtils.java
deleted file mode 100644
index f203e999..0000000
--- a/packages/Tethering/src/android/net/util/PrefixUtils.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 android.net.util;
-
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-
-/**
- * @hide
- */
-public class PrefixUtils {
- private static final IpPrefix[] MIN_NON_FORWARDABLE_PREFIXES = {
- pfx("127.0.0.0/8"), // IPv4 loopback
- pfx("169.254.0.0/16"), // IPv4 link-local, RFC3927#section-8
- pfx("::/3"),
- pfx("fe80::/64"), // IPv6 link-local
- pfx("fc00::/7"), // IPv6 ULA
- pfx("ff02::/8"), // IPv6 link-local multicast
- };
-
- public static final IpPrefix DEFAULT_WIFI_P2P_PREFIX = pfx("192.168.49.0/24");
-
- /** Get non forwardable prefixes. */
- public static Set<IpPrefix> getNonForwardablePrefixes() {
- final HashSet<IpPrefix> prefixes = new HashSet<>();
- addNonForwardablePrefixes(prefixes);
- return prefixes;
- }
-
- /** Add non forwardable prefixes. */
- public static void addNonForwardablePrefixes(Set<IpPrefix> prefixes) {
- Collections.addAll(prefixes, MIN_NON_FORWARDABLE_PREFIXES);
- }
-
- /** Get local prefixes from |lp|. */
- public static Set<IpPrefix> localPrefixesFrom(LinkProperties lp) {
- final HashSet<IpPrefix> localPrefixes = new HashSet<>();
- if (lp == null) return localPrefixes;
-
- for (LinkAddress addr : lp.getAllLinkAddresses()) {
- if (addr.getAddress().isLinkLocalAddress()) continue;
- localPrefixes.add(asIpPrefix(addr));
- }
- // TODO: Add directly-connected routes as well (ones from which we did
- // not also form a LinkAddress)?
-
- return localPrefixes;
- }
-
- /** Convert LinkAddress |addr| to IpPrefix. */
- public static IpPrefix asIpPrefix(LinkAddress addr) {
- return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
- }
-
- /** Convert InetAddress |ip| to IpPrefix. */
- public static IpPrefix ipAddressAsPrefix(InetAddress ip) {
- final int bitLength = (ip instanceof Inet4Address)
- ? NetworkConstants.IPV4_ADDR_BITS
- : NetworkConstants.IPV6_ADDR_BITS;
- return new IpPrefix(ip, bitLength);
- }
-
- private static IpPrefix pfx(String prefixStr) {
- return new IpPrefix(prefixStr);
- }
-}
diff --git a/packages/Tethering/src/android/net/util/TetheringMessageBase.java b/packages/Tethering/src/android/net/util/TetheringMessageBase.java
deleted file mode 100644
index 1b763ce..0000000
--- a/packages/Tethering/src/android/net/util/TetheringMessageBase.java
+++ /dev/null
@@ -1,25 +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.net.util;
-
-/**
- * This class defines Message.what base addresses for various state machine.
- */
-public class TetheringMessageBase {
- public static final int BASE_MASTER = 0;
- public static final int BASE_IPSERVER = 100;
-
-}
diff --git a/packages/Tethering/src/android/net/util/TetheringUtils.java b/packages/Tethering/src/android/net/util/TetheringUtils.java
deleted file mode 100644
index b17b4ba..0000000
--- a/packages/Tethering/src/android/net/util/TetheringUtils.java
+++ /dev/null
@@ -1,132 +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.net.util;
-
-import android.net.TetherStatsParcel;
-import android.net.TetheringRequestParcel;
-
-import androidx.annotation.NonNull;
-
-import java.io.FileDescriptor;
-import java.net.SocketException;
-import java.util.Objects;
-
-/**
- * The classes and the methods for tethering utilization.
- *
- * {@hide}
- */
-public class TetheringUtils {
- /**
- * The object which records offload Tx/Rx forwarded bytes/packets.
- * TODO: Replace the inner class ForwardedStats of class OffloadHardwareInterface with
- * this class as well.
- */
- public static class ForwardedStats {
- public final long rxBytes;
- public final long rxPackets;
- public final long txBytes;
- public final long txPackets;
-
- public ForwardedStats() {
- rxBytes = 0;
- rxPackets = 0;
- txBytes = 0;
- txPackets = 0;
- }
-
- public ForwardedStats(long rxBytes, long txBytes) {
- this.rxBytes = rxBytes;
- this.rxPackets = 0;
- this.txBytes = txBytes;
- this.txPackets = 0;
- }
-
- public ForwardedStats(long rxBytes, long rxPackets, long txBytes, long txPackets) {
- this.rxBytes = rxBytes;
- this.rxPackets = rxPackets;
- this.txBytes = txBytes;
- this.txPackets = txPackets;
- }
-
- public ForwardedStats(@NonNull TetherStatsParcel tetherStats) {
- rxBytes = tetherStats.rxBytes;
- rxPackets = tetherStats.rxPackets;
- txBytes = tetherStats.txBytes;
- txPackets = tetherStats.txPackets;
- }
-
- public ForwardedStats(@NonNull ForwardedStats other) {
- rxBytes = other.rxBytes;
- rxPackets = other.rxPackets;
- txBytes = other.txBytes;
- txPackets = other.txPackets;
- }
-
- /** Add Tx/Rx bytes/packets and return the result as a new object. */
- @NonNull
- public ForwardedStats add(@NonNull ForwardedStats other) {
- return new ForwardedStats(rxBytes + other.rxBytes, rxPackets + other.rxPackets,
- txBytes + other.txBytes, txPackets + other.txPackets);
- }
-
- /** Subtract Tx/Rx bytes/packets and return the result as a new object. */
- @NonNull
- public ForwardedStats subtract(@NonNull ForwardedStats other) {
- // TODO: Perhaps throw an exception if any negative difference value just in case.
- final long rxBytesDiff = Math.max(rxBytes - other.rxBytes, 0);
- final long rxPacketsDiff = Math.max(rxPackets - other.rxPackets, 0);
- final long txBytesDiff = Math.max(txBytes - other.txBytes, 0);
- final long txPacketsDiff = Math.max(txPackets - other.txPackets, 0);
- return new ForwardedStats(rxBytesDiff, rxPacketsDiff, txBytesDiff, txPacketsDiff);
- }
-
- /** Returns the string representation of this object. */
- @NonNull
- public String toString() {
- return String.format("ForwardedStats(rxb: %d, rxp: %d, txb: %d, txp: %d)", rxBytes,
- rxPackets, txBytes, txPackets);
- }
- }
-
- /**
- * Configures a socket for receiving ICMPv6 router solicitations and sending advertisements.
- * @param fd the socket's {@link FileDescriptor}.
- * @param ifIndex the interface index.
- */
- public static native void setupRaSocket(FileDescriptor fd, int ifIndex)
- throws SocketException;
-
- /**
- * Read s as an unsigned 16-bit integer.
- */
- public static int uint16(short s) {
- return s & 0xffff;
- }
-
- /** Check whether two TetheringRequestParcels are the same. */
- public static boolean isTetheringRequestEquals(final TetheringRequestParcel request,
- final TetheringRequestParcel otherRequest) {
- if (request == otherRequest) return true;
-
- return request != null && otherRequest != null
- && request.tetheringType == otherRequest.tetheringType
- && Objects.equals(request.localIPv4Address, otherRequest.localIPv4Address)
- && Objects.equals(request.staticClientAddress, otherRequest.staticClientAddress)
- && request.exemptFromEntitlementCheck == otherRequest.exemptFromEntitlementCheck
- && request.showProvisioningUi == otherRequest.showProvisioningUi;
- }
-}
diff --git a/packages/Tethering/src/android/net/util/VersionedBroadcastListener.java b/packages/Tethering/src/android/net/util/VersionedBroadcastListener.java
deleted file mode 100644
index e2804ab..0000000
--- a/packages/Tethering/src/android/net/util/VersionedBroadcastListener.java
+++ /dev/null
@@ -1,106 +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.net.util;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-import android.util.Log;
-
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
-
-
-/**
- * A utility class that runs the provided callback on the provided handler when
- * intents matching the provided filter arrive. Intents received by a stale
- * receiver are safely ignored.
- *
- * Calls to startListening() and stopListening() must happen on the same thread.
- *
- * @hide
- */
-public class VersionedBroadcastListener {
- private static final boolean DBG = false;
-
- private final String mTag;
- private final Context mContext;
- private final Handler mHandler;
- private final IntentFilter mFilter;
- private final Consumer<Intent> mCallback;
- private final AtomicInteger mGenerationNumber;
- private BroadcastReceiver mReceiver;
-
- public VersionedBroadcastListener(String tag, Context ctx, Handler handler,
- IntentFilter filter, Consumer<Intent> callback) {
- mTag = tag;
- mContext = ctx;
- mHandler = handler;
- mFilter = filter;
- mCallback = callback;
- mGenerationNumber = new AtomicInteger(0);
- }
-
- /** Start listening to intent broadcast. */
- public void startListening() {
- if (DBG) Log.d(mTag, "startListening");
- if (mReceiver != null) return;
-
- mReceiver = new Receiver(mTag, mGenerationNumber, mCallback);
- mContext.registerReceiver(mReceiver, mFilter, null, mHandler);
- }
-
- /** Stop listening to intent broadcast. */
- public void stopListening() {
- if (DBG) Log.d(mTag, "stopListening");
- if (mReceiver == null) return;
-
- mGenerationNumber.incrementAndGet();
- mContext.unregisterReceiver(mReceiver);
- mReceiver = null;
- }
-
- private static class Receiver extends BroadcastReceiver {
- public final String tag;
- public final AtomicInteger atomicGenerationNumber;
- public final Consumer<Intent> callback;
- // Used to verify this receiver is still current.
- public final int generationNumber;
-
- Receiver(String tag, AtomicInteger atomicGenerationNumber, Consumer<Intent> callback) {
- this.tag = tag;
- this.atomicGenerationNumber = atomicGenerationNumber;
- this.callback = callback;
- generationNumber = atomicGenerationNumber.incrementAndGet();
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- final int currentGenerationNumber = atomicGenerationNumber.get();
-
- if (DBG) {
- Log.d(tag, "receiver generationNumber=" + generationNumber
- + ", current generationNumber=" + currentGenerationNumber);
- }
- if (generationNumber != currentGenerationNumber) return;
-
- callback.accept(intent);
- }
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
deleted file mode 100644
index 20f30ea..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ /dev/null
@@ -1,778 +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.networkstack.tethering;
-
-import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
-import static android.net.NetworkStats.METERED_NO;
-import static android.net.NetworkStats.ROAMING_NO;
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-import static android.net.NetworkStats.UID_TETHERING;
-import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
-
-import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
-
-import android.app.usage.NetworkStatsManager;
-import android.net.INetd;
-import android.net.MacAddress;
-import android.net.NetworkStats;
-import android.net.NetworkStats.Entry;
-import android.net.TetherOffloadRuleParcel;
-import android.net.TetherStatsParcel;
-import android.net.ip.IpServer;
-import android.net.netstats.provider.NetworkStatsProvider;
-import android.net.util.SharedLog;
-import android.net.util.TetheringUtils.ForwardedStats;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.SparseArray;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.IndentingPrintWriter;
-
-import java.net.Inet6Address;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * This coordinator is responsible for providing BPF offload relevant functionality.
- * - Get tethering stats.
- * - Set data limit.
- * - Set global alert.
- * - Add/remove forwarding rules.
- *
- * @hide
- */
-public class BpfCoordinator {
- private static final String TAG = BpfCoordinator.class.getSimpleName();
- private static final int DUMP_TIMEOUT_MS = 10_000;
-
- @VisibleForTesting
- enum StatsType {
- STATS_PER_IFACE,
- STATS_PER_UID,
- }
-
- @NonNull
- private final Handler mHandler;
- @NonNull
- private final INetd mNetd;
- @NonNull
- private final SharedLog mLog;
- @NonNull
- private final Dependencies mDeps;
- @Nullable
- private final BpfTetherStatsProvider mStatsProvider;
-
- // True if BPF offload is supported, false otherwise. The BPF offload could be disabled by
- // a runtime resource overlay package or device configuration. This flag is only initialized
- // in the constructor because it is hard to unwind all existing change once device
- // configuration is changed. Especially the forwarding rules. Keep the same setting
- // to make it simpler. See also TetheringConfiguration.
- private final boolean mIsBpfEnabled;
-
- // Tracks whether BPF tethering is started or not. This is set by tethering before it
- // starts the first IpServer and is cleared by tethering shortly before the last IpServer
- // is stopped. Note that rule updates (especially deletions, but sometimes additions as
- // well) may arrive when this is false. If they do, they must be communicated to netd.
- // Changes in data limits may also arrive when this is false, and if they do, they must
- // also be communicated to netd.
- private boolean mPollingStarted = false;
-
- // Tracking remaining alert quota. Unlike limit quota is subject to interface, the alert
- // quota is interface independent and global for tether offload.
- private long mRemainingAlertQuota = QUOTA_UNLIMITED;
-
- // Maps upstream interface index to offloaded traffic statistics.
- // Always contains the latest total bytes/packets, since each upstream was started, received
- // from the BPF maps for each interface.
- private final SparseArray<ForwardedStats> mStats = new SparseArray<>();
-
- // Maps upstream interface names to interface quotas.
- // Always contains the latest value received from the framework for each interface, regardless
- // of whether offload is currently running (or is even supported) on that interface. Only
- // includes interfaces that have a quota set. Note that this map is used for storing the quota
- // which is set from the service. Because the service uses the interface name to present the
- // interface, this map uses the interface name to be the mapping index.
- private final HashMap<String, Long> mInterfaceQuotas = new HashMap<>();
-
- // Maps upstream interface index to interface names.
- // Store all interface name since boot. Used for lookup what interface name it is from the
- // tether stats got from netd because netd reports interface index to present an interface.
- // TODO: Remove the unused interface name.
- private final SparseArray<String> mInterfaceNames = new SparseArray<>();
-
- // Map of downstream rule maps. Each of these maps represents the IPv6 forwarding rules for a
- // given downstream. Each map:
- // - Is owned by the IpServer that is responsible for that downstream.
- // - Must only be modified by that IpServer.
- // - Is created when the IpServer adds its first rule, and deleted when the IpServer deletes
- // its last rule (or clears its rules).
- // TODO: Perhaps seal the map and rule operations which communicates with netd into a class.
- // TODO: Does this need to be a LinkedHashMap or can it just be a HashMap? Also, could it be
- // a ConcurrentHashMap, in order to avoid the copies in tetherOffloadRuleClear
- // and tetherOffloadRuleUpdate?
- // TODO: Perhaps use one-dimensional map and access specific downstream rules via downstream
- // index. For doing that, IpServer must guarantee that it always has a valid IPv6 downstream
- // interface index while calling function to clear all rules. IpServer may be calling clear
- // rules function without a valid IPv6 downstream interface index even if it may have one
- // before. IpServer would need to call getInterfaceParams() in the constructor instead of when
- // startIpv6() is called, and make mInterfaceParams final.
- private final HashMap<IpServer, LinkedHashMap<Inet6Address, Ipv6ForwardingRule>>
- mIpv6ForwardingRules = new LinkedHashMap<>();
-
- // Runnable that used by scheduling next polling of stats.
- private final Runnable mScheduledPollingTask = () -> {
- updateForwardedStatsFromNetd();
- maybeSchedulePollingStats();
- };
-
- @VisibleForTesting
- public abstract static class Dependencies {
- /** Get handler. */
- @NonNull public abstract Handler getHandler();
-
- /** Get netd. */
- @NonNull public abstract INetd getNetd();
-
- /** Get network stats manager. */
- @NonNull public abstract NetworkStatsManager getNetworkStatsManager();
-
- /** Get shared log. */
- @NonNull public abstract SharedLog getSharedLog();
-
- /** Get tethering configuration. */
- @Nullable public abstract TetheringConfiguration getTetherConfig();
- }
-
- @VisibleForTesting
- public BpfCoordinator(@NonNull Dependencies deps) {
- mDeps = deps;
- mHandler = mDeps.getHandler();
- mNetd = mDeps.getNetd();
- mLog = mDeps.getSharedLog().forSubComponent(TAG);
- mIsBpfEnabled = isBpfEnabled();
- BpfTetherStatsProvider provider = new BpfTetherStatsProvider();
- try {
- mDeps.getNetworkStatsManager().registerNetworkStatsProvider(
- getClass().getSimpleName(), provider);
- } catch (RuntimeException e) {
- // TODO: Perhaps not allow to use BPF offload because the reregistration failure
- // implied that no data limit could be applies on a metered upstream if any.
- Log.wtf(TAG, "Cannot register offload stats provider: " + e);
- provider = null;
- }
- mStatsProvider = provider;
- }
-
- /**
- * Start BPF tethering offload stats polling when the first upstream is started.
- * Note that this can be only called on handler thread.
- * TODO: Perhaps check BPF support before starting.
- * TODO: Start the stats polling only if there is any client on the downstream.
- */
- public void startPolling() {
- if (mPollingStarted) return;
-
- if (!mIsBpfEnabled) {
- mLog.i("Offload disabled");
- return;
- }
-
- mPollingStarted = true;
- maybeSchedulePollingStats();
-
- mLog.i("Polling started");
- }
-
- /**
- * Stop BPF tethering offload stats polling.
- * The data limit cleanup and the tether stats maps cleanup are not implemented here.
- * These cleanups rely on all IpServers calling #tetherOffloadRuleRemove. After the
- * last rule is removed from the upstream, #tetherOffloadRuleRemove does the cleanup
- * functionality.
- * Note that this can be only called on handler thread.
- */
- public void stopPolling() {
- if (!mPollingStarted) return;
-
- // Stop scheduled polling tasks and poll the latest stats from BPF maps.
- if (mHandler.hasCallbacks(mScheduledPollingTask)) {
- mHandler.removeCallbacks(mScheduledPollingTask);
- }
- updateForwardedStatsFromNetd();
- mPollingStarted = false;
-
- mLog.i("Polling stopped");
- }
-
- /**
- * Add forwarding rule. After adding the first rule on a given upstream, must add the data
- * limit on the given upstream.
- * Note that this can be only called on handler thread.
- */
- public void tetherOffloadRuleAdd(
- @NonNull final IpServer ipServer, @NonNull final Ipv6ForwardingRule rule) {
- if (!mIsBpfEnabled) return;
-
- try {
- // TODO: Perhaps avoid to add a duplicate rule.
- mNetd.tetherOffloadRuleAdd(rule.toTetherOffloadRuleParcel());
- } catch (RemoteException | ServiceSpecificException e) {
- mLog.e("Could not add IPv6 forwarding rule: ", e);
- return;
- }
-
- if (!mIpv6ForwardingRules.containsKey(ipServer)) {
- mIpv6ForwardingRules.put(ipServer, new LinkedHashMap<Inet6Address,
- Ipv6ForwardingRule>());
- }
- LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = mIpv6ForwardingRules.get(ipServer);
-
- // Setup the data limit on the given upstream if the first rule is added.
- final int upstreamIfindex = rule.upstreamIfindex;
- if (!isAnyRuleOnUpstream(upstreamIfindex)) {
- // If failed to set a data limit, probably should not use this upstream, because
- // the upstream may not want to blow through the data limit that was told to apply.
- // TODO: Perhaps stop the coordinator.
- boolean success = updateDataLimit(upstreamIfindex);
- if (!success) {
- final String iface = mInterfaceNames.get(upstreamIfindex);
- mLog.e("Setting data limit for " + iface + " failed.");
- }
- }
-
- // Must update the adding rule after calling #isAnyRuleOnUpstream because it needs to
- // check if it is about adding a first rule for a given upstream.
- rules.put(rule.address, rule);
- }
-
- /**
- * Remove forwarding rule. After removing the last rule on a given upstream, must clear
- * data limit, update the last tether stats and remove the tether stats in the BPF maps.
- * Note that this can be only called on handler thread.
- */
- public void tetherOffloadRuleRemove(
- @NonNull final IpServer ipServer, @NonNull final Ipv6ForwardingRule rule) {
- if (!mIsBpfEnabled) return;
-
- try {
- // TODO: Perhaps avoid to remove a non-existent rule.
- mNetd.tetherOffloadRuleRemove(rule.toTetherOffloadRuleParcel());
- } catch (RemoteException | ServiceSpecificException e) {
- mLog.e("Could not remove IPv6 forwarding rule: ", e);
- return;
- }
-
- LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = mIpv6ForwardingRules.get(ipServer);
- if (rules == null) return;
-
- // Must remove rules before calling #isAnyRuleOnUpstream because it needs to check if
- // the last rule is removed for a given upstream. If no rule is removed, return early.
- // Avoid unnecessary work on a non-existent rule which may have never been added or
- // removed already.
- if (rules.remove(rule.address) == null) return;
-
- // Remove the downstream entry if it has no more rule.
- if (rules.isEmpty()) {
- mIpv6ForwardingRules.remove(ipServer);
- }
-
- // Do cleanup functionality if there is no more rule on the given upstream.
- final int upstreamIfindex = rule.upstreamIfindex;
- if (!isAnyRuleOnUpstream(upstreamIfindex)) {
- try {
- final TetherStatsParcel stats =
- mNetd.tetherOffloadGetAndClearStats(upstreamIfindex);
- // Update the last stats delta and delete the local cache for a given upstream.
- updateQuotaAndStatsFromSnapshot(new TetherStatsParcel[] {stats});
- mStats.remove(upstreamIfindex);
- } catch (RemoteException | ServiceSpecificException e) {
- Log.wtf(TAG, "Exception when cleanup tether stats for upstream index "
- + upstreamIfindex + ": ", e);
- }
- }
- }
-
- /**
- * Clear all forwarding rules for a given downstream.
- * Note that this can be only called on handler thread.
- */
- public void tetherOffloadRuleClear(@NonNull final IpServer ipServer) {
- if (!mIsBpfEnabled) return;
-
- final LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = mIpv6ForwardingRules.get(
- ipServer);
- if (rules == null) return;
-
- // Need to build a rule list because the rule map may be changed in the iteration.
- for (final Ipv6ForwardingRule rule : new ArrayList<Ipv6ForwardingRule>(rules.values())) {
- tetherOffloadRuleRemove(ipServer, rule);
- }
- }
-
- /**
- * Update existing forwarding rules to new upstream for a given downstream.
- * Note that this can be only called on handler thread.
- */
- public void tetherOffloadRuleUpdate(@NonNull final IpServer ipServer, int newUpstreamIfindex) {
- if (!mIsBpfEnabled) return;
-
- final LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = mIpv6ForwardingRules.get(
- ipServer);
- if (rules == null) return;
-
- // Need to build a rule list because the rule map may be changed in the iteration.
- for (final Ipv6ForwardingRule rule : new ArrayList<Ipv6ForwardingRule>(rules.values())) {
- // Remove the old rule before adding the new one because the map uses the same key for
- // both rules. Reversing the processing order causes that the new rule is removed as
- // unexpected.
- // TODO: Add new rule first to reduce the latency which has no rule.
- tetherOffloadRuleRemove(ipServer, rule);
- tetherOffloadRuleAdd(ipServer, rule.onNewUpstream(newUpstreamIfindex));
- }
- }
-
- /**
- * Add upstream name to lookup table. The lookup table is used for tether stats interface name
- * lookup because the netd only reports interface index in BPF tether stats but the service
- * expects the interface name in NetworkStats object.
- * Note that this can be only called on handler thread.
- */
- public void addUpstreamNameToLookupTable(int upstreamIfindex, @NonNull String upstreamIface) {
- if (!mIsBpfEnabled) return;
-
- if (upstreamIfindex == 0 || TextUtils.isEmpty(upstreamIface)) return;
-
- // The same interface index to name mapping may be added by different IpServer objects or
- // re-added by reconnection on the same upstream interface. Ignore the duplicate one.
- final String iface = mInterfaceNames.get(upstreamIfindex);
- if (iface == null) {
- mInterfaceNames.put(upstreamIfindex, upstreamIface);
- } else if (!TextUtils.equals(iface, upstreamIface)) {
- Log.wtf(TAG, "The upstream interface name " + upstreamIface
- + " is different from the existing interface name "
- + iface + " for index " + upstreamIfindex);
- }
- }
-
- /**
- * Dump information.
- * Block the function until all the data are dumped on the handler thread or timed-out. The
- * reason is that dumpsys invokes this function on the thread of caller and the data may only
- * be allowed to be accessed on the handler thread.
- */
- public void dump(@NonNull IndentingPrintWriter pw) {
- final ConditionVariable dumpDone = new ConditionVariable();
- mHandler.post(() -> {
- pw.println("mIsBpfEnabled: " + mIsBpfEnabled);
- pw.println("Polling " + (mPollingStarted ? "started" : "not started"));
- pw.println("Stats provider " + (mStatsProvider != null
- ? "registered" : "not registered"));
- pw.println("Upstream quota: " + mInterfaceQuotas.toString());
- pw.println("Polling interval: " + getPollingInterval() + " ms");
-
- pw.println("Forwarding stats:");
- pw.increaseIndent();
- if (mStats.size() == 0) {
- pw.println("<empty>");
- } else {
- dumpStats(pw);
- }
- pw.decreaseIndent();
-
- pw.println("Forwarding rules:");
- pw.increaseIndent();
- if (mIpv6ForwardingRules.size() == 0) {
- pw.println("<empty>");
- } else {
- dumpIpv6ForwardingRules(pw);
- }
- pw.decreaseIndent();
-
- dumpDone.open();
- });
- if (!dumpDone.block(DUMP_TIMEOUT_MS)) {
- pw.println("... dump timed-out after " + DUMP_TIMEOUT_MS + "ms");
- }
- }
-
- private void dumpStats(@NonNull IndentingPrintWriter pw) {
- for (int i = 0; i < mStats.size(); i++) {
- final int upstreamIfindex = mStats.keyAt(i);
- final ForwardedStats stats = mStats.get(upstreamIfindex);
- pw.println(String.format("%d(%s) - %s", upstreamIfindex, mInterfaceNames.get(
- upstreamIfindex), stats.toString()));
- }
- }
-
- private void dumpIpv6ForwardingRules(@NonNull IndentingPrintWriter pw) {
- for (Map.Entry<IpServer, LinkedHashMap<Inet6Address, Ipv6ForwardingRule>> entry :
- mIpv6ForwardingRules.entrySet()) {
- IpServer ipServer = entry.getKey();
- // The rule downstream interface index is paired with the interface name from
- // IpServer#interfaceName. See #startIPv6, #updateIpv6ForwardingRules in IpServer.
- final String downstreamIface = ipServer.interfaceName();
- pw.println("[" + downstreamIface + "]: iif(iface) oif(iface) v6addr srcmac dstmac");
-
- pw.increaseIndent();
- LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = entry.getValue();
- for (Ipv6ForwardingRule rule : rules.values()) {
- final int upstreamIfindex = rule.upstreamIfindex;
- pw.println(String.format("%d(%s) %d(%s) %s %s %s", upstreamIfindex,
- mInterfaceNames.get(upstreamIfindex), rule.downstreamIfindex,
- downstreamIface, rule.address, rule.srcMac, rule.dstMac));
- }
- pw.decreaseIndent();
- }
- }
-
- /** IPv6 forwarding rule class. */
- public static class Ipv6ForwardingRule {
- public final int upstreamIfindex;
- public final int downstreamIfindex;
-
- @NonNull
- public final Inet6Address address;
- @NonNull
- public final MacAddress srcMac;
- @NonNull
- public final MacAddress dstMac;
-
- public Ipv6ForwardingRule(int upstreamIfindex, int downstreamIfIndex,
- @NonNull Inet6Address address, @NonNull MacAddress srcMac,
- @NonNull MacAddress dstMac) {
- this.upstreamIfindex = upstreamIfindex;
- this.downstreamIfindex = downstreamIfIndex;
- this.address = address;
- this.srcMac = srcMac;
- this.dstMac = dstMac;
- }
-
- /** Return a new rule object which updates with new upstream index. */
- @NonNull
- public Ipv6ForwardingRule onNewUpstream(int newUpstreamIfindex) {
- return new Ipv6ForwardingRule(newUpstreamIfindex, downstreamIfindex, address, srcMac,
- dstMac);
- }
-
- /**
- * Don't manipulate TetherOffloadRuleParcel directly because implementing onNewUpstream()
- * would be error-prone due to generated stable AIDL classes not having a copy constructor.
- */
- @NonNull
- public TetherOffloadRuleParcel toTetherOffloadRuleParcel() {
- final TetherOffloadRuleParcel parcel = new TetherOffloadRuleParcel();
- parcel.inputInterfaceIndex = upstreamIfindex;
- parcel.outputInterfaceIndex = downstreamIfindex;
- parcel.destination = address.getAddress();
- parcel.prefixLength = 128;
- parcel.srcL2Address = srcMac.toByteArray();
- parcel.dstL2Address = dstMac.toByteArray();
- return parcel;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof Ipv6ForwardingRule)) return false;
- Ipv6ForwardingRule that = (Ipv6ForwardingRule) o;
- return this.upstreamIfindex == that.upstreamIfindex
- && this.downstreamIfindex == that.downstreamIfindex
- && Objects.equals(this.address, that.address)
- && Objects.equals(this.srcMac, that.srcMac)
- && Objects.equals(this.dstMac, that.dstMac);
- }
-
- @Override
- public int hashCode() {
- // TODO: if this is ever used in production code, don't pass ifindices
- // to Objects.hash() to avoid autoboxing overhead.
- return Objects.hash(upstreamIfindex, downstreamIfindex, address, srcMac, dstMac);
- }
- }
-
- /**
- * A BPF tethering stats provider to provide network statistics to the system.
- * Note that this class' data may only be accessed on the handler thread.
- */
- @VisibleForTesting
- class BpfTetherStatsProvider extends NetworkStatsProvider {
- // The offloaded traffic statistics per interface that has not been reported since the
- // last call to pushTetherStats. Only the interfaces that were ever tethering upstreams
- // and has pending tether stats delta are included in this NetworkStats object.
- private NetworkStats mIfaceStats = new NetworkStats(0L, 0);
-
- // The same stats as above, but counts network stats per uid.
- private NetworkStats mUidStats = new NetworkStats(0L, 0);
-
- @Override
- public void onRequestStatsUpdate(int token) {
- mHandler.post(() -> pushTetherStats());
- }
-
- @Override
- public void onSetAlert(long quotaBytes) {
- mHandler.post(() -> updateAlertQuota(quotaBytes));
- }
-
- @Override
- public void onSetLimit(@NonNull String iface, long quotaBytes) {
- if (quotaBytes < QUOTA_UNLIMITED) {
- throw new IllegalArgumentException("invalid quota value " + quotaBytes);
- }
-
- mHandler.post(() -> {
- final Long curIfaceQuota = mInterfaceQuotas.get(iface);
-
- if (null == curIfaceQuota && QUOTA_UNLIMITED == quotaBytes) return;
-
- if (quotaBytes == QUOTA_UNLIMITED) {
- mInterfaceQuotas.remove(iface);
- } else {
- mInterfaceQuotas.put(iface, quotaBytes);
- }
- maybeUpdateDataLimit(iface);
- });
- }
-
- @VisibleForTesting
- void pushTetherStats() {
- try {
- // The token is not used for now. See b/153606961.
- notifyStatsUpdated(0 /* token */, mIfaceStats, mUidStats);
-
- // Clear the accumulated tether stats delta after reported. Note that create a new
- // empty object because NetworkStats#clear is @hide.
- mIfaceStats = new NetworkStats(0L, 0);
- mUidStats = new NetworkStats(0L, 0);
- } catch (RuntimeException e) {
- mLog.e("Cannot report network stats: ", e);
- }
- }
-
- private void accumulateDiff(@NonNull NetworkStats ifaceDiff,
- @NonNull NetworkStats uidDiff) {
- mIfaceStats = mIfaceStats.add(ifaceDiff);
- mUidStats = mUidStats.add(uidDiff);
- }
- }
-
- private boolean isBpfEnabled() {
- final TetheringConfiguration config = mDeps.getTetherConfig();
- return (config != null) ? config.isBpfOffloadEnabled() : true /* default value */;
- }
-
- private int getInterfaceIndexFromRules(@NonNull String ifName) {
- for (LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules : mIpv6ForwardingRules
- .values()) {
- for (Ipv6ForwardingRule rule : rules.values()) {
- final int upstreamIfindex = rule.upstreamIfindex;
- if (TextUtils.equals(ifName, mInterfaceNames.get(upstreamIfindex))) {
- return upstreamIfindex;
- }
- }
- }
- return 0;
- }
-
- private long getQuotaBytes(@NonNull String iface) {
- final Long limit = mInterfaceQuotas.get(iface);
- final long quotaBytes = (limit != null) ? limit : QUOTA_UNLIMITED;
-
- return quotaBytes;
- }
-
- private boolean sendDataLimitToNetd(int ifIndex, long quotaBytes) {
- if (ifIndex == 0) {
- Log.wtf(TAG, "Invalid interface index.");
- return false;
- }
-
- try {
- mNetd.tetherOffloadSetInterfaceQuota(ifIndex, quotaBytes);
- } catch (RemoteException | ServiceSpecificException e) {
- mLog.e("Exception when updating quota " + quotaBytes + ": ", e);
- return false;
- }
-
- return true;
- }
-
- // Handle the data limit update from the service which is the stats provider registered for.
- private void maybeUpdateDataLimit(@NonNull String iface) {
- // Set data limit only on a given upstream which has at least one rule. If we can't get
- // an interface index for a given interface name, it means either there is no rule for
- // a given upstream or the interface name is not an upstream which is monitored by the
- // coordinator.
- final int ifIndex = getInterfaceIndexFromRules(iface);
- if (ifIndex == 0) return;
-
- final long quotaBytes = getQuotaBytes(iface);
- sendDataLimitToNetd(ifIndex, quotaBytes);
- }
-
- // Handle the data limit update while adding forwarding rules.
- private boolean updateDataLimit(int ifIndex) {
- final String iface = mInterfaceNames.get(ifIndex);
- if (iface == null) {
- mLog.e("Fail to get the interface name for index " + ifIndex);
- return false;
- }
- final long quotaBytes = getQuotaBytes(iface);
- return sendDataLimitToNetd(ifIndex, quotaBytes);
- }
-
- private boolean isAnyRuleOnUpstream(int upstreamIfindex) {
- for (LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules : mIpv6ForwardingRules
- .values()) {
- for (Ipv6ForwardingRule rule : rules.values()) {
- if (upstreamIfindex == rule.upstreamIfindex) return true;
- }
- }
- return false;
- }
-
- @NonNull
- private NetworkStats buildNetworkStats(@NonNull StatsType type, int ifIndex,
- @NonNull final ForwardedStats diff) {
- NetworkStats stats = new NetworkStats(0L, 0);
- final String iface = mInterfaceNames.get(ifIndex);
- if (iface == null) {
- // TODO: Use Log.wtf once the coordinator owns full control of tether stats from netd.
- // For now, netd may add the empty stats for the upstream which is not monitored by
- // the coordinator. Silently ignore it.
- return stats;
- }
- final int uid = (type == StatsType.STATS_PER_UID) ? UID_TETHERING : UID_ALL;
- // Note that the argument 'metered', 'roaming' and 'defaultNetwork' are not recorded for
- // network stats snapshot. See NetworkStatsRecorder#recordSnapshotLocked.
- return stats.addEntry(new Entry(iface, uid, SET_DEFAULT, TAG_NONE, METERED_NO,
- ROAMING_NO, DEFAULT_NETWORK_NO, diff.rxBytes, diff.rxPackets,
- diff.txBytes, diff.txPackets, 0L /* operations */));
- }
-
- private void updateAlertQuota(long newQuota) {
- if (newQuota < QUOTA_UNLIMITED) {
- throw new IllegalArgumentException("invalid quota value " + newQuota);
- }
- if (mRemainingAlertQuota == newQuota) return;
-
- mRemainingAlertQuota = newQuota;
- if (mRemainingAlertQuota == 0) {
- mLog.i("onAlertReached");
- if (mStatsProvider != null) mStatsProvider.notifyAlertReached();
- }
- }
-
- private void updateQuotaAndStatsFromSnapshot(
- @NonNull final TetherStatsParcel[] tetherStatsList) {
- long usedAlertQuota = 0;
- for (TetherStatsParcel tetherStats : tetherStatsList) {
- final Integer ifIndex = tetherStats.ifIndex;
- final ForwardedStats curr = new ForwardedStats(tetherStats);
- final ForwardedStats base = mStats.get(ifIndex);
- final ForwardedStats diff = (base != null) ? curr.subtract(base) : curr;
- usedAlertQuota += diff.rxBytes + diff.txBytes;
-
- // Update the local cache for counting tether stats delta.
- mStats.put(ifIndex, curr);
-
- // Update the accumulated tether stats delta to the stats provider for the service
- // querying.
- if (mStatsProvider != null) {
- try {
- mStatsProvider.accumulateDiff(
- buildNetworkStats(StatsType.STATS_PER_IFACE, ifIndex, diff),
- buildNetworkStats(StatsType.STATS_PER_UID, ifIndex, diff));
- } catch (ArrayIndexOutOfBoundsException e) {
- Log.wtf(TAG, "Fail to update the accumulated stats delta for interface index "
- + ifIndex + " : ", e);
- }
- }
- }
-
- if (mRemainingAlertQuota > 0 && usedAlertQuota > 0) {
- // Trim to zero if overshoot.
- final long newQuota = Math.max(mRemainingAlertQuota - usedAlertQuota, 0);
- updateAlertQuota(newQuota);
- }
-
- // TODO: Count the used limit quota for notifying data limit reached.
- }
-
- private void updateForwardedStatsFromNetd() {
- final TetherStatsParcel[] tetherStatsList;
- try {
- // The reported tether stats are total data usage for all currently-active upstream
- // interfaces since tethering start.
- tetherStatsList = mNetd.tetherOffloadGetStats();
- } catch (RemoteException | ServiceSpecificException e) {
- mLog.e("Problem fetching tethering stats: ", e);
- return;
- }
- updateQuotaAndStatsFromSnapshot(tetherStatsList);
- }
-
- @VisibleForTesting
- int getPollingInterval() {
- // The valid range of interval is DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS..max_long.
- // Ignore the config value is less than the minimum polling interval. Note that the
- // minimum interval definition is invoked as OffloadController#isPollingStatsNeeded does.
- // TODO: Perhaps define a minimum polling interval constant.
- final TetheringConfiguration config = mDeps.getTetherConfig();
- final int configInterval = (config != null) ? config.getOffloadPollInterval() : 0;
- return Math.max(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS, configInterval);
- }
-
- private void maybeSchedulePollingStats() {
- if (!mPollingStarted) return;
-
- if (mHandler.hasCallbacks(mScheduledPollingTask)) {
- mHandler.removeCallbacks(mScheduledPollingTask);
- }
-
- mHandler.postDelayed(mScheduledPollingTask, getPollingInterval());
- }
-
- // Return forwarding rule map. This is used for testing only.
- // Note that this can be only called on handler thread.
- @NonNull
- @VisibleForTesting
- final HashMap<IpServer, LinkedHashMap<Inet6Address, Ipv6ForwardingRule>>
- getForwardingRulesForTesting() {
- return mIpv6ForwardingRules;
- }
-
- // Return upstream interface name map. This is used for testing only.
- // Note that this can be only called on handler thread.
- @NonNull
- @VisibleForTesting
- final SparseArray<String> getInterfaceNamesForTesting() {
- return mInterfaceNames;
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/ConnectedClientsTracker.java b/packages/Tethering/src/com/android/networkstack/tethering/ConnectedClientsTracker.java
deleted file mode 100644
index 8a96988..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/ConnectedClientsTracker.java
+++ /dev/null
@@ -1,183 +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.networkstack.tethering;
-
-import static android.net.TetheringManager.TETHERING_WIFI;
-
-import android.net.MacAddress;
-import android.net.TetheredClient;
-import android.net.TetheredClient.AddressInfo;
-import android.net.ip.IpServer;
-import android.net.wifi.WifiClient;
-import android.os.SystemClock;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Tracker for clients connected to downstreams.
- *
- * <p>This class is not thread safe, it is intended to be used only from the tethering handler
- * thread.
- */
-public class ConnectedClientsTracker {
- private final Clock mClock;
-
- @NonNull
- private List<WifiClient> mLastWifiClients = Collections.emptyList();
- @NonNull
- private List<TetheredClient> mLastTetheredClients = Collections.emptyList();
-
- @VisibleForTesting
- static class Clock {
- public long elapsedRealtime() {
- return SystemClock.elapsedRealtime();
- }
- }
-
- public ConnectedClientsTracker() {
- this(new Clock());
- }
-
- @VisibleForTesting
- ConnectedClientsTracker(Clock clock) {
- mClock = clock;
- }
-
- /**
- * Update the tracker with new connected clients.
- *
- * <p>The new list can be obtained through {@link #getLastTetheredClients()}.
- * @param ipServers The IpServers used to assign addresses to clients.
- * @param wifiClients The list of L2-connected WiFi clients. Null for no change since last
- * update.
- * @return True if the list of clients changed since the last calculation.
- */
- public boolean updateConnectedClients(
- Iterable<IpServer> ipServers, @Nullable List<WifiClient> wifiClients) {
- final long now = mClock.elapsedRealtime();
-
- if (wifiClients != null) {
- mLastWifiClients = wifiClients;
- }
- final Set<MacAddress> wifiClientMacs = getClientMacs(mLastWifiClients);
-
- // Build the list of non-expired leases from all IpServers, grouped by mac address
- final Map<MacAddress, TetheredClient> clientsMap = new HashMap<>();
- for (IpServer server : ipServers) {
- for (TetheredClient client : server.getAllLeases()) {
- if (client.getTetheringType() == TETHERING_WIFI
- && !wifiClientMacs.contains(client.getMacAddress())) {
- // Skip leases of WiFi clients that are not (or no longer) L2-connected
- continue;
- }
- final TetheredClient prunedClient = pruneExpired(client, now);
- if (prunedClient == null) continue; // All addresses expired
-
- addLease(clientsMap, prunedClient);
- }
- }
-
- // TODO: add IPv6 addresses from netlink
-
- // Add connected WiFi clients that do not have any known address
- for (MacAddress client : wifiClientMacs) {
- if (clientsMap.containsKey(client)) continue;
- clientsMap.put(client, new TetheredClient(
- client, Collections.emptyList() /* addresses */, TETHERING_WIFI));
- }
-
- final HashSet<TetheredClient> clients = new HashSet<>(clientsMap.values());
- final boolean clientsChanged = clients.size() != mLastTetheredClients.size()
- || !clients.containsAll(mLastTetheredClients);
- mLastTetheredClients = Collections.unmodifiableList(new ArrayList<>(clients));
- return clientsChanged;
- }
-
- private static void addLease(Map<MacAddress, TetheredClient> clientsMap, TetheredClient lease) {
- final TetheredClient aggregateClient = clientsMap.getOrDefault(
- lease.getMacAddress(), lease);
- if (aggregateClient == lease) {
- // This is the first lease with this mac address
- clientsMap.put(lease.getMacAddress(), lease);
- return;
- }
-
- // Only add the address info; this assumes that the tethering type is the same when the mac
- // address is the same. If a client is connected through different tethering types with the
- // same mac address, connected clients callbacks will report all of its addresses under only
- // one of these tethering types. This keeps the API simple considering that such a scenario
- // would really be a rare edge case.
- clientsMap.put(lease.getMacAddress(), aggregateClient.addAddresses(lease));
- }
-
- /**
- * Get the last list of tethered clients, as calculated in {@link #updateConnectedClients}.
- *
- * <p>The returned list is immutable.
- */
- @NonNull
- public List<TetheredClient> getLastTetheredClients() {
- return mLastTetheredClients;
- }
-
- private static boolean hasExpiredAddress(List<AddressInfo> addresses, long now) {
- for (AddressInfo info : addresses) {
- if (info.getExpirationTime() <= now) {
- return true;
- }
- }
- return false;
- }
-
- @Nullable
- private static TetheredClient pruneExpired(TetheredClient client, long now) {
- final List<AddressInfo> addresses = client.getAddresses();
- if (addresses.size() == 0) return null;
- if (!hasExpiredAddress(addresses, now)) return client;
-
- final ArrayList<AddressInfo> newAddrs = new ArrayList<>(addresses.size() - 1);
- for (AddressInfo info : addresses) {
- if (info.getExpirationTime() > now) {
- newAddrs.add(info);
- }
- }
-
- if (newAddrs.size() == 0) {
- return null;
- }
- return new TetheredClient(client.getMacAddress(), newAddrs, client.getTetheringType());
- }
-
- @NonNull
- private static Set<MacAddress> getClientMacs(@NonNull List<WifiClient> clients) {
- final Set<MacAddress> macs = new HashSet<>(clients.size());
- for (WifiClient c : clients) {
- macs.add(c.getMacAddress());
- }
- return macs;
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
deleted file mode 100644
index 9dace70..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
+++ /dev/null
@@ -1,646 +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.networkstack.tethering;
-
-import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
-import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
-import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
-import static android.net.TetheringConstants.EXTRA_TETHER_PROVISIONING_RESPONSE;
-import static android.net.TetheringConstants.EXTRA_TETHER_SILENT_PROVISIONING_ACTION;
-import static android.net.TetheringConstants.EXTRA_TETHER_SUBID;
-import static android.net.TetheringConstants.EXTRA_TETHER_UI_PROVISIONING_APP_NAME;
-import static android.net.TetheringManager.TETHERING_BLUETOOTH;
-import static android.net.TetheringManager.TETHERING_ETHERNET;
-import static android.net.TetheringManager.TETHERING_INVALID;
-import static android.net.TetheringManager.TETHERING_USB;
-import static android.net.TetheringManager.TETHERING_WIFI;
-import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.util.SharedLog;
-import android.os.Bundle;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Parcel;
-import android.os.PersistableBundle;
-import android.os.ResultReceiver;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.telephony.CarrierConfigManager;
-import android.util.SparseIntArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.PrintWriter;
-import java.util.BitSet;
-
-/**
- * Re-check tethering provisioning for enabled downstream tether types.
- * Reference TetheringManager.TETHERING_{@code *} for each tether type.
- *
- * All methods of this class must be accessed from the thread of tethering
- * state machine.
- * @hide
- */
-public class EntitlementManager {
- private static final String TAG = EntitlementManager.class.getSimpleName();
- private static final boolean DBG = false;
-
- @VisibleForTesting
- protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
- private static final String ACTION_PROVISIONING_ALARM =
- "com.android.networkstack.tethering.PROVISIONING_RECHECK_ALARM";
-
- private final ComponentName mSilentProvisioningService;
- private static final int MS_PER_HOUR = 60 * 60 * 1000;
- private static final int DUMP_TIMEOUT = 10_000;
-
- // The BitSet is the bit map of each enabled downstream types, ex:
- // {@link TetheringManager.TETHERING_WIFI}
- // {@link TetheringManager.TETHERING_USB}
- // {@link TetheringManager.TETHERING_BLUETOOTH}
- private final BitSet mCurrentDownstreams;
- private final BitSet mExemptedDownstreams;
- private final Context mContext;
- private final SharedLog mLog;
- private final SparseIntArray mEntitlementCacheValue;
- private final Handler mHandler;
- // Key: TetheringManager.TETHERING_*(downstream).
- // Value: TetheringManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result).
- private final SparseIntArray mCurrentEntitlementResults;
- private final Runnable mPermissionChangeCallback;
- private PendingIntent mProvisioningRecheckAlarm;
- private boolean mLastCellularUpstreamPermitted = true;
- private boolean mUsingCellularAsUpstream = false;
- private boolean mNeedReRunProvisioningUi = false;
- private OnUiEntitlementFailedListener mListener;
- private TetheringConfigurationFetcher mFetcher;
-
- public EntitlementManager(Context ctx, Handler h, SharedLog log,
- Runnable callback) {
- mContext = ctx;
- mLog = log.forSubComponent(TAG);
- mCurrentDownstreams = new BitSet();
- mExemptedDownstreams = new BitSet();
- mCurrentEntitlementResults = new SparseIntArray();
- mEntitlementCacheValue = new SparseIntArray();
- mPermissionChangeCallback = callback;
- mHandler = h;
- mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PROVISIONING_ALARM),
- null, mHandler);
- mSilentProvisioningService = ComponentName.unflattenFromString(
- mContext.getResources().getString(R.string.config_wifi_tether_enable));
- }
-
- public void setOnUiEntitlementFailedListener(final OnUiEntitlementFailedListener listener) {
- mListener = listener;
- }
-
- /** Callback fired when UI entitlement failed. */
- public interface OnUiEntitlementFailedListener {
- /**
- * Ui entitlement check fails in |downstream|.
- *
- * @param downstream tethering type from TetheringManager.TETHERING_{@code *}.
- */
- void onUiEntitlementFailed(int downstream);
- }
-
- public void setTetheringConfigurationFetcher(final TetheringConfigurationFetcher fetcher) {
- mFetcher = fetcher;
- }
-
- /** Interface to fetch TetheringConfiguration. */
- public interface TetheringConfigurationFetcher {
- /**
- * Fetch current tethering configuration. This will be called to ensure whether entitlement
- * check is needed.
- * @return TetheringConfiguration instance.
- */
- TetheringConfiguration fetchTetheringConfiguration();
- }
-
- /**
- * Check if cellular upstream is permitted.
- */
- public boolean isCellularUpstreamPermitted() {
- final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
-
- return isCellularUpstreamPermitted(config);
- }
-
- private boolean isCellularUpstreamPermitted(final TetheringConfiguration config) {
- if (!isTetherProvisioningRequired(config)) return true;
-
- // If provisioning is required and EntitlementManager doesn't know any downstreams, cellular
- // upstream should not be enabled. Enable cellular upstream for exempted downstreams only
- // when there is no non-exempted downstream.
- if (mCurrentDownstreams.isEmpty()) return !mExemptedDownstreams.isEmpty();
-
- return mCurrentEntitlementResults.indexOfValue(TETHER_ERROR_NO_ERROR) > -1;
- }
-
- /**
- * Set exempted downstream type. If there is only exempted downstream type active,
- * corresponding entitlement check will not be run and cellular upstream will be permitted
- * by default. If a privileged app enables tethering without a provisioning check, and then
- * another app enables tethering of the same type but does not disable the provisioning check,
- * then the downstream immediately loses exempt status and a provisioning check is run.
- * If any non-exempted downstream type is active, the cellular upstream will be gated by the
- * result of entitlement check from non-exempted downstreams. If entitlement check is still
- * in progress on non-exempt downstreams, ceullar upstream would default be disabled. When any
- * non-exempted downstream gets positive entitlement result, ceullar upstream will be enabled.
- */
- public void setExemptedDownstreamType(final int type) {
- mExemptedDownstreams.set(type, true);
- }
-
- /**
- * This is called when tethering starts.
- * Launch provisioning app if upstream is cellular.
- *
- * @param downstreamType tethering type from TetheringManager.TETHERING_{@code *}
- * @param showProvisioningUi a boolean indicating whether to show the
- * provisioning app UI if there is one.
- */
- public void startProvisioningIfNeeded(int downstreamType, boolean showProvisioningUi) {
- if (!isValidDownstreamType(downstreamType)) return;
-
- mCurrentDownstreams.set(downstreamType, true);
-
- mExemptedDownstreams.set(downstreamType, false);
-
- final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- if (!isTetherProvisioningRequired(config)) return;
-
- // If upstream is not cellular, provisioning app would not be launched
- // till upstream change to cellular.
- if (mUsingCellularAsUpstream) {
- if (showProvisioningUi) {
- runUiTetherProvisioning(downstreamType, config);
- } else {
- runSilentTetherProvisioning(downstreamType, config);
- }
- mNeedReRunProvisioningUi = false;
- } else {
- mNeedReRunProvisioningUi |= showProvisioningUi;
- }
- }
-
- /**
- * Tell EntitlementManager that a given type of tethering has been disabled
- *
- * @param type tethering type from TetheringManager.TETHERING_{@code *}
- */
- public void stopProvisioningIfNeeded(int downstreamType) {
- if (!isValidDownstreamType(downstreamType)) return;
-
- mCurrentDownstreams.set(downstreamType, false);
- // There are lurking bugs where the notion of "provisioning required" or
- // "tethering supported" may change without without tethering being notified properly.
- // Remove the mapping all the time no matter provisioning is required or not.
- removeDownstreamMapping(downstreamType);
- mExemptedDownstreams.set(downstreamType, false);
- }
-
- /**
- * Notify EntitlementManager if upstream is cellular or not.
- *
- * @param isCellular whether tethering upstream is cellular.
- */
- public void notifyUpstream(boolean isCellular) {
- if (DBG) {
- mLog.i("notifyUpstream: " + isCellular
- + ", mLastCellularUpstreamPermitted: " + mLastCellularUpstreamPermitted
- + ", mNeedReRunProvisioningUi: " + mNeedReRunProvisioningUi);
- }
- mUsingCellularAsUpstream = isCellular;
-
- if (mUsingCellularAsUpstream) {
- final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- maybeRunProvisioning(config);
- }
- }
-
- /** Run provisioning if needed */
- public void maybeRunProvisioning() {
- final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- maybeRunProvisioning(config);
- }
-
- private void maybeRunProvisioning(final TetheringConfiguration config) {
- if (mCurrentDownstreams.isEmpty() || !isTetherProvisioningRequired(config)) {
- return;
- }
-
- // Whenever any entitlement value changes, all downstreams will re-evaluate whether they
- // are allowed. Therefore even if the silent check here ends in a failure and the UI later
- // yields success, then the downstream that got a failure will re-evaluate as a result of
- // the change and get the new correct value.
- for (int downstream = mCurrentDownstreams.nextSetBit(0); downstream >= 0;
- downstream = mCurrentDownstreams.nextSetBit(downstream + 1)) {
- if (mCurrentEntitlementResults.indexOfKey(downstream) < 0) {
- if (mNeedReRunProvisioningUi) {
- mNeedReRunProvisioningUi = false;
- runUiTetherProvisioning(downstream, config);
- } else {
- runSilentTetherProvisioning(downstream, config);
- }
- }
- }
- }
-
- /**
- * Check if the device requires a provisioning check in order to enable tethering.
- *
- * @param config an object that encapsulates the various tethering configuration elements.
- * @return a boolean - {@code true} indicating tether provisioning is required by the carrier.
- */
- @VisibleForTesting
- protected boolean isTetherProvisioningRequired(final TetheringConfiguration config) {
- if (SystemProperties.getBoolean(DISABLE_PROVISIONING_SYSPROP_KEY, false)
- || config.provisioningApp.length == 0) {
- return false;
- }
- if (carrierConfigAffirmsEntitlementCheckNotRequired(config)) {
- return false;
- }
- return (config.provisioningApp.length == 2);
- }
-
- /**
- * Re-check tethering provisioning for all enabled tether types.
- * Reference TetheringManager.TETHERING_{@code *} for each tether type.
- *
- * @param config an object that encapsulates the various tethering configuration elements.
- * Note: this method is only called from TetherMaster on the handler thread.
- * If there are new callers from different threads, the logic should move to
- * masterHandler to avoid race conditions.
- */
- public void reevaluateSimCardProvisioning(final TetheringConfiguration config) {
- if (DBG) mLog.i("reevaluateSimCardProvisioning");
-
- if (!mHandler.getLooper().isCurrentThread()) {
- // Except for test, this log should not appear in normal flow.
- mLog.log("reevaluateSimCardProvisioning() don't run in TetherMaster thread");
- }
- mEntitlementCacheValue.clear();
- mCurrentEntitlementResults.clear();
-
- // TODO: refine provisioning check to isTetherProvisioningRequired() ??
- if (!config.hasMobileHotspotProvisionApp()
- || carrierConfigAffirmsEntitlementCheckNotRequired(config)) {
- evaluateCellularPermission(config);
- return;
- }
-
- if (mUsingCellularAsUpstream) {
- maybeRunProvisioning(config);
- }
- }
-
- /**
- * Get carrier configuration bundle.
- * @param config an object that encapsulates the various tethering configuration elements.
- * */
- public PersistableBundle getCarrierConfig(final TetheringConfiguration config) {
- final CarrierConfigManager configManager = (CarrierConfigManager) mContext
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager == null) return null;
-
- final PersistableBundle carrierConfig = configManager.getConfigForSubId(
- config.activeDataSubId);
-
- if (CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
- return carrierConfig;
- }
-
- return null;
- }
-
- // The logic here is aimed solely at confirming that a CarrierConfig exists
- // and affirms that entitlement checks are not required.
- //
- // TODO: find a better way to express this, or alter the checking process
- // entirely so that this is more intuitive.
- private boolean carrierConfigAffirmsEntitlementCheckNotRequired(
- final TetheringConfiguration config) {
- // Check carrier config for entitlement checks
- final PersistableBundle carrierConfig = getCarrierConfig(config);
- if (carrierConfig == null) return false;
-
- // A CarrierConfigManager was found and it has a config.
- final boolean isEntitlementCheckRequired = carrierConfig.getBoolean(
- CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
- return !isEntitlementCheckRequired;
- }
-
- /**
- * Run no UI tethering provisioning check.
- * @param type tethering type from TetheringManager.TETHERING_{@code *}
- * @param subId default data subscription ID.
- */
- @VisibleForTesting
- protected Intent runSilentTetherProvisioning(int type, final TetheringConfiguration config) {
- if (DBG) mLog.i("runSilentTetherProvisioning: " + type);
- // For silent provisioning, settings would stop tethering when entitlement fail.
- ResultReceiver receiver = buildProxyReceiver(type, false/* notifyFail */, null);
-
- Intent intent = new Intent();
- intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
- intent.putExtra(EXTRA_RUN_PROVISION, true);
- intent.putExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION, config.provisioningAppNoUi);
- intent.putExtra(EXTRA_TETHER_PROVISIONING_RESPONSE, config.provisioningResponse);
- intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
- intent.putExtra(EXTRA_TETHER_SUBID, config.activeDataSubId);
- intent.setComponent(mSilentProvisioningService);
- // Only admin user can change tethering and SilentTetherProvisioning don't need to
- // show UI, it is fine to always start setting's background service as system user.
- mContext.startService(intent);
- return intent;
- }
-
- private void runUiTetherProvisioning(int type, final TetheringConfiguration config) {
- ResultReceiver receiver = buildProxyReceiver(type, true/* notifyFail */, null);
- runUiTetherProvisioning(type, config, receiver);
- }
-
- /**
- * Run the UI-enabled tethering provisioning check.
- * @param type tethering type from TetheringManager.TETHERING_{@code *}
- * @param subId default data subscription ID.
- * @param receiver to receive entitlement check result.
- */
- @VisibleForTesting
- protected Intent runUiTetherProvisioning(int type, final TetheringConfiguration config,
- ResultReceiver receiver) {
- if (DBG) mLog.i("runUiTetherProvisioning: " + type);
-
- Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING_UI);
- intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
- intent.putExtra(EXTRA_TETHER_UI_PROVISIONING_APP_NAME, config.provisioningApp);
- intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
- intent.putExtra(EXTRA_TETHER_SUBID, config.activeDataSubId);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- // Only launch entitlement UI for system user. Entitlement UI should not appear for other
- // user because only admin user is allowed to change tethering.
- mContext.startActivity(intent);
- return intent;
- }
-
- // Not needed to check if this don't run on the handler thread because it's private.
- private void scheduleProvisioningRechecks(final TetheringConfiguration config) {
- if (mProvisioningRecheckAlarm == null) {
- final int period = config.provisioningCheckPeriod;
- if (period <= 0) return;
-
- Intent intent = new Intent(ACTION_PROVISIONING_ALARM);
- mProvisioningRecheckAlarm = PendingIntent.getBroadcast(mContext, 0, intent, 0);
- AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
- Context.ALARM_SERVICE);
- long periodMs = period * MS_PER_HOUR;
- long firstAlarmTime = SystemClock.elapsedRealtime() + periodMs;
- alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, firstAlarmTime, periodMs,
- mProvisioningRecheckAlarm);
- }
- }
-
- private void cancelTetherProvisioningRechecks() {
- if (mProvisioningRecheckAlarm != null) {
- AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
- Context.ALARM_SERVICE);
- alarmManager.cancel(mProvisioningRecheckAlarm);
- mProvisioningRecheckAlarm = null;
- }
- }
-
- private void evaluateCellularPermission(final TetheringConfiguration config) {
- final boolean permitted = isCellularUpstreamPermitted(config);
-
- if (DBG) {
- mLog.i("Cellular permission change from " + mLastCellularUpstreamPermitted
- + " to " + permitted);
- }
-
- if (mLastCellularUpstreamPermitted != permitted) {
- mLog.log("Cellular permission change: " + permitted);
- mPermissionChangeCallback.run();
- }
- // Only schedule periodic re-check when tether is provisioned
- // and the result is ok.
- if (permitted && mCurrentEntitlementResults.size() > 0) {
- scheduleProvisioningRechecks(config);
- } else {
- cancelTetherProvisioningRechecks();
- }
- mLastCellularUpstreamPermitted = permitted;
- }
-
- /**
- * Add the mapping between provisioning result and tethering type.
- * Notify UpstreamNetworkMonitor if Cellular permission changes.
- *
- * @param type tethering type from TetheringManager.TETHERING_{@code *}
- * @param resultCode Provisioning result
- */
- protected void addDownstreamMapping(int type, int resultCode) {
- mLog.i("addDownstreamMapping: " + type + ", result: " + resultCode
- + " ,TetherTypeRequested: " + mCurrentDownstreams.get(type));
- if (!mCurrentDownstreams.get(type)) return;
-
- mCurrentEntitlementResults.put(type, resultCode);
- final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- evaluateCellularPermission(config);
- }
-
- /**
- * Remove the mapping for input tethering type.
- * @param type tethering type from TetheringManager.TETHERING_{@code *}
- */
- protected void removeDownstreamMapping(int type) {
- mLog.i("removeDownstreamMapping: " + type);
- mCurrentEntitlementResults.delete(type);
- final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- evaluateCellularPermission(config);
- }
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (ACTION_PROVISIONING_ALARM.equals(intent.getAction())) {
- mLog.log("Received provisioning alarm");
- final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- reevaluateSimCardProvisioning(config);
- }
- }
- };
-
- private static boolean isValidDownstreamType(int type) {
- switch (type) {
- case TETHERING_BLUETOOTH:
- case TETHERING_ETHERNET:
- case TETHERING_USB:
- case TETHERING_WIFI:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Dump the infromation of EntitlementManager.
- * @param pw {@link PrintWriter} is used to print formatted
- */
- public void dump(PrintWriter pw) {
- final ConditionVariable mWaiting = new ConditionVariable();
- mHandler.post(() -> {
- pw.print("isCellularUpstreamPermitted: ");
- pw.println(isCellularUpstreamPermitted());
- for (int type = mCurrentDownstreams.nextSetBit(0); type >= 0;
- type = mCurrentDownstreams.nextSetBit(type + 1)) {
- pw.print("Type: ");
- pw.print(typeString(type));
- if (mCurrentEntitlementResults.indexOfKey(type) > -1) {
- pw.print(", Value: ");
- pw.println(errorString(mCurrentEntitlementResults.get(type)));
- } else {
- pw.println(", Value: empty");
- }
- }
- mWaiting.open();
- });
- if (!mWaiting.block(DUMP_TIMEOUT)) {
- pw.println("... dump timed out after " + DUMP_TIMEOUT + "ms");
- }
- pw.print("Exempted: [");
- for (int type = mExemptedDownstreams.nextSetBit(0); type >= 0;
- type = mExemptedDownstreams.nextSetBit(type + 1)) {
- pw.print(typeString(type));
- pw.print(", ");
- }
- pw.println("]");
- }
-
- private static String typeString(int type) {
- switch (type) {
- case TETHERING_BLUETOOTH: return "TETHERING_BLUETOOTH";
- case TETHERING_INVALID: return "TETHERING_INVALID";
- case TETHERING_USB: return "TETHERING_USB";
- case TETHERING_WIFI: return "TETHERING_WIFI";
- default:
- return String.format("TETHERING UNKNOWN TYPE (%d)", type);
- }
- }
-
- private static String errorString(int value) {
- switch (value) {
- case TETHER_ERROR_ENTITLEMENT_UNKNOWN: return "TETHER_ERROR_ENTITLEMENT_UNKONWN";
- case TETHER_ERROR_NO_ERROR: return "TETHER_ERROR_NO_ERROR";
- case TETHER_ERROR_PROVISIONING_FAILED: return "TETHER_ERROR_PROVISIONING_FAILED";
- default:
- return String.format("UNKNOWN ERROR (%d)", value);
- }
- }
-
- private ResultReceiver buildProxyReceiver(int type, boolean notifyFail,
- final ResultReceiver receiver) {
- ResultReceiver rr = new ResultReceiver(mHandler) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- int updatedCacheValue = updateEntitlementCacheValue(type, resultCode);
- addDownstreamMapping(type, updatedCacheValue);
- if (updatedCacheValue == TETHER_ERROR_PROVISIONING_FAILED && notifyFail) {
- mListener.onUiEntitlementFailed(type);
- }
- if (receiver != null) receiver.send(updatedCacheValue, null);
- }
- };
-
- return writeToParcel(rr);
- }
-
- // Instances of ResultReceiver need to be public classes for remote processes to be able
- // to load them (otherwise, ClassNotFoundException). For private classes, this method
- // performs a trick : round-trip parceling any instance of ResultReceiver will return a
- // vanilla instance of ResultReceiver sharing the binder token with the original receiver.
- // The binder token has a reference to the original instance of the private class and will
- // still call its methods, and can be sent over. However it cannot be used for anything
- // else than sending over a Binder call.
- // While round-trip parceling is not great, there is currently no other way of generating
- // a vanilla instance of ResultReceiver because all its fields are private.
- private ResultReceiver writeToParcel(final ResultReceiver receiver) {
- Parcel parcel = Parcel.obtain();
- receiver.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel);
- parcel.recycle();
- return receiverForSending;
- }
-
- /**
- * Update the last entitlement value to internal cache
- *
- * @param type tethering type from TetheringManager.TETHERING_{@code *}
- * @param resultCode last entitlement value
- * @return the last updated entitlement value
- */
- private int updateEntitlementCacheValue(int type, int resultCode) {
- if (DBG) {
- mLog.i("updateEntitlementCacheValue: " + type + ", result: " + resultCode);
- }
- if (resultCode == TETHER_ERROR_NO_ERROR) {
- mEntitlementCacheValue.put(type, resultCode);
- return resultCode;
- } else {
- mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISIONING_FAILED);
- return TETHER_ERROR_PROVISIONING_FAILED;
- }
- }
-
- /** Get the last value of the tethering entitlement check. */
- public void requestLatestTetheringEntitlementResult(int downstream, ResultReceiver receiver,
- boolean showEntitlementUi) {
- if (!isValidDownstreamType(downstream)) {
- receiver.send(TETHER_ERROR_ENTITLEMENT_UNKNOWN, null);
- return;
- }
-
- final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- if (!isTetherProvisioningRequired(config)) {
- receiver.send(TETHER_ERROR_NO_ERROR, null);
- return;
- }
-
- final int cacheValue = mEntitlementCacheValue.get(
- downstream, TETHER_ERROR_ENTITLEMENT_UNKNOWN);
- if (cacheValue == TETHER_ERROR_NO_ERROR || !showEntitlementUi) {
- receiver.send(cacheValue, null);
- } else {
- ResultReceiver proxy = buildProxyReceiver(downstream, false/* notifyFail */, receiver);
- runUiTetherProvisioning(downstream, config, proxy);
- }
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/IPv6TetheringCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/IPv6TetheringCoordinator.java
deleted file mode 100644
index f3dcaa2..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/IPv6TetheringCoordinator.java
+++ /dev/null
@@ -1,328 +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 com.android.networkstack.tethering;
-
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.RouteInfo;
-import android.net.ip.IpServer;
-import android.net.util.NetworkConstants;
-import android.net.util.SharedLog;
-import android.util.Log;
-
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.Random;
-
-
-/**
- * IPv6 tethering is rather different from IPv4 owing to the absence of NAT.
- * This coordinator is responsible for evaluating the dedicated prefixes
- * assigned to the device and deciding how to divvy them up among downstream
- * interfaces.
- *
- * @hide
- */
-public class IPv6TetheringCoordinator {
- private static final String TAG = IPv6TetheringCoordinator.class.getSimpleName();
- private static final boolean DBG = false;
- private static final boolean VDBG = false;
-
- private static class Downstream {
- public final IpServer ipServer;
- public final int mode; // IpServer.STATE_*
- // Used to append to a ULA /48, constructing a ULA /64 for local use.
- public final short subnetId;
-
- Downstream(IpServer ipServer, int mode, short subnetId) {
- this.ipServer = ipServer;
- this.mode = mode;
- this.subnetId = subnetId;
- }
- }
-
- private final ArrayList<IpServer> mNotifyList;
- private final SharedLog mLog;
- // NOTE: mActiveDownstreams is a list and not a hash data structure because
- // we keep active downstreams in arrival order. This is done so /64s can
- // be parceled out on a "first come, first served" basis and a /64 used by
- // a downstream that is no longer active can be redistributed to any next
- // waiting active downstream (again, in arrival order).
- private final LinkedList<Downstream> mActiveDownstreams;
- private final byte[] mUniqueLocalPrefix;
- private short mNextSubnetId;
- private UpstreamNetworkState mUpstreamNetworkState;
-
- public IPv6TetheringCoordinator(ArrayList<IpServer> notifyList, SharedLog log) {
- mNotifyList = notifyList;
- mLog = log.forSubComponent(TAG);
- mActiveDownstreams = new LinkedList<>();
- mUniqueLocalPrefix = generateUniqueLocalPrefix();
- mNextSubnetId = 0;
- }
-
- /** Add active downstream to ipv6 tethering candidate list. */
- public void addActiveDownstream(IpServer downstream, int mode) {
- if (findDownstream(downstream) == null) {
- // Adding a new downstream appends it to the list. Adding a
- // downstream a second time without first removing it has no effect.
- // We never change the mode of a downstream except by first removing
- // it and then re-adding it (with its new mode specified);
- if (mActiveDownstreams.offer(new Downstream(downstream, mode, mNextSubnetId))) {
- // Make sure subnet IDs are always positive. They are appended
- // to a ULA /48 to make a ULA /64 for local use.
- mNextSubnetId = (short) Math.max(0, mNextSubnetId + 1);
- }
- updateIPv6TetheringInterfaces();
- }
- }
-
- /** Remove downstream from ipv6 tethering candidate list. */
- public void removeActiveDownstream(IpServer downstream) {
- stopIPv6TetheringOn(downstream);
- if (mActiveDownstreams.remove(findDownstream(downstream))) {
- updateIPv6TetheringInterfaces();
- }
-
- // When tethering is stopping we can reset the subnet counter.
- if (mNotifyList.isEmpty()) {
- if (!mActiveDownstreams.isEmpty()) {
- Log.wtf(TAG, "Tethering notify list empty, IPv6 downstreams non-empty.");
- }
- mNextSubnetId = 0;
- }
- }
-
- /**
- * Call when UpstreamNetworkState may be changed.
- * If upstream has ipv6 for tethering, update this new UpstreamNetworkState
- * to IpServer. Otherwise stop ipv6 tethering on downstream interfaces.
- */
- public void updateUpstreamNetworkState(UpstreamNetworkState ns) {
- if (VDBG) {
- Log.d(TAG, "updateUpstreamNetworkState: " + toDebugString(ns));
- }
- if (TetheringInterfaceUtils.getIPv6Interface(ns) == null) {
- stopIPv6TetheringOnAllInterfaces();
- setUpstreamNetworkState(null);
- return;
- }
-
- if (mUpstreamNetworkState != null
- && !ns.network.equals(mUpstreamNetworkState.network)) {
- stopIPv6TetheringOnAllInterfaces();
- }
-
- setUpstreamNetworkState(ns);
- updateIPv6TetheringInterfaces();
- }
-
- private void stopIPv6TetheringOnAllInterfaces() {
- for (IpServer ipServer : mNotifyList) {
- stopIPv6TetheringOn(ipServer);
- }
- }
-
- private void setUpstreamNetworkState(UpstreamNetworkState ns) {
- if (ns == null) {
- mUpstreamNetworkState = null;
- } else {
- // Make a deep copy of the parts we need.
- mUpstreamNetworkState = new UpstreamNetworkState(
- new LinkProperties(ns.linkProperties),
- new NetworkCapabilities(ns.networkCapabilities),
- new Network(ns.network));
- }
-
- mLog.log("setUpstreamNetworkState: " + toDebugString(mUpstreamNetworkState));
- }
-
- private void updateIPv6TetheringInterfaces() {
- for (IpServer ipServer : mNotifyList) {
- final LinkProperties lp = getInterfaceIPv6LinkProperties(ipServer);
- ipServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, getTtlAdjustment(), 0, lp);
- break;
- }
- }
-
- private int getTtlAdjustment() {
- if (mUpstreamNetworkState == null || mUpstreamNetworkState.networkCapabilities == null) {
- return 0;
- }
-
- // If upstream is cellular, set the TTL in Router Advertisements to "network-set TTL" - 1
- // for carrier requirement.
- if (mUpstreamNetworkState.networkCapabilities.hasTransport(
- NetworkCapabilities.TRANSPORT_CELLULAR)) {
- return -1;
- }
-
- // For other non-cellular upstream, set TTL as "network-set TTL" + 1 to preventing arbitrary
- // distinction between tethered and untethered traffic.
- return 1;
- }
-
- private LinkProperties getInterfaceIPv6LinkProperties(IpServer ipServer) {
- final Downstream ds = findDownstream(ipServer);
- if (ds == null) return null;
-
- if (ds.mode == IpServer.STATE_LOCAL_ONLY) {
- // Build a Unique Locally-assigned Prefix configuration.
- return getUniqueLocalConfig(mUniqueLocalPrefix, ds.subnetId);
- }
-
- // This downstream is in IpServer.STATE_TETHERED mode.
- if (mUpstreamNetworkState == null || mUpstreamNetworkState.linkProperties == null) {
- return null;
- }
-
- // NOTE: Here, in future, we would have policies to decide how to divvy
- // up the available dedicated prefixes among downstream interfaces.
- // At this time we have no such mechanism--we only support tethering
- // IPv6 toward the oldest (first requested) active downstream.
-
- final Downstream currentActive = mActiveDownstreams.peek();
- if (currentActive != null && currentActive.ipServer == ipServer) {
- final LinkProperties lp = getIPv6OnlyLinkProperties(
- mUpstreamNetworkState.linkProperties);
- if (lp.hasIpv6DefaultRoute() && lp.hasGlobalIpv6Address()) {
- return lp;
- }
- }
-
- return null;
- }
-
- Downstream findDownstream(IpServer ipServer) {
- for (Downstream ds : mActiveDownstreams) {
- if (ds.ipServer == ipServer) return ds;
- }
- return null;
- }
-
- private static LinkProperties getIPv6OnlyLinkProperties(LinkProperties lp) {
- final LinkProperties v6only = new LinkProperties();
- if (lp == null) {
- return v6only;
- }
-
- // NOTE: At this time we don't copy over any information about any
- // stacked links. No current stacked link configuration has IPv6.
-
- v6only.setInterfaceName(lp.getInterfaceName());
-
- v6only.setMtu(lp.getMtu());
-
- for (LinkAddress linkAddr : lp.getLinkAddresses()) {
- if (linkAddr.isGlobalPreferred() && linkAddr.getPrefixLength() == 64) {
- v6only.addLinkAddress(linkAddr);
- }
- }
-
- for (RouteInfo routeInfo : lp.getRoutes()) {
- final IpPrefix destination = routeInfo.getDestination();
- if ((destination.getAddress() instanceof Inet6Address)
- && (destination.getPrefixLength() <= 64)) {
- v6only.addRoute(routeInfo);
- }
- }
-
- for (InetAddress dnsServer : lp.getDnsServers()) {
- if (isIPv6GlobalAddress(dnsServer)) {
- // For now we include ULAs.
- v6only.addDnsServer(dnsServer);
- }
- }
-
- v6only.setDomains(lp.getDomains());
-
- return v6only;
- }
-
- // TODO: Delete this and switch to LinkAddress#isGlobalPreferred once we
- // announce our own IPv6 address as DNS server.
- private static boolean isIPv6GlobalAddress(InetAddress ip) {
- return (ip instanceof Inet6Address)
- && !ip.isAnyLocalAddress()
- && !ip.isLoopbackAddress()
- && !ip.isLinkLocalAddress()
- && !ip.isSiteLocalAddress()
- && !ip.isMulticastAddress();
- }
-
- private static LinkProperties getUniqueLocalConfig(byte[] ulp, short subnetId) {
- final LinkProperties lp = new LinkProperties();
-
- final IpPrefix local48 = makeUniqueLocalPrefix(ulp, (short) 0, 48);
- lp.addRoute(new RouteInfo(local48, null, null, RouteInfo.RTN_UNICAST));
-
- final IpPrefix local64 = makeUniqueLocalPrefix(ulp, subnetId, 64);
- // Because this is a locally-generated ULA, we don't have an upstream
- // address. But because the downstream IP address management code gets
- // its prefix from the upstream's IP address, we create a fake one here.
- lp.addLinkAddress(new LinkAddress(local64.getAddress(), 64));
-
- lp.setMtu(NetworkConstants.ETHER_MTU);
- return lp;
- }
-
- private static IpPrefix makeUniqueLocalPrefix(byte[] in6addr, short subnetId, int prefixlen) {
- final byte[] bytes = Arrays.copyOf(in6addr, in6addr.length);
- bytes[7] = (byte) (subnetId >> 8);
- bytes[8] = (byte) subnetId;
- final InetAddress addr;
- try {
- addr = InetAddress.getByAddress(bytes);
- } catch (UnknownHostException e) {
- throw new IllegalStateException("Invalid address length: " + bytes.length, e);
- }
- return new IpPrefix(addr, prefixlen);
- }
-
- // Generates a Unique Locally-assigned Prefix:
- //
- // https://tools.ietf.org/html/rfc4193#section-3.1
- //
- // The result is a /48 that can be used for local-only communications.
- private static byte[] generateUniqueLocalPrefix() {
- final byte[] ulp = new byte[6]; // 6 = 48bits / 8bits/byte
- (new Random()).nextBytes(ulp);
-
- final byte[] in6addr = Arrays.copyOf(ulp, NetworkConstants.IPV6_ADDR_LEN);
- in6addr[0] = (byte) 0xfd; // fc00::/7 and L=1
-
- return in6addr;
- }
-
- private static String toDebugString(UpstreamNetworkState ns) {
- if (ns == null) {
- return "UpstreamNetworkState{null}";
- }
- return ns.toString();
- }
-
- private static void stopIPv6TetheringOn(IpServer ipServer) {
- ipServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java
deleted file mode 100644
index 88c77b0..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java
+++ /dev/null
@@ -1,811 +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.networkstack.tethering;
-
-import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
-import static android.net.NetworkStats.METERED_NO;
-import static android.net.NetworkStats.ROAMING_NO;
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-import static android.net.NetworkStats.UID_TETHERING;
-import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
-import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
-
-import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.usage.NetworkStatsManager;
-import android.content.ContentResolver;
-import android.net.InetAddresses;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkStats;
-import android.net.NetworkStats.Entry;
-import android.net.RouteInfo;
-import android.net.netlink.ConntrackMessage;
-import android.net.netlink.NetlinkConstants;
-import android.net.netlink.NetlinkSocket;
-import android.net.netstats.provider.NetworkStatsProvider;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.provider.Settings;
-import android.system.ErrnoException;
-import android.system.OsConstants;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * A class to encapsulate the business logic of programming the tethering
- * hardware offload interface.
- *
- * @hide
- */
-public class OffloadController {
- private static final String TAG = OffloadController.class.getSimpleName();
- private static final boolean DBG = false;
- private static final String ANYIP = "0.0.0.0";
- private static final ForwardedStats EMPTY_STATS = new ForwardedStats();
-
- @VisibleForTesting
- enum StatsType {
- STATS_PER_IFACE,
- STATS_PER_UID,
- }
-
- private enum UpdateType { IF_NEEDED, FORCE };
-
- private final Handler mHandler;
- private final OffloadHardwareInterface mHwInterface;
- private final ContentResolver mContentResolver;
- @Nullable
- private final OffloadTetheringStatsProvider mStatsProvider;
- private final SharedLog mLog;
- private final HashMap<String, LinkProperties> mDownstreams;
- private boolean mConfigInitialized;
- private boolean mControlInitialized;
- private LinkProperties mUpstreamLinkProperties;
- // The complete set of offload-exempt prefixes passed in via Tethering from
- // all upstream and downstream sources.
- private Set<IpPrefix> mExemptPrefixes;
- // A strictly "smaller" set of prefixes, wherein offload-approved prefixes
- // (e.g. downstream on-link prefixes) have been removed and replaced with
- // prefixes representing only the locally-assigned IP addresses.
- private Set<String> mLastLocalPrefixStrs;
-
- // Maps upstream interface names to offloaded traffic statistics.
- // Always contains the latest value received from the hardware for each interface, regardless of
- // whether offload is currently running on that interface.
- private ConcurrentHashMap<String, ForwardedStats> mForwardedStats =
- new ConcurrentHashMap<>(16, 0.75F, 1);
-
- // Maps upstream interface names to interface quotas.
- // Always contains the latest value received from the framework for each interface, regardless
- // of whether offload is currently running (or is even supported) on that interface. Only
- // includes upstream interfaces that have a quota set.
- private HashMap<String, Long> mInterfaceQuotas = new HashMap<>();
-
- // Tracking remaining alert quota. Unlike limit quota is subject to interface, the alert
- // quota is interface independent and global for tether offload. Note that this is only
- // accessed on the handler thread and in the constructor.
- private long mRemainingAlertQuota = QUOTA_UNLIMITED;
- // Runnable that used to schedule the next stats poll.
- private final Runnable mScheduledPollingTask = () -> {
- updateStatsForCurrentUpstream();
- maybeSchedulePollingStats();
- };
-
- private int mNatUpdateCallbacksReceived;
- private int mNatUpdateNetlinkErrors;
-
- @NonNull
- private final Dependencies mDeps;
-
- // TODO: Put more parameters in constructor into dependency object.
- interface Dependencies {
- @NonNull
- TetheringConfiguration getTetherConfig();
- }
-
- public OffloadController(Handler h, OffloadHardwareInterface hwi,
- ContentResolver contentResolver, NetworkStatsManager nsm, SharedLog log,
- @NonNull Dependencies deps) {
- mHandler = h;
- mHwInterface = hwi;
- mContentResolver = contentResolver;
- mLog = log.forSubComponent(TAG);
- mDownstreams = new HashMap<>();
- mExemptPrefixes = new HashSet<>();
- mLastLocalPrefixStrs = new HashSet<>();
- OffloadTetheringStatsProvider provider = new OffloadTetheringStatsProvider();
- try {
- nsm.registerNetworkStatsProvider(getClass().getSimpleName(), provider);
- } catch (RuntimeException e) {
- Log.wtf(TAG, "Cannot register offload stats provider: " + e);
- provider = null;
- }
- mStatsProvider = provider;
- mDeps = deps;
- }
-
- /** Start hardware offload. */
- public boolean start() {
- if (started()) return true;
-
- if (isOffloadDisabled()) {
- mLog.i("tethering offload disabled");
- return false;
- }
-
- if (!mConfigInitialized) {
- mConfigInitialized = mHwInterface.initOffloadConfig();
- if (!mConfigInitialized) {
- mLog.i("tethering offload config not supported");
- stop();
- return false;
- }
- }
-
- mControlInitialized = mHwInterface.initOffloadControl(
- // OffloadHardwareInterface guarantees that these callback
- // methods are called on the handler passed to it, which is the
- // same as mHandler, as coordinated by the setup in Tethering.
- new OffloadHardwareInterface.ControlCallback() {
- @Override
- public void onStarted() {
- if (!started()) return;
- mLog.log("onStarted");
- }
-
- @Override
- public void onStoppedError() {
- if (!started()) return;
- mLog.log("onStoppedError");
- }
-
- @Override
- public void onStoppedUnsupported() {
- if (!started()) return;
- mLog.log("onStoppedUnsupported");
- // Poll for statistics and trigger a sweep of tethering
- // stats by observers. This might not succeed, but it's
- // worth trying anyway. We need to do this because from
- // this point on we continue with software forwarding,
- // and we need to synchronize stats and limits between
- // software and hardware forwarding.
- updateStatsForAllUpstreams();
- if (mStatsProvider != null) mStatsProvider.pushTetherStats();
- }
-
- @Override
- public void onSupportAvailable() {
- if (!started()) return;
- mLog.log("onSupportAvailable");
-
- // [1] Poll for statistics and trigger a sweep of stats
- // by observers. We need to do this to ensure that any
- // limits set take into account any software tethering
- // traffic that has been happening in the meantime.
- updateStatsForAllUpstreams();
- if (mStatsProvider != null) mStatsProvider.pushTetherStats();
- // [2] (Re)Push all state.
- computeAndPushLocalPrefixes(UpdateType.FORCE);
- pushAllDownstreamState();
- pushUpstreamParameters(null);
- }
-
- @Override
- public void onStoppedLimitReached() {
- if (!started()) return;
- mLog.log("onStoppedLimitReached");
-
- // We cannot reliably determine on which interface the limit was reached,
- // because the HAL interface does not specify it. We cannot just use the
- // current upstream, because that might have changed since the time that
- // the HAL queued the callback.
- // TODO: rev the HAL so that it provides an interface name.
-
- updateStatsForCurrentUpstream();
- if (mStatsProvider != null) {
- mStatsProvider.pushTetherStats();
- // Push stats to service does not cause the service react to it
- // immediately. Inform the service about limit reached.
- mStatsProvider.notifyLimitReached();
- }
- }
-
- @Override
- public void onNatTimeoutUpdate(int proto,
- String srcAddr, int srcPort,
- String dstAddr, int dstPort) {
- if (!started()) return;
- updateNatTimeout(proto, srcAddr, srcPort, dstAddr, dstPort);
- }
- });
-
- final boolean isStarted = started();
- if (!isStarted) {
- mLog.i("tethering offload control not supported");
- stop();
- } else {
- mLog.log("tethering offload started");
- mNatUpdateCallbacksReceived = 0;
- mNatUpdateNetlinkErrors = 0;
- maybeSchedulePollingStats();
- }
- return isStarted;
- }
-
- /** Stop hardware offload. */
- public void stop() {
- // Completely stops tethering offload. After this method is called, it is no longer safe to
- // call any HAL method, no callbacks from the hardware will be delivered, and any in-flight
- // callbacks must be ignored. Offload may be started again by calling start().
- final boolean wasStarted = started();
- updateStatsForCurrentUpstream();
- mUpstreamLinkProperties = null;
- mHwInterface.stopOffloadControl();
- mControlInitialized = false;
- mConfigInitialized = false;
- if (mHandler.hasCallbacks(mScheduledPollingTask)) {
- mHandler.removeCallbacks(mScheduledPollingTask);
- }
- if (wasStarted) mLog.log("tethering offload stopped");
- }
-
- private boolean started() {
- return mConfigInitialized && mControlInitialized;
- }
-
- @VisibleForTesting
- class OffloadTetheringStatsProvider extends NetworkStatsProvider {
- // These stats must only ever be touched on the handler thread.
- @NonNull
- private NetworkStats mIfaceStats = new NetworkStats(0L, 0);
- @NonNull
- private NetworkStats mUidStats = new NetworkStats(0L, 0);
-
- /**
- * A helper function that collect tether stats from local hashmap. Note that this does not
- * invoke binder call.
- */
- @VisibleForTesting
- @NonNull
- NetworkStats getTetherStats(@NonNull StatsType how) {
- NetworkStats stats = new NetworkStats(0L, 0);
- final int uid = (how == StatsType.STATS_PER_UID) ? UID_TETHERING : UID_ALL;
-
- for (final Map.Entry<String, ForwardedStats> kv : mForwardedStats.entrySet()) {
- final ForwardedStats value = kv.getValue();
- final Entry entry = new Entry(kv.getKey(), uid, SET_DEFAULT, TAG_NONE, METERED_NO,
- ROAMING_NO, DEFAULT_NETWORK_NO, value.rxBytes, 0L, value.txBytes, 0L, 0L);
- stats = stats.addEntry(entry);
- }
-
- return stats;
- }
-
- @Override
- public void onSetLimit(String iface, long quotaBytes) {
- // Listen for all iface is necessary since upstream might be changed after limit
- // is set.
- mHandler.post(() -> {
- final Long curIfaceQuota = mInterfaceQuotas.get(iface);
-
- // If the quota is set to unlimited, the value set to HAL is Long.MAX_VALUE,
- // which is ~8.4 x 10^6 TiB, no one can actually reach it. Thus, it is not
- // useful to set it multiple times.
- // Otherwise, the quota needs to be updated to tell HAL to re-count from now even
- // if the quota is the same as the existing one.
- if (null == curIfaceQuota && QUOTA_UNLIMITED == quotaBytes) return;
-
- if (quotaBytes == QUOTA_UNLIMITED) {
- mInterfaceQuotas.remove(iface);
- } else {
- mInterfaceQuotas.put(iface, quotaBytes);
- }
- maybeUpdateDataLimit(iface);
- });
- }
-
- /**
- * Push stats to service, but does not cause a force polling. Note that this can only be
- * called on the handler thread.
- */
- public void pushTetherStats() {
- // TODO: remove the accumulated stats and report the diff from HAL directly.
- final NetworkStats ifaceDiff =
- getTetherStats(StatsType.STATS_PER_IFACE).subtract(mIfaceStats);
- final NetworkStats uidDiff =
- getTetherStats(StatsType.STATS_PER_UID).subtract(mUidStats);
- try {
- notifyStatsUpdated(0 /* token */, ifaceDiff, uidDiff);
- mIfaceStats = mIfaceStats.add(ifaceDiff);
- mUidStats = mUidStats.add(uidDiff);
- } catch (RuntimeException e) {
- mLog.e("Cannot report network stats: ", e);
- }
- }
-
- @Override
- public void onRequestStatsUpdate(int token) {
- // Do not attempt to update stats by querying the offload HAL
- // synchronously from a different thread than the Handler thread. http://b/64771555.
- mHandler.post(() -> {
- updateStatsForCurrentUpstream();
- pushTetherStats();
- });
- }
-
- @Override
- public void onSetAlert(long quotaBytes) {
- // TODO: Ask offload HAL to notify alert without stopping traffic.
- // Post it to handler thread since it access remaining quota bytes.
- mHandler.post(() -> {
- updateAlertQuota(quotaBytes);
- maybeSchedulePollingStats();
- });
- }
- }
-
- private String currentUpstreamInterface() {
- return (mUpstreamLinkProperties != null)
- ? mUpstreamLinkProperties.getInterfaceName() : null;
- }
-
- private void maybeUpdateStats(String iface) {
- if (TextUtils.isEmpty(iface)) {
- return;
- }
-
- // Always called on the handler thread.
- //
- // Use get()/put() instead of updating ForwardedStats in place because we can be called
- // concurrently with getTetherStats. In combination with the guarantees provided by
- // ConcurrentHashMap, this ensures that getTetherStats always gets the most recent copy of
- // the stats for each interface, and does not observe partial writes where rxBytes is
- // updated and txBytes is not.
- ForwardedStats diff = mHwInterface.getForwardedStats(iface);
- final long usedAlertQuota = diff.rxBytes + diff.txBytes;
- ForwardedStats base = mForwardedStats.get(iface);
- if (base != null) {
- diff.add(base);
- }
-
- // Update remaining alert quota if it is still positive.
- if (mRemainingAlertQuota > 0 && usedAlertQuota > 0) {
- // Trim to zero if overshoot.
- final long newQuota = Math.max(mRemainingAlertQuota - usedAlertQuota, 0);
- updateAlertQuota(newQuota);
- }
-
- mForwardedStats.put(iface, diff);
- // diff is a new object, just created by getForwardedStats(). Therefore, anyone reading from
- // mForwardedStats (i.e., any caller of getTetherStats) will see the new stats immediately.
- }
-
- /**
- * Update remaining alert quota, fire the {@link NetworkStatsProvider#notifyAlertReached()}
- * callback when it reaches zero. This can be invoked either from service setting the alert, or
- * {@code maybeUpdateStats} when updating stats. Note that this can be only called on
- * handler thread.
- *
- * @param newQuota non-negative value to indicate the new quota, or
- * {@link NetworkStatsProvider#QUOTA_UNLIMITED} to indicate there is no
- * quota.
- */
- private void updateAlertQuota(long newQuota) {
- if (newQuota < QUOTA_UNLIMITED) {
- throw new IllegalArgumentException("invalid quota value " + newQuota);
- }
- if (mRemainingAlertQuota == newQuota) return;
-
- mRemainingAlertQuota = newQuota;
- if (mRemainingAlertQuota == 0) {
- mLog.i("notifyAlertReached");
- if (mStatsProvider != null) mStatsProvider.notifyAlertReached();
- }
- }
-
- /**
- * Schedule polling if needed, this will be stopped if offload has been
- * stopped or remaining quota reaches zero or upstream is empty.
- * Note that this can be only called on handler thread.
- */
- private void maybeSchedulePollingStats() {
- if (!isPollingStatsNeeded()) return;
-
- if (mHandler.hasCallbacks(mScheduledPollingTask)) {
- mHandler.removeCallbacks(mScheduledPollingTask);
- }
- mHandler.postDelayed(mScheduledPollingTask,
- mDeps.getTetherConfig().getOffloadPollInterval());
- }
-
- private boolean isPollingStatsNeeded() {
- return started() && mRemainingAlertQuota > 0
- && !TextUtils.isEmpty(currentUpstreamInterface())
- && mDeps.getTetherConfig() != null
- && mDeps.getTetherConfig().getOffloadPollInterval()
- >= DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
- }
-
- private boolean maybeUpdateDataLimit(String iface) {
- // setDataLimit may only be called while offload is occurring on this upstream.
- if (!started() || !TextUtils.equals(iface, currentUpstreamInterface())) {
- return true;
- }
-
- Long limit = mInterfaceQuotas.get(iface);
- if (limit == null) {
- limit = Long.MAX_VALUE;
- }
-
- return mHwInterface.setDataLimit(iface, limit);
- }
-
- private void updateStatsForCurrentUpstream() {
- maybeUpdateStats(currentUpstreamInterface());
- }
-
- private void updateStatsForAllUpstreams() {
- // In practice, there should only ever be a single digit number of
- // upstream interfaces over the lifetime of an active tethering session.
- // Roughly speaking, imagine a very ambitious one or two of each of the
- // following interface types: [ "rmnet_data", "wlan", "eth", "rndis" ].
- for (Map.Entry<String, ForwardedStats> kv : mForwardedStats.entrySet()) {
- maybeUpdateStats(kv.getKey());
- }
- }
-
- /** Set current tethering upstream LinkProperties. */
- public void setUpstreamLinkProperties(LinkProperties lp) {
- if (!started() || Objects.equals(mUpstreamLinkProperties, lp)) return;
-
- final String prevUpstream = currentUpstreamInterface();
-
- mUpstreamLinkProperties = (lp != null) ? new LinkProperties(lp) : null;
- // Make sure we record this interface in the ForwardedStats map.
- final String iface = currentUpstreamInterface();
- if (!TextUtils.isEmpty(iface)) mForwardedStats.putIfAbsent(iface, EMPTY_STATS);
-
- maybeSchedulePollingStats();
-
- // TODO: examine return code and decide what to do if programming
- // upstream parameters fails (probably just wait for a subsequent
- // onOffloadEvent() callback to tell us offload is available again and
- // then reapply all state).
- computeAndPushLocalPrefixes(UpdateType.IF_NEEDED);
- pushUpstreamParameters(prevUpstream);
- }
-
- /** Set local prefixes. */
- public void setLocalPrefixes(Set<IpPrefix> localPrefixes) {
- mExemptPrefixes = localPrefixes;
-
- if (!started()) return;
- computeAndPushLocalPrefixes(UpdateType.IF_NEEDED);
- }
-
- /** Update current downstream LinkProperties. */
- public void notifyDownstreamLinkProperties(LinkProperties lp) {
- final String ifname = lp.getInterfaceName();
- final LinkProperties oldLp = mDownstreams.put(ifname, new LinkProperties(lp));
- if (Objects.equals(oldLp, lp)) return;
-
- if (!started()) return;
- pushDownstreamState(oldLp, lp);
- }
-
- private void pushDownstreamState(LinkProperties oldLp, LinkProperties newLp) {
- final String ifname = newLp.getInterfaceName();
- final List<RouteInfo> oldRoutes =
- (oldLp != null) ? oldLp.getRoutes() : Collections.EMPTY_LIST;
- final List<RouteInfo> newRoutes = newLp.getRoutes();
-
- // For each old route, if not in new routes: remove.
- for (RouteInfo ri : oldRoutes) {
- if (shouldIgnoreDownstreamRoute(ri)) continue;
- if (!newRoutes.contains(ri)) {
- mHwInterface.removeDownstreamPrefix(ifname, ri.getDestination().toString());
- }
- }
-
- // For each new route, if not in old routes: add.
- for (RouteInfo ri : newRoutes) {
- if (shouldIgnoreDownstreamRoute(ri)) continue;
- if (!oldRoutes.contains(ri)) {
- mHwInterface.addDownstreamPrefix(ifname, ri.getDestination().toString());
- }
- }
- }
-
- private void pushAllDownstreamState() {
- for (LinkProperties lp : mDownstreams.values()) {
- pushDownstreamState(null, lp);
- }
- }
-
- /** Remove downstream interface from offload hardware. */
- public void removeDownstreamInterface(String ifname) {
- final LinkProperties lp = mDownstreams.remove(ifname);
- if (lp == null) return;
-
- if (!started()) return;
-
- for (RouteInfo route : lp.getRoutes()) {
- if (shouldIgnoreDownstreamRoute(route)) continue;
- mHwInterface.removeDownstreamPrefix(ifname, route.getDestination().toString());
- }
- }
-
- private boolean isOffloadDisabled() {
- final int defaultDisposition = mHwInterface.getDefaultTetherOffloadDisabled();
- return (Settings.Global.getInt(
- mContentResolver, TETHER_OFFLOAD_DISABLED, defaultDisposition) != 0);
- }
-
- private boolean pushUpstreamParameters(String prevUpstream) {
- final String iface = currentUpstreamInterface();
-
- if (TextUtils.isEmpty(iface)) {
- final boolean rval = mHwInterface.setUpstreamParameters("", ANYIP, ANYIP, null);
- // Update stats after we've told the hardware to stop forwarding so
- // we don't miss packets.
- maybeUpdateStats(prevUpstream);
- return rval;
- }
-
- // A stacked interface cannot be an upstream for hardware offload.
- // Consequently, we examine only the primary interface name, look at
- // getAddresses() rather than getAllAddresses(), and check getRoutes()
- // rather than getAllRoutes().
- final ArrayList<String> v6gateways = new ArrayList<>();
- String v4addr = null;
- String v4gateway = null;
-
- for (InetAddress ip : mUpstreamLinkProperties.getAddresses()) {
- if (ip instanceof Inet4Address) {
- v4addr = ip.getHostAddress();
- break;
- }
- }
-
- // Find the gateway addresses of all default routes of either address family.
- for (RouteInfo ri : mUpstreamLinkProperties.getRoutes()) {
- if (!ri.hasGateway()) continue;
-
- final String gateway = ri.getGateway().getHostAddress();
- final InetAddress address = ri.getDestination().getAddress();
- if (ri.isDefaultRoute() && address instanceof Inet4Address) {
- v4gateway = gateway;
- } else if (ri.isDefaultRoute() && address instanceof Inet6Address) {
- v6gateways.add(gateway);
- }
- }
-
- boolean success = mHwInterface.setUpstreamParameters(
- iface, v4addr, v4gateway, (v6gateways.isEmpty() ? null : v6gateways));
-
- if (!success) {
- return success;
- }
-
- // Update stats after we've told the hardware to change routing so we don't miss packets.
- maybeUpdateStats(prevUpstream);
-
- // Data limits can only be set once offload is running on the upstream.
- success = maybeUpdateDataLimit(iface);
- if (!success) {
- // If we failed to set a data limit, don't use this upstream, because we don't want to
- // blow through the data limit that we were told to apply.
- mLog.log("Setting data limit for " + iface + " failed, disabling offload.");
- stop();
- }
-
- return success;
- }
-
- private boolean computeAndPushLocalPrefixes(UpdateType how) {
- final boolean force = (how == UpdateType.FORCE);
- final Set<String> localPrefixStrs = computeLocalPrefixStrings(
- mExemptPrefixes, mUpstreamLinkProperties);
- if (!force && mLastLocalPrefixStrs.equals(localPrefixStrs)) return true;
-
- mLastLocalPrefixStrs = localPrefixStrs;
- return mHwInterface.setLocalPrefixes(new ArrayList<>(localPrefixStrs));
- }
-
- // TODO: Factor in downstream LinkProperties once that information is available.
- private static Set<String> computeLocalPrefixStrings(
- Set<IpPrefix> localPrefixes, LinkProperties upstreamLinkProperties) {
- // Create an editable copy.
- final Set<IpPrefix> prefixSet = new HashSet<>(localPrefixes);
-
- // TODO: If a downstream interface (not currently passed in) is reusing
- // the /64 of the upstream (64share) then:
- //
- // [a] remove that /64 from the local prefixes
- // [b] add in /128s for IP addresses on the downstream interface
- // [c] add in /128s for IP addresses on the upstream interface
- //
- // Until downstream information is available here, simply add /128s from
- // the upstream network; they'll just be redundant with their /64.
- if (upstreamLinkProperties != null) {
- for (LinkAddress linkAddr : upstreamLinkProperties.getLinkAddresses()) {
- if (!linkAddr.isGlobalPreferred()) continue;
- final InetAddress ip = linkAddr.getAddress();
- if (!(ip instanceof Inet6Address)) continue;
- prefixSet.add(new IpPrefix(ip, 128));
- }
- }
-
- final HashSet<String> localPrefixStrs = new HashSet<>();
- for (IpPrefix pfx : prefixSet) localPrefixStrs.add(pfx.toString());
- return localPrefixStrs;
- }
-
- private static boolean shouldIgnoreDownstreamRoute(RouteInfo route) {
- // Ignore any link-local routes.
- final IpPrefix destination = route.getDestination();
- final LinkAddress linkAddr = new LinkAddress(destination.getAddress(),
- destination.getPrefixLength());
- if (!linkAddr.isGlobalPreferred()) return true;
-
- return false;
- }
-
- /** Dump information. */
- public void dump(IndentingPrintWriter pw) {
- if (isOffloadDisabled()) {
- pw.println("Offload disabled");
- return;
- }
- final boolean isStarted = started();
- pw.println("Offload HALs " + (isStarted ? "started" : "not started"));
- LinkProperties lp = mUpstreamLinkProperties;
- String upstream = (lp != null) ? lp.getInterfaceName() : null;
- pw.println("Current upstream: " + upstream);
- pw.println("Exempt prefixes: " + mLastLocalPrefixStrs);
- pw.println("NAT timeout update callbacks received during the "
- + (isStarted ? "current" : "last")
- + " offload session: "
- + mNatUpdateCallbacksReceived);
- pw.println("NAT timeout update netlink errors during the "
- + (isStarted ? "current" : "last")
- + " offload session: "
- + mNatUpdateNetlinkErrors);
- }
-
- private void updateNatTimeout(
- int proto, String srcAddr, int srcPort, String dstAddr, int dstPort) {
- final String protoName = protoNameFor(proto);
- if (protoName == null) {
- mLog.e("Unknown NAT update callback protocol: " + proto);
- return;
- }
-
- final Inet4Address src = parseIPv4Address(srcAddr);
- if (src == null) {
- mLog.e("Failed to parse IPv4 address: " + srcAddr);
- return;
- }
-
- if (!isValidUdpOrTcpPort(srcPort)) {
- mLog.e("Invalid src port: " + srcPort);
- return;
- }
-
- final Inet4Address dst = parseIPv4Address(dstAddr);
- if (dst == null) {
- mLog.e("Failed to parse IPv4 address: " + dstAddr);
- return;
- }
-
- if (!isValidUdpOrTcpPort(dstPort)) {
- mLog.e("Invalid dst port: " + dstPort);
- return;
- }
-
- mNatUpdateCallbacksReceived++;
- final String natDescription = String.format("%s (%s, %s) -> (%s, %s)",
- protoName, srcAddr, srcPort, dstAddr, dstPort);
- if (DBG) {
- mLog.log("NAT timeout update: " + natDescription);
- }
-
- final int timeoutSec = connectionTimeoutUpdateSecondsFor(proto);
- final byte[] msg = ConntrackMessage.newIPv4TimeoutUpdateRequest(
- proto, src, srcPort, dst, dstPort, timeoutSec);
-
- try {
- NetlinkSocket.sendOneShotKernelMessage(OsConstants.NETLINK_NETFILTER, msg);
- } catch (ErrnoException e) {
- mNatUpdateNetlinkErrors++;
- mLog.e("Error updating NAT conntrack entry >" + natDescription + "<: " + e
- + ", msg: " + NetlinkConstants.hexify(msg));
- mLog.log("NAT timeout update callbacks received: " + mNatUpdateCallbacksReceived);
- mLog.log("NAT timeout update netlink errors: " + mNatUpdateNetlinkErrors);
- }
- }
-
- private static Inet4Address parseIPv4Address(String addrString) {
- try {
- final InetAddress ip = InetAddresses.parseNumericAddress(addrString);
- // TODO: Consider other sanitization steps here, including perhaps:
- // not eql to 0.0.0.0
- // not within 169.254.0.0/16
- // not within ::ffff:0.0.0.0/96
- // not within ::/96
- // et cetera.
- if (ip instanceof Inet4Address) {
- return (Inet4Address) ip;
- }
- } catch (IllegalArgumentException iae) { }
- return null;
- }
-
- private static String protoNameFor(int proto) {
- // OsConstants values are not constant expressions; no switch statement.
- if (proto == OsConstants.IPPROTO_UDP) {
- return "UDP";
- } else if (proto == OsConstants.IPPROTO_TCP) {
- return "TCP";
- }
- return null;
- }
-
- private static int connectionTimeoutUpdateSecondsFor(int proto) {
- // TODO: Replace this with more thoughtful work, perhaps reading from
- // and maybe writing to any required
- //
- // /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_*
- // /proc/sys/net/netfilter/nf_conntrack_udp_timeout{,_stream}
- //
- // entries. TBD.
- if (proto == OsConstants.IPPROTO_TCP) {
- // Cf. /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
- return 432000;
- } else {
- // Cf. /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream
- return 180;
- }
- }
-
- private static boolean isValidUdpOrTcpPort(int port) {
- return port > 0 && port < 65536;
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
deleted file mode 100644
index 33b9d00..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ /dev/null
@@ -1,564 +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.networkstack.tethering;
-
-import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
-import static android.net.util.TetheringUtils.uint16;
-
-import android.annotation.NonNull;
-import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
-import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
-import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
-import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
-import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
-import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
-import android.net.netlink.NetlinkSocket;
-import android.net.netlink.StructNlMsgHdr;
-import android.net.util.SharedLog;
-import android.net.util.SocketUtils;
-import android.os.Handler;
-import android.os.NativeHandle;
-import android.os.RemoteException;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.FileDescriptor;
-import java.io.InterruptedIOException;
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.NoSuchElementException;
-
-
-/**
- * Capture tethering dependencies, for injection.
- *
- * @hide
- */
-public class OffloadHardwareInterface {
- private static final String TAG = OffloadHardwareInterface.class.getSimpleName();
- private static final String YIELDS = " -> ";
- // Change this value to control whether tether offload is enabled or
- // disabled by default in the absence of an explicit Settings value.
- // See accompanying unittest to distinguish 0 from non-0 values.
- private static final int DEFAULT_TETHER_OFFLOAD_DISABLED = 0;
- private static final String NO_INTERFACE_NAME = "";
- private static final String NO_IPV4_ADDRESS = "";
- private static final String NO_IPV4_GATEWAY = "";
- // Reference kernel/uapi/linux/netfilter/nfnetlink_compat.h
- private static final int NF_NETLINK_CONNTRACK_NEW = 1;
- private static final int NF_NETLINK_CONNTRACK_UPDATE = 2;
- private static final int NF_NETLINK_CONNTRACK_DESTROY = 4;
- // Reference libnetfilter_conntrack/linux_nfnetlink_conntrack.h
- public static final short NFNL_SUBSYS_CTNETLINK = 1;
- public static final short IPCTNL_MSG_CT_GET = 1;
-
- private final long NETLINK_MESSAGE_TIMEOUT_MS = 500;
-
- private final Handler mHandler;
- private final SharedLog mLog;
- private final Dependencies mDeps;
- private IOffloadControl mOffloadControl;
- private TetheringOffloadCallback mTetheringOffloadCallback;
- private ControlCallback mControlCallback;
-
- /** The callback to notify status of offload management process. */
- public static class ControlCallback {
- /** Offload started. */
- public void onStarted() {}
- /**
- * Offload stopped because an error has occurred in lower layer.
- */
- public void onStoppedError() {}
- /**
- * Offload stopped because the device has moved to a bearer on which hardware offload is
- * not supported. Subsequent calls to setUpstreamParameters and add/removeDownstream will
- * likely fail and cannot be presumed to be saved inside of the hardware management process.
- * Upon receiving #onSupportAvailable(), the caller should reprogram the hardware to begin
- * offload again.
- */
- public void onStoppedUnsupported() {}
- /** Indicate that offload is able to proivde support for this time. */
- public void onSupportAvailable() {}
- /** Offload stopped because of usage limit reached. */
- public void onStoppedLimitReached() {}
-
- /** Indicate to update NAT timeout. */
- public void onNatTimeoutUpdate(int proto,
- String srcAddr, int srcPort,
- String dstAddr, int dstPort) {}
- }
-
- /** The object which records Tx/Rx forwarded bytes. */
- public static class ForwardedStats {
- public long rxBytes;
- public long txBytes;
-
- public ForwardedStats() {
- rxBytes = 0;
- txBytes = 0;
- }
-
- @VisibleForTesting
- public ForwardedStats(long rxBytes, long txBytes) {
- this.rxBytes = rxBytes;
- this.txBytes = txBytes;
- }
-
- /** Add Tx/Rx bytes. */
- public void add(ForwardedStats other) {
- rxBytes += other.rxBytes;
- txBytes += other.txBytes;
- }
-
- /** Returns the string representation of this object. */
- public String toString() {
- return String.format("rx:%s tx:%s", rxBytes, txBytes);
- }
- }
-
- public OffloadHardwareInterface(Handler h, SharedLog log) {
- this(h, log, new Dependencies(log));
- }
-
- OffloadHardwareInterface(Handler h, SharedLog log, Dependencies deps) {
- mHandler = h;
- mLog = log.forSubComponent(TAG);
- mDeps = deps;
- }
-
- /** Capture OffloadHardwareInterface dependencies, for injection. */
- static class Dependencies {
- private final SharedLog mLog;
-
- Dependencies(SharedLog log) {
- mLog = log;
- }
-
- public IOffloadConfig getOffloadConfig() {
- try {
- return IOffloadConfig.getService(true /*retry*/);
- } catch (RemoteException | NoSuchElementException e) {
- mLog.e("getIOffloadConfig error " + e);
- return null;
- }
- }
-
- public IOffloadControl getOffloadControl() {
- try {
- return IOffloadControl.getService(true /*retry*/);
- } catch (RemoteException | NoSuchElementException e) {
- mLog.e("tethering offload control not supported: " + e);
- return null;
- }
- }
-
- public NativeHandle createConntrackSocket(final int groups) {
- final FileDescriptor fd;
- try {
- fd = NetlinkSocket.forProto(OsConstants.NETLINK_NETFILTER);
- } catch (ErrnoException e) {
- mLog.e("Unable to create conntrack socket " + e);
- return null;
- }
-
- final SocketAddress sockAddr = SocketUtils.makeNetlinkSocketAddress(0, groups);
- try {
- Os.bind(fd, sockAddr);
- } catch (ErrnoException | SocketException e) {
- mLog.e("Unable to bind conntrack socket for groups " + groups + " error: " + e);
- try {
- SocketUtils.closeSocket(fd);
- } catch (IOException ie) {
- // Nothing we can do here
- }
- return null;
- }
- try {
- Os.connect(fd, sockAddr);
- } catch (ErrnoException | SocketException e) {
- mLog.e("connect to kernel fail for groups " + groups + " error: " + e);
- try {
- SocketUtils.closeSocket(fd);
- } catch (IOException ie) {
- // Nothing we can do here
- }
- return null;
- }
-
- return new NativeHandle(fd, true);
- }
- }
-
- /** Get default value indicating whether offload is supported. */
- public int getDefaultTetherOffloadDisabled() {
- return DEFAULT_TETHER_OFFLOAD_DISABLED;
- }
-
- /**
- * Offload management process need to know conntrack rules to support NAT, but it may not have
- * permission to create netlink netfilter sockets. Create two netlink netfilter sockets and
- * share them with offload management process.
- */
- public boolean initOffloadConfig() {
- final IOffloadConfig offloadConfig = mDeps.getOffloadConfig();
- if (offloadConfig == null) {
- mLog.e("Could not find IOffloadConfig service");
- return false;
- }
- // Per the IConfigOffload definition:
- //
- // h1 provides a file descriptor bound to the following netlink groups
- // (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY).
- //
- // h2 provides a file descriptor bound to the following netlink groups
- // (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY).
- final NativeHandle h1 = mDeps.createConntrackSocket(
- NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
- if (h1 == null) return false;
-
- sendNetlinkMessage(h1, (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
- (short) (NLM_F_REQUEST | NLM_F_DUMP));
-
- final NativeHandle h2 = mDeps.createConntrackSocket(
- NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
- if (h2 == null) {
- closeFdInNativeHandle(h1);
- return false;
- }
-
- final CbResults results = new CbResults();
- try {
- offloadConfig.setHandles(h1, h2,
- (boolean success, String errMsg) -> {
- results.mSuccess = success;
- results.mErrMsg = errMsg;
- });
- } catch (RemoteException e) {
- record("initOffloadConfig, setHandles fail", e);
- return false;
- }
- // Explicitly close FDs.
- closeFdInNativeHandle(h1);
- closeFdInNativeHandle(h2);
-
- record("initOffloadConfig, setHandles results:", results);
- return results.mSuccess;
- }
-
- @VisibleForTesting
- public void sendNetlinkMessage(@NonNull NativeHandle handle, short type, short flags) {
- final int length = StructNlMsgHdr.STRUCT_SIZE;
- final byte[] msg = new byte[length];
- final StructNlMsgHdr nlh = new StructNlMsgHdr();
- final ByteBuffer byteBuffer = ByteBuffer.wrap(msg);
- nlh.nlmsg_len = length;
- nlh.nlmsg_type = type;
- nlh.nlmsg_flags = flags;
- nlh.nlmsg_seq = 1;
- nlh.pack(byteBuffer);
- try {
- NetlinkSocket.sendMessage(handle.getFileDescriptor(), msg, 0 /* offset */, length,
- NETLINK_MESSAGE_TIMEOUT_MS);
- } catch (ErrnoException | InterruptedIOException e) {
- mLog.e("Unable to send netfilter message, error: " + e);
- }
- }
-
- private void closeFdInNativeHandle(final NativeHandle h) {
- try {
- h.close();
- } catch (IOException | IllegalStateException e) {
- // IllegalStateException means fd is already closed, do nothing here.
- // Also nothing we can do if IOException.
- }
- }
-
- /** Initialize the tethering offload HAL. */
- public boolean initOffloadControl(ControlCallback controlCb) {
- mControlCallback = controlCb;
-
- if (mOffloadControl == null) {
- mOffloadControl = mDeps.getOffloadControl();
- if (mOffloadControl == null) {
- mLog.e("tethering IOffloadControl.getService() returned null");
- return false;
- }
- }
-
- final String logmsg = String.format("initOffloadControl(%s)",
- (controlCb == null) ? "null"
- : "0x" + Integer.toHexString(System.identityHashCode(controlCb)));
-
- mTetheringOffloadCallback = new TetheringOffloadCallback(mHandler, mControlCallback, mLog);
- final CbResults results = new CbResults();
- try {
- mOffloadControl.initOffload(
- mTetheringOffloadCallback,
- (boolean success, String errMsg) -> {
- results.mSuccess = success;
- results.mErrMsg = errMsg;
- });
- } catch (RemoteException e) {
- record(logmsg, e);
- return false;
- }
-
- record(logmsg, results);
- return results.mSuccess;
- }
-
- /** Stop IOffloadControl. */
- public void stopOffloadControl() {
- if (mOffloadControl != null) {
- try {
- mOffloadControl.stopOffload(
- (boolean success, String errMsg) -> {
- if (!success) mLog.e("stopOffload failed: " + errMsg);
- });
- } catch (RemoteException e) {
- mLog.e("failed to stopOffload: " + e);
- }
- }
- mOffloadControl = null;
- mTetheringOffloadCallback = null;
- mControlCallback = null;
- mLog.log("stopOffloadControl()");
- }
-
- /** Get Tx/Rx usage from last query. */
- public ForwardedStats getForwardedStats(String upstream) {
- final String logmsg = String.format("getForwardedStats(%s)", upstream);
-
- final ForwardedStats stats = new ForwardedStats();
- try {
- mOffloadControl.getForwardedStats(
- upstream,
- (long rxBytes, long txBytes) -> {
- stats.rxBytes = (rxBytes > 0) ? rxBytes : 0;
- stats.txBytes = (txBytes > 0) ? txBytes : 0;
- });
- } catch (RemoteException e) {
- record(logmsg, e);
- return stats;
- }
-
- return stats;
- }
-
- /** Set local prefixes to offload management process. */
- public boolean setLocalPrefixes(ArrayList<String> localPrefixes) {
- final String logmsg = String.format("setLocalPrefixes([%s])",
- String.join(",", localPrefixes));
-
- final CbResults results = new CbResults();
- try {
- mOffloadControl.setLocalPrefixes(localPrefixes,
- (boolean success, String errMsg) -> {
- results.mSuccess = success;
- results.mErrMsg = errMsg;
- });
- } catch (RemoteException e) {
- record(logmsg, e);
- return false;
- }
-
- record(logmsg, results);
- return results.mSuccess;
- }
-
- /** Set data limit value to offload management process. */
- public boolean setDataLimit(String iface, long limit) {
-
- final String logmsg = String.format("setDataLimit(%s, %d)", iface, limit);
-
- final CbResults results = new CbResults();
- try {
- mOffloadControl.setDataLimit(
- iface, limit,
- (boolean success, String errMsg) -> {
- results.mSuccess = success;
- results.mErrMsg = errMsg;
- });
- } catch (RemoteException e) {
- record(logmsg, e);
- return false;
- }
-
- record(logmsg, results);
- return results.mSuccess;
- }
-
- /** Set upstream parameters to offload management process. */
- public boolean setUpstreamParameters(
- String iface, String v4addr, String v4gateway, ArrayList<String> v6gws) {
- iface = (iface != null) ? iface : NO_INTERFACE_NAME;
- v4addr = (v4addr != null) ? v4addr : NO_IPV4_ADDRESS;
- v4gateway = (v4gateway != null) ? v4gateway : NO_IPV4_GATEWAY;
- v6gws = (v6gws != null) ? v6gws : new ArrayList<>();
-
- final String logmsg = String.format("setUpstreamParameters(%s, %s, %s, [%s])",
- iface, v4addr, v4gateway, String.join(",", v6gws));
-
- final CbResults results = new CbResults();
- try {
- mOffloadControl.setUpstreamParameters(
- iface, v4addr, v4gateway, v6gws,
- (boolean success, String errMsg) -> {
- results.mSuccess = success;
- results.mErrMsg = errMsg;
- });
- } catch (RemoteException e) {
- record(logmsg, e);
- return false;
- }
-
- record(logmsg, results);
- return results.mSuccess;
- }
-
- /** Add downstream prefix to offload management process. */
- public boolean addDownstreamPrefix(String ifname, String prefix) {
- final String logmsg = String.format("addDownstreamPrefix(%s, %s)", ifname, prefix);
-
- final CbResults results = new CbResults();
- try {
- mOffloadControl.addDownstream(ifname, prefix,
- (boolean success, String errMsg) -> {
- results.mSuccess = success;
- results.mErrMsg = errMsg;
- });
- } catch (RemoteException e) {
- record(logmsg, e);
- return false;
- }
-
- record(logmsg, results);
- return results.mSuccess;
- }
-
- /** Remove downstream prefix from offload management process. */
- public boolean removeDownstreamPrefix(String ifname, String prefix) {
- final String logmsg = String.format("removeDownstreamPrefix(%s, %s)", ifname, prefix);
-
- final CbResults results = new CbResults();
- try {
- mOffloadControl.removeDownstream(ifname, prefix,
- (boolean success, String errMsg) -> {
- results.mSuccess = success;
- results.mErrMsg = errMsg;
- });
- } catch (RemoteException e) {
- record(logmsg, e);
- return false;
- }
-
- record(logmsg, results);
- return results.mSuccess;
- }
-
- private void record(String msg, Throwable t) {
- mLog.e(msg + YIELDS + "exception: " + t);
- }
-
- private void record(String msg, CbResults results) {
- final String logmsg = msg + YIELDS + results;
- if (!results.mSuccess) {
- mLog.e(logmsg);
- } else {
- mLog.log(logmsg);
- }
- }
-
- private static class TetheringOffloadCallback extends ITetheringOffloadCallback.Stub {
- public final Handler handler;
- public final ControlCallback controlCb;
- public final SharedLog log;
-
- TetheringOffloadCallback(Handler h, ControlCallback cb, SharedLog sharedLog) {
- handler = h;
- controlCb = cb;
- log = sharedLog;
- }
-
- @Override
- public void onEvent(int event) {
- handler.post(() -> {
- switch (event) {
- case OffloadCallbackEvent.OFFLOAD_STARTED:
- controlCb.onStarted();
- break;
- case OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR:
- controlCb.onStoppedError();
- break;
- case OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED:
- controlCb.onStoppedUnsupported();
- break;
- case OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE:
- controlCb.onSupportAvailable();
- break;
- case OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED:
- controlCb.onStoppedLimitReached();
- break;
- default:
- log.e("Unsupported OffloadCallbackEvent: " + event);
- }
- });
- }
-
- @Override
- public void updateTimeout(NatTimeoutUpdate params) {
- handler.post(() -> {
- controlCb.onNatTimeoutUpdate(
- networkProtocolToOsConstant(params.proto),
- params.src.addr, uint16(params.src.port),
- params.dst.addr, uint16(params.dst.port));
- });
- }
- }
-
- private static int networkProtocolToOsConstant(int proto) {
- switch (proto) {
- case NetworkProtocol.TCP: return OsConstants.IPPROTO_TCP;
- case NetworkProtocol.UDP: return OsConstants.IPPROTO_UDP;
- default:
- // The caller checks this value and will log an error. Just make
- // sure it won't collide with valid OsContants.IPPROTO_* values.
- return -Math.abs(proto);
- }
- }
-
- private static class CbResults {
- boolean mSuccess;
- String mErrMsg;
-
- @Override
- public String toString() {
- if (mSuccess) {
- return "ok";
- } else {
- return "fail: " + mErrMsg;
- }
- }
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java
deleted file mode 100644
index 160a166..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java
+++ /dev/null
@@ -1,254 +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.networkstack.tethering;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.ip.IpServer;
-import android.net.util.PrefixUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-
-import androidx.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.IndentingPrintWriter;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-
-/**
- * This class coordinate IP addresses conflict problem.
- *
- * Tethering downstream IP addresses may conflict with network assigned addresses. This
- * coordinator is responsible for recording all of network assigned addresses and dispatched
- * free address to downstream interfaces.
- *
- * This class is not thread-safe and should be accessed on the same tethering internal thread.
- * @hide
- */
-public class PrivateAddressCoordinator {
- public static final int PREFIX_LENGTH = 24;
-
- private static final int MAX_UBYTE = 256;
- private static final int BYTE_MASK = 0xff;
- // reserved for bluetooth tethering.
- private static final int BLUETOOTH_RESERVED = 44;
- private static final byte DEFAULT_ID = (byte) 42;
-
- // Upstream monitor would be stopped when tethering is down. When tethering restart, downstream
- // address may be requested before coordinator get current upstream notification. To ensure
- // coordinator do not select conflict downstream prefix, mUpstreamPrefixMap would not be cleared
- // when tethering is down. Instead coordinator would remove all depcreted upstreams from
- // mUpstreamPrefixMap when tethering is starting. See #maybeRemoveDeprectedUpstreams().
- private final ArrayMap<Network, List<IpPrefix>> mUpstreamPrefixMap;
- private final ArraySet<IpServer> mDownstreams;
- // IANA has reserved the following three blocks of the IP address space for private intranets:
- // 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
- // Tethering use 192.168.0.0/16 that has 256 contiguous class C network numbers.
- private static final String DEFAULT_TETHERING_PREFIX = "192.168.0.0/16";
- private final IpPrefix mTetheringPrefix;
- private final ConnectivityManager mConnectivityMgr;
-
- public PrivateAddressCoordinator(Context context) {
- mDownstreams = new ArraySet<>();
- mUpstreamPrefixMap = new ArrayMap<>();
- mTetheringPrefix = new IpPrefix(DEFAULT_TETHERING_PREFIX);
- mConnectivityMgr = (ConnectivityManager) context.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- }
-
- /**
- * Record a new upstream IpPrefix which may conflict with tethering downstreams.
- * The downstreams will be notified if a conflict is found.
- */
- public void updateUpstreamPrefix(final Network network, final LinkProperties lp) {
- final ArrayList<IpPrefix> ipv4Prefixes = getIpv4Prefixes(lp.getAllLinkAddresses());
- if (ipv4Prefixes.isEmpty()) {
- removeUpstreamPrefix(network);
- return;
- }
-
- mUpstreamPrefixMap.put(network, ipv4Prefixes);
- handleMaybePrefixConflict(ipv4Prefixes);
- }
-
- private ArrayList<IpPrefix> getIpv4Prefixes(final List<LinkAddress> linkAddresses) {
- final ArrayList<IpPrefix> list = new ArrayList<>();
- for (LinkAddress address : linkAddresses) {
- if (!address.isIpv4()) continue;
-
- list.add(PrefixUtils.asIpPrefix(address));
- }
-
- return list;
- }
-
- private void handleMaybePrefixConflict(final List<IpPrefix> prefixes) {
- for (IpServer downstream : mDownstreams) {
- final IpPrefix target = getDownstreamPrefix(downstream);
- if (target == null) continue;
-
- for (IpPrefix source : prefixes) {
- if (isConflictPrefix(source, target)) {
- downstream.sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT);
- break;
- }
- }
- }
- }
-
- /** Remove IpPrefix records corresponding to input network. */
- public void removeUpstreamPrefix(final Network network) {
- mUpstreamPrefixMap.remove(network);
- }
-
- private void maybeRemoveDeprectedUpstreams() {
- if (!mDownstreams.isEmpty() || mUpstreamPrefixMap.isEmpty()) return;
-
- final ArrayList<Network> toBeRemoved = new ArrayList<>();
- List<Network> allNetworks = Arrays.asList(mConnectivityMgr.getAllNetworks());
- for (int i = 0; i < mUpstreamPrefixMap.size(); i++) {
- final Network network = mUpstreamPrefixMap.keyAt(i);
- if (!allNetworks.contains(network)) toBeRemoved.add(network);
- }
-
- mUpstreamPrefixMap.removeAll(toBeRemoved);
- }
-
- /**
- * Pick a random available address and mark its prefix as in use for the provided IpServer,
- * returns null if there is no available address.
- */
- @Nullable
- public LinkAddress requestDownstreamAddress(final IpServer ipServer) {
- maybeRemoveDeprectedUpstreams();
-
- // Address would be 192.168.[subAddress]/24.
- final byte[] bytes = mTetheringPrefix.getRawAddress();
- final int subAddress = getRandomSubAddr();
- final int subNet = (subAddress >> 8) & BYTE_MASK;
- bytes[3] = getSanitizedAddressSuffix(subAddress, (byte) 0, (byte) 1, (byte) 0xff);
- for (int i = 0; i < MAX_UBYTE; i++) {
- final int newSubNet = (subNet + i) & BYTE_MASK;
- if (newSubNet == BLUETOOTH_RESERVED) continue;
-
- bytes[2] = (byte) newSubNet;
- final InetAddress addr;
- try {
- addr = InetAddress.getByAddress(bytes);
- } catch (UnknownHostException e) {
- throw new IllegalStateException("Invalid address, shouldn't happen.", e);
- }
-
- final IpPrefix prefix = new IpPrefix(addr, PREFIX_LENGTH);
- // Check whether this prefix is in use.
- if (isDownstreamPrefixInUse(prefix)) continue;
- // Check whether this prefix is conflict with any current upstream network.
- if (isConflictWithUpstream(prefix)) continue;
-
- mDownstreams.add(ipServer);
- return new LinkAddress(addr, PREFIX_LENGTH);
- }
-
- // No available address.
- return null;
- }
-
- /** Get random sub address value. Return value is in 0 ~ 0xffff. */
- @VisibleForTesting
- public int getRandomSubAddr() {
- return ((new Random()).nextInt()) & 0xffff; // subNet is in 0 ~ 0xffff.
- }
-
- private byte getSanitizedAddressSuffix(final int source, byte... excluded) {
- final byte subId = (byte) (source & BYTE_MASK);
- for (byte value : excluded) {
- if (subId == value) return DEFAULT_ID;
- }
-
- return subId;
- }
-
- /** Release downstream record for IpServer. */
- public void releaseDownstream(final IpServer ipServer) {
- mDownstreams.remove(ipServer);
- }
-
- /** Clear current upstream prefixes records. */
- public void clearUpstreamPrefixes() {
- mUpstreamPrefixMap.clear();
- }
-
- private boolean isConflictWithUpstream(final IpPrefix source) {
- for (int i = 0; i < mUpstreamPrefixMap.size(); i++) {
- final List<IpPrefix> list = mUpstreamPrefixMap.valueAt(i);
- for (IpPrefix target : list) {
- if (isConflictPrefix(source, target)) return true;
- }
- }
- return false;
- }
-
- private boolean isConflictPrefix(final IpPrefix prefix1, final IpPrefix prefix2) {
- if (prefix2.getPrefixLength() < prefix1.getPrefixLength()) {
- return prefix2.contains(prefix1.getAddress());
- }
-
- return prefix1.contains(prefix2.getAddress());
- }
-
- private boolean isDownstreamPrefixInUse(final IpPrefix source) {
- // This class always generates downstream prefixes with the same prefix length, so
- // prefixes cannot be contained in each other. They can only be equal to each other.
- for (IpServer downstream : mDownstreams) {
- final IpPrefix prefix = getDownstreamPrefix(downstream);
- if (source.equals(prefix)) return true;
- }
- return false;
- }
-
- private IpPrefix getDownstreamPrefix(final IpServer downstream) {
- final LinkAddress address = downstream.getAddress();
- if (address == null) return null;
-
- return PrefixUtils.asIpPrefix(address);
- }
-
- void dump(final IndentingPrintWriter pw) {
- pw.decreaseIndent();
- pw.println("mUpstreamPrefixMap:");
- pw.increaseIndent();
- for (int i = 0; i < mUpstreamPrefixMap.size(); i++) {
- pw.println(mUpstreamPrefixMap.keyAt(i) + " - " + mUpstreamPrefixMap.valueAt(i));
- }
- pw.decreaseIndent();
- pw.println("mDownstreams:");
- pw.increaseIndent();
- for (IpServer ipServer : mDownstreams) {
- pw.println(ipServer.interfaceType() + " - " + ipServer.getAddress());
- }
- pw.decreaseIndent();
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
deleted file mode 100644
index 3695ec6..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ /dev/null
@@ -1,2431 +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.
- */
-
-package com.android.networkstack.tethering;
-
-import static android.Manifest.permission.NETWORK_SETTINGS;
-import static android.Manifest.permission.NETWORK_STACK;
-import static android.content.pm.PackageManager.GET_ACTIVITIES;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.hardware.usb.UsbManager.USB_CONFIGURED;
-import static android.hardware.usb.UsbManager.USB_CONNECTED;
-import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM;
-import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
-import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
-import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
-import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
-import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
-import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED;
-import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY;
-import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER;
-import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER;
-import static android.net.TetheringManager.EXTRA_ERRORED_TETHER;
-import static android.net.TetheringManager.TETHERING_BLUETOOTH;
-import static android.net.TetheringManager.TETHERING_ETHERNET;
-import static android.net.TetheringManager.TETHERING_INVALID;
-import static android.net.TetheringManager.TETHERING_NCM;
-import static android.net.TetheringManager.TETHERING_USB;
-import static android.net.TetheringManager.TETHERING_WIFI;
-import static android.net.TetheringManager.TETHERING_WIFI_P2P;
-import static android.net.TetheringManager.TETHERING_WIGIG;
-import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
-import static android.net.TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
-import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
-import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
-import static android.net.util.TetheringMessageBase.BASE_MASTER;
-import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
-import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
-import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
-import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
-import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
-import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
-import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
-import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
-
-import android.app.usage.NetworkStatsManager;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothPan;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfile.ServiceListener;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.hardware.usb.UsbManager;
-import android.net.ConnectivityManager;
-import android.net.EthernetManager;
-import android.net.IIntResultListener;
-import android.net.INetd;
-import android.net.ITetheringEventCallback;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.TetherStatesParcel;
-import android.net.TetheredClient;
-import android.net.TetheringCallbackStartedParcel;
-import android.net.TetheringConfigurationParcel;
-import android.net.TetheringRequestParcel;
-import android.net.ip.IpServer;
-import android.net.shared.NetdUtils;
-import android.net.util.BaseNetdUnsolicitedEventListener;
-import android.net.util.InterfaceSet;
-import android.net.util.PrefixUtils;
-import android.net.util.SharedLog;
-import android.net.util.TetheringUtils;
-import android.net.util.VersionedBroadcastListener;
-import android.net.wifi.WifiClient;
-import android.net.wifi.WifiManager;
-import android.net.wifi.p2p.WifiP2pGroup;
-import android.net.wifi.p2p.WifiP2pInfo;
-import android.net.wifi.p2p.WifiP2pManager;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.ServiceSpecificException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.telephony.PhoneStateListener;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.RejectedExecutionException;
-
-/**
- *
- * This class holds much of the business logic to allow Android devices
- * to act as IP gateways via USB, BT, and WiFi interfaces.
- */
-public class Tethering {
-
- private static final String TAG = Tethering.class.getSimpleName();
- private static final boolean DBG = false;
- private static final boolean VDBG = false;
-
- private static final Class[] sMessageClasses = {
- Tethering.class, TetherMasterSM.class, IpServer.class
- };
- private static final SparseArray<String> sMagicDecoderRing =
- MessageUtils.findMessageNames(sMessageClasses);
- // Keep in sync with NETID_UNSET in system/netd/include/netid_client.h
- private static final int NETID_UNSET = 0;
-
- private static class TetherState {
- public final IpServer ipServer;
- public int lastState;
- public int lastError;
-
- TetherState(IpServer ipServer) {
- this.ipServer = ipServer;
- // Assume all state machines start out available and with no errors.
- lastState = IpServer.STATE_AVAILABLE;
- lastError = TETHER_ERROR_NO_ERROR;
- }
-
- public boolean isCurrentlyServing() {
- switch (lastState) {
- case IpServer.STATE_TETHERED:
- case IpServer.STATE_LOCAL_ONLY:
- return true;
- default:
- return false;
- }
- }
- }
-
- /**
- * Cookie added when registering {@link android.net.TetheringManager.TetheringEventCallback}.
- */
- private static class CallbackCookie {
- public final boolean hasListClientsPermission;
-
- private CallbackCookie(boolean hasListClientsPermission) {
- this.hasListClientsPermission = hasListClientsPermission;
- }
- }
-
- private final SharedLog mLog = new SharedLog(TAG);
- private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks =
- new RemoteCallbackList<>();
- // Currently active tethering requests per tethering type. Only one of each type can be
- // requested at a time. After a tethering type is requested, the map keeps tethering parameters
- // to be used after the interface comes up asynchronously.
- private final SparseArray<TetheringRequestParcel> mActiveTetheringRequests =
- new SparseArray<>();
-
- // used to synchronize public access to members
- // TODO(b/153621704): remove mPublicSync to make Tethering lock free
- private final Object mPublicSync;
- private final Context mContext;
- private final ArrayMap<String, TetherState> mTetherStates;
- private final BroadcastReceiver mStateReceiver;
- private final Looper mLooper;
- private final StateMachine mTetherMasterSM;
- private final OffloadController mOffloadController;
- private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
- // TODO: Figure out how to merge this and other downstream-tracking objects
- // into a single coherent structure.
- // Use LinkedHashSet for predictable ordering order for ConnectedClientsTracker.
- private final LinkedHashSet<IpServer> mForwardedDownstreams;
- private final VersionedBroadcastListener mCarrierConfigChange;
- private final TetheringDependencies mDeps;
- private final EntitlementManager mEntitlementMgr;
- private final Handler mHandler;
- private final INetd mNetd;
- private final NetdCallback mNetdCallback;
- private final UserRestrictionActionListener mTetheringRestriction;
- private final ActiveDataSubIdListener mActiveDataSubIdListener;
- private final ConnectedClientsTracker mConnectedClientsTracker;
- private final TetheringThreadExecutor mExecutor;
- private final TetheringNotificationUpdater mNotificationUpdater;
- private final UserManager mUserManager;
- private final BpfCoordinator mBpfCoordinator;
- private final PrivateAddressCoordinator mPrivateAddressCoordinator;
- private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
- // All the usage of mTetheringEventCallback should run in the same thread.
- private ITetheringEventCallback mTetheringEventCallback = null;
-
- private volatile TetheringConfiguration mConfig;
- private InterfaceSet mCurrentUpstreamIfaceSet;
-
- private boolean mRndisEnabled; // track the RNDIS function enabled state
- // True iff. WiFi tethering should be started when soft AP is ready.
- private boolean mWifiTetherRequested;
- private Network mTetherUpstream;
- private TetherStatesParcel mTetherStatesParcel;
- private boolean mDataSaverEnabled = false;
- private String mWifiP2pTetherInterface = null;
- private int mOffloadStatus = TETHER_HARDWARE_OFFLOAD_STOPPED;
-
- @GuardedBy("mPublicSync")
- private EthernetManager.TetheredInterfaceRequest mEthernetIfaceRequest;
- @GuardedBy("mPublicSync")
- private String mConfiguredEthernetIface;
- @GuardedBy("mPublicSync")
- private EthernetCallback mEthernetCallback;
-
- public Tethering(TetheringDependencies deps) {
- mLog.mark("Tethering.constructed");
- mDeps = deps;
- mContext = mDeps.getContext();
- mNetd = mDeps.getINetd(mContext);
- mLooper = mDeps.getTetheringLooper();
- mNotificationUpdater = mDeps.getNotificationUpdater(mContext, mLooper);
-
- mPublicSync = new Object();
-
- mTetherStates = new ArrayMap<>();
- mConnectedClientsTracker = new ConnectedClientsTracker();
-
- mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper, deps);
- mTetherMasterSM.start();
-
- mHandler = mTetherMasterSM.getHandler();
- mOffloadController = mDeps.getOffloadController(mHandler, mLog,
- new OffloadController.Dependencies() {
-
- @Override
- public TetheringConfiguration getTetherConfig() {
- return mConfig;
- }
- });
- mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
- TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
- mForwardedDownstreams = new LinkedHashSet<>();
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
- // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream
- // permission is changed according to entitlement check result.
- mEntitlementMgr = mDeps.getEntitlementManager(mContext, mHandler, mLog,
- () -> mTetherMasterSM.sendMessage(
- TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED));
- mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> {
- mLog.log("OBSERVED UiEnitlementFailed");
- stopTethering(downstream);
- });
- mEntitlementMgr.setTetheringConfigurationFetcher(() -> {
- return mConfig;
- });
-
- mCarrierConfigChange = new VersionedBroadcastListener(
- "CarrierConfigChangeListener", mContext, mHandler, filter,
- (Intent ignored) -> {
- mLog.log("OBSERVED carrier config change");
- updateConfiguration();
- mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
- });
-
- mStateReceiver = new StateReceiver();
-
- mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- mTetheringRestriction = new UserRestrictionActionListener(
- mUserManager, this, mNotificationUpdater);
- mExecutor = new TetheringThreadExecutor(mHandler);
- mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
- mNetdCallback = new NetdCallback();
- mPrivateAddressCoordinator = new PrivateAddressCoordinator(mContext);
-
- // Load tethering configuration.
- updateConfiguration();
-
- // Must be initialized after tethering configuration is loaded because BpfCoordinator
- // constructor needs to use the configuration.
- mBpfCoordinator = mDeps.getBpfCoordinator(
- new BpfCoordinator.Dependencies() {
- @NonNull
- public Handler getHandler() {
- return mHandler;
- }
-
- @NonNull
- public INetd getNetd() {
- return mNetd;
- }
-
- @NonNull
- public NetworkStatsManager getNetworkStatsManager() {
- return mContext.getSystemService(NetworkStatsManager.class);
- }
-
- @NonNull
- public SharedLog getSharedLog() {
- return mLog;
- }
-
- @Nullable
- public TetheringConfiguration getTetherConfig() {
- return mConfig;
- }
- });
-
- startStateMachineUpdaters();
- }
-
- /**
- * Start to register callbacks.
- * Call this function when tethering is ready to handle callback events.
- */
- private void startStateMachineUpdaters() {
- try {
- mNetd.registerUnsolicitedEventListener(mNetdCallback);
- } catch (RemoteException e) {
- mLog.e("Unable to register netd UnsolicitedEventListener");
- }
- mCarrierConfigChange.startListening();
- mContext.getSystemService(TelephonyManager.class).listen(mActiveDataSubIdListener,
- PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(UsbManager.ACTION_USB_STATE);
- filter.addAction(CONNECTIVITY_ACTION);
- filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
- filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
- filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
- filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED);
- filter.addAction(ACTION_RESTRICT_BACKGROUND_CHANGED);
- mContext.registerReceiver(mStateReceiver, filter, null, mHandler);
-
- final IntentFilter noUpstreamFilter = new IntentFilter();
- noUpstreamFilter.addAction(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING);
- mContext.registerReceiver(
- mStateReceiver, noUpstreamFilter, PERMISSION_MAINLINE_NETWORK_STACK, mHandler);
-
- final WifiManager wifiManager = getWifiManager();
- if (wifiManager != null) {
- wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback());
- }
-
- startTrackDefaultNetwork();
- }
-
- private class TetheringThreadExecutor implements Executor {
- private final Handler mTetherHandler;
- TetheringThreadExecutor(Handler handler) {
- mTetherHandler = handler;
- }
- @Override
- public void execute(Runnable command) {
- if (!mTetherHandler.post(command)) {
- throw new RejectedExecutionException(mTetherHandler + " is shutting down");
- }
- }
- }
-
- private class ActiveDataSubIdListener extends PhoneStateListener {
- ActiveDataSubIdListener(Executor executor) {
- super(executor);
- }
-
- @Override
- public void onActiveDataSubscriptionIdChanged(int subId) {
- mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId
- + " to " + subId);
- if (subId == mActiveDataSubId) return;
-
- mActiveDataSubId = subId;
- updateConfiguration();
- mNotificationUpdater.onActiveDataSubscriptionIdChanged(subId);
- // To avoid launching unexpected provisioning checks, ignore re-provisioning
- // when no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning()
- // will be triggered again when CarrierConfig is loaded.
- if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
- mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
- } else {
- mLog.log("IGNORED reevaluate provisioning, no carrier config loaded");
- }
- }
- }
-
- private WifiManager getWifiManager() {
- return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- }
-
- // NOTE: This is always invoked on the mLooper thread.
- private void updateConfiguration() {
- mConfig = mDeps.generateTetheringConfiguration(mContext, mLog, mActiveDataSubId);
- mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
- reportConfigurationChanged(mConfig.toStableParcelable());
- }
-
- private void maybeDunSettingChanged() {
- final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext);
- if (isDunRequired == mConfig.isDunRequired) return;
- updateConfiguration();
- }
-
- private class NetdCallback extends BaseNetdUnsolicitedEventListener {
- @Override
- public void onInterfaceChanged(String ifName, boolean up) {
- mHandler.post(() -> interfaceStatusChanged(ifName, up));
- }
-
- @Override
- public void onInterfaceLinkStateChanged(String ifName, boolean up) {
- mHandler.post(() -> interfaceLinkStateChanged(ifName, up));
- }
-
- @Override
- public void onInterfaceAdded(String ifName) {
- mHandler.post(() -> interfaceAdded(ifName));
- }
-
- @Override
- public void onInterfaceRemoved(String ifName) {
- mHandler.post(() -> interfaceRemoved(ifName));
- }
- }
-
- private class TetheringSoftApCallback implements WifiManager.SoftApCallback {
- // TODO: Remove onStateChanged override when this method has default on
- // WifiManager#SoftApCallback interface.
- // Wifi listener for state change of the soft AP
- @Override
- public void onStateChanged(final int state, final int failureReason) {
- // Nothing
- }
-
- // Called by wifi when the number of soft AP clients changed.
- @Override
- public void onConnectedClientsChanged(final List<WifiClient> clients) {
- updateConnectedClients(clients);
- }
- }
-
- void interfaceStatusChanged(String iface, boolean up) {
- // Never called directly: only called from interfaceLinkStateChanged.
- // See NetlinkHandler.cpp: notifyInterfaceChanged.
- if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
- synchronized (mPublicSync) {
- if (up) {
- maybeTrackNewInterfaceLocked(iface);
- } else {
- if (ifaceNameToType(iface) == TETHERING_BLUETOOTH
- || ifaceNameToType(iface) == TETHERING_WIGIG) {
- stopTrackingInterfaceLocked(iface);
- } else {
- // Ignore usb0 down after enabling RNDIS.
- // We will handle disconnect in interfaceRemoved.
- // Similarly, ignore interface down for WiFi. We monitor WiFi AP status
- // through the WifiManager.WIFI_AP_STATE_CHANGED_ACTION intent.
- if (VDBG) Log.d(TAG, "ignore interface down for " + iface);
- }
- }
- }
- }
-
- void interfaceLinkStateChanged(String iface, boolean up) {
- interfaceStatusChanged(iface, up);
- }
-
- private int ifaceNameToType(String iface) {
- final TetheringConfiguration cfg = mConfig;
-
- if (cfg.isWifi(iface)) {
- return TETHERING_WIFI;
- } else if (cfg.isWigig(iface)) {
- return TETHERING_WIGIG;
- } else if (cfg.isWifiP2p(iface)) {
- return TETHERING_WIFI_P2P;
- } else if (cfg.isUsb(iface)) {
- return TETHERING_USB;
- } else if (cfg.isBluetooth(iface)) {
- return TETHERING_BLUETOOTH;
- } else if (cfg.isNcm(iface)) {
- return TETHERING_NCM;
- }
- return TETHERING_INVALID;
- }
-
- void interfaceAdded(String iface) {
- if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
- synchronized (mPublicSync) {
- maybeTrackNewInterfaceLocked(iface);
- }
- }
-
- void interfaceRemoved(String iface) {
- if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
- synchronized (mPublicSync) {
- stopTrackingInterfaceLocked(iface);
- }
- }
-
- void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) {
- mHandler.post(() -> {
- final TetheringRequestParcel unfinishedRequest = mActiveTetheringRequests.get(
- request.tetheringType);
- // If tethering is already enabled with a different request,
- // disable before re-enabling.
- if (unfinishedRequest != null
- && !TetheringUtils.isTetheringRequestEquals(unfinishedRequest, request)) {
- enableTetheringInternal(request.tetheringType, false /* disabled */, null);
- mEntitlementMgr.stopProvisioningIfNeeded(request.tetheringType);
- }
- mActiveTetheringRequests.put(request.tetheringType, request);
-
- if (request.exemptFromEntitlementCheck) {
- mEntitlementMgr.setExemptedDownstreamType(request.tetheringType);
- } else {
- mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,
- request.showProvisioningUi);
- }
- enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
- });
- }
-
- void stopTethering(int type) {
- mHandler.post(() -> {
- mActiveTetheringRequests.remove(type);
-
- enableTetheringInternal(type, false /* disabled */, null);
- mEntitlementMgr.stopProvisioningIfNeeded(type);
- });
- }
-
- /**
- * Enables or disables tethering for the given type. If provisioning is required, it will
- * schedule provisioning rechecks for the specified interface.
- */
- private void enableTetheringInternal(int type, boolean enable,
- final IIntResultListener listener) {
- int result = TETHER_ERROR_NO_ERROR;
- switch (type) {
- case TETHERING_WIFI:
- result = setWifiTethering(enable);
- break;
- case TETHERING_USB:
- result = setUsbTethering(enable);
- break;
- case TETHERING_BLUETOOTH:
- setBluetoothTethering(enable, listener);
- break;
- case TETHERING_NCM:
- result = setNcmTethering(enable);
- break;
- case TETHERING_ETHERNET:
- result = setEthernetTethering(enable);
- break;
- default:
- Log.w(TAG, "Invalid tether type.");
- result = TETHER_ERROR_UNKNOWN_TYPE;
- }
-
- // The result of Bluetooth tethering will be sent by #setBluetoothTethering.
- if (type != TETHERING_BLUETOOTH) {
- sendTetherResult(listener, result, type);
- }
- }
-
- private void sendTetherResult(final IIntResultListener listener, final int result,
- final int type) {
- if (listener != null) {
- try {
- listener.onResult(result);
- } catch (RemoteException e) { }
- }
-
- // If changing tethering fail, remove corresponding request
- // no matter who trigger the start/stop.
- if (result != TETHER_ERROR_NO_ERROR) mActiveTetheringRequests.remove(type);
- }
-
- private int setWifiTethering(final boolean enable) {
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mPublicSync) {
- final WifiManager mgr = getWifiManager();
- if (mgr == null) {
- mLog.e("setWifiTethering: failed to get WifiManager!");
- return TETHER_ERROR_SERVICE_UNAVAIL;
- }
- if ((enable && mgr.startTetheredHotspot(null /* use existing softap config */))
- || (!enable && mgr.stopSoftAp())) {
- mWifiTetherRequested = enable;
- return TETHER_ERROR_NO_ERROR;
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
-
- return TETHER_ERROR_INTERNAL_ERROR;
- }
-
- private void setBluetoothTethering(final boolean enable, final IIntResultListener listener) {
- final BluetoothAdapter adapter = mDeps.getBluetoothAdapter();
- if (adapter == null || !adapter.isEnabled()) {
- Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: "
- + (adapter == null));
- sendTetherResult(listener, TETHER_ERROR_SERVICE_UNAVAIL, TETHERING_BLUETOOTH);
- return;
- }
-
- adapter.getProfileProxy(mContext, new ServiceListener() {
- @Override
- public void onServiceDisconnected(int profile) { }
-
- @Override
- public void onServiceConnected(int profile, BluetoothProfile proxy) {
- // Clear identify is fine because caller already pass tethering permission at
- // ConnectivityService#startTethering()(or stopTethering) before the control comes
- // here. Bluetooth will check tethering permission again that there is
- // Context#getOpPackageName() under BluetoothPan#setBluetoothTethering() to get
- // caller's package name for permission check.
- // Calling BluetoothPan#setBluetoothTethering() here means the package name always
- // be system server. If calling identity is not cleared, that package's uid might
- // not match calling uid and end up in permission denied.
- final long identityToken = Binder.clearCallingIdentity();
- try {
- ((BluetoothPan) proxy).setBluetoothTethering(enable);
- } finally {
- Binder.restoreCallingIdentity(identityToken);
- }
- // TODO: Enabling bluetooth tethering can fail asynchronously here.
- // We should figure out a way to bubble up that failure instead of sending success.
- final int result = (((BluetoothPan) proxy).isTetheringOn() == enable)
- ? TETHER_ERROR_NO_ERROR
- : TETHER_ERROR_INTERNAL_ERROR;
- sendTetherResult(listener, result, TETHERING_BLUETOOTH);
- adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
- }
- }, BluetoothProfile.PAN);
- }
-
- private int setEthernetTethering(final boolean enable) {
- final EthernetManager em = (EthernetManager) mContext.getSystemService(
- Context.ETHERNET_SERVICE);
- synchronized (mPublicSync) {
- if (enable) {
- if (mEthernetCallback != null) {
- Log.d(TAG, "Ethernet tethering already started");
- return TETHER_ERROR_NO_ERROR;
- }
-
- mEthernetCallback = new EthernetCallback();
- mEthernetIfaceRequest = em.requestTetheredInterface(mExecutor, mEthernetCallback);
- } else {
- stopEthernetTetheringLocked();
- }
- }
- return TETHER_ERROR_NO_ERROR;
- }
-
- private void stopEthernetTetheringLocked() {
- if (mConfiguredEthernetIface != null) {
- stopTrackingInterfaceLocked(mConfiguredEthernetIface);
- mConfiguredEthernetIface = null;
- }
- if (mEthernetCallback != null) {
- mEthernetIfaceRequest.release();
- mEthernetCallback = null;
- mEthernetIfaceRequest = null;
- }
- }
-
- private class EthernetCallback implements EthernetManager.TetheredInterfaceCallback {
- @Override
- public void onAvailable(String iface) {
- synchronized (mPublicSync) {
- if (this != mEthernetCallback) {
- // Ethernet callback arrived after Ethernet tethering stopped. Ignore.
- return;
- }
- maybeTrackNewInterfaceLocked(iface, TETHERING_ETHERNET);
- changeInterfaceState(iface, IpServer.STATE_TETHERED);
- mConfiguredEthernetIface = iface;
- }
- }
-
- @Override
- public void onUnavailable() {
- synchronized (mPublicSync) {
- if (this != mEthernetCallback) {
- // onAvailable called after stopping Ethernet tethering.
- return;
- }
- stopEthernetTetheringLocked();
- }
- }
- }
-
- int tether(String iface) {
- return tether(iface, IpServer.STATE_TETHERED);
- }
-
- private int tether(String iface, int requestedState) {
- if (DBG) Log.d(TAG, "Tethering " + iface);
- synchronized (mPublicSync) {
- TetherState tetherState = mTetherStates.get(iface);
- if (tetherState == null) {
- Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring");
- return TETHER_ERROR_UNKNOWN_IFACE;
- }
- // Ignore the error status of the interface. If the interface is available,
- // the errors are referring to past tethering attempts anyway.
- if (tetherState.lastState != IpServer.STATE_AVAILABLE) {
- Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring");
- return TETHER_ERROR_UNAVAIL_IFACE;
- }
- // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's queue but not yet
- // processed, this will be a no-op and it will not return an error.
- //
- // This code cannot race with untether() because they both synchronize on mPublicSync.
- // TODO: reexamine the threading and messaging model to totally remove mPublicSync.
- final int type = tetherState.ipServer.interfaceType();
- final TetheringRequestParcel request = mActiveTetheringRequests.get(type, null);
- if (request != null) {
- mActiveTetheringRequests.delete(type);
- }
- tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, requestedState, 0,
- request);
- return TETHER_ERROR_NO_ERROR;
- }
- }
-
- int untether(String iface) {
- if (DBG) Log.d(TAG, "Untethering " + iface);
- synchronized (mPublicSync) {
- TetherState tetherState = mTetherStates.get(iface);
- if (tetherState == null) {
- Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
- return TETHER_ERROR_UNKNOWN_IFACE;
- }
- if (!tetherState.isCurrentlyServing()) {
- Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring");
- return TETHER_ERROR_UNAVAIL_IFACE;
- }
- tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_UNREQUESTED);
- return TETHER_ERROR_NO_ERROR;
- }
- }
-
- void untetherAll() {
- stopTethering(TETHERING_WIFI);
- stopTethering(TETHERING_WIFI_P2P);
- stopTethering(TETHERING_USB);
- stopTethering(TETHERING_BLUETOOTH);
- stopTethering(TETHERING_ETHERNET);
- }
-
- int getLastTetherError(String iface) {
- synchronized (mPublicSync) {
- TetherState tetherState = mTetherStates.get(iface);
- if (tetherState == null) {
- Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface
- + ", ignoring");
- return TETHER_ERROR_UNKNOWN_IFACE;
- }
- return tetherState.lastError;
- }
- }
-
- private boolean isProvisioningNeededButUnavailable() {
- return isTetherProvisioningRequired() && !doesEntitlementPackageExist();
- }
-
- boolean isTetherProvisioningRequired() {
- final TetheringConfiguration cfg = mConfig;
- return mEntitlementMgr.isTetherProvisioningRequired(cfg);
- }
-
- private boolean doesEntitlementPackageExist() {
- // provisioningApp must contain package and class name.
- if (mConfig.provisioningApp.length != 2) {
- return false;
- }
-
- final PackageManager pm = mContext.getPackageManager();
- try {
- pm.getPackageInfo(mConfig.provisioningApp[0], GET_ACTIVITIES);
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
- return true;
- }
-
- // TODO: Figure out how to update for local hotspot mode interfaces.
- private void sendTetherStateChangedBroadcast() {
- if (!isTetheringSupported()) return;
-
- final ArrayList<String> availableList = new ArrayList<>();
- final ArrayList<String> tetherList = new ArrayList<>();
- final ArrayList<String> localOnlyList = new ArrayList<>();
- final ArrayList<String> erroredList = new ArrayList<>();
- final ArrayList<Integer> lastErrorList = new ArrayList<>();
-
- final TetheringConfiguration cfg = mConfig;
- mTetherStatesParcel = new TetherStatesParcel();
-
- int downstreamTypesMask = DOWNSTREAM_NONE;
- synchronized (mPublicSync) {
- for (int i = 0; i < mTetherStates.size(); i++) {
- TetherState tetherState = mTetherStates.valueAt(i);
- String iface = mTetherStates.keyAt(i);
- if (tetherState.lastError != TETHER_ERROR_NO_ERROR) {
- erroredList.add(iface);
- lastErrorList.add(tetherState.lastError);
- } else if (tetherState.lastState == IpServer.STATE_AVAILABLE) {
- availableList.add(iface);
- } else if (tetherState.lastState == IpServer.STATE_LOCAL_ONLY) {
- localOnlyList.add(iface);
- } else if (tetherState.lastState == IpServer.STATE_TETHERED) {
- if (cfg.isUsb(iface)) {
- downstreamTypesMask |= (1 << TETHERING_USB);
- } else if (cfg.isWifi(iface)) {
- downstreamTypesMask |= (1 << TETHERING_WIFI);
- } else if (cfg.isBluetooth(iface)) {
- downstreamTypesMask |= (1 << TETHERING_BLUETOOTH);
- }
- tetherList.add(iface);
- }
- }
- }
-
- mTetherStatesParcel.availableList = availableList.toArray(new String[0]);
- mTetherStatesParcel.tetheredList = tetherList.toArray(new String[0]);
- mTetherStatesParcel.localOnlyList = localOnlyList.toArray(new String[0]);
- mTetherStatesParcel.erroredIfaceList = erroredList.toArray(new String[0]);
- mTetherStatesParcel.lastErrorList = new int[lastErrorList.size()];
- Iterator<Integer> iterator = lastErrorList.iterator();
- for (int i = 0; i < lastErrorList.size(); i++) {
- mTetherStatesParcel.lastErrorList[i] = iterator.next().intValue();
- }
- reportTetherStateChanged(mTetherStatesParcel);
-
- final Intent bcast = new Intent(ACTION_TETHER_STATE_CHANGED);
- bcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- bcast.putStringArrayListExtra(EXTRA_AVAILABLE_TETHER, availableList);
- bcast.putStringArrayListExtra(EXTRA_ACTIVE_LOCAL_ONLY, localOnlyList);
- bcast.putStringArrayListExtra(EXTRA_ACTIVE_TETHER, tetherList);
- bcast.putStringArrayListExtra(EXTRA_ERRORED_TETHER, erroredList);
- mContext.sendStickyBroadcastAsUser(bcast, UserHandle.ALL);
- if (DBG) {
- Log.d(TAG, String.format(
- "sendTetherStateChangedBroadcast %s=[%s] %s=[%s] %s=[%s] %s=[%s]",
- "avail", TextUtils.join(",", availableList),
- "local_only", TextUtils.join(",", localOnlyList),
- "tether", TextUtils.join(",", tetherList),
- "error", TextUtils.join(",", erroredList)));
- }
-
- mNotificationUpdater.onDownstreamChanged(downstreamTypesMask);
- }
-
- private class StateReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context content, Intent intent) {
- final String action = intent.getAction();
- if (action == null) return;
-
- if (action.equals(UsbManager.ACTION_USB_STATE)) {
- handleUsbAction(intent);
- } else if (action.equals(CONNECTIVITY_ACTION)) {
- handleConnectivityAction(intent);
- } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
- handleWifiApAction(intent);
- } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
- handleWifiP2pAction(intent);
- } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
- mLog.log("OBSERVED configuration changed");
- updateConfiguration();
- } else if (action.equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) {
- mLog.log("OBSERVED user restrictions changed");
- handleUserRestrictionAction();
- } else if (action.equals(ACTION_RESTRICT_BACKGROUND_CHANGED)) {
- mLog.log("OBSERVED data saver changed");
- handleDataSaverChanged();
- } else if (action.equals(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING)) {
- untetherAll();
- }
- }
-
- private void handleConnectivityAction(Intent intent) {
- final NetworkInfo networkInfo =
- (NetworkInfo) intent.getParcelableExtra(EXTRA_NETWORK_INFO);
- if (networkInfo == null
- || networkInfo.getDetailedState() == NetworkInfo.DetailedState.FAILED) {
- return;
- }
-
- if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString());
- mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
- }
-
- private void handleUsbAction(Intent intent) {
- final boolean usbConnected = intent.getBooleanExtra(USB_CONNECTED, false);
- final boolean usbConfigured = intent.getBooleanExtra(USB_CONFIGURED, false);
- final boolean rndisEnabled = intent.getBooleanExtra(USB_FUNCTION_RNDIS, false);
- final boolean ncmEnabled = intent.getBooleanExtra(USB_FUNCTION_NCM, false);
-
- mLog.log(String.format("USB bcast connected:%s configured:%s rndis:%s",
- usbConnected, usbConfigured, rndisEnabled));
-
- // There are three types of ACTION_USB_STATE:
- //
- // - DISCONNECTED (USB_CONNECTED and USB_CONFIGURED are 0)
- // Meaning: USB connection has ended either because of
- // software reset or hard unplug.
- //
- // - CONNECTED (USB_CONNECTED is 1, USB_CONFIGURED is 0)
- // Meaning: the first stage of USB protocol handshake has
- // occurred but it is not complete.
- //
- // - CONFIGURED (USB_CONNECTED and USB_CONFIGURED are 1)
- // Meaning: the USB handshake is completely done and all the
- // functions are ready to use.
- //
- // For more explanation, see b/62552150 .
- synchronized (Tethering.this.mPublicSync) {
- if (!usbConnected && mRndisEnabled) {
- // Turn off tethering if it was enabled and there is a disconnect.
- tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_USB);
- mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_USB);
- } else if (usbConfigured && rndisEnabled) {
- // Tether if rndis is enabled and usb is configured.
- tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_USB);
- } else if (usbConnected && ncmEnabled) {
- tetherMatchingInterfaces(IpServer.STATE_LOCAL_ONLY, TETHERING_NCM);
- }
- mRndisEnabled = usbConfigured && rndisEnabled;
- }
- }
-
- private void handleWifiApAction(Intent intent) {
- final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
- final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
- final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED);
-
- synchronized (Tethering.this.mPublicSync) {
- switch (curState) {
- case WifiManager.WIFI_AP_STATE_ENABLING:
- // We can see this state on the way to both enabled and failure states.
- break;
- case WifiManager.WIFI_AP_STATE_ENABLED:
- enableWifiIpServingLocked(ifname, ipmode);
- break;
- case WifiManager.WIFI_AP_STATE_DISABLING:
- // We can see this state on the way to disabled.
- break;
- case WifiManager.WIFI_AP_STATE_DISABLED:
- case WifiManager.WIFI_AP_STATE_FAILED:
- default:
- disableWifiIpServingLocked(ifname, curState);
- break;
- }
- }
- }
-
- private boolean isGroupOwner(WifiP2pGroup group) {
- return group != null && group.isGroupOwner()
- && !TextUtils.isEmpty(group.getInterface());
- }
-
- private void handleWifiP2pAction(Intent intent) {
- if (mConfig.isWifiP2pLegacyTetheringMode()) return;
-
- final WifiP2pInfo p2pInfo =
- (WifiP2pInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
- final WifiP2pGroup group =
- (WifiP2pGroup) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
-
- if (VDBG) {
- Log.d(TAG, "WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group);
- }
-
- synchronized (Tethering.this.mPublicSync) {
- // if no group is formed, bring it down if needed.
- if (p2pInfo == null || !p2pInfo.groupFormed) {
- disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
- mWifiP2pTetherInterface = null;
- return;
- }
-
- // If there is a group but the device is not the owner, bail out.
- if (!isGroupOwner(group)) return;
-
- // If already serving from the correct interface, nothing to do.
- if (group.getInterface().equals(mWifiP2pTetherInterface)) return;
-
- // If already serving from another interface, turn it down first.
- if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) {
- mLog.w("P2P tethered interface " + mWifiP2pTetherInterface
- + "is different from current interface "
- + group.getInterface() + ", re-tether it");
- disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
- }
-
- // Finally bring up serving on the new interface
- mWifiP2pTetherInterface = group.getInterface();
- enableWifiIpServingLocked(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY);
- }
- }
-
- private void handleUserRestrictionAction() {
- mTetheringRestriction.onUserRestrictionsChanged();
- }
-
- private void handleDataSaverChanged() {
- final ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- final boolean isDataSaverEnabled = connMgr.getRestrictBackgroundStatus()
- != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
-
- if (mDataSaverEnabled == isDataSaverEnabled) return;
-
- mDataSaverEnabled = isDataSaverEnabled;
- if (mDataSaverEnabled) {
- untetherAll();
- }
- }
- }
-
- @VisibleForTesting
- boolean isTetheringActive() {
- return mActiveTetheringRequests.size() > 0;
- }
-
- @VisibleForTesting
- protected static class UserRestrictionActionListener {
- private final UserManager mUserMgr;
- private final Tethering mWrapper;
- private final TetheringNotificationUpdater mNotificationUpdater;
- public boolean mDisallowTethering;
-
- public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering wrapper,
- @NonNull TetheringNotificationUpdater updater) {
- mUserMgr = um;
- mWrapper = wrapper;
- mNotificationUpdater = updater;
- mDisallowTethering = false;
- }
-
- public void onUserRestrictionsChanged() {
- // getUserRestrictions gets restriction for this process' user, which is the primary
- // user. This is fine because DISALLOW_CONFIG_TETHERING can only be set on the primary
- // user. See UserManager.DISALLOW_CONFIG_TETHERING.
- final Bundle restrictions = mUserMgr.getUserRestrictions();
- final boolean newlyDisallowed =
- restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
- final boolean prevDisallowed = mDisallowTethering;
- mDisallowTethering = newlyDisallowed;
-
- final boolean tetheringDisallowedChanged = (newlyDisallowed != prevDisallowed);
- if (!tetheringDisallowedChanged) {
- return;
- }
-
- if (!newlyDisallowed) {
- // Clear the restricted notification when user is allowed to have tethering
- // function.
- mNotificationUpdater.tetheringRestrictionLifted();
- return;
- }
-
- if (mWrapper.isTetheringActive()) {
- // Restricted notification is shown when tethering function is disallowed on
- // user's device.
- mNotificationUpdater.notifyTetheringDisabledByRestriction();
-
- // Untether from all downstreams since tethering is disallowed.
- mWrapper.untetherAll();
- }
- // TODO(b/148139325): send tetheringSupported on restriction change
- }
- }
-
- private void disableWifiIpServingLockedCommon(int tetheringType, String ifname, int apState) {
- mLog.log("Canceling WiFi tethering request -"
- + " type=" + tetheringType
- + " interface=" + ifname
- + " state=" + apState);
-
- if (!TextUtils.isEmpty(ifname)) {
- final TetherState ts = mTetherStates.get(ifname);
- if (ts != null) {
- ts.ipServer.unwanted();
- return;
- }
- }
-
- for (int i = 0; i < mTetherStates.size(); i++) {
- final IpServer ipServer = mTetherStates.valueAt(i).ipServer;
- if (ipServer.interfaceType() == tetheringType) {
- ipServer.unwanted();
- return;
- }
- }
-
- mLog.log("Error disabling Wi-Fi IP serving; "
- + (TextUtils.isEmpty(ifname) ? "no interface name specified"
- : "specified interface: " + ifname));
- }
-
- private void disableWifiIpServingLocked(String ifname, int apState) {
- // Regardless of whether we requested this transition, the AP has gone
- // down. Don't try to tether again unless we're requested to do so.
- // TODO: Remove this altogether, once Wi-Fi reliably gives us an
- // interface name with every broadcast.
- mWifiTetherRequested = false;
-
- disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState);
- }
-
- private void disableWifiP2pIpServingLockedIfNeeded(String ifname) {
- if (TextUtils.isEmpty(ifname)) return;
-
- disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0);
- }
-
- private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
- // Map wifiIpMode values to IpServer.Callback serving states, inferring
- // from mWifiTetherRequested as a final "best guess".
- final int ipServingMode;
- switch (wifiIpMode) {
- case IFACE_IP_MODE_TETHERED:
- ipServingMode = IpServer.STATE_TETHERED;
- break;
- case IFACE_IP_MODE_LOCAL_ONLY:
- ipServingMode = IpServer.STATE_LOCAL_ONLY;
- break;
- default:
- mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode);
- return;
- }
-
- if (!TextUtils.isEmpty(ifname)) {
- maybeTrackNewInterfaceLocked(ifname);
- changeInterfaceState(ifname, ipServingMode);
- } else {
- mLog.e(String.format(
- "Cannot enable IP serving in mode %s on missing interface name",
- ipServingMode));
- }
- }
-
- // TODO: Consider renaming to something more accurate in its description.
- // This method:
- // - allows requesting either tethering or local hotspot serving states
- // - handles both enabling and disabling serving states
- // - only tethers the first matching interface in listInterfaces()
- // order of a given type
- private void tetherMatchingInterfaces(int requestedState, int interfaceType) {
- if (VDBG) {
- Log.d(TAG, "tetherMatchingInterfaces(" + requestedState + ", " + interfaceType + ")");
- }
-
- String[] ifaces = null;
- try {
- ifaces = mNetd.interfaceGetList();
- } catch (RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "Error listing Interfaces", e);
- return;
- }
- String chosenIface = null;
- if (ifaces != null) {
- for (String iface : ifaces) {
- if (ifaceNameToType(iface) == interfaceType) {
- chosenIface = iface;
- break;
- }
- }
- }
- if (chosenIface == null) {
- Log.e(TAG, "could not find iface of type " + interfaceType);
- return;
- }
-
- changeInterfaceState(chosenIface, requestedState);
- }
-
- private void changeInterfaceState(String ifname, int requestedState) {
- final int result;
- switch (requestedState) {
- case IpServer.STATE_UNAVAILABLE:
- case IpServer.STATE_AVAILABLE:
- result = untether(ifname);
- break;
- case IpServer.STATE_TETHERED:
- case IpServer.STATE_LOCAL_ONLY:
- result = tether(ifname, requestedState);
- break;
- default:
- Log.wtf(TAG, "Unknown interface state: " + requestedState);
- return;
- }
- if (result != TETHER_ERROR_NO_ERROR) {
- Log.e(TAG, "unable start or stop tethering on iface " + ifname);
- return;
- }
- }
-
- TetheringConfiguration getTetheringConfiguration() {
- return mConfig;
- }
-
- boolean hasTetherableConfiguration() {
- final TetheringConfiguration cfg = mConfig;
- final boolean hasDownstreamConfiguration =
- (cfg.tetherableUsbRegexs.length != 0)
- || (cfg.tetherableWifiRegexs.length != 0)
- || (cfg.tetherableBluetoothRegexs.length != 0);
- final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty()
- || cfg.chooseUpstreamAutomatically;
-
- return hasDownstreamConfiguration && hasUpstreamConfiguration;
- }
-
- // TODO - update callers to use getTetheringConfiguration(),
- // which has only final members.
- String[] getTetherableUsbRegexs() {
- return copy(mConfig.tetherableUsbRegexs);
- }
-
- String[] getTetherableWifiRegexs() {
- return copy(mConfig.tetherableWifiRegexs);
- }
-
- String[] getTetherableBluetoothRegexs() {
- return copy(mConfig.tetherableBluetoothRegexs);
- }
-
- int setUsbTethering(boolean enable) {
- if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
- UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
- if (usbManager == null) {
- mLog.e("setUsbTethering: failed to get UsbManager!");
- return TETHER_ERROR_SERVICE_UNAVAIL;
- }
-
- synchronized (mPublicSync) {
- usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_RNDIS
- : UsbManager.FUNCTION_NONE);
- }
- return TETHER_ERROR_NO_ERROR;
- }
-
- private int setNcmTethering(boolean enable) {
- if (VDBG) Log.d(TAG, "setNcmTethering(" + enable + ")");
- UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
- synchronized (mPublicSync) {
- usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_NCM
- : UsbManager.FUNCTION_NONE);
- }
- return TETHER_ERROR_NO_ERROR;
- }
-
- // TODO review API - figure out how to delete these entirely.
- String[] getTetheredIfaces() {
- ArrayList<String> list = new ArrayList<String>();
- synchronized (mPublicSync) {
- for (int i = 0; i < mTetherStates.size(); i++) {
- TetherState tetherState = mTetherStates.valueAt(i);
- if (tetherState.lastState == IpServer.STATE_TETHERED) {
- list.add(mTetherStates.keyAt(i));
- }
- }
- }
- return list.toArray(new String[list.size()]);
- }
-
- String[] getTetherableIfaces() {
- ArrayList<String> list = new ArrayList<String>();
- synchronized (mPublicSync) {
- for (int i = 0; i < mTetherStates.size(); i++) {
- TetherState tetherState = mTetherStates.valueAt(i);
- if (tetherState.lastState == IpServer.STATE_AVAILABLE) {
- list.add(mTetherStates.keyAt(i));
- }
- }
- }
- return list.toArray(new String[list.size()]);
- }
-
- String[] getTetheredDhcpRanges() {
- // TODO: this is only valid for the old DHCP server. Latest search suggests it is only used
- // by WifiP2pServiceImpl to start dnsmasq: remove/deprecate after migrating callers.
- return mConfig.legacyDhcpRanges;
- }
-
- String[] getErroredIfaces() {
- ArrayList<String> list = new ArrayList<String>();
- synchronized (mPublicSync) {
- for (int i = 0; i < mTetherStates.size(); i++) {
- TetherState tetherState = mTetherStates.valueAt(i);
- if (tetherState.lastError != TETHER_ERROR_NO_ERROR) {
- list.add(mTetherStates.keyAt(i));
- }
- }
- }
- return list.toArray(new String[list.size()]);
- }
-
- private void logMessage(State state, int what) {
- mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
- }
-
- private boolean upstreamWanted() {
- if (!mForwardedDownstreams.isEmpty()) return true;
-
- synchronized (mPublicSync) {
- return mWifiTetherRequested;
- }
- }
-
- // Needed because the canonical source of upstream truth is just the
- // upstream interface set, |mCurrentUpstreamIfaceSet|.
- private boolean pertainsToCurrentUpstream(UpstreamNetworkState ns) {
- if (ns != null && ns.linkProperties != null && mCurrentUpstreamIfaceSet != null) {
- for (String ifname : ns.linkProperties.getAllInterfaceNames()) {
- if (mCurrentUpstreamIfaceSet.ifnames.contains(ifname)) {
- return true;
- }
- }
- }
- return false;
- }
-
- class TetherMasterSM extends StateMachine {
- // an interface SM has requested Tethering/Local Hotspot
- static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MASTER + 1;
- // an interface SM has unrequested Tethering/Local Hotspot
- static final int EVENT_IFACE_SERVING_STATE_INACTIVE = BASE_MASTER + 2;
- // upstream connection change - do the right thing
- static final int CMD_UPSTREAM_CHANGED = BASE_MASTER + 3;
- // we don't have a valid upstream conn, check again after a delay
- static final int CMD_RETRY_UPSTREAM = BASE_MASTER + 4;
- // Events from NetworkCallbacks that we process on the master state
- // machine thread on behalf of the UpstreamNetworkMonitor.
- static final int EVENT_UPSTREAM_CALLBACK = BASE_MASTER + 5;
- // we treated the error and want now to clear it
- static final int CMD_CLEAR_ERROR = BASE_MASTER + 6;
- static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7;
- // Events from EntitlementManager to choose upstream again.
- static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MASTER + 8;
- private final State mInitialState;
- private final State mTetherModeAliveState;
-
- private final State mSetIpForwardingEnabledErrorState;
- private final State mSetIpForwardingDisabledErrorState;
- private final State mStartTetheringErrorState;
- private final State mStopTetheringErrorState;
- private final State mSetDnsForwardersErrorState;
-
- // This list is a little subtle. It contains all the interfaces that currently are
- // requesting tethering, regardless of whether these interfaces are still members of
- // mTetherStates. This allows us to maintain the following predicates:
- //
- // 1) mTetherStates contains the set of all currently existing, tetherable, link state up
- // interfaces.
- // 2) mNotifyList contains all state machines that may have outstanding tethering state
- // that needs to be torn down.
- //
- // Because we excise interfaces immediately from mTetherStates, we must maintain mNotifyList
- // so that the garbage collector does not clean up the state machine before it has a chance
- // to tear itself down.
- private final ArrayList<IpServer> mNotifyList;
- private final IPv6TetheringCoordinator mIPv6TetheringCoordinator;
- private final OffloadWrapper mOffload;
-
- private static final int UPSTREAM_SETTLE_TIME_MS = 10000;
-
- TetherMasterSM(String name, Looper looper, TetheringDependencies deps) {
- super(name, looper);
-
- mInitialState = new InitialState();
- mTetherModeAliveState = new TetherModeAliveState();
- mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
- mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState();
- mStartTetheringErrorState = new StartTetheringErrorState();
- mStopTetheringErrorState = new StopTetheringErrorState();
- mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
-
- addState(mInitialState);
- addState(mTetherModeAliveState);
- addState(mSetIpForwardingEnabledErrorState);
- addState(mSetIpForwardingDisabledErrorState);
- addState(mStartTetheringErrorState);
- addState(mStopTetheringErrorState);
- addState(mSetDnsForwardersErrorState);
-
- mNotifyList = new ArrayList<>();
- mIPv6TetheringCoordinator = deps.getIPv6TetheringCoordinator(mNotifyList, mLog);
- mOffload = new OffloadWrapper();
-
- setInitialState(mInitialState);
- }
-
- class InitialState extends State {
- @Override
- public boolean processMessage(Message message) {
- logMessage(this, message.what);
- switch (message.what) {
- case EVENT_IFACE_SERVING_STATE_ACTIVE: {
- final IpServer who = (IpServer) message.obj;
- if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
- handleInterfaceServingStateActive(message.arg1, who);
- transitionTo(mTetherModeAliveState);
- break;
- }
- case EVENT_IFACE_SERVING_STATE_INACTIVE: {
- final IpServer who = (IpServer) message.obj;
- if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
- handleInterfaceServingStateInactive(who);
- break;
- }
- case EVENT_IFACE_UPDATE_LINKPROPERTIES:
- // Silently ignore these for now.
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
- }
-
- protected boolean turnOnMasterTetherSettings() {
- final TetheringConfiguration cfg = mConfig;
- try {
- mNetd.ipfwdEnableForwarding(TAG);
- } catch (RemoteException | ServiceSpecificException e) {
- mLog.e(e);
- transitionTo(mSetIpForwardingEnabledErrorState);
- return false;
- }
-
- // TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
- // Legacy DHCP server is disabled if passed an empty ranges array
- final String[] dhcpRanges = cfg.enableLegacyDhcpServer
- ? cfg.legacyDhcpRanges : new String[0];
- try {
- NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
- } catch (RemoteException | ServiceSpecificException e) {
- try {
- // Stop and retry.
- mNetd.tetherStop();
- NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
- } catch (RemoteException | ServiceSpecificException ee) {
- mLog.e(ee);
- transitionTo(mStartTetheringErrorState);
- return false;
- }
- }
- mLog.log("SET master tether settings: ON");
- return true;
- }
-
- protected boolean turnOffMasterTetherSettings() {
- try {
- mNetd.tetherStop();
- } catch (RemoteException | ServiceSpecificException e) {
- mLog.e(e);
- transitionTo(mStopTetheringErrorState);
- return false;
- }
- try {
- mNetd.ipfwdDisableForwarding(TAG);
- } catch (RemoteException | ServiceSpecificException e) {
- mLog.e(e);
- transitionTo(mSetIpForwardingDisabledErrorState);
- return false;
- }
- transitionTo(mInitialState);
- mLog.log("SET master tether settings: OFF");
- return true;
- }
-
- protected void chooseUpstreamType(boolean tryCell) {
- // We rebuild configuration on ACTION_CONFIGURATION_CHANGED, but we
- // do not currently know how to watch for changes in DUN settings.
- maybeDunSettingChanged();
-
- final TetheringConfiguration config = mConfig;
- final UpstreamNetworkState ns = (config.chooseUpstreamAutomatically)
- ? mUpstreamNetworkMonitor.getCurrentPreferredUpstream()
- : mUpstreamNetworkMonitor.selectPreferredUpstreamType(
- config.preferredUpstreamIfaceTypes);
- if (ns == null) {
- if (tryCell) {
- mUpstreamNetworkMonitor.registerMobileNetworkRequest();
- // We think mobile should be coming up; don't set a retry.
- } else {
- sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
- }
- }
- setUpstreamNetwork(ns);
- final Network newUpstream = (ns != null) ? ns.network : null;
- if (mTetherUpstream != newUpstream) {
- mTetherUpstream = newUpstream;
- mUpstreamNetworkMonitor.setCurrentUpstream(mTetherUpstream);
- reportUpstreamChanged(ns);
- }
- }
-
- protected void setUpstreamNetwork(UpstreamNetworkState ns) {
- InterfaceSet ifaces = null;
- if (ns != null) {
- // Find the interface with the default IPv4 route. It may be the
- // interface described by linkProperties, or one of the interfaces
- // stacked on top of it.
- mLog.i("Looking for default routes on: " + ns.linkProperties);
- ifaces = TetheringInterfaceUtils.getTetheringInterfaces(ns);
- mLog.i("Found upstream interface(s): " + ifaces);
- }
-
- if (ifaces != null) {
- setDnsForwarders(ns.network, ns.linkProperties);
- }
- notifyDownstreamsOfNewUpstreamIface(ifaces);
- if (ns != null && pertainsToCurrentUpstream(ns)) {
- // If we already have UpstreamNetworkState for this network update it immediately.
- handleNewUpstreamNetworkState(ns);
- } else if (mCurrentUpstreamIfaceSet == null) {
- // There are no available upstream networks.
- handleNewUpstreamNetworkState(null);
- }
- }
-
- protected void setDnsForwarders(final Network network, final LinkProperties lp) {
- // TODO: Set v4 and/or v6 DNS per available connectivity.
- final Collection<InetAddress> dnses = lp.getDnsServers();
- // TODO: Properly support the absence of DNS servers.
- final String[] dnsServers;
- if (dnses != null && !dnses.isEmpty()) {
- dnsServers = new String[dnses.size()];
- int i = 0;
- for (InetAddress dns : dnses) {
- dnsServers[i++] = dns.getHostAddress();
- }
- } else {
- dnsServers = mConfig.defaultIPv4DNS;
- }
- final int netId = (network != null) ? network.getNetId() : NETID_UNSET;
- try {
- mNetd.tetherDnsSet(netId, dnsServers);
- mLog.log(String.format(
- "SET DNS forwarders: network=%s dnsServers=%s",
- network, Arrays.toString(dnsServers)));
- } catch (RemoteException | ServiceSpecificException e) {
- // TODO: Investigate how this can fail and what exactly
- // happens if/when such failures occur.
- mLog.e("setting DNS forwarders failed, " + e);
- transitionTo(mSetDnsForwardersErrorState);
- }
- }
-
- protected void notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces) {
- mCurrentUpstreamIfaceSet = ifaces;
- for (IpServer ipServer : mNotifyList) {
- ipServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifaces);
- }
- }
-
- protected void handleNewUpstreamNetworkState(UpstreamNetworkState ns) {
- mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
- mOffload.updateUpstreamNetworkState(ns);
- }
-
- private void handleInterfaceServingStateActive(int mode, IpServer who) {
- if (mNotifyList.indexOf(who) < 0) {
- mNotifyList.add(who);
- mIPv6TetheringCoordinator.addActiveDownstream(who, mode);
- }
-
- if (mode == IpServer.STATE_TETHERED) {
- // No need to notify OffloadController just yet as there are no
- // "offload-able" prefixes to pass along. This will handled
- // when the TISM informs Tethering of its LinkProperties.
- mForwardedDownstreams.add(who);
- } else {
- mOffload.excludeDownstreamInterface(who.interfaceName());
- mForwardedDownstreams.remove(who);
- }
-
- // If this is a Wi-Fi interface, notify WifiManager of the active serving state.
- if (who.interfaceType() == TETHERING_WIFI) {
- final WifiManager mgr = getWifiManager();
- final String iface = who.interfaceName();
- switch (mode) {
- case IpServer.STATE_TETHERED:
- mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED);
- break;
- case IpServer.STATE_LOCAL_ONLY:
- mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY);
- break;
- default:
- Log.wtf(TAG, "Unknown active serving mode: " + mode);
- break;
- }
- }
- }
-
- private void handleInterfaceServingStateInactive(IpServer who) {
- mNotifyList.remove(who);
- mIPv6TetheringCoordinator.removeActiveDownstream(who);
- mOffload.excludeDownstreamInterface(who.interfaceName());
- mForwardedDownstreams.remove(who);
- updateConnectedClients(null /* wifiClients */);
-
- // If this is a Wi-Fi interface, tell WifiManager of any errors
- // or the inactive serving state.
- if (who.interfaceType() == TETHERING_WIFI) {
- if (who.lastError() != TETHER_ERROR_NO_ERROR) {
- getWifiManager().updateInterfaceIpState(
- who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR);
- } else {
- getWifiManager().updateInterfaceIpState(
- who.interfaceName(), IFACE_IP_MODE_UNSPECIFIED);
- }
- }
- }
-
- private void addUpstreamPrefixes(final UpstreamNetworkState ns) {
- mPrivateAddressCoordinator.updateUpstreamPrefix(ns.network, ns.linkProperties);
- }
-
- private void removeUpstreamPrefixes(final UpstreamNetworkState ns) {
- mPrivateAddressCoordinator.removeUpstreamPrefix(ns.network);
- }
-
- @VisibleForTesting
- void handleUpstreamNetworkMonitorCallback(int arg1, Object o) {
- if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) {
- mOffload.sendOffloadExemptPrefixes((Set<IpPrefix>) o);
- return;
- }
-
- final UpstreamNetworkState ns = (UpstreamNetworkState) o;
- switch (arg1) {
- case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
- addUpstreamPrefixes(ns);
- break;
- case UpstreamNetworkMonitor.EVENT_ON_LOST:
- removeUpstreamPrefixes(ns);
- break;
- }
-
- if (ns == null || !pertainsToCurrentUpstream(ns)) {
- // TODO: In future, this is where upstream evaluation and selection
- // could be handled for notifications which include sufficient data.
- // For example, after CONNECTIVITY_ACTION listening is removed, here
- // is where we could observe a Wi-Fi network becoming available and
- // passing validation.
- if (mCurrentUpstreamIfaceSet == null) {
- // If we have no upstream interface, try to run through upstream
- // selection again. If, for example, IPv4 connectivity has shown up
- // after IPv6 (e.g., 464xlat became available) we want the chance to
- // notice and act accordingly.
- chooseUpstreamType(false);
- }
- return;
- }
-
- switch (arg1) {
- case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES:
- if (ns.network.equals(mTetherUpstream)) {
- mNotificationUpdater.onUpstreamCapabilitiesChanged(ns.networkCapabilities);
- }
- handleNewUpstreamNetworkState(ns);
- break;
- case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
- chooseUpstreamType(false);
- break;
- case UpstreamNetworkMonitor.EVENT_ON_LOST:
- // TODO: Re-evaluate possible upstreams. Currently upstream
- // reevaluation is triggered via received CONNECTIVITY_ACTION
- // broadcasts that result in being passed a
- // TetherMasterSM.CMD_UPSTREAM_CHANGED.
- handleNewUpstreamNetworkState(null);
- break;
- default:
- mLog.e("Unknown arg1 value: " + arg1);
- break;
- }
- }
-
- class TetherModeAliveState extends State {
- boolean mUpstreamWanted = false;
- boolean mTryCell = true;
-
- @Override
- public void enter() {
- // If turning on master tether settings fails, we have already
- // transitioned to an error state; exit early.
- if (!turnOnMasterTetherSettings()) {
- return;
- }
-
- mUpstreamNetworkMonitor.startObserveAllNetworks();
-
- // TODO: De-duplicate with updateUpstreamWanted() below.
- if (upstreamWanted()) {
- mUpstreamWanted = true;
- mOffload.start();
- chooseUpstreamType(true);
- mTryCell = false;
- }
-
- // TODO: Check the upstream interface if it is managed by BPF offload.
- mBpfCoordinator.startPolling();
- }
-
- @Override
- public void exit() {
- mOffload.stop();
- mUpstreamNetworkMonitor.stop();
- notifyDownstreamsOfNewUpstreamIface(null);
- handleNewUpstreamNetworkState(null);
- if (mTetherUpstream != null) {
- mTetherUpstream = null;
- reportUpstreamChanged(null);
- }
- mBpfCoordinator.stopPolling();
- }
-
- private boolean updateUpstreamWanted() {
- final boolean previousUpstreamWanted = mUpstreamWanted;
- mUpstreamWanted = upstreamWanted();
- if (mUpstreamWanted != previousUpstreamWanted) {
- if (mUpstreamWanted) {
- mOffload.start();
- } else {
- mOffload.stop();
- }
- }
- return previousUpstreamWanted;
- }
-
- @Override
- public boolean processMessage(Message message) {
- logMessage(this, message.what);
- boolean retValue = true;
- switch (message.what) {
- case EVENT_IFACE_SERVING_STATE_ACTIVE: {
- IpServer who = (IpServer) message.obj;
- if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
- handleInterfaceServingStateActive(message.arg1, who);
- who.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED,
- mCurrentUpstreamIfaceSet);
- // If there has been a change and an upstream is now
- // desired, kick off the selection process.
- final boolean previousUpstreamWanted = updateUpstreamWanted();
- if (!previousUpstreamWanted && mUpstreamWanted) {
- chooseUpstreamType(true);
- }
- break;
- }
- case EVENT_IFACE_SERVING_STATE_INACTIVE: {
- IpServer who = (IpServer) message.obj;
- if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
- handleInterfaceServingStateInactive(who);
-
- if (mNotifyList.isEmpty()) {
- // This transitions us out of TetherModeAliveState,
- // either to InitialState or an error state.
- turnOffMasterTetherSettings();
- break;
- }
-
- if (DBG) {
- Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size()
- + " live requests:");
- for (IpServer o : mNotifyList) {
- Log.d(TAG, " " + o);
- }
- }
- // If there has been a change and an upstream is no
- // longer desired, release any mobile requests.
- final boolean previousUpstreamWanted = updateUpstreamWanted();
- if (previousUpstreamWanted && !mUpstreamWanted) {
- mUpstreamNetworkMonitor.releaseMobileNetworkRequest();
- }
- break;
- }
- case EVENT_IFACE_UPDATE_LINKPROPERTIES: {
- final LinkProperties newLp = (LinkProperties) message.obj;
- if (message.arg1 == IpServer.STATE_TETHERED) {
- mOffload.updateDownstreamLinkProperties(newLp);
- } else {
- mOffload.excludeDownstreamInterface(newLp.getInterfaceName());
- }
- break;
- }
- case EVENT_UPSTREAM_PERMISSION_CHANGED:
- case CMD_UPSTREAM_CHANGED:
- updateUpstreamWanted();
- if (!mUpstreamWanted) break;
-
- // Need to try DUN immediately if Wi-Fi goes down.
- chooseUpstreamType(true);
- mTryCell = false;
- break;
- case CMD_RETRY_UPSTREAM:
- updateUpstreamWanted();
- if (!mUpstreamWanted) break;
-
- chooseUpstreamType(mTryCell);
- mTryCell = !mTryCell;
- break;
- case EVENT_UPSTREAM_CALLBACK: {
- updateUpstreamWanted();
- if (mUpstreamWanted) {
- handleUpstreamNetworkMonitorCallback(message.arg1, message.obj);
- }
- break;
- }
- default:
- retValue = false;
- break;
- }
- return retValue;
- }
- }
-
- class ErrorState extends State {
- private int mErrorNotification;
-
- @Override
- public boolean processMessage(Message message) {
- boolean retValue = true;
- switch (message.what) {
- case EVENT_IFACE_SERVING_STATE_ACTIVE:
- IpServer who = (IpServer) message.obj;
- who.sendMessage(mErrorNotification);
- break;
- case CMD_CLEAR_ERROR:
- mErrorNotification = TETHER_ERROR_NO_ERROR;
- transitionTo(mInitialState);
- break;
- default:
- retValue = false;
- }
- return retValue;
- }
-
- void notify(int msgType) {
- mErrorNotification = msgType;
- for (IpServer ipServer : mNotifyList) {
- ipServer.sendMessage(msgType);
- }
- }
-
- }
-
- class SetIpForwardingEnabledErrorState extends ErrorState {
- @Override
- public void enter() {
- Log.e(TAG, "Error in setIpForwardingEnabled");
- notify(IpServer.CMD_IP_FORWARDING_ENABLE_ERROR);
- }
- }
-
- class SetIpForwardingDisabledErrorState extends ErrorState {
- @Override
- public void enter() {
- Log.e(TAG, "Error in setIpForwardingDisabled");
- notify(IpServer.CMD_IP_FORWARDING_DISABLE_ERROR);
- }
- }
-
- class StartTetheringErrorState extends ErrorState {
- @Override
- public void enter() {
- Log.e(TAG, "Error in startTethering");
- notify(IpServer.CMD_START_TETHERING_ERROR);
- try {
- mNetd.ipfwdDisableForwarding(TAG);
- } catch (RemoteException | ServiceSpecificException e) { }
- }
- }
-
- class StopTetheringErrorState extends ErrorState {
- @Override
- public void enter() {
- Log.e(TAG, "Error in stopTethering");
- notify(IpServer.CMD_STOP_TETHERING_ERROR);
- try {
- mNetd.ipfwdDisableForwarding(TAG);
- } catch (RemoteException | ServiceSpecificException e) { }
- }
- }
-
- class SetDnsForwardersErrorState extends ErrorState {
- @Override
- public void enter() {
- Log.e(TAG, "Error in setDnsForwarders");
- notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR);
- try {
- mNetd.tetherStop();
- } catch (RemoteException | ServiceSpecificException e) { }
- try {
- mNetd.ipfwdDisableForwarding(TAG);
- } catch (RemoteException | ServiceSpecificException e) { }
- }
- }
-
- // A wrapper class to handle multiple situations where several calls to
- // the OffloadController need to happen together.
- //
- // TODO: This suggests that the interface between OffloadController and
- // Tethering is in need of improvement. Refactor these calls into the
- // OffloadController implementation.
- class OffloadWrapper {
- public void start() {
- final int status = mOffloadController.start() ? TETHER_HARDWARE_OFFLOAD_STARTED
- : TETHER_HARDWARE_OFFLOAD_FAILED;
- updateOffloadStatus(status);
- sendOffloadExemptPrefixes();
- }
-
- public void stop() {
- mOffloadController.stop();
- updateOffloadStatus(TETHER_HARDWARE_OFFLOAD_STOPPED);
- }
-
- public void updateUpstreamNetworkState(UpstreamNetworkState ns) {
- mOffloadController.setUpstreamLinkProperties(
- (ns != null) ? ns.linkProperties : null);
- }
-
- public void updateDownstreamLinkProperties(LinkProperties newLp) {
- // Update the list of offload-exempt prefixes before adding
- // new prefixes on downstream interfaces to the offload HAL.
- sendOffloadExemptPrefixes();
- mOffloadController.notifyDownstreamLinkProperties(newLp);
- }
-
- public void excludeDownstreamInterface(String ifname) {
- // This and other interfaces may be in local-only hotspot mode;
- // resend all local prefixes to the OffloadController.
- sendOffloadExemptPrefixes();
- mOffloadController.removeDownstreamInterface(ifname);
- }
-
- public void sendOffloadExemptPrefixes() {
- sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes());
- }
-
- public void sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes) {
- // Add in well-known minimum set.
- PrefixUtils.addNonForwardablePrefixes(localPrefixes);
- // Add tragically hardcoded prefixes.
- localPrefixes.add(PrefixUtils.DEFAULT_WIFI_P2P_PREFIX);
-
- // Maybe add prefixes or addresses for downstreams, depending on
- // the IP serving mode of each.
- for (IpServer ipServer : mNotifyList) {
- final LinkProperties lp = ipServer.linkProperties();
-
- switch (ipServer.servingMode()) {
- case IpServer.STATE_UNAVAILABLE:
- case IpServer.STATE_AVAILABLE:
- // No usable LinkProperties in these states.
- continue;
- case IpServer.STATE_TETHERED:
- // Only add IPv4 /32 and IPv6 /128 prefixes. The
- // directly-connected prefixes will be sent as
- // downstream "offload-able" prefixes.
- for (LinkAddress addr : lp.getAllLinkAddresses()) {
- final InetAddress ip = addr.getAddress();
- if (ip.isLinkLocalAddress()) continue;
- localPrefixes.add(PrefixUtils.ipAddressAsPrefix(ip));
- }
- break;
- case IpServer.STATE_LOCAL_ONLY:
- // Add prefixes covering all local IPs.
- localPrefixes.addAll(PrefixUtils.localPrefixesFrom(lp));
- break;
- }
- }
-
- mOffloadController.setLocalPrefixes(localPrefixes);
- }
-
- private void updateOffloadStatus(final int newStatus) {
- if (newStatus == mOffloadStatus) return;
-
- mOffloadStatus = newStatus;
- reportOffloadStatusChanged(mOffloadStatus);
- }
- }
- }
-
- private void startTrackDefaultNetwork() {
- mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest(),
- mEntitlementMgr);
- }
-
- /** Get the latest value of the tethering entitlement check. */
- void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
- boolean showEntitlementUi) {
- if (receiver == null) return;
-
- mHandler.post(() -> {
- mEntitlementMgr.requestLatestTetheringEntitlementResult(type, receiver,
- showEntitlementUi);
- });
- }
-
- /** Register tethering event callback */
- void registerTetheringEventCallback(ITetheringEventCallback callback) {
- final boolean hasListPermission =
- hasCallingPermission(NETWORK_SETTINGS)
- || hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)
- || hasCallingPermission(NETWORK_STACK);
- mHandler.post(() -> {
- mTetheringEventCallbacks.register(callback, new CallbackCookie(hasListPermission));
- final TetheringCallbackStartedParcel parcel = new TetheringCallbackStartedParcel();
- parcel.tetheringSupported = isTetheringSupported();
- parcel.upstreamNetwork = mTetherUpstream;
- parcel.config = mConfig.toStableParcelable();
- parcel.states =
- mTetherStatesParcel != null ? mTetherStatesParcel : emptyTetherStatesParcel();
- parcel.tetheredClients = hasListPermission
- ? mConnectedClientsTracker.getLastTetheredClients()
- : Collections.emptyList();
- parcel.offloadStatus = mOffloadStatus;
- try {
- callback.onCallbackStarted(parcel);
- } catch (RemoteException e) {
- // Not really very much to do here.
- }
- });
- }
-
- private TetherStatesParcel emptyTetherStatesParcel() {
- final TetherStatesParcel parcel = new TetherStatesParcel();
- parcel.availableList = new String[0];
- parcel.tetheredList = new String[0];
- parcel.localOnlyList = new String[0];
- parcel.erroredIfaceList = new String[0];
- parcel.lastErrorList = new int[0];
-
- return parcel;
- }
-
- private boolean hasCallingPermission(@NonNull String permission) {
- return mContext.checkCallingPermission(permission) == PERMISSION_GRANTED;
- }
-
- /** Unregister tethering event callback */
- void unregisterTetheringEventCallback(ITetheringEventCallback callback) {
- mHandler.post(() -> {
- mTetheringEventCallbacks.unregister(callback);
- });
- }
-
- private void reportUpstreamChanged(UpstreamNetworkState ns) {
- final int length = mTetheringEventCallbacks.beginBroadcast();
- final Network network = (ns != null) ? ns.network : null;
- final NetworkCapabilities capabilities = (ns != null) ? ns.networkCapabilities : null;
- try {
- for (int i = 0; i < length; i++) {
- try {
- mTetheringEventCallbacks.getBroadcastItem(i).onUpstreamChanged(network);
- } catch (RemoteException e) {
- // Not really very much to do here.
- }
- }
- } finally {
- mTetheringEventCallbacks.finishBroadcast();
- }
- // Need to notify capabilities change after upstream network changed because new network's
- // capabilities should be checked every time.
- mNotificationUpdater.onUpstreamCapabilitiesChanged(capabilities);
- }
-
- private void reportConfigurationChanged(TetheringConfigurationParcel config) {
- final int length = mTetheringEventCallbacks.beginBroadcast();
- try {
- for (int i = 0; i < length; i++) {
- try {
- mTetheringEventCallbacks.getBroadcastItem(i).onConfigurationChanged(config);
- // TODO(b/148139325): send tetheringSupported on configuration change
- } catch (RemoteException e) {
- // Not really very much to do here.
- }
- }
- } finally {
- mTetheringEventCallbacks.finishBroadcast();
- }
- }
-
- private void reportTetherStateChanged(TetherStatesParcel states) {
- final int length = mTetheringEventCallbacks.beginBroadcast();
- try {
- for (int i = 0; i < length; i++) {
- try {
- mTetheringEventCallbacks.getBroadcastItem(i).onTetherStatesChanged(states);
- } catch (RemoteException e) {
- // Not really very much to do here.
- }
- }
- } finally {
- mTetheringEventCallbacks.finishBroadcast();
- }
- }
-
- private void reportTetherClientsChanged(List<TetheredClient> clients) {
- final int length = mTetheringEventCallbacks.beginBroadcast();
- try {
- for (int i = 0; i < length; i++) {
- try {
- final CallbackCookie cookie =
- (CallbackCookie) mTetheringEventCallbacks.getBroadcastCookie(i);
- if (!cookie.hasListClientsPermission) continue;
- mTetheringEventCallbacks.getBroadcastItem(i).onTetherClientsChanged(clients);
- } catch (RemoteException e) {
- // Not really very much to do here.
- }
- }
- } finally {
- mTetheringEventCallbacks.finishBroadcast();
- }
- }
-
- private void reportOffloadStatusChanged(final int status) {
- final int length = mTetheringEventCallbacks.beginBroadcast();
- try {
- for (int i = 0; i < length; i++) {
- try {
- mTetheringEventCallbacks.getBroadcastItem(i).onOffloadStatusChanged(status);
- } catch (RemoteException e) {
- // Not really very much to do here.
- }
- }
- } finally {
- mTetheringEventCallbacks.finishBroadcast();
- }
- }
-
- // if ro.tether.denied = true we default to no tethering
- // gservices could set the secure setting to 1 though to enable it on a build where it
- // had previously been turned off.
- boolean isTetheringSupported() {
- final int defaultVal = mDeps.isTetheringDenied() ? 0 : 1;
- final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
- final boolean tetherEnabledInSettings = tetherSupported
- && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
-
- return tetherEnabledInSettings && hasTetherableConfiguration()
- && !isProvisioningNeededButUnavailable();
- }
-
- void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
- // Binder.java closes the resource for us.
- @SuppressWarnings("resource")
- final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump.");
- return;
- }
-
- pw.println("Tethering:");
- pw.increaseIndent();
-
- pw.println("Configuration:");
- pw.increaseIndent();
- final TetheringConfiguration cfg = mConfig;
- cfg.dump(pw);
- pw.decreaseIndent();
-
- pw.println("Entitlement:");
- pw.increaseIndent();
- mEntitlementMgr.dump(pw);
- pw.decreaseIndent();
-
- synchronized (mPublicSync) {
- pw.println("Tether state:");
- pw.increaseIndent();
- for (int i = 0; i < mTetherStates.size(); i++) {
- final String iface = mTetherStates.keyAt(i);
- final TetherState tetherState = mTetherStates.valueAt(i);
- pw.print(iface + " - ");
-
- switch (tetherState.lastState) {
- case IpServer.STATE_UNAVAILABLE:
- pw.print("UnavailableState");
- break;
- case IpServer.STATE_AVAILABLE:
- pw.print("AvailableState");
- break;
- case IpServer.STATE_TETHERED:
- pw.print("TetheredState");
- break;
- case IpServer.STATE_LOCAL_ONLY:
- pw.print("LocalHotspotState");
- break;
- default:
- pw.print("UnknownState");
- break;
- }
- pw.println(" - lastError = " + tetherState.lastError);
- }
- pw.println("Upstream wanted: " + upstreamWanted());
- pw.println("Current upstream interface(s): " + mCurrentUpstreamIfaceSet);
- pw.decreaseIndent();
- }
-
- pw.println("Hardware offload:");
- pw.increaseIndent();
- mOffloadController.dump(pw);
- pw.decreaseIndent();
-
- pw.println("BPF offload:");
- pw.increaseIndent();
- mBpfCoordinator.dump(pw);
- pw.decreaseIndent();
-
- pw.println("Private address coordinator:");
- pw.increaseIndent();
- mPrivateAddressCoordinator.dump(pw);
- pw.decreaseIndent();
-
- pw.println("Log:");
- pw.increaseIndent();
- if (argsContain(args, "--short")) {
- pw.println("<log removed for brevity>");
- } else {
- mLog.dump(fd, pw, args);
- }
- pw.decreaseIndent();
-
- pw.decreaseIndent();
- }
-
- private static boolean argsContain(String[] args, String target) {
- for (String arg : args) {
- if (target.equals(arg)) return true;
- }
- return false;
- }
-
- private void updateConnectedClients(final List<WifiClient> wifiClients) {
- if (mConnectedClientsTracker.updateConnectedClients(mForwardedDownstreams, wifiClients)) {
- reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients());
- }
- }
-
- private IpServer.Callback makeControlCallback() {
- return new IpServer.Callback() {
- @Override
- public void updateInterfaceState(IpServer who, int state, int lastError) {
- notifyInterfaceStateChange(who, state, lastError);
- }
-
- @Override
- public void updateLinkProperties(IpServer who, LinkProperties newLp) {
- notifyLinkPropertiesChanged(who, newLp);
- }
-
- @Override
- public void dhcpLeasesChanged() {
- updateConnectedClients(null /* wifiClients */);
- }
-
- @Override
- public void requestEnableTethering(int tetheringType, boolean enabled) {
- enableTetheringInternal(tetheringType, enabled, null);
- }
- };
- }
-
- // TODO: Move into TetherMasterSM.
- private void notifyInterfaceStateChange(IpServer who, int state, int error) {
- final String iface = who.interfaceName();
- synchronized (mPublicSync) {
- final TetherState tetherState = mTetherStates.get(iface);
- if (tetherState != null && tetherState.ipServer.equals(who)) {
- tetherState.lastState = state;
- tetherState.lastError = error;
- } else {
- if (DBG) Log.d(TAG, "got notification from stale iface " + iface);
- }
- }
-
- mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error));
-
- // If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
- // Thus we give a chance for TetherMasterSM to recover to InitialState
- // by sending CMD_CLEAR_ERROR
- if (error == TETHER_ERROR_INTERNAL_ERROR) {
- mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
- }
- int which;
- switch (state) {
- case IpServer.STATE_UNAVAILABLE:
- case IpServer.STATE_AVAILABLE:
- which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
- break;
- case IpServer.STATE_TETHERED:
- case IpServer.STATE_LOCAL_ONLY:
- which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
- break;
- default:
- Log.wtf(TAG, "Unknown interface state: " + state);
- return;
- }
- mTetherMasterSM.sendMessage(which, state, 0, who);
- sendTetherStateChangedBroadcast();
- }
-
- private void notifyLinkPropertiesChanged(IpServer who, LinkProperties newLp) {
- final String iface = who.interfaceName();
- final int state;
- synchronized (mPublicSync) {
- final TetherState tetherState = mTetherStates.get(iface);
- if (tetherState != null && tetherState.ipServer.equals(who)) {
- state = tetherState.lastState;
- } else {
- mLog.log("got notification from stale iface " + iface);
- return;
- }
- }
-
- mLog.log(String.format(
- "OBSERVED LinkProperties update iface=%s state=%s lp=%s",
- iface, IpServer.getStateString(state), newLp));
- final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
- mTetherMasterSM.sendMessage(which, state, 0, newLp);
- }
-
- private void maybeTrackNewInterfaceLocked(final String iface) {
- // If we don't care about this type of interface, ignore.
- final int interfaceType = ifaceNameToType(iface);
- if (interfaceType == TETHERING_INVALID) {
- mLog.log(iface + " is not a tetherable iface, ignoring");
- return;
- }
- maybeTrackNewInterfaceLocked(iface, interfaceType);
- }
-
- private void maybeTrackNewInterfaceLocked(final String iface, int interfaceType) {
- // If we have already started a TISM for this interface, skip.
- if (mTetherStates.containsKey(iface)) {
- mLog.log("active iface (" + iface + ") reported as added, ignoring");
- return;
- }
-
- mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
- final TetherState tetherState = new TetherState(
- new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mBpfCoordinator,
- makeControlCallback(), mConfig.enableLegacyDhcpServer,
- mConfig.isBpfOffloadEnabled(), mPrivateAddressCoordinator,
- mDeps.getIpServerDependencies()));
- mTetherStates.put(iface, tetherState);
- tetherState.ipServer.start();
- }
-
- private void stopTrackingInterfaceLocked(final String iface) {
- final TetherState tetherState = mTetherStates.get(iface);
- if (tetherState == null) {
- mLog.log("attempting to remove unknown iface (" + iface + "), ignoring");
- return;
- }
- tetherState.ipServer.stop();
- mLog.log("removing TetheringInterfaceStateMachine for: " + iface);
- mTetherStates.remove(iface);
- }
-
- private static String[] copy(String[] strarray) {
- return Arrays.copyOf(strarray, strarray.length);
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
deleted file mode 100644
index e1771a5..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ /dev/null
@@ -1,485 +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.networkstack.tethering;
-
-import static android.content.Context.TELEPHONY_SERVICE;
-import static android.net.ConnectivityManager.TYPE_ETHERNET;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
-import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
-import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.TetheringConfigurationParcel;
-import android.net.util.SharedLog;
-import android.provider.DeviceConfig;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.StringJoiner;
-
-
-/**
- * A utility class to encapsulate the various tethering configuration elements.
- *
- * This configuration data includes elements describing upstream properties
- * (preferred and required types of upstream connectivity as well as default
- * DNS servers to use if none are available) and downstream properties (such
- * as regular expressions use to match suitable downstream interfaces and the
- * DHCPv4 ranges to use).
- *
- * @hide
- */
-public class TetheringConfiguration {
- private static final String TAG = TetheringConfiguration.class.getSimpleName();
-
- private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
- // Default ranges used for the legacy DHCP server.
- // USB is 192.168.42.1 and 255.255.255.0
- // Wifi is 192.168.43.1 and 255.255.255.0
- // BT is limited to max default of 5 connections. 192.168.44.1 to 192.168.48.1
- // with 255.255.255.0
- // P2P is 192.168.49.1 and 255.255.255.0
- private static final String[] LEGACY_DHCP_DEFAULT_RANGE = {
- "192.168.42.2", "192.168.42.254", "192.168.43.2", "192.168.43.254",
- "192.168.44.2", "192.168.44.254", "192.168.45.2", "192.168.45.254",
- "192.168.46.2", "192.168.46.254", "192.168.47.2", "192.168.47.254",
- "192.168.48.2", "192.168.48.254", "192.168.49.2", "192.168.49.254",
- };
-
- private static final String[] DEFAULT_IPV4_DNS = {"8.8.4.4", "8.8.8.8"};
-
- /**
- * Override enabling BPF offload configuration for tethering.
- */
- public static final String OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD =
- "override_tether_enable_bpf_offload";
-
- /**
- * Use the old dnsmasq DHCP server for tethering instead of the framework implementation.
- */
- public static final String TETHER_ENABLE_LEGACY_DHCP_SERVER =
- "tether_enable_legacy_dhcp_server";
-
- /**
- * Default value that used to periodic polls tether offload stats from tethering offload HAL
- * to make the data warnings work.
- */
- public static final int DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS = 5000;
-
- public final String[] tetherableUsbRegexs;
- public final String[] tetherableWifiRegexs;
- public final String[] tetherableWigigRegexs;
- public final String[] tetherableWifiP2pRegexs;
- public final String[] tetherableBluetoothRegexs;
- public final String[] tetherableNcmRegexs;
- public final boolean isDunRequired;
- public final boolean chooseUpstreamAutomatically;
- public final Collection<Integer> preferredUpstreamIfaceTypes;
- public final String[] legacyDhcpRanges;
- public final String[] defaultIPv4DNS;
- public final boolean enableLegacyDhcpServer;
-
- public final String[] provisioningApp;
- public final String provisioningAppNoUi;
- public final int provisioningCheckPeriod;
- public final String provisioningResponse;
-
- public final int activeDataSubId;
-
- private final int mOffloadPollInterval;
- // TODO: Add to TetheringConfigurationParcel if required.
- private final boolean mEnableBpfOffload;
-
- public TetheringConfiguration(Context ctx, SharedLog log, int id) {
- final SharedLog configLog = log.forSubComponent("config");
-
- activeDataSubId = id;
- Resources res = getResources(ctx, activeDataSubId);
-
- tetherableUsbRegexs = getResourceStringArray(res, R.array.config_tether_usb_regexs);
- tetherableNcmRegexs = getResourceStringArray(res, R.array.config_tether_ncm_regexs);
- // TODO: Evaluate deleting this altogether now that Wi-Fi always passes
- // us an interface name. Careful consideration needs to be given to
- // implications for Settings and for provisioning checks.
- tetherableWifiRegexs = getResourceStringArray(res, R.array.config_tether_wifi_regexs);
- tetherableWigigRegexs = getResourceStringArray(res, R.array.config_tether_wigig_regexs);
- tetherableWifiP2pRegexs = getResourceStringArray(
- res, R.array.config_tether_wifi_p2p_regexs);
- tetherableBluetoothRegexs = getResourceStringArray(
- res, R.array.config_tether_bluetooth_regexs);
-
- isDunRequired = checkDunRequired(ctx);
-
- chooseUpstreamAutomatically = getResourceBoolean(
- res, R.bool.config_tether_upstream_automatic, false /** defaultValue */);
- preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired);
-
- legacyDhcpRanges = getLegacyDhcpRanges(res);
- defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
- mEnableBpfOffload = getEnableBpfOffload(res);
- enableLegacyDhcpServer = getEnableLegacyDhcpServer(res);
-
- provisioningApp = getResourceStringArray(res, R.array.config_mobile_hotspot_provision_app);
- provisioningAppNoUi = getResourceString(res,
- R.string.config_mobile_hotspot_provision_app_no_ui);
- provisioningCheckPeriod = getResourceInteger(res,
- R.integer.config_mobile_hotspot_provision_check_period,
- 0 /* No periodic re-check */);
- provisioningResponse = getResourceString(res,
- R.string.config_mobile_hotspot_provision_response);
-
- mOffloadPollInterval = getResourceInteger(res,
- R.integer.config_tether_offload_poll_interval,
- DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
-
- configLog.log(toString());
- }
-
- /** Check whether input interface belong to usb.*/
- public boolean isUsb(String iface) {
- return matchesDownstreamRegexs(iface, tetherableUsbRegexs);
- }
-
- /** Check whether input interface belong to wifi.*/
- public boolean isWifi(String iface) {
- return matchesDownstreamRegexs(iface, tetherableWifiRegexs);
- }
-
- /** Check whether input interface belong to wigig.*/
- public boolean isWigig(String iface) {
- return matchesDownstreamRegexs(iface, tetherableWigigRegexs);
- }
-
- /** Check whether this interface is Wifi P2P interface. */
- public boolean isWifiP2p(String iface) {
- return matchesDownstreamRegexs(iface, tetherableWifiP2pRegexs);
- }
-
- /** Check whether using legacy mode for wifi P2P. */
- public boolean isWifiP2pLegacyTetheringMode() {
- return (tetherableWifiP2pRegexs == null || tetherableWifiP2pRegexs.length == 0);
- }
-
- /** Check whether input interface belong to bluetooth.*/
- public boolean isBluetooth(String iface) {
- return matchesDownstreamRegexs(iface, tetherableBluetoothRegexs);
- }
-
- /** Check if interface is ncm */
- public boolean isNcm(String iface) {
- return matchesDownstreamRegexs(iface, tetherableNcmRegexs);
- }
-
- /** Check whether no ui entitlement application is available.*/
- public boolean hasMobileHotspotProvisionApp() {
- return !TextUtils.isEmpty(provisioningAppNoUi);
- }
-
- /** Does the dumping.*/
- public void dump(PrintWriter pw) {
- pw.print("activeDataSubId: ");
- pw.println(activeDataSubId);
-
- dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs);
- dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs);
- dumpStringArray(pw, "tetherableWifiP2pRegexs", tetherableWifiP2pRegexs);
- dumpStringArray(pw, "tetherableBluetoothRegexs", tetherableBluetoothRegexs);
- dumpStringArray(pw, "tetherableNcmRegexs", tetherableNcmRegexs);
-
- pw.print("isDunRequired: ");
- pw.println(isDunRequired);
-
- pw.print("chooseUpstreamAutomatically: ");
- pw.println(chooseUpstreamAutomatically);
- pw.print("legacyPreredUpstreamIfaceTypes: ");
- pw.println(Arrays.toString(toIntArray(preferredUpstreamIfaceTypes)));
-
- dumpStringArray(pw, "legacyDhcpRanges", legacyDhcpRanges);
- dumpStringArray(pw, "defaultIPv4DNS", defaultIPv4DNS);
-
- pw.print("offloadPollInterval: ");
- pw.println(mOffloadPollInterval);
-
- dumpStringArray(pw, "provisioningApp", provisioningApp);
- pw.print("provisioningAppNoUi: ");
- pw.println(provisioningAppNoUi);
-
- pw.print("enableBpfOffload: ");
- pw.println(mEnableBpfOffload);
-
- pw.print("enableLegacyDhcpServer: ");
- pw.println(enableLegacyDhcpServer);
- }
-
- /** Returns the string representation of this object.*/
- public String toString() {
- final StringJoiner sj = new StringJoiner(" ");
- sj.add(String.format("activeDataSubId:%d", activeDataSubId));
- sj.add(String.format("tetherableUsbRegexs:%s", makeString(tetherableUsbRegexs)));
- sj.add(String.format("tetherableWifiRegexs:%s", makeString(tetherableWifiRegexs)));
- sj.add(String.format("tetherableWifiP2pRegexs:%s", makeString(tetherableWifiP2pRegexs)));
- sj.add(String.format("tetherableBluetoothRegexs:%s",
- makeString(tetherableBluetoothRegexs)));
- sj.add(String.format("isDunRequired:%s", isDunRequired));
- sj.add(String.format("chooseUpstreamAutomatically:%s", chooseUpstreamAutomatically));
- sj.add(String.format("offloadPollInterval:%d", mOffloadPollInterval));
- sj.add(String.format("preferredUpstreamIfaceTypes:%s",
- toIntArray(preferredUpstreamIfaceTypes)));
- sj.add(String.format("provisioningApp:%s", makeString(provisioningApp)));
- sj.add(String.format("provisioningAppNoUi:%s", provisioningAppNoUi));
- sj.add(String.format("enableBpfOffload:%s", mEnableBpfOffload));
- sj.add(String.format("enableLegacyDhcpServer:%s", enableLegacyDhcpServer));
- return String.format("TetheringConfiguration{%s}", sj.toString());
- }
-
- private static void dumpStringArray(PrintWriter pw, String label, String[] values) {
- pw.print(label);
- pw.print(": ");
-
- if (values != null) {
- final StringJoiner sj = new StringJoiner(", ", "[", "]");
- for (String value : values) sj.add(value);
- pw.print(sj.toString());
- } else {
- pw.print("null");
- }
-
- pw.println();
- }
-
- private static String makeString(String[] strings) {
- if (strings == null) return "null";
- final StringJoiner sj = new StringJoiner(",", "[", "]");
- for (String s : strings) sj.add(s);
- return sj.toString();
- }
-
- /** Check whether dun is required. */
- public static boolean checkDunRequired(Context ctx) {
- final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE);
- // TelephonyManager would uses the active data subscription, which should be the one used
- // by tethering.
- return (tm != null) ? tm.isTetheringApnRequired() : false;
- }
-
- public int getOffloadPollInterval() {
- return mOffloadPollInterval;
- }
-
- public boolean isBpfOffloadEnabled() {
- return mEnableBpfOffload;
- }
-
- private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) {
- final int[] ifaceTypes = res.getIntArray(R.array.config_tether_upstream_types);
- final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length);
- for (int i : ifaceTypes) {
- switch (i) {
- case TYPE_MOBILE:
- case TYPE_MOBILE_HIPRI:
- if (dunRequired) continue;
- break;
- case TYPE_MOBILE_DUN:
- if (!dunRequired) continue;
- break;
- }
- upstreamIfaceTypes.add(i);
- }
-
- // Fix up upstream interface types for DUN or mobile. NOTE: independent
- // of the value of |dunRequired|, cell data of one form or another is
- // *always* an upstream, regardless of the upstream interface types
- // specified by configuration resources.
- if (dunRequired) {
- appendIfNotPresent(upstreamIfaceTypes, TYPE_MOBILE_DUN);
- } else {
- // Do not modify if a cellular interface type is already present in the
- // upstream interface types. Add TYPE_MOBILE and TYPE_MOBILE_HIPRI if no
- // cellular interface types are found in the upstream interface types.
- // This preserves backwards compatibility and prevents the DUN and default
- // mobile types incorrectly appearing together, which could happen on
- // previous releases in the common case where checkDunRequired returned
- // DUN_UNSPECIFIED.
- if (!containsOneOf(upstreamIfaceTypes, TYPE_MOBILE, TYPE_MOBILE_HIPRI)) {
- upstreamIfaceTypes.add(TYPE_MOBILE);
- upstreamIfaceTypes.add(TYPE_MOBILE_HIPRI);
- }
- }
-
- // Always make sure our good friend Ethernet is present.
- // TODO: consider unilaterally forcing this at the front.
- prependIfNotPresent(upstreamIfaceTypes, TYPE_ETHERNET);
-
- return upstreamIfaceTypes;
- }
-
- private static boolean matchesDownstreamRegexs(String iface, String[] regexs) {
- for (String regex : regexs) {
- if (iface.matches(regex)) return true;
- }
- return false;
- }
-
- private static String[] getLegacyDhcpRanges(Resources res) {
- final String[] fromResource = getResourceStringArray(res, R.array.config_tether_dhcp_range);
- if ((fromResource.length > 0) && (fromResource.length % 2 == 0)) {
- return fromResource;
- }
- return copy(LEGACY_DHCP_DEFAULT_RANGE);
- }
-
- private static String getResourceString(Resources res, final int resId) {
- try {
- return res.getString(resId);
- } catch (Resources.NotFoundException e) {
- return "";
- }
- }
-
- private static boolean getResourceBoolean(Resources res, int resId, boolean defaultValue) {
- try {
- return res.getBoolean(resId);
- } catch (Resources.NotFoundException e404) {
- return defaultValue;
- }
- }
-
- private static String[] getResourceStringArray(Resources res, int resId) {
- try {
- final String[] strArray = res.getStringArray(resId);
- return (strArray != null) ? strArray : EMPTY_STRING_ARRAY;
- } catch (Resources.NotFoundException e404) {
- return EMPTY_STRING_ARRAY;
- }
- }
-
- private static int getResourceInteger(Resources res, int resId, int defaultValue) {
- try {
- return res.getInteger(resId);
- } catch (Resources.NotFoundException e404) {
- return defaultValue;
- }
- }
-
- private boolean getEnableBpfOffload(final Resources res) {
- // Get BPF offload config
- // Priority 1: Device config
- // Priority 2: Resource config
- // Priority 3: Default value
- final boolean defaultValue = getResourceBoolean(
- res, R.bool.config_tether_enable_bpf_offload, true /** default value */);
-
- return getDeviceConfigBoolean(OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD, defaultValue);
- }
-
- private boolean getEnableLegacyDhcpServer(final Resources res) {
- return getResourceBoolean(
- res, R.bool.config_tether_enable_legacy_dhcp_server, false /** defaultValue */)
- || getDeviceConfigBoolean(
- TETHER_ENABLE_LEGACY_DHCP_SERVER, false /** defaultValue */);
- }
-
- private boolean getDeviceConfigBoolean(final String name, final boolean defaultValue) {
- // Due to the limitation of static mock for testing, using #getDeviceConfigProperty instead
- // of DeviceConfig#getBoolean. If using #getBoolean here, the test can't know that the
- // returned boolean value comes from device config or default value (because of null
- // property string). See the test case testBpfOffload{*} in TetheringConfigurationTest.java.
- final String value = getDeviceConfigProperty(name);
- return value != null ? Boolean.parseBoolean(value) : defaultValue;
- }
-
- @VisibleForTesting
- protected String getDeviceConfigProperty(String name) {
- return DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, name);
- }
-
- private Resources getResources(Context ctx, int subId) {
- if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- return getResourcesForSubIdWrapper(ctx, subId);
- } else {
- return ctx.getResources();
- }
- }
-
- @VisibleForTesting
- protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
- return SubscriptionManager.getResourcesForSubId(ctx, subId);
- }
-
- private static String[] copy(String[] strarray) {
- return Arrays.copyOf(strarray, strarray.length);
- }
-
- private static void prependIfNotPresent(ArrayList<Integer> list, int value) {
- if (list.contains(value)) return;
- list.add(0, value);
- }
-
- private static void appendIfNotPresent(ArrayList<Integer> list, int value) {
- if (list.contains(value)) return;
- list.add(value);
- }
-
- private static boolean containsOneOf(ArrayList<Integer> list, Integer... values) {
- for (Integer value : values) {
- if (list.contains(value)) return true;
- }
- return false;
- }
-
- private static int[] toIntArray(Collection<Integer> values) {
- final int[] result = new int[values.size()];
- int index = 0;
- for (Integer value : values) {
- result[index++] = value;
- }
- return result;
- }
-
- /**
- * Convert this TetheringConfiguration to a TetheringConfigurationParcel.
- */
- public TetheringConfigurationParcel toStableParcelable() {
- final TetheringConfigurationParcel parcel = new TetheringConfigurationParcel();
- parcel.subId = activeDataSubId;
- parcel.tetherableUsbRegexs = tetherableUsbRegexs;
- parcel.tetherableWifiRegexs = tetherableWifiRegexs;
- parcel.tetherableBluetoothRegexs = tetherableBluetoothRegexs;
- parcel.isDunRequired = isDunRequired;
- parcel.chooseUpstreamAutomatically = chooseUpstreamAutomatically;
-
- parcel.preferredUpstreamIfaceTypes = toIntArray(preferredUpstreamIfaceTypes);
-
- parcel.legacyDhcpRanges = legacyDhcpRanges;
- parcel.defaultIPv4DNS = defaultIPv4DNS;
- parcel.enableLegacyDhcpServer = enableLegacyDhcpServer;
- parcel.provisioningApp = provisioningApp;
- parcel.provisioningAppNoUi = provisioningAppNoUi;
- parcel.provisioningCheckPeriod = provisioningCheckPeriod;
- return parcel;
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
deleted file mode 100644
index 131a5fb..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.networkstack.tethering;
-
-import android.app.usage.NetworkStatsManager;
-import android.bluetooth.BluetoothAdapter;
-import android.content.Context;
-import android.net.INetd;
-import android.net.NetworkRequest;
-import android.net.ip.IpServer;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.util.StateMachine;
-
-import java.util.ArrayList;
-
-
-/**
- * Capture tethering dependencies, for injection.
- *
- * @hide
- */
-public abstract class TetheringDependencies {
- /**
- * Get a reference to the BpfCoordinator to be used by tethering.
- */
- public @NonNull BpfCoordinator getBpfCoordinator(
- @NonNull BpfCoordinator.Dependencies deps) {
- return new BpfCoordinator(deps);
- }
-
- /**
- * Get a reference to the offload hardware interface to be used by tethering.
- */
- public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
- return new OffloadHardwareInterface(h, log);
- }
-
- /**
- * Get a reference to the offload controller to be used by tethering.
- */
- @NonNull
- public OffloadController getOffloadController(@NonNull Handler h,
- @NonNull SharedLog log, @NonNull OffloadController.Dependencies deps) {
- final NetworkStatsManager statsManager =
- (NetworkStatsManager) getContext().getSystemService(Context.NETWORK_STATS_SERVICE);
- return new OffloadController(h, getOffloadHardwareInterface(h, log),
- getContext().getContentResolver(), statsManager, log, deps);
- }
-
-
- /**
- * Get a reference to the UpstreamNetworkMonitor to be used by tethering.
- */
- public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx, StateMachine target,
- SharedLog log, int what) {
- return new UpstreamNetworkMonitor(ctx, target, log, what);
- }
-
- /**
- * Get a reference to the IPv6TetheringCoordinator to be used by tethering.
- */
- public IPv6TetheringCoordinator getIPv6TetheringCoordinator(
- ArrayList<IpServer> notifyList, SharedLog log) {
- return new IPv6TetheringCoordinator(notifyList, log);
- }
-
- /**
- * Get dependencies to be used by IpServer.
- */
- public abstract IpServer.Dependencies getIpServerDependencies();
-
- /**
- * Indicates whether tethering is supported on the device.
- */
- public boolean isTetheringSupported() {
- return true;
- }
-
- /**
- * Get the NetworkRequest that should be fulfilled by the default network.
- */
- public abstract NetworkRequest getDefaultNetworkRequest();
-
- /**
- * Get a reference to the EntitlementManager to be used by tethering.
- */
- public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log,
- Runnable callback) {
- return new EntitlementManager(ctx, h, log, callback);
- }
-
- /**
- * Generate a new TetheringConfiguration according to input sub Id.
- */
- public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
- int subId) {
- return new TetheringConfiguration(ctx, log, subId);
- }
-
- /**
- * Get a reference to INetd to be used by tethering.
- */
- public INetd getINetd(Context context) {
- return INetd.Stub.asInterface(
- (IBinder) context.getSystemService(Context.NETD_SERVICE));
- }
-
- /**
- * Get a reference to the TetheringNotificationUpdater to be used by tethering.
- */
- public TetheringNotificationUpdater getNotificationUpdater(@NonNull final Context ctx,
- @NonNull final Looper looper) {
- return new TetheringNotificationUpdater(ctx, looper);
- }
-
- /**
- * Get tethering thread looper.
- */
- public abstract Looper getTetheringLooper();
-
- /**
- * Get Context of TetheringSerice.
- */
- public abstract Context getContext();
-
- /**
- * Get a reference to BluetoothAdapter to be used by tethering.
- */
- public abstract BluetoothAdapter getBluetoothAdapter();
-
- /**
- * Get SystemProperties which indicate whether tethering is denied.
- */
- public boolean isTetheringDenied() {
- return TextUtils.equals(SystemProperties.get("ro.tether.denied"), "true");
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringInterfaceUtils.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringInterfaceUtils.java
deleted file mode 100644
index ff38f71..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringInterfaceUtils.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.networkstack.tethering;
-
-import android.annotation.Nullable;
-import android.net.LinkProperties;
-import android.net.NetworkCapabilities;
-import android.net.RouteInfo;
-import android.net.util.InterfaceSet;
-
-import com.android.net.module.util.NetUtils;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * @hide
- */
-public final class TetheringInterfaceUtils {
- private static final InetAddress IN6ADDR_ANY = getByAddress(
- new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
- private static final InetAddress INADDR_ANY = getByAddress(new byte[] {0, 0, 0, 0});
-
- /**
- * Get upstream interfaces for tethering based on default routes for IPv4/IPv6.
- * @return null if there is no usable interface, or a set of at least one interface otherwise.
- */
- public static @Nullable InterfaceSet getTetheringInterfaces(UpstreamNetworkState ns) {
- if (ns == null) {
- return null;
- }
-
- final LinkProperties lp = ns.linkProperties;
- final String if4 = getInterfaceForDestination(lp, INADDR_ANY);
- final String if6 = getIPv6Interface(ns);
-
- return (if4 == null && if6 == null) ? null : new InterfaceSet(if4, if6);
- }
-
- /**
- * Get the upstream interface for IPv6 tethering.
- * @return null if there is no usable interface, or the interface name otherwise.
- */
- public static @Nullable String getIPv6Interface(UpstreamNetworkState ns) {
- // Broadly speaking:
- //
- // [1] does the upstream have an IPv6 default route?
- //
- // and
- //
- // [2] does the upstream have one or more global IPv6 /64s
- // dedicated to this device?
- //
- // In lieu of Prefix Delegation and other evaluation of whether a
- // prefix may or may not be dedicated to this device, for now just
- // check whether the upstream is TRANSPORT_CELLULAR. This works
- // because "[t]he 3GPP network allocates each default bearer a unique
- // /64 prefix", per RFC 6459, Section 5.2.
- final boolean canTether =
- (ns != null) && (ns.network != null)
- && (ns.linkProperties != null) && (ns.networkCapabilities != null)
- // At least one upstream DNS server:
- && ns.linkProperties.hasIpv6DnsServer()
- // Minimal amount of IPv6 provisioning:
- && ns.linkProperties.hasGlobalIpv6Address()
- // Temporary approximation of "dedicated prefix":
- && ns.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
-
- return canTether
- ? getInterfaceForDestination(ns.linkProperties, IN6ADDR_ANY)
- : null;
- }
-
- private static String getInterfaceForDestination(LinkProperties lp, InetAddress dst) {
- final RouteInfo ri = (lp != null)
- ? NetUtils.selectBestRoute(lp.getAllRoutes(), dst)
- : null;
- return (ri != null) ? ri.getInterface() : null;
- }
-
- private static InetAddress getByAddress(final byte[] addr) {
- try {
- return InetAddress.getByAddress(null, addr);
- } catch (UnknownHostException e) {
- throw new AssertionError("illegal address length" + addr.length);
- }
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java
deleted file mode 100644
index 593d04a..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java
+++ /dev/null
@@ -1,360 +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.networkstack.tethering;
-
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
-import static android.text.TextUtils.isEmpty;
-
-import android.app.Notification;
-import android.app.Notification.Action;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.net.NetworkCapabilities;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.util.SparseArray;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.IntDef;
-import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * A class to display tethering-related notifications.
- *
- * <p>This class is not thread safe, it is intended to be used only from the tethering handler
- * thread. However the constructor is an exception, as it is called on another thread ;
- * therefore for thread safety all members of this class MUST either be final or initialized
- * to their default value (0, false or null).
- *
- * @hide
- */
-public class TetheringNotificationUpdater {
- private static final String TAG = TetheringNotificationUpdater.class.getSimpleName();
- private static final String CHANNEL_ID = "TETHERING_STATUS";
- private static final String WIFI_DOWNSTREAM = "WIFI";
- private static final String USB_DOWNSTREAM = "USB";
- private static final String BLUETOOTH_DOWNSTREAM = "BT";
- @VisibleForTesting
- static final String ACTION_DISABLE_TETHERING =
- "com.android.server.connectivity.tethering.DISABLE_TETHERING";
- private static final boolean NOTIFY_DONE = true;
- private static final boolean NO_NOTIFY = false;
- @VisibleForTesting
- static final int EVENT_SHOW_NO_UPSTREAM = 1;
- // Id to update and cancel restricted notification. Must be unique within the tethering app.
- @VisibleForTesting
- static final int RESTRICTED_NOTIFICATION_ID = 1001;
- // Id to update and cancel no upstream notification. Must be unique within the tethering app.
- @VisibleForTesting
- static final int NO_UPSTREAM_NOTIFICATION_ID = 1002;
- // Id to update and cancel roaming notification. Must be unique within the tethering app.
- @VisibleForTesting
- static final int ROAMING_NOTIFICATION_ID = 1003;
- @VisibleForTesting
- static final int NO_ICON_ID = 0;
- @VisibleForTesting
- static final int DOWNSTREAM_NONE = 0;
- // Refer to TelephonyManager#getSimCarrierId for more details about carrier id.
- @VisibleForTesting
- static final int VERIZON_CARRIER_ID = 1839;
- private final Context mContext;
- private final NotificationManager mNotificationManager;
- private final NotificationChannel mChannel;
- private final Handler mHandler;
-
- // WARNING : the constructor is called on a different thread. Thread safety therefore
- // relies on these values being initialized to 0, false or null, and not any other value. If you
- // need to change this, you will need to change the thread where the constructor is invoked, or
- // to introduce synchronization.
- // Downstream type is one of ConnectivityManager.TETHERING_* constants, 0 1 or 2.
- // This value has to be made 1 2 and 4, and OR'd with the others.
- private int mDownstreamTypesMask = DOWNSTREAM_NONE;
- private boolean mNoUpstream = false;
- private boolean mRoaming = false;
-
- // WARNING : this value is not able to being initialized to 0 and must have volatile because
- // telephony service is not guaranteed that is up before tethering service starts. If telephony
- // is up later than tethering, TetheringNotificationUpdater will use incorrect and valid
- // subscription id(0) to query resources. Therefore, initialized subscription id must be
- // INVALID_SUBSCRIPTION_ID.
- private volatile int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- RESTRICTED_NOTIFICATION_ID,
- NO_UPSTREAM_NOTIFICATION_ID,
- ROAMING_NOTIFICATION_ID
- })
- @interface NotificationId {}
-
- private static final class MccMncOverrideInfo {
- public final String visitedMccMnc;
- public final int homeMcc;
- public final int homeMnc;
- MccMncOverrideInfo(String visitedMccMnc, int mcc, int mnc) {
- this.visitedMccMnc = visitedMccMnc;
- this.homeMcc = mcc;
- this.homeMnc = mnc;
- }
- }
-
- private static final SparseArray<MccMncOverrideInfo> sCarrierIdToMccMnc = new SparseArray<>();
-
- static {
- sCarrierIdToMccMnc.put(VERIZON_CARRIER_ID, new MccMncOverrideInfo("20404", 311, 480));
- }
-
- public TetheringNotificationUpdater(@NonNull final Context context,
- @NonNull final Looper looper) {
- mContext = context;
- mNotificationManager = (NotificationManager) context.createContextAsUser(UserHandle.ALL, 0)
- .getSystemService(Context.NOTIFICATION_SERVICE);
- mChannel = new NotificationChannel(
- CHANNEL_ID,
- context.getResources().getString(R.string.notification_channel_tethering_status),
- NotificationManager.IMPORTANCE_LOW);
- mNotificationManager.createNotificationChannel(mChannel);
- mHandler = new NotificationHandler(looper);
- }
-
- private class NotificationHandler extends Handler {
- NotificationHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch(msg.what) {
- case EVENT_SHOW_NO_UPSTREAM:
- notifyTetheringNoUpstream();
- break;
- }
- }
- }
-
- /** Called when downstream has changed */
- public void onDownstreamChanged(@IntRange(from = 0, to = 7) final int downstreamTypesMask) {
- updateActiveNotifications(
- mActiveDataSubId, downstreamTypesMask, mNoUpstream, mRoaming);
- }
-
- /** Called when active data subscription id changed */
- public void onActiveDataSubscriptionIdChanged(final int subId) {
- updateActiveNotifications(subId, mDownstreamTypesMask, mNoUpstream, mRoaming);
- }
-
- /** Called when upstream network capabilities changed */
- public void onUpstreamCapabilitiesChanged(@Nullable final NetworkCapabilities capabilities) {
- final boolean isNoUpstream = (capabilities == null);
- final boolean isRoaming = capabilities != null
- && !capabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING);
- updateActiveNotifications(
- mActiveDataSubId, mDownstreamTypesMask, isNoUpstream, isRoaming);
- }
-
- @NonNull
- @VisibleForTesting
- final Handler getHandler() {
- return mHandler;
- }
-
- @NonNull
- @VisibleForTesting
- Resources getResourcesForSubId(@NonNull final Context context, final int subId) {
- final Resources res = SubscriptionManager.getResourcesForSubId(context, subId);
- final TelephonyManager tm =
- ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
- .createForSubscriptionId(mActiveDataSubId);
- final int carrierId = tm.getSimCarrierId();
- final String mccmnc = tm.getSimOperator();
- final MccMncOverrideInfo overrideInfo = sCarrierIdToMccMnc.get(carrierId);
- if (overrideInfo != null && overrideInfo.visitedMccMnc.equals(mccmnc)) {
- // Re-configure MCC/MNC value to specific carrier to get right resources.
- final Configuration config = res.getConfiguration();
- config.mcc = overrideInfo.homeMcc;
- config.mnc = overrideInfo.homeMnc;
- return context.createConfigurationContext(config).getResources();
- }
- return res;
- }
-
- private void updateActiveNotifications(final int subId, final int downstreamTypes,
- final boolean noUpstream, final boolean isRoaming) {
- final boolean tetheringActiveChanged =
- (downstreamTypes == DOWNSTREAM_NONE) != (mDownstreamTypesMask == DOWNSTREAM_NONE);
- final boolean subIdChanged = subId != mActiveDataSubId;
- final boolean upstreamChanged = noUpstream != mNoUpstream;
- final boolean roamingChanged = isRoaming != mRoaming;
- final boolean updateAll = tetheringActiveChanged || subIdChanged;
- mActiveDataSubId = subId;
- mDownstreamTypesMask = downstreamTypes;
- mNoUpstream = noUpstream;
- mRoaming = isRoaming;
-
- if (updateAll || upstreamChanged) updateNoUpstreamNotification();
- if (updateAll || roamingChanged) updateRoamingNotification();
- }
-
- private void updateNoUpstreamNotification() {
- final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE;
-
- if (tetheringInactive || !mNoUpstream || setupNoUpstreamNotification() == NO_NOTIFY) {
- clearNotification(NO_UPSTREAM_NOTIFICATION_ID);
- mHandler.removeMessages(EVENT_SHOW_NO_UPSTREAM);
- }
- }
-
- private void updateRoamingNotification() {
- final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE;
-
- if (tetheringInactive || !mRoaming || setupRoamingNotification() == NO_NOTIFY) {
- clearNotification(ROAMING_NOTIFICATION_ID);
- }
- }
-
- @VisibleForTesting
- void tetheringRestrictionLifted() {
- clearNotification(RESTRICTED_NOTIFICATION_ID);
- }
-
- private void clearNotification(@NotificationId final int id) {
- mNotificationManager.cancel(null /* tag */, id);
- }
-
- @VisibleForTesting
- static String getSettingsPackageName(@NonNull final PackageManager pm) {
- final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
- final ComponentName settingsComponent = settingsIntent.resolveActivity(pm);
- return settingsComponent != null
- ? settingsComponent.getPackageName() : "com.android.settings";
- }
-
- @VisibleForTesting
- void notifyTetheringDisabledByRestriction() {
- final Resources res = getResourcesForSubId(mContext, mActiveDataSubId);
- final String title = res.getString(R.string.disable_tether_notification_title);
- final String message = res.getString(R.string.disable_tether_notification_message);
- if (isEmpty(title) || isEmpty(message)) return;
-
- final PendingIntent pi = PendingIntent.getActivity(
- mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */),
- 0 /* requestCode */,
- new Intent(Settings.ACTION_TETHER_SETTINGS)
- .setPackage(getSettingsPackageName(mContext.getPackageManager())),
- Intent.FLAG_ACTIVITY_NEW_TASK | PendingIntent.FLAG_IMMUTABLE,
- null /* options */);
-
- showNotification(R.drawable.stat_sys_tether_general, title, message,
- RESTRICTED_NOTIFICATION_ID, false /* ongoing */, pi, new Action[0]);
- }
-
- private void notifyTetheringNoUpstream() {
- final Resources res = getResourcesForSubId(mContext, mActiveDataSubId);
- final String title = res.getString(R.string.no_upstream_notification_title);
- final String message = res.getString(R.string.no_upstream_notification_message);
- final String disableButton =
- res.getString(R.string.no_upstream_notification_disable_button);
- if (isEmpty(title) || isEmpty(message) || isEmpty(disableButton)) return;
-
- final Intent intent = new Intent(ACTION_DISABLE_TETHERING);
- intent.setPackage(mContext.getPackageName());
- final PendingIntent pi = PendingIntent.getBroadcast(
- mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */),
- 0 /* requestCode */,
- intent,
- PendingIntent.FLAG_IMMUTABLE);
- final Action action = new Action.Builder(NO_ICON_ID, disableButton, pi).build();
-
- showNotification(R.drawable.stat_sys_tether_general, title, message,
- NO_UPSTREAM_NOTIFICATION_ID, true /* ongoing */, null /* pendingIntent */, action);
- }
-
- private boolean setupRoamingNotification() {
- final Resources res = getResourcesForSubId(mContext, mActiveDataSubId);
- final boolean upstreamRoamingNotification =
- res.getBoolean(R.bool.config_upstream_roaming_notification);
-
- if (!upstreamRoamingNotification) return NO_NOTIFY;
-
- final String title = res.getString(R.string.upstream_roaming_notification_title);
- final String message = res.getString(R.string.upstream_roaming_notification_message);
- if (isEmpty(title) || isEmpty(message)) return NO_NOTIFY;
-
- final PendingIntent pi = PendingIntent.getActivity(
- mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */),
- 0 /* requestCode */,
- new Intent(Settings.ACTION_TETHER_SETTINGS)
- .setPackage(getSettingsPackageName(mContext.getPackageManager())),
- Intent.FLAG_ACTIVITY_NEW_TASK | PendingIntent.FLAG_IMMUTABLE,
- null /* options */);
-
- showNotification(R.drawable.stat_sys_tether_general, title, message,
- ROAMING_NOTIFICATION_ID, true /* ongoing */, pi, new Action[0]);
- return NOTIFY_DONE;
- }
-
- private boolean setupNoUpstreamNotification() {
- final Resources res = getResourcesForSubId(mContext, mActiveDataSubId);
- final int delayToShowUpstreamNotification =
- res.getInteger(R.integer.delay_to_show_no_upstream_after_no_backhaul);
-
- if (delayToShowUpstreamNotification < 0) return NO_NOTIFY;
-
- mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_SHOW_NO_UPSTREAM),
- delayToShowUpstreamNotification);
- return NOTIFY_DONE;
- }
-
- private void showNotification(@DrawableRes final int iconId, @NonNull final String title,
- @NonNull final String message, @NotificationId final int id, final boolean ongoing,
- @Nullable PendingIntent pi, @NonNull final Action... actions) {
- final Notification notification =
- new Notification.Builder(mContext, mChannel.getId())
- .setSmallIcon(iconId)
- .setContentTitle(title)
- .setContentText(message)
- .setOngoing(ongoing)
- .setColor(mContext.getColor(
- android.R.color.system_notification_accent_color))
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setCategory(Notification.CATEGORY_STATUS)
- .setContentIntent(pi)
- .setActions(actions)
- .build();
-
- mNotificationManager.notify(null /* tag */, id, notification);
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
deleted file mode 100644
index d084ca0..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
+++ /dev/null
@@ -1,374 +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.networkstack.tethering;
-
-import static android.Manifest.permission.ACCESS_NETWORK_STATE;
-import static android.Manifest.permission.NETWORK_STACK;
-import static android.Manifest.permission.TETHER_PRIVILEGED;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
-import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED;
-import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
-
-import android.app.Service;
-import android.bluetooth.BluetoothAdapter;
-import android.content.Context;
-import android.content.Intent;
-import android.net.IIntResultListener;
-import android.net.INetworkStackConnector;
-import android.net.ITetheringConnector;
-import android.net.ITetheringEventCallback;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.NetworkStack;
-import android.net.TetheringRequestParcel;
-import android.net.dhcp.DhcpServerCallbacks;
-import android.net.dhcp.DhcpServingParamsParcel;
-import android.net.ip.IpServer;
-import android.os.Binder;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.provider.Settings;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Android service used to manage tethering.
- *
- * <p>The service returns a binder for the system server to communicate with the tethering.
- */
-public class TetheringService extends Service {
- private static final String TAG = TetheringService.class.getSimpleName();
-
- private TetheringConnector mConnector;
-
- @Override
- public void onCreate() {
- final TetheringDependencies deps = makeTetheringDependencies();
- // The Tethering object needs a fully functional context to start, so this can't be done
- // in the constructor.
- mConnector = new TetheringConnector(makeTethering(deps), TetheringService.this);
- }
-
- /**
- * Make a reference to Tethering object.
- */
- @VisibleForTesting
- public Tethering makeTethering(TetheringDependencies deps) {
- System.loadLibrary("tetherutilsjni");
- return new Tethering(deps);
- }
-
- @NonNull
- @Override
- public IBinder onBind(Intent intent) {
- return mConnector;
- }
-
- private static class TetheringConnector extends ITetheringConnector.Stub {
- private final TetheringService mService;
- private final Tethering mTethering;
-
- TetheringConnector(Tethering tether, TetheringService service) {
- mTethering = tether;
- mService = service;
- }
-
- @Override
- public void tether(String iface, String callerPkg, IIntResultListener listener) {
- if (checkAndNotifyCommonError(callerPkg, listener)) return;
-
- try {
- listener.onResult(mTethering.tether(iface));
- } catch (RemoteException e) { }
- }
-
- @Override
- public void untether(String iface, String callerPkg, IIntResultListener listener) {
- if (checkAndNotifyCommonError(callerPkg, listener)) return;
-
- try {
- listener.onResult(mTethering.untether(iface));
- } catch (RemoteException e) { }
- }
-
- @Override
- public void setUsbTethering(boolean enable, String callerPkg, IIntResultListener listener) {
- if (checkAndNotifyCommonError(callerPkg, listener)) return;
-
- try {
- listener.onResult(mTethering.setUsbTethering(enable));
- } catch (RemoteException e) { }
- }
-
- @Override
- public void startTethering(TetheringRequestParcel request, String callerPkg,
- IIntResultListener listener) {
- if (checkAndNotifyCommonError(callerPkg,
- request.exemptFromEntitlementCheck /* onlyAllowPrivileged */,
- listener)) {
- return;
- }
-
- mTethering.startTethering(request, listener);
- }
-
- @Override
- public void stopTethering(int type, String callerPkg, IIntResultListener listener) {
- if (checkAndNotifyCommonError(callerPkg, listener)) return;
-
- try {
- mTethering.stopTethering(type);
- listener.onResult(TETHER_ERROR_NO_ERROR);
- } catch (RemoteException e) { }
- }
-
- @Override
- public void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
- boolean showEntitlementUi, String callerPkg) {
- if (checkAndNotifyCommonError(callerPkg, receiver)) return;
-
- mTethering.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
- }
-
- @Override
- public void registerTetheringEventCallback(ITetheringEventCallback callback,
- String callerPkg) {
- try {
- if (!hasTetherAccessPermission()) {
- callback.onCallbackStopped(TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
- return;
- }
- mTethering.registerTetheringEventCallback(callback);
- } catch (RemoteException e) { }
- }
-
- @Override
- public void unregisterTetheringEventCallback(ITetheringEventCallback callback,
- String callerPkg) {
- try {
- if (!hasTetherAccessPermission()) {
- callback.onCallbackStopped(TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
- return;
- }
- mTethering.unregisterTetheringEventCallback(callback);
- } catch (RemoteException e) { }
- }
-
- @Override
- public void stopAllTethering(String callerPkg, IIntResultListener listener) {
- if (checkAndNotifyCommonError(callerPkg, listener)) return;
-
- try {
- mTethering.untetherAll();
- listener.onResult(TETHER_ERROR_NO_ERROR);
- } catch (RemoteException e) { }
- }
-
- @Override
- public void isTetheringSupported(String callerPkg, IIntResultListener listener) {
- if (checkAndNotifyCommonError(callerPkg, listener)) return;
-
- try {
- listener.onResult(TETHER_ERROR_NO_ERROR);
- } catch (RemoteException e) { }
- }
-
- @Override
- protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
- @Nullable String[] args) {
- mTethering.dump(fd, writer, args);
- }
-
- private boolean checkAndNotifyCommonError(String callerPkg, IIntResultListener listener) {
- return checkAndNotifyCommonError(callerPkg, false /* onlyAllowPrivileged */, listener);
- }
-
- private boolean checkAndNotifyCommonError(final String callerPkg,
- final boolean onlyAllowPrivileged, final IIntResultListener listener) {
- try {
- if (!hasTetherChangePermission(callerPkg, onlyAllowPrivileged)) {
- listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
- return true;
- }
- if (!mTethering.isTetheringSupported()) {
- listener.onResult(TETHER_ERROR_UNSUPPORTED);
- return true;
- }
- } catch (RemoteException e) {
- return true;
- }
-
- return false;
- }
-
- private boolean checkAndNotifyCommonError(String callerPkg, ResultReceiver receiver) {
- if (!hasTetherChangePermission(callerPkg, false /* onlyAllowPrivileged */)) {
- receiver.send(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, null);
- return true;
- }
- if (!mTethering.isTetheringSupported()) {
- receiver.send(TETHER_ERROR_UNSUPPORTED, null);
- return true;
- }
-
- return false;
- }
-
- private boolean hasNetworkStackPermission() {
- return checkCallingOrSelfPermission(NETWORK_STACK)
- || checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private boolean hasTetherPrivilegedPermission() {
- return checkCallingOrSelfPermission(TETHER_PRIVILEGED);
- }
-
- private boolean checkCallingOrSelfPermission(final String permission) {
- return mService.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
- }
-
- private boolean hasTetherChangePermission(final String callerPkg,
- final boolean onlyAllowPrivileged) {
- if (onlyAllowPrivileged && !hasNetworkStackPermission()) return false;
-
- if (hasTetherPrivilegedPermission()) return true;
-
- if (mTethering.isTetherProvisioningRequired()) return false;
-
- int uid = Binder.getCallingUid();
- // If callerPkg's uid is not same as Binder.getCallingUid(),
- // checkAndNoteWriteSettingsOperation will return false and the operation will be
- // denied.
- return mService.checkAndNoteWriteSettingsOperation(mService, uid, callerPkg,
- false /* throwException */);
- }
-
- private boolean hasTetherAccessPermission() {
- if (hasTetherPrivilegedPermission()) return true;
-
- return mService.checkCallingOrSelfPermission(
- ACCESS_NETWORK_STATE) == PERMISSION_GRANTED;
- }
- }
-
- /**
- * Check if the package is a allowed to write settings. This also accounts that such an access
- * happened.
- *
- * @return {@code true} iff the package is allowed to write settings.
- */
- @VisibleForTesting
- boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid,
- @NonNull String callingPackage, boolean throwException) {
- return Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPackage,
- throwException);
- }
-
- /**
- * An injection method for testing.
- */
- @VisibleForTesting
- public TetheringDependencies makeTetheringDependencies() {
- return new TetheringDependencies() {
- @Override
- public NetworkRequest getDefaultNetworkRequest() {
- // TODO: b/147280869, add a proper system API to replace this.
- final NetworkRequest trackDefaultRequest = new NetworkRequest.Builder()
- .clearCapabilities()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .build();
- return trackDefaultRequest;
- }
-
- @Override
- public Looper getTetheringLooper() {
- final HandlerThread tetherThread = new HandlerThread("android.tethering");
- tetherThread.start();
- return tetherThread.getLooper();
- }
-
- @Override
- public Context getContext() {
- return TetheringService.this;
- }
-
- @Override
- public IpServer.Dependencies getIpServerDependencies() {
- return new IpServer.Dependencies() {
- @Override
- public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
- DhcpServerCallbacks cb) {
- try {
- final INetworkStackConnector service = getNetworkStackConnector();
- if (service == null) return;
-
- service.makeDhcpServer(ifName, params, cb);
- } catch (RemoteException e) {
- Log.e(TAG, "Fail to make dhcp server");
- try {
- cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
- } catch (RemoteException re) { }
- }
- }
- };
- }
-
- // TODO: replace this by NetworkStackClient#getRemoteConnector after refactoring
- // networkStackClient.
- static final int NETWORKSTACK_TIMEOUT_MS = 60_000;
- private INetworkStackConnector getNetworkStackConnector() {
- IBinder connector;
- try {
- final long before = System.currentTimeMillis();
- while ((connector = NetworkStack.getService()) == null) {
- if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
- Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector");
- return null;
- }
- Thread.sleep(200);
- }
- } catch (InterruptedException e) {
- Log.wtf(TAG, "Interrupted, fail to get INetworkStackConnector");
- return null;
- }
- return INetworkStackConnector.Stub.asInterface(connector);
- }
-
- @Override
- public BluetoothAdapter getBluetoothAdapter() {
- return BluetoothAdapter.getDefaultAdapter();
- }
- };
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
deleted file mode 100644
index 320427c..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
+++ /dev/null
@@ -1,607 +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.networkstack.tethering;
-
-import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
-import static android.net.ConnectivityManager.TYPE_ETHERNET;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
-import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.IpPrefix;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.util.PrefixUtils;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.util.Log;
-import android.util.SparseIntArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.StateMachine;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-
-/**
- * A class to centralize all the network and link properties information
- * pertaining to the current and any potential upstream network.
- *
- * The owner of UNM gets it to register network callbacks by calling the
- * following methods :
- * Calling #startTrackDefaultNetwork() to track the system default network.
- * Calling #startObserveAllNetworks() to observe all networks. Listening all
- * networks is necessary while the expression of preferred upstreams remains
- * a list of legacy connectivity types. In future, this can be revisited.
- * Calling #registerMobileNetworkRequest() to bring up mobile DUN/HIPRI network.
- *
- * The methods and data members of this class are only to be accessed and
- * modified from the tethering master state machine thread. Any other
- * access semantics would necessitate the addition of locking.
- *
- * TODO: Move upstream selection logic here.
- *
- * All callback methods are run on the same thread as the specified target
- * state machine. This class does not require locking when accessed from this
- * thread. Access from other threads is not advised.
- *
- * @hide
- */
-public class UpstreamNetworkMonitor {
- private static final String TAG = UpstreamNetworkMonitor.class.getSimpleName();
- private static final boolean DBG = false;
- private static final boolean VDBG = false;
-
- public static final int EVENT_ON_CAPABILITIES = 1;
- public static final int EVENT_ON_LINKPROPERTIES = 2;
- public static final int EVENT_ON_LOST = 3;
- public static final int NOTIFY_LOCAL_PREFIXES = 10;
- // This value is used by deprecated preferredUpstreamIfaceTypes selection which is default
- // disabled.
- @VisibleForTesting
- public static final int TYPE_NONE = -1;
-
- private static final int CALLBACK_LISTEN_ALL = 1;
- private static final int CALLBACK_DEFAULT_INTERNET = 2;
- private static final int CALLBACK_MOBILE_REQUEST = 3;
-
- private static final SparseIntArray sLegacyTypeToTransport = new SparseIntArray();
- static {
- sLegacyTypeToTransport.put(TYPE_MOBILE, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_MOBILE_DUN, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_MOBILE_HIPRI, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_WIFI, NetworkCapabilities.TRANSPORT_WIFI);
- sLegacyTypeToTransport.put(TYPE_BLUETOOTH, NetworkCapabilities.TRANSPORT_BLUETOOTH);
- sLegacyTypeToTransport.put(TYPE_ETHERNET, NetworkCapabilities.TRANSPORT_ETHERNET);
- }
-
- private final Context mContext;
- private final SharedLog mLog;
- private final StateMachine mTarget;
- private final Handler mHandler;
- private final int mWhat;
- private final HashMap<Network, UpstreamNetworkState> mNetworkMap = new HashMap<>();
- private HashSet<IpPrefix> mLocalPrefixes;
- private ConnectivityManager mCM;
- private EntitlementManager mEntitlementMgr;
- private NetworkCallback mListenAllCallback;
- private NetworkCallback mDefaultNetworkCallback;
- private NetworkCallback mMobileNetworkCallback;
- private boolean mDunRequired;
- // Whether the current default upstream is mobile or not.
- private boolean mIsDefaultCellularUpstream;
- // The current system default network (not really used yet).
- private Network mDefaultInternetNetwork;
- // The current upstream network used for tethering.
- private Network mTetheringUpstreamNetwork;
-
- public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, SharedLog log, int what) {
- mContext = ctx;
- mTarget = tgt;
- mHandler = mTarget.getHandler();
- mLog = log.forSubComponent(TAG);
- mWhat = what;
- mLocalPrefixes = new HashSet<>();
- mIsDefaultCellularUpstream = false;
- }
-
- @VisibleForTesting
- public UpstreamNetworkMonitor(
- ConnectivityManager cm, StateMachine tgt, SharedLog log, int what) {
- this((Context) null, tgt, log, what);
- mCM = cm;
- }
-
- /**
- * Tracking the system default network. This method should be called when system is ready.
- *
- * @param defaultNetworkRequest should be the same as ConnectivityService default request
- * @param entitle a EntitlementManager object to communicate between EntitlementManager and
- * UpstreamNetworkMonitor
- */
- public void startTrackDefaultNetwork(NetworkRequest defaultNetworkRequest,
- EntitlementManager entitle) {
-
- // defaultNetworkRequest is not really a "request", just a way of tracking the system
- // default network. It's guaranteed not to actually bring up any networks because it's
- // the should be the same request as the ConnectivityService default request, and thus
- // shares fate with it. We can't use registerDefaultNetworkCallback because it will not
- // track the system default network if there is a VPN that applies to our UID.
- if (mDefaultNetworkCallback == null) {
- mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_DEFAULT_INTERNET);
- cm().requestNetwork(defaultNetworkRequest, mDefaultNetworkCallback, mHandler);
- }
- if (mEntitlementMgr == null) {
- mEntitlementMgr = entitle;
- }
- }
-
- /** Listen all networks. */
- public void startObserveAllNetworks() {
- stop();
-
- final NetworkRequest listenAllRequest = new NetworkRequest.Builder()
- .clearCapabilities().build();
- mListenAllCallback = new UpstreamNetworkCallback(CALLBACK_LISTEN_ALL);
- cm().registerNetworkCallback(listenAllRequest, mListenAllCallback, mHandler);
- }
-
- /**
- * Stop tracking candidate tethering upstreams and release mobile network request.
- * Note: this function is used when tethering is stopped because tethering do not need to
- * choose upstream anymore. But it would not stop default network tracking because
- * EntitlementManager may need to know default network to decide whether to request entitlement
- * check even tethering is not active yet.
- */
- public void stop() {
- releaseMobileNetworkRequest();
-
- releaseCallback(mListenAllCallback);
- mListenAllCallback = null;
-
- mTetheringUpstreamNetwork = null;
- mNetworkMap.clear();
- }
-
- /** Setup or teardown DUN connection according to |dunRequired|. */
- public void updateMobileRequiresDun(boolean dunRequired) {
- final boolean valueChanged = (mDunRequired != dunRequired);
- mDunRequired = dunRequired;
- if (valueChanged && mobileNetworkRequested()) {
- releaseMobileNetworkRequest();
- registerMobileNetworkRequest();
- }
- }
-
- /** Whether mobile network is requested. */
- public boolean mobileNetworkRequested() {
- return (mMobileNetworkCallback != null);
- }
-
- /** Request mobile network if mobile upstream is permitted. */
- public void registerMobileNetworkRequest() {
- if (!isCellularUpstreamPermitted()) {
- mLog.i("registerMobileNetworkRequest() is not permitted");
- releaseMobileNetworkRequest();
- return;
- }
- if (mMobileNetworkCallback != null) {
- mLog.e("registerMobileNetworkRequest() already registered");
- return;
- }
-
- final NetworkRequest mobileUpstreamRequest;
- if (mDunRequired) {
- mobileUpstreamRequest = new NetworkRequest.Builder()
- .addCapability(NET_CAPABILITY_DUN)
- .removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
- .addTransportType(TRANSPORT_CELLULAR).build();
- } else {
- mobileUpstreamRequest = new NetworkRequest.Builder()
- .addCapability(NET_CAPABILITY_INTERNET)
- .addTransportType(TRANSPORT_CELLULAR).build();
- }
-
- // The existing default network and DUN callbacks will be notified.
- // Therefore, to avoid duplicate notifications, we only register a no-op.
- mMobileNetworkCallback = new UpstreamNetworkCallback(CALLBACK_MOBILE_REQUEST);
-
- // The following use of the legacy type system cannot be removed until
- // upstream selection no longer finds networks by legacy type.
- // See also http://b/34364553 .
- final int legacyType = mDunRequired ? TYPE_MOBILE_DUN : TYPE_MOBILE_HIPRI;
-
- // TODO: Change the timeout from 0 (no onUnavailable callback) to some
- // moderate callback timeout. This might be useful for updating some UI.
- // Additionally, we log a message to aid in any subsequent debugging.
- mLog.i("requesting mobile upstream network: " + mobileUpstreamRequest);
-
- cm().requestNetwork(mobileUpstreamRequest, 0, legacyType, mHandler,
- mMobileNetworkCallback);
- }
-
- /** Release mobile network request. */
- public void releaseMobileNetworkRequest() {
- if (mMobileNetworkCallback == null) return;
-
- cm().unregisterNetworkCallback(mMobileNetworkCallback);
- mMobileNetworkCallback = null;
- }
-
- // So many TODOs here, but chief among them is: make this functionality an
- // integral part of this class such that whenever a higher priority network
- // becomes available and useful we (a) file a request to keep it up as
- // necessary and (b) change all upstream tracking state accordingly (by
- // passing LinkProperties up to Tethering).
- /**
- * Select the first available network from |perferredTypes|.
- */
- public UpstreamNetworkState selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
- final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType(
- mNetworkMap.values(), preferredTypes, isCellularUpstreamPermitted());
-
- mLog.log("preferred upstream type: " + typeStatePair.type);
-
- switch (typeStatePair.type) {
- case TYPE_MOBILE_DUN:
- case TYPE_MOBILE_HIPRI:
- // Tethering just selected mobile upstream in spite of the default network being
- // not mobile. This can happen because of the priority list.
- // Notify EntitlementManager to check permission for using mobile upstream.
- if (!mIsDefaultCellularUpstream) {
- mEntitlementMgr.maybeRunProvisioning();
- }
- // If we're on DUN, put our own grab on it.
- registerMobileNetworkRequest();
- break;
- case TYPE_NONE:
- // If we found NONE and mobile upstream is permitted we don't want to do this
- // as we want any previous requests to keep trying to bring up something we can use.
- if (!isCellularUpstreamPermitted()) releaseMobileNetworkRequest();
- break;
- default:
- // If we've found an active upstream connection that's not DUN/HIPRI
- // we should stop any outstanding DUN/HIPRI requests.
- releaseMobileNetworkRequest();
- break;
- }
-
- return typeStatePair.ns;
- }
-
- /**
- * Get current preferred upstream network. If default network is cellular and DUN is required,
- * preferred upstream would be DUN otherwise preferred upstream is the same as default network.
- * Returns null if no current upstream is available.
- */
- public UpstreamNetworkState getCurrentPreferredUpstream() {
- final UpstreamNetworkState dfltState = (mDefaultInternetNetwork != null)
- ? mNetworkMap.get(mDefaultInternetNetwork)
- : null;
- if (isNetworkUsableAndNotCellular(dfltState)) return dfltState;
-
- if (!isCellularUpstreamPermitted()) return null;
-
- if (!mDunRequired) return dfltState;
-
- // Find a DUN network. Note that code in Tethering causes a DUN request
- // to be filed, but this might be moved into this class in future.
- return findFirstDunNetwork(mNetworkMap.values());
- }
-
- /** Tell UpstreamNetworkMonitor which network is the current upstream of tethering. */
- public void setCurrentUpstream(Network upstream) {
- mTetheringUpstreamNetwork = upstream;
- }
-
- /** Return local prefixes. */
- public Set<IpPrefix> getLocalPrefixes() {
- return (Set<IpPrefix>) mLocalPrefixes.clone();
- }
-
- private boolean isCellularUpstreamPermitted() {
- if (mEntitlementMgr != null) {
- return mEntitlementMgr.isCellularUpstreamPermitted();
- } else {
- // This flow should only happens in testing.
- return true;
- }
- }
-
- private void handleAvailable(Network network) {
- if (mNetworkMap.containsKey(network)) return;
-
- if (VDBG) Log.d(TAG, "onAvailable for " + network);
- mNetworkMap.put(network, new UpstreamNetworkState(null, null, network));
- }
-
- private void handleNetCap(Network network, NetworkCapabilities newNc) {
- final UpstreamNetworkState prev = mNetworkMap.get(network);
- if (prev == null || newNc.equals(prev.networkCapabilities)) {
- // Ignore notifications about networks for which we have not yet
- // received onAvailable() (should never happen) and any duplicate
- // notifications (e.g. matching more than one of our callbacks).
- return;
- }
-
- if (VDBG) {
- Log.d(TAG, String.format("EVENT_ON_CAPABILITIES for %s: %s",
- network, newNc));
- }
-
- mNetworkMap.put(network, new UpstreamNetworkState(
- prev.linkProperties, newNc, network));
- // TODO: If sufficient information is available to select a more
- // preferable upstream, do so now and notify the target.
- notifyTarget(EVENT_ON_CAPABILITIES, network);
- }
-
- private void handleLinkProp(Network network, LinkProperties newLp) {
- final UpstreamNetworkState prev = mNetworkMap.get(network);
- if (prev == null || newLp.equals(prev.linkProperties)) {
- // Ignore notifications about networks for which we have not yet
- // received onAvailable() (should never happen) and any duplicate
- // notifications (e.g. matching more than one of our callbacks).
- return;
- }
-
- if (VDBG) {
- Log.d(TAG, String.format("EVENT_ON_LINKPROPERTIES for %s: %s",
- network, newLp));
- }
-
- mNetworkMap.put(network, new UpstreamNetworkState(
- newLp, prev.networkCapabilities, network));
- // TODO: If sufficient information is available to select a more
- // preferable upstream, do so now and notify the target.
- notifyTarget(EVENT_ON_LINKPROPERTIES, network);
- }
-
- private void handleLost(Network network) {
- // There are few TODOs within ConnectivityService's rematching code
- // pertaining to spurious onLost() notifications.
- //
- // TODO: simplify this, probably if favor of code that:
- // - selects a new upstream if mTetheringUpstreamNetwork has
- // been lost (by any callback)
- // - deletes the entry from the map only when the LISTEN_ALL
- // callback gets notified.
-
- if (!mNetworkMap.containsKey(network)) {
- // Ignore loss of networks about which we had not previously
- // learned any information or for which we have already processed
- // an onLost() notification.
- return;
- }
-
- if (VDBG) Log.d(TAG, "EVENT_ON_LOST for " + network);
-
- // TODO: If sufficient information is available to select a more
- // preferable upstream, do so now and notify the target. Likewise,
- // if the current upstream network is gone, notify the target of the
- // fact that we now have no upstream at all.
- notifyTarget(EVENT_ON_LOST, mNetworkMap.remove(network));
- }
-
- private void recomputeLocalPrefixes() {
- final HashSet<IpPrefix> localPrefixes = allLocalPrefixes(mNetworkMap.values());
- if (!mLocalPrefixes.equals(localPrefixes)) {
- mLocalPrefixes = localPrefixes;
- notifyTarget(NOTIFY_LOCAL_PREFIXES, localPrefixes.clone());
- }
- }
-
- // Fetch (and cache) a ConnectivityManager only if and when we need one.
- private ConnectivityManager cm() {
- if (mCM == null) {
- // MUST call the String variant to be able to write unittests.
- mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- }
- return mCM;
- }
-
- /**
- * A NetworkCallback class that handles information of interest directly
- * in the thread on which it is invoked. To avoid locking, this MUST be
- * run on the same thread as the target state machine's handler.
- */
- private class UpstreamNetworkCallback extends NetworkCallback {
- private final int mCallbackType;
-
- UpstreamNetworkCallback(int callbackType) {
- mCallbackType = callbackType;
- }
-
- @Override
- public void onAvailable(Network network) {
- handleAvailable(network);
- }
-
- @Override
- public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) {
- if (mCallbackType == CALLBACK_DEFAULT_INTERNET) {
- mDefaultInternetNetwork = network;
- final boolean newIsCellular = isCellular(newNc);
- if (mIsDefaultCellularUpstream != newIsCellular) {
- mIsDefaultCellularUpstream = newIsCellular;
- mEntitlementMgr.notifyUpstream(newIsCellular);
- }
- return;
- }
-
- handleNetCap(network, newNc);
- }
-
- @Override
- public void onLinkPropertiesChanged(Network network, LinkProperties newLp) {
- if (mCallbackType == CALLBACK_DEFAULT_INTERNET) return;
-
- handleLinkProp(network, newLp);
- // Any non-LISTEN_ALL callback will necessarily concern a network that will
- // also match the LISTEN_ALL callback by construction of the LISTEN_ALL callback.
- // So it's not useful to do this work for non-LISTEN_ALL callbacks.
- if (mCallbackType == CALLBACK_LISTEN_ALL) {
- recomputeLocalPrefixes();
- }
- }
-
- @Override
- public void onLost(Network network) {
- if (mCallbackType == CALLBACK_DEFAULT_INTERNET) {
- mDefaultInternetNetwork = null;
- mIsDefaultCellularUpstream = false;
- mEntitlementMgr.notifyUpstream(false);
- return;
- }
-
- handleLost(network);
- // Any non-LISTEN_ALL callback will necessarily concern a network that will
- // also match the LISTEN_ALL callback by construction of the LISTEN_ALL callback.
- // So it's not useful to do this work for non-LISTEN_ALL callbacks.
- if (mCallbackType == CALLBACK_LISTEN_ALL) {
- recomputeLocalPrefixes();
- }
- }
- }
-
- private void releaseCallback(NetworkCallback cb) {
- if (cb != null) cm().unregisterNetworkCallback(cb);
- }
-
- private void notifyTarget(int which, Network network) {
- notifyTarget(which, mNetworkMap.get(network));
- }
-
- private void notifyTarget(int which, Object obj) {
- mTarget.sendMessage(mWhat, which, 0, obj);
- }
-
- private static class TypeStatePair {
- public int type = TYPE_NONE;
- public UpstreamNetworkState ns = null;
- }
-
- private static TypeStatePair findFirstAvailableUpstreamByType(
- Iterable<UpstreamNetworkState> netStates, Iterable<Integer> preferredTypes,
- boolean isCellularUpstreamPermitted) {
- final TypeStatePair result = new TypeStatePair();
-
- for (int type : preferredTypes) {
- NetworkCapabilities nc;
- try {
- nc = networkCapabilitiesForType(type);
- } catch (IllegalArgumentException iae) {
- Log.e(TAG, "No NetworkCapabilities mapping for legacy type: " + type);
- continue;
- }
- if (!isCellularUpstreamPermitted && isCellular(nc)) {
- continue;
- }
-
- for (UpstreamNetworkState value : netStates) {
- if (!nc.satisfiedByNetworkCapabilities(value.networkCapabilities)) {
- continue;
- }
-
- result.type = type;
- result.ns = value;
- return result;
- }
- }
-
- return result;
- }
-
- private static HashSet<IpPrefix> allLocalPrefixes(Iterable<UpstreamNetworkState> netStates) {
- final HashSet<IpPrefix> prefixSet = new HashSet<>();
-
- for (UpstreamNetworkState ns : netStates) {
- final LinkProperties lp = ns.linkProperties;
- if (lp == null) continue;
- prefixSet.addAll(PrefixUtils.localPrefixesFrom(lp));
- }
-
- return prefixSet;
- }
-
- private static boolean isCellular(UpstreamNetworkState ns) {
- return (ns != null) && isCellular(ns.networkCapabilities);
- }
-
- private static boolean isCellular(NetworkCapabilities nc) {
- return (nc != null) && nc.hasTransport(TRANSPORT_CELLULAR)
- && nc.hasCapability(NET_CAPABILITY_NOT_VPN);
- }
-
- private static boolean hasCapability(UpstreamNetworkState ns, int netCap) {
- return (ns != null) && (ns.networkCapabilities != null)
- && ns.networkCapabilities.hasCapability(netCap);
- }
-
- private static boolean isNetworkUsableAndNotCellular(UpstreamNetworkState ns) {
- return (ns != null) && (ns.networkCapabilities != null) && (ns.linkProperties != null)
- && !isCellular(ns.networkCapabilities);
- }
-
- private static UpstreamNetworkState findFirstDunNetwork(
- Iterable<UpstreamNetworkState> netStates) {
- for (UpstreamNetworkState ns : netStates) {
- if (isCellular(ns) && hasCapability(ns, NET_CAPABILITY_DUN)) return ns;
- }
-
- return null;
- }
-
- /**
- * Given a legacy type (TYPE_WIFI, ...) returns the corresponding NetworkCapabilities instance.
- * This function is used for deprecated legacy type and be disabled by default.
- */
- @VisibleForTesting
- public static NetworkCapabilities networkCapabilitiesForType(int type) {
- final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
-
- // Map from type to transports.
- final int notFound = -1;
- final int transport = sLegacyTypeToTransport.get(type, notFound);
- if (transport == notFound) {
- throw new IllegalArgumentException("unknown legacy type: " + type);
- }
- builder.addTransportType(transport);
-
- if (type == TYPE_MOBILE_DUN) {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
- // DUN is restricted network, see NetworkCapabilities#FORCE_RESTRICTED_CAPABILITIES.
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- } else {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- }
- return builder.build();
- }
-}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkState.java b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkState.java
deleted file mode 100644
index bab9f84..0000000
--- a/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkState.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.networkstack.tethering;
-
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-
-import androidx.annotation.NonNull;
-
-/**
- * Snapshot of tethering upstream network state.
- */
-public class UpstreamNetworkState {
- /** {@link LinkProperties}. */
- public final LinkProperties linkProperties;
- /** {@link NetworkCapabilities}. */
- public final NetworkCapabilities networkCapabilities;
- /** {@link Network}. */
- public final Network network;
-
- /** Constructs a new UpstreamNetworkState. */
- public UpstreamNetworkState(LinkProperties linkProperties,
- NetworkCapabilities networkCapabilities, Network network) {
- this.linkProperties = linkProperties;
- this.networkCapabilities = networkCapabilities;
- this.network = network;
- }
-
- @NonNull
- @Override
- public String toString() {
- return String.format("UpstreamNetworkState{%s, %s, %s}",
- network == null ? "null" : network,
- networkCapabilities == null ? "null" : networkCapabilities,
- linkProperties == null ? "null" : linkProperties);
- }
-}
diff --git a/packages/Tethering/tests/integration/Android.bp b/packages/Tethering/tests/integration/Android.bp
deleted file mode 100644
index ed69b7d..0000000
--- a/packages/Tethering/tests/integration/Android.bp
+++ /dev/null
@@ -1,85 +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.
-//
-java_defaults {
- name: "TetheringIntegrationTestsDefaults",
- srcs: [
- "src/**/*.java",
- "src/**/*.kt",
- ],
- static_libs: [
- "NetworkStackApiStableLib",
- "androidx.test.rules",
- "frameworks-base-testutils",
- "mockito-target-extended-minus-junit4",
- "net-tests-utils",
- "testables",
- ],
- libs: [
- "android.test.runner",
- "android.test.base",
- "android.test.mock",
- ],
- jni_libs: [
- // For mockito extended
- "libdexmakerjvmtiagent",
- "libstaticjvmtiagent",
- ],
- jarjar_rules: ":NetworkStackJarJarRules",
-}
-
-android_library {
- name: "TetheringIntegrationTestsLib",
- platform_apis: true,
- defaults: ["TetheringIntegrationTestsDefaults"],
- visibility: ["//cts/tests/tests/tethering"]
-}
-
-android_test {
- name: "TetheringIntegrationTests",
- platform_apis: true,
- defaults: ["TetheringIntegrationTestsDefaults"],
- test_suites: [
- "device-tests",
- "mts",
- ],
- compile_multilib: "both",
-}
-
-// Special version of the tethering tests that includes all tests necessary for code coverage
-// purposes. This is currently the union of TetheringTests, TetheringIntegrationTests and
-// NetworkStackTests.
-android_test {
- name: "TetheringCoverageTests",
- platform_apis: true,
- test_suites: ["device-tests", "mts"],
- test_config: "AndroidTest_Coverage.xml",
- defaults: ["libnetworkstackutilsjni_deps"],
- static_libs: [
- "NetworkStaticLibTestsLib",
- "NetworkStackTestsLib",
- "TetheringTestsLib",
- "TetheringIntegrationTestsLib",
- ],
- jni_libs: [
- // For mockito extended
- "libdexmakerjvmtiagent",
- "libstaticjvmtiagent",
- // For NetworkStackUtils included in NetworkStackBase
- "libnetworkstackutilsjni",
- ],
- compile_multilib: "both",
- manifest: "AndroidManifest_coverage.xml",
-}
\ No newline at end of file
diff --git a/packages/Tethering/tests/integration/AndroidManifest.xml b/packages/Tethering/tests/integration/AndroidManifest.xml
deleted file mode 100644
index fddfaad..0000000
--- a/packages/Tethering/tests/integration/AndroidManifest.xml
+++ /dev/null
@@ -1,28 +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.networkstack.tethering.tests.integration">
-
- <uses-permission android:name="android.permission.INTERNET"/>
-
- <application android:debuggable="true">
- <uses-library android:name="android.test.runner" />
- </application>
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.networkstack.tethering.tests.integration"
- android:label="Tethering integration tests">
- </instrumentation>
-</manifest>
diff --git a/packages/Tethering/tests/integration/AndroidManifest_coverage.xml b/packages/Tethering/tests/integration/AndroidManifest_coverage.xml
deleted file mode 100644
index 06de00d..0000000
--- a/packages/Tethering/tests/integration/AndroidManifest_coverage.xml
+++ /dev/null
@@ -1,29 +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"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.android.networkstack.tethering.tests.coverage">
-
- <application tools:replace="android:label"
- android:debuggable="true"
- android:label="Tethering coverage tests">
- <uses-library android:name="android.test.runner" />
- </application>
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.networkstack.tethering.tests.coverage"
- android:label="Tethering coverage tests">
- </instrumentation>
-</manifest>
diff --git a/packages/Tethering/tests/integration/AndroidTest_Coverage.xml b/packages/Tethering/tests/integration/AndroidTest_Coverage.xml
deleted file mode 100644
index 3def209..0000000
--- a/packages/Tethering/tests/integration/AndroidTest_Coverage.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<configuration description="Runs coverage tests for Tethering">
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
- <option name="test-file-name" value="TetheringCoverageTests.apk" />
- </target_preparer>
-
- <option name="test-tag" value="TetheringCoverageTests" />
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="com.android.networkstack.tethering.tests.coverage" />
- <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
- <option name="hidden-api-checks" value="false"/>
- </test>
-</configuration>
\ No newline at end of file
diff --git a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
deleted file mode 100644
index 9bb01ae..0000000
--- a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ /dev/null
@@ -1,567 +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.net;
-
-import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
-import static android.Manifest.permission.NETWORK_SETTINGS;
-import static android.Manifest.permission.TETHER_PRIVILEGED;
-import static android.net.TetheringManager.TETHERING_ETHERNET;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
-
-import android.app.UiAutomation;
-import android.content.Context;
-import android.net.EthernetManager.TetheredInterfaceCallback;
-import android.net.EthernetManager.TetheredInterfaceRequest;
-import android.net.TetheringManager.StartTetheringCallback;
-import android.net.TetheringManager.TetheringEventCallback;
-import android.net.TetheringManager.TetheringRequest;
-import android.net.dhcp.DhcpAckPacket;
-import android.net.dhcp.DhcpOfferPacket;
-import android.net.dhcp.DhcpPacket;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.system.Os;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.testutils.HandlerUtilsKt;
-import com.android.testutils.TapPacketReader;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.FileDescriptor;
-import java.net.Inet4Address;
-import java.net.InterfaceAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class EthernetTetheringTest {
-
- private static final String TAG = EthernetTetheringTest.class.getSimpleName();
- private static final int TIMEOUT_MS = 5000;
- private static final int PACKET_READ_TIMEOUT_MS = 100;
- private static final int DHCP_DISCOVER_ATTEMPTS = 10;
- private static final byte[] DHCP_REQUESTED_PARAMS = new byte[] {
- DhcpPacket.DHCP_SUBNET_MASK,
- DhcpPacket.DHCP_ROUTER,
- DhcpPacket.DHCP_DNS_SERVER,
- DhcpPacket.DHCP_LEASE_TIME,
- };
- private static final String DHCP_HOSTNAME = "testhostname";
-
- private final Context mContext = InstrumentationRegistry.getContext();
- private final EthernetManager mEm = mContext.getSystemService(EthernetManager.class);
- private final TetheringManager mTm = mContext.getSystemService(TetheringManager.class);
-
- private TestNetworkInterface mTestIface;
- private HandlerThread mHandlerThread;
- private Handler mHandler;
- private TapPacketReader mTapPacketReader;
-
- private TetheredInterfaceRequester mTetheredInterfaceRequester;
- private MyTetheringEventCallback mTetheringEventCallback;
-
- private UiAutomation mUiAutomation =
- InstrumentationRegistry.getInstrumentation().getUiAutomation();
- private boolean mRunTests;
-
- @Before
- public void setUp() throws Exception {
- // Needed to create a TestNetworkInterface, to call requestTetheredInterface, and to receive
- // tethered client callbacks.
- mUiAutomation.adoptShellPermissionIdentity(
- MANAGE_TEST_NETWORKS, NETWORK_SETTINGS, TETHER_PRIVILEGED);
- mRunTests = mTm.isTetheringSupported() && mEm != null;
- assumeTrue(mRunTests);
-
- mHandlerThread = new HandlerThread(getClass().getSimpleName());
- mHandlerThread.start();
- mHandler = new Handler(mHandlerThread.getLooper());
- mTetheredInterfaceRequester = new TetheredInterfaceRequester(mHandler, mEm);
- }
-
- private void cleanUp() throws Exception {
- mTm.stopTethering(TETHERING_ETHERNET);
- if (mTetheringEventCallback != null) {
- mTetheringEventCallback.awaitInterfaceUntethered();
- mTetheringEventCallback.unregister();
- mTetheringEventCallback = null;
- }
- if (mTapPacketReader != null) {
- TapPacketReader reader = mTapPacketReader;
- mHandler.post(() -> reader.stop());
- mTapPacketReader = null;
- }
- mHandlerThread.quitSafely();
- mTetheredInterfaceRequester.release();
- mEm.setIncludeTestInterfaces(false);
- maybeDeleteTestInterface();
- }
-
- @After
- public void tearDown() throws Exception {
- try {
- if (mRunTests) cleanUp();
- } finally {
- mUiAutomation.dropShellPermissionIdentity();
- }
- }
-
- @Test
- public void testVirtualEthernetAlreadyExists() throws Exception {
- // This test requires manipulating packets. Skip if there is a physical Ethernet connected.
- assumeFalse(mEm.isAvailable());
-
- mTestIface = createTestInterface();
- // This must be done now because as soon as setIncludeTestInterfaces(true) is called, the
- // interface will be placed in client mode, which will delete the link-local address.
- // At that point NetworkInterface.getByName() will cease to work on the interface, because
- // starting in R NetworkInterface can no longer see interfaces without IP addresses.
- int mtu = getMTU(mTestIface);
-
- Log.d(TAG, "Including test interfaces");
- mEm.setIncludeTestInterfaces(true);
-
- final String iface = mTetheredInterfaceRequester.getInterface();
- assertEquals("TetheredInterfaceCallback for unexpected interface",
- mTestIface.getInterfaceName(), iface);
-
- checkVirtualEthernet(mTestIface, mtu);
- }
-
- @Test
- public void testVirtualEthernet() throws Exception {
- // This test requires manipulating packets. Skip if there is a physical Ethernet connected.
- assumeFalse(mEm.isAvailable());
-
- CompletableFuture<String> futureIface = mTetheredInterfaceRequester.requestInterface();
-
- mEm.setIncludeTestInterfaces(true);
-
- mTestIface = createTestInterface();
-
- final String iface = futureIface.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
- assertEquals("TetheredInterfaceCallback for unexpected interface",
- mTestIface.getInterfaceName(), iface);
-
- checkVirtualEthernet(mTestIface, getMTU(mTestIface));
- }
-
- @Test
- public void testStaticIpv4() throws Exception {
- assumeFalse(mEm.isAvailable());
-
- mEm.setIncludeTestInterfaces(true);
-
- mTestIface = createTestInterface();
-
- final String iface = mTetheredInterfaceRequester.getInterface();
- assertEquals("TetheredInterfaceCallback for unexpected interface",
- mTestIface.getInterfaceName(), iface);
-
- assertInvalidStaticIpv4Request(iface, null, null);
- assertInvalidStaticIpv4Request(iface, "2001:db8::1/64", "2001:db8:2::/64");
- assertInvalidStaticIpv4Request(iface, "192.0.2.2/28", "2001:db8:2::/28");
- assertInvalidStaticIpv4Request(iface, "2001:db8:2::/28", "192.0.2.2/28");
- assertInvalidStaticIpv4Request(iface, "192.0.2.2/28", null);
- assertInvalidStaticIpv4Request(iface, null, "192.0.2.2/28");
- assertInvalidStaticIpv4Request(iface, "192.0.2.3/27", "192.0.2.2/28");
-
- final String localAddr = "192.0.2.3/28";
- final String clientAddr = "192.0.2.2/28";
- mTetheringEventCallback = enableEthernetTethering(iface,
- requestWithStaticIpv4(localAddr, clientAddr));
-
- mTetheringEventCallback.awaitInterfaceTethered();
- assertInterfaceHasIpAddress(iface, localAddr);
-
- byte[] client1 = MacAddress.fromString("1:2:3:4:5:6").toByteArray();
- byte[] client2 = MacAddress.fromString("a:b:c:d:e:f").toByteArray();
-
- FileDescriptor fd = mTestIface.getFileDescriptor().getFileDescriptor();
- mTapPacketReader = makePacketReader(fd, getMTU(mTestIface));
- DhcpResults dhcpResults = runDhcp(fd, client1);
- assertEquals(new LinkAddress(clientAddr), dhcpResults.ipAddress);
-
- try {
- runDhcp(fd, client2);
- fail("Only one client should get an IP address");
- } catch (TimeoutException expected) { }
-
- }
-
- private boolean isAdbOverNetwork() {
- // If adb TCP port opened, this test may running by adb over network.
- return (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1)
- || (SystemProperties.getInt("service.adb.tcp.port", -1) > -1);
- }
-
- @Test
- public void testPhysicalEthernet() throws Exception {
- assumeTrue(mEm.isAvailable());
- // Do not run this test if adb is over network and ethernet is connected.
- // It is likely the adb run over ethernet, the adb would break when ethernet is switching
- // from client mode to server mode. See b/160389275.
- assumeFalse(isAdbOverNetwork());
-
- // Get an interface to use.
- final String iface = mTetheredInterfaceRequester.getInterface();
-
- // Enable Ethernet tethering and check that it starts.
- mTetheringEventCallback = enableEthernetTethering(iface);
-
- // There is nothing more we can do on a physical interface without connecting an actual
- // client, which is not possible in this test.
- }
-
- private static final class MyTetheringEventCallback implements TetheringEventCallback {
- private final TetheringManager mTm;
- private final CountDownLatch mTetheringStartedLatch = new CountDownLatch(1);
- private final CountDownLatch mTetheringStoppedLatch = new CountDownLatch(1);
- private final CountDownLatch mClientConnectedLatch = new CountDownLatch(1);
- private final String mIface;
-
- private volatile boolean mInterfaceWasTethered = false;
- private volatile boolean mUnregistered = false;
- private volatile Collection<TetheredClient> mClients = null;
-
- MyTetheringEventCallback(TetheringManager tm, String iface) {
- mTm = tm;
- mIface = iface;
- }
-
- public void unregister() {
- mTm.unregisterTetheringEventCallback(this);
- mUnregistered = true;
- }
-
- @Override
- public void onTetheredInterfacesChanged(List<String> interfaces) {
- // Ignore stale callbacks registered by previous test cases.
- if (mUnregistered) return;
-
- final boolean wasTethered = mTetheringStartedLatch.getCount() == 0;
- if (!mInterfaceWasTethered && (mIface == null || interfaces.contains(mIface))) {
- // This interface is being tethered for the first time.
- Log.d(TAG, "Tethering started: " + interfaces);
- mInterfaceWasTethered = true;
- mTetheringStartedLatch.countDown();
- } else if (mInterfaceWasTethered && !interfaces.contains(mIface)) {
- Log.d(TAG, "Tethering stopped: " + interfaces);
- mTetheringStoppedLatch.countDown();
- }
- }
-
- public void awaitInterfaceTethered() throws Exception {
- assertTrue("Ethernet not tethered after " + TIMEOUT_MS + "ms",
- mTetheringStartedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
-
- public void awaitInterfaceUntethered() throws Exception {
- // Don't block teardown if the interface was never tethered.
- // This is racy because the interface might become tethered right after this check, but
- // that can only happen in tearDown if startTethering timed out, which likely means
- // the test has already failed.
- if (!mInterfaceWasTethered) return;
-
- assertTrue(mIface + " not untethered after " + TIMEOUT_MS + "ms",
- mTetheringStoppedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
-
- @Override
- public void onError(String ifName, int error) {
- // Ignore stale callbacks registered by previous test cases.
- if (mUnregistered) return;
-
- fail("TetheringEventCallback got error:" + error + " on iface " + ifName);
- }
-
- @Override
- public void onClientsChanged(Collection<TetheredClient> clients) {
- // Ignore stale callbacks registered by previous test cases.
- if (mUnregistered) return;
-
- Log.d(TAG, "Got clients changed: " + clients);
- mClients = clients;
- if (clients.size() > 0) {
- mClientConnectedLatch.countDown();
- }
- }
-
- public Collection<TetheredClient> awaitClientConnected() throws Exception {
- assertTrue("Did not receive client connected callback after " + TIMEOUT_MS + "ms",
- mClientConnectedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- return mClients;
- }
- }
-
- private MyTetheringEventCallback enableEthernetTethering(String iface,
- TetheringRequest request) throws Exception {
- MyTetheringEventCallback callback = new MyTetheringEventCallback(mTm, iface);
- mTm.registerTetheringEventCallback(mHandler::post, callback);
-
- StartTetheringCallback startTetheringCallback = new StartTetheringCallback() {
- @Override
- public void onTetheringFailed(int resultCode) {
- fail("Unexpectedly got onTetheringFailed");
- }
- };
- Log.d(TAG, "Starting Ethernet tethering");
- mTm.startTethering(request, mHandler::post /* executor */, startTetheringCallback);
- callback.awaitInterfaceTethered();
- return callback;
- }
-
- private MyTetheringEventCallback enableEthernetTethering(String iface) throws Exception {
- return enableEthernetTethering(iface,
- new TetheringRequest.Builder(TETHERING_ETHERNET)
- .setShouldShowEntitlementUi(false).build());
- }
-
- private int getMTU(TestNetworkInterface iface) throws SocketException {
- NetworkInterface nif = NetworkInterface.getByName(iface.getInterfaceName());
- assertNotNull("Can't get NetworkInterface object for " + iface.getInterfaceName(), nif);
- return nif.getMTU();
- }
-
- private TapPacketReader makePacketReader(FileDescriptor fd, int mtu) {
- final TapPacketReader reader = new TapPacketReader(mHandler, fd, mtu);
- mHandler.post(() -> reader.start());
- HandlerUtilsKt.waitForIdle(mHandler, TIMEOUT_MS);
- return reader;
- }
-
- private void checkVirtualEthernet(TestNetworkInterface iface, int mtu) throws Exception {
- FileDescriptor fd = iface.getFileDescriptor().getFileDescriptor();
- mTapPacketReader = makePacketReader(fd, mtu);
- mTetheringEventCallback = enableEthernetTethering(iface.getInterfaceName());
- checkTetheredClientCallbacks(fd);
- }
-
- private DhcpResults runDhcp(FileDescriptor fd, byte[] clientMacAddr) throws Exception {
- // We have to retransmit DHCP requests because IpServer declares itself to be ready before
- // its DhcpServer is actually started. TODO: fix this race and remove this loop.
- DhcpPacket offerPacket = null;
- for (int i = 0; i < DHCP_DISCOVER_ATTEMPTS; i++) {
- Log.d(TAG, "Sending DHCP discover");
- sendDhcpDiscover(fd, clientMacAddr);
- offerPacket = getNextDhcpPacket();
- if (offerPacket instanceof DhcpOfferPacket) break;
- }
- if (!(offerPacket instanceof DhcpOfferPacket)) {
- throw new TimeoutException("No DHCPOFFER received on interface within timeout");
- }
-
- sendDhcpRequest(fd, offerPacket, clientMacAddr);
- DhcpPacket ackPacket = getNextDhcpPacket();
- if (!(ackPacket instanceof DhcpAckPacket)) {
- throw new TimeoutException("No DHCPACK received on interface within timeout");
- }
-
- return ackPacket.toDhcpResults();
- }
-
- private void checkTetheredClientCallbacks(FileDescriptor fd) throws Exception {
- // Create a fake client.
- byte[] clientMacAddr = new byte[6];
- new Random().nextBytes(clientMacAddr);
-
- DhcpResults dhcpResults = runDhcp(fd, clientMacAddr);
-
- final Collection<TetheredClient> clients = mTetheringEventCallback.awaitClientConnected();
- assertEquals(1, clients.size());
- final TetheredClient client = clients.iterator().next();
-
- // Check the MAC address.
- assertEquals(MacAddress.fromBytes(clientMacAddr), client.getMacAddress());
- assertEquals(TETHERING_ETHERNET, client.getTetheringType());
-
- // Check the hostname.
- assertEquals(1, client.getAddresses().size());
- TetheredClient.AddressInfo info = client.getAddresses().get(0);
- assertEquals(DHCP_HOSTNAME, info.getHostname());
-
- // Check the address is the one that was handed out in the DHCP ACK.
- assertLinkAddressMatches(dhcpResults.ipAddress, info.getAddress());
-
- // Check that the lifetime is correct +/- 10s.
- final long now = SystemClock.elapsedRealtime();
- final long actualLeaseDuration = (info.getAddress().getExpirationTime() - now) / 1000;
- final String msg = String.format("IP address should have lifetime of %d, got %d",
- dhcpResults.leaseDuration, actualLeaseDuration);
- assertTrue(msg, Math.abs(dhcpResults.leaseDuration - actualLeaseDuration) < 10);
- }
-
- private DhcpPacket getNextDhcpPacket() throws ParseException {
- byte[] packet;
- while ((packet = mTapPacketReader.popPacket(PACKET_READ_TIMEOUT_MS)) != null) {
- try {
- return DhcpPacket.decodeFullPacket(packet, packet.length, DhcpPacket.ENCAP_L2);
- } catch (DhcpPacket.ParseException e) {
- // Not a DHCP packet. Continue.
- }
- }
- return null;
- }
-
- private static final class TetheredInterfaceRequester implements TetheredInterfaceCallback {
- private final CountDownLatch mInterfaceAvailableLatch = new CountDownLatch(1);
- private final Handler mHandler;
- private final EthernetManager mEm;
-
- private TetheredInterfaceRequest mRequest;
- private final CompletableFuture<String> mFuture = new CompletableFuture<>();
-
- TetheredInterfaceRequester(Handler handler, EthernetManager em) {
- mHandler = handler;
- mEm = em;
- }
-
- @Override
- public void onAvailable(String iface) {
- Log.d(TAG, "Ethernet interface available: " + iface);
- mFuture.complete(iface);
- }
-
- @Override
- public void onUnavailable() {
- mFuture.completeExceptionally(new IllegalStateException("onUnavailable received"));
- }
-
- public CompletableFuture<String> requestInterface() {
- assertNull("BUG: more than one tethered interface request", mRequest);
- Log.d(TAG, "Requesting tethered interface");
- mRequest = mEm.requestTetheredInterface(mHandler::post, this);
- return mFuture;
- }
-
- public String getInterface() throws Exception {
- return requestInterface().get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
- }
-
- public void release() {
- if (mRequest != null) {
- mFuture.obtrudeException(new IllegalStateException("Request already released"));
- mRequest.release();
- mRequest = null;
- }
- }
- }
-
- private void sendDhcpDiscover(FileDescriptor fd, byte[] macAddress) throws Exception {
- ByteBuffer packet = DhcpPacket.buildDiscoverPacket(DhcpPacket.ENCAP_L2,
- new Random().nextInt() /* transactionId */, (short) 0 /* secs */,
- macAddress, false /* unicast */, DHCP_REQUESTED_PARAMS,
- false /* rapid commit */, DHCP_HOSTNAME);
- sendPacket(fd, packet);
- }
-
- private void sendDhcpRequest(FileDescriptor fd, DhcpPacket offerPacket, byte[] macAddress)
- throws Exception {
- DhcpResults results = offerPacket.toDhcpResults();
- Inet4Address clientIp = (Inet4Address) results.ipAddress.getAddress();
- Inet4Address serverIdentifier = results.serverAddress;
- ByteBuffer packet = DhcpPacket.buildRequestPacket(DhcpPacket.ENCAP_L2,
- 0 /* transactionId */, (short) 0 /* secs */, DhcpPacket.INADDR_ANY /* clientIp */,
- false /* broadcast */, macAddress, clientIp /* requestedIpAddress */,
- serverIdentifier, DHCP_REQUESTED_PARAMS, DHCP_HOSTNAME);
- sendPacket(fd, packet);
- }
-
- private void sendPacket(FileDescriptor fd, ByteBuffer packet) throws Exception {
- assertNotNull("Only tests on virtual interfaces can send packets", fd);
- Os.write(fd, packet);
- }
-
- public void assertLinkAddressMatches(LinkAddress l1, LinkAddress l2) {
- // Check all fields except the deprecation and expiry times.
- String msg = String.format("LinkAddresses do not match. expected: %s actual: %s", l1, l2);
- assertTrue(msg, l1.isSameAddressAs(l2));
- assertEquals("LinkAddress flags do not match", l1.getFlags(), l2.getFlags());
- assertEquals("LinkAddress scope does not match", l1.getScope(), l2.getScope());
- }
-
- private TetheringRequest requestWithStaticIpv4(String local, String client) {
- LinkAddress localAddr = local == null ? null : new LinkAddress(local);
- LinkAddress clientAddr = client == null ? null : new LinkAddress(client);
- return new TetheringRequest.Builder(TETHERING_ETHERNET)
- .setStaticIpv4Addresses(localAddr, clientAddr)
- .setShouldShowEntitlementUi(false).build();
- }
-
- private void assertInvalidStaticIpv4Request(String iface, String local, String client)
- throws Exception {
- try {
- enableEthernetTethering(iface, requestWithStaticIpv4(local, client));
- fail("Unexpectedly accepted invalid IPv4 configuration: " + local + ", " + client);
- } catch (IllegalArgumentException | NullPointerException expected) { }
- }
-
- private void assertInterfaceHasIpAddress(String iface, String expected) throws Exception {
- LinkAddress expectedAddr = new LinkAddress(expected);
- NetworkInterface nif = NetworkInterface.getByName(iface);
- for (InterfaceAddress ia : nif.getInterfaceAddresses()) {
- final LinkAddress addr = new LinkAddress(ia.getAddress(), ia.getNetworkPrefixLength());
- if (expectedAddr.equals(addr)) {
- return;
- }
- }
- fail("Expected " + iface + " to have IP address " + expected + ", found "
- + nif.getInterfaceAddresses());
- }
-
- private TestNetworkInterface createTestInterface() throws Exception {
- TestNetworkManager tnm = mContext.getSystemService(TestNetworkManager.class);
- TestNetworkInterface iface = tnm.createTapInterface();
- Log.d(TAG, "Created test interface " + iface.getInterfaceName());
- assertNotNull(NetworkInterface.getByName(iface.getInterfaceName()));
- return iface;
- }
-
- private void maybeDeleteTestInterface() throws Exception {
- if (mTestIface != null) {
- mTestIface.getFileDescriptor().close();
- Log.d(TAG, "Deleted test interface " + mTestIface.getInterfaceName());
- mTestIface = null;
- }
- }
-}
diff --git a/packages/Tethering/tests/unit/Android.bp b/packages/Tethering/tests/unit/Android.bp
deleted file mode 100644
index 45c7b65..0000000
--- a/packages/Tethering/tests/unit/Android.bp
+++ /dev/null
@@ -1,93 +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.
-//
-
-// Tests in this folder are included both in unit tests and CTS.
-java_library {
- name: "TetheringCommonTests",
- srcs: [
- "common/**/*.java",
- "common/**/*.kt"
- ],
- static_libs: [
- "androidx.test.rules",
- "net-tests-utils",
- ],
- // TODO(b/147200698) change sdk_version to module-current and remove framework-minus-apex
- sdk_version: "core_platform",
- libs: [
- "framework-minus-apex",
- "framework-tethering.impl",
- ],
- visibility: ["//cts/tests/tests/tethering"],
-}
-
-java_defaults {
- name: "TetheringTestsDefaults",
- srcs: [
- "src/**/*.java",
- "src/**/*.kt",
- ],
- static_libs: [
- "TetheringApiCurrentLib",
- "TetheringCommonTests",
- "androidx.test.rules",
- "frameworks-base-testutils",
- "mockito-target-extended-minus-junit4",
- "net-tests-utils",
- "testables",
- ],
- // TODO(b/147200698) change sdk_version to module-current and
- // remove framework-minus-apex, ext, and framework-res
- sdk_version: "core_platform",
- libs: [
- "android.test.runner",
- "android.test.base",
- "android.test.mock",
- "ext",
- "framework-minus-apex",
- "framework-res",
- "framework-tethering.impl",
- "framework-wifi.stubs.module_lib",
- ],
- jni_libs: [
- // For mockito extended
- "libdexmakerjvmtiagent",
- "libstaticjvmtiagent",
- ],
- jarjar_rules: "jarjar-rules.txt",
-}
-
-// Library containing the unit tests. This is used by the coverage test target to pull in the
-// unit test code. It is not currently used by the tests themselves because all the build
-// configuration needed by the tests is in the TetheringTestsDefaults rule.
-android_library {
- name: "TetheringTestsLib",
- defaults: ["TetheringTestsDefaults"],
- visibility: [
- "//frameworks/base/packages/Tethering/tests/integration",
- ]
-}
-
-android_test {
- name: "TetheringTests",
- platform_apis: true,
- test_suites: [
- "device-tests",
- "mts",
- ],
- defaults: ["TetheringTestsDefaults"],
- compile_multilib: "both",
-}
diff --git a/packages/Tethering/tests/unit/AndroidManifest.xml b/packages/Tethering/tests/unit/AndroidManifest.xml
deleted file mode 100644
index 355342f..0000000
--- a/packages/Tethering/tests/unit/AndroidManifest.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.networkstack.tethering.tests.unit">
-
- <application android:debuggable="true">
- <uses-library android:name="android.test.runner" />
- <service
- android:name="com.android.networkstack.tethering.MockTetheringService"
- android:permission="android.permission.TETHER_PRIVILEGED"
- android:exported="true">
- <intent-filter>
- <action android:name="com.android.networkstack.tethering.TetheringService"/>
- </intent-filter>
- </service>
- </application>
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.networkstack.tethering.tests.unit"
- android:label="Tethering service tests">
- </instrumentation>
-</manifest>
diff --git a/packages/Tethering/tests/unit/common/android/net/TetheredClientTest.kt b/packages/Tethering/tests/unit/common/android/net/TetheredClientTest.kt
deleted file mode 100644
index 55c59dd..0000000
--- a/packages/Tethering/tests/unit/common/android/net/TetheredClientTest.kt
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net
-
-import android.net.InetAddresses.parseNumericAddress
-import android.net.TetheredClient.AddressInfo
-import android.net.TetheringManager.TETHERING_BLUETOOTH
-import android.net.TetheringManager.TETHERING_USB
-import android.system.OsConstants.RT_SCOPE_UNIVERSE
-import androidx.test.filters.SmallTest
-import androidx.test.runner.AndroidJUnit4
-import com.android.testutils.assertParcelSane
-import org.junit.Test
-import org.junit.runner.RunWith
-import kotlin.test.assertEquals
-import kotlin.test.assertNotEquals
-
-private val TEST_MACADDR = MacAddress.fromBytes(byteArrayOf(12, 23, 34, 45, 56, 67))
-private val TEST_OTHER_MACADDR = MacAddress.fromBytes(byteArrayOf(23, 34, 45, 56, 67, 78))
-private val TEST_ADDR1 = makeLinkAddress("192.168.113.3", prefixLength = 24, expTime = 123L)
-private val TEST_ADDR2 = makeLinkAddress("fe80::1:2:3", prefixLength = 64, expTime = 456L)
-private val TEST_HOSTNAME = "test_hostname"
-private val TEST_OTHER_HOSTNAME = "test_other_hostname"
-private val TEST_ADDRINFO1 = AddressInfo(TEST_ADDR1, TEST_HOSTNAME)
-private val TEST_ADDRINFO2 = AddressInfo(TEST_ADDR2, null)
-
-private fun makeLinkAddress(addr: String, prefixLength: Int, expTime: Long) = LinkAddress(
- parseNumericAddress(addr),
- prefixLength,
- 0 /* flags */,
- RT_SCOPE_UNIVERSE,
- expTime /* deprecationTime */,
- expTime /* expirationTime */)
-
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-class TetheredClientTest {
- @Test
- fun testParceling() {
- assertParcelSane(TEST_ADDRINFO1, fieldCount = 2)
- assertParcelSane(makeTestClient(), fieldCount = 3)
- }
-
- @Test
- fun testEquals() {
- assertEquals(makeTestClient(), makeTestClient())
-
- // Different mac address
- assertNotEquals(makeTestClient(), TetheredClient(
- TEST_OTHER_MACADDR,
- listOf(TEST_ADDRINFO1, TEST_ADDRINFO2),
- TETHERING_BLUETOOTH))
-
- // Different hostname
- assertNotEquals(makeTestClient(), TetheredClient(
- TEST_MACADDR,
- listOf(AddressInfo(TEST_ADDR1, TEST_OTHER_HOSTNAME), TEST_ADDRINFO2),
- TETHERING_BLUETOOTH))
-
- // Null hostname
- assertNotEquals(makeTestClient(), TetheredClient(
- TEST_MACADDR,
- listOf(AddressInfo(TEST_ADDR1, null), TEST_ADDRINFO2),
- TETHERING_BLUETOOTH))
-
- // Missing address
- assertNotEquals(makeTestClient(), TetheredClient(
- TEST_MACADDR,
- listOf(TEST_ADDRINFO2),
- TETHERING_BLUETOOTH))
-
- // Different type
- assertNotEquals(makeTestClient(), TetheredClient(
- TEST_MACADDR,
- listOf(TEST_ADDRINFO1, TEST_ADDRINFO2),
- TETHERING_USB))
- }
-
- @Test
- fun testAddAddresses() {
- val client1 = TetheredClient(TEST_MACADDR, listOf(TEST_ADDRINFO1), TETHERING_USB)
- val client2 = TetheredClient(TEST_OTHER_MACADDR, listOf(TEST_ADDRINFO2), TETHERING_USB)
- assertEquals(TetheredClient(
- TEST_MACADDR,
- listOf(TEST_ADDRINFO1, TEST_ADDRINFO2),
- TETHERING_USB), client1.addAddresses(client2))
- }
-
- @Test
- fun testGetters() {
- assertEquals(TEST_MACADDR, makeTestClient().macAddress)
- assertEquals(listOf(TEST_ADDRINFO1, TEST_ADDRINFO2), makeTestClient().addresses)
- assertEquals(TETHERING_BLUETOOTH, makeTestClient().tetheringType)
- }
-
- @Test
- fun testAddressInfo_Getters() {
- assertEquals(TEST_ADDR1, TEST_ADDRINFO1.address)
- assertEquals(TEST_ADDR2, TEST_ADDRINFO2.address)
- assertEquals(TEST_HOSTNAME, TEST_ADDRINFO1.hostname)
- assertEquals(null, TEST_ADDRINFO2.hostname)
- }
-
- private fun makeTestClient() = TetheredClient(
- TEST_MACADDR,
- listOf(TEST_ADDRINFO1, TEST_ADDRINFO2),
- TETHERING_BLUETOOTH)
-}
\ No newline at end of file
diff --git a/packages/Tethering/tests/unit/jarjar-rules.txt b/packages/Tethering/tests/unit/jarjar-rules.txt
deleted file mode 100644
index ec2d2b0..0000000
--- a/packages/Tethering/tests/unit/jarjar-rules.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-# Don't jar-jar the entire package because this test use some
-# internal classes (like ArrayUtils in com.android.internal.util)
-rule com.android.internal.util.BitUtils* com.android.networkstack.tethering.util.BitUtils@1
-rule com.android.internal.util.IndentingPrintWriter.java* com.android.networkstack.tethering.util.IndentingPrintWriter.java@1
-rule com.android.internal.util.IState.java* com.android.networkstack.tethering.util.IState.java@1
-rule com.android.internal.util.MessageUtils* com.android.networkstack.tethering.util.MessageUtils@1
-rule com.android.internal.util.State* com.android.networkstack.tethering.util.State@1
-rule com.android.internal.util.StateMachine* com.android.networkstack.tethering.util.StateMachine@1
-rule com.android.internal.util.TrafficStatsConstants* com.android.networkstack.tethering.util.TrafficStatsConstants@1
-
-rule android.util.LocalLog* com.android.networkstack.tethering.util.LocalLog@1
diff --git a/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java b/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java
deleted file mode 100644
index a8857b2..0000000
--- a/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java
+++ /dev/null
@@ -1,123 +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.net.dhcp;
-
-import static android.net.InetAddresses.parseNumericAddress;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.net.LinkAddress;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DhcpServingParamsParcelExtTest {
- private static final Inet4Address TEST_ADDRESS = inet4Addr("192.168.0.123");
- private static final Inet4Address TEST_CLIENT_ADDRESS = inet4Addr("192.168.0.42");
- private static final int TEST_ADDRESS_PARCELED = 0xc0a8007b;
- private static final int TEST_CLIENT_ADDRESS_PARCELED = 0xc0a8002a;
- private static final int TEST_PREFIX_LENGTH = 17;
- private static final int TEST_LEASE_TIME_SECS = 120;
- private static final int TEST_MTU = 1000;
- private static final Set<Inet4Address> TEST_ADDRESS_SET =
- new HashSet<Inet4Address>(Arrays.asList(
- new Inet4Address[] {inet4Addr("192.168.1.123"), inet4Addr("192.168.1.124")}));
- private static final Set<Integer> TEST_ADDRESS_SET_PARCELED =
- new HashSet<Integer>(Arrays.asList(new Integer[] {0xc0a8017b, 0xc0a8017c}));
-
- private DhcpServingParamsParcelExt mParcel;
-
- @Before
- public void setUp() {
- mParcel = new DhcpServingParamsParcelExt();
- }
-
- @Test
- public void testSetServerAddr() {
- mParcel.setServerAddr(new LinkAddress(TEST_ADDRESS, TEST_PREFIX_LENGTH));
-
- assertEquals(TEST_ADDRESS_PARCELED, mParcel.serverAddr);
- assertEquals(TEST_PREFIX_LENGTH, mParcel.serverAddrPrefixLength);
- }
-
- @Test
- public void testSetDefaultRouters() {
- mParcel.setDefaultRouters(TEST_ADDRESS_SET);
- assertEquals(TEST_ADDRESS_SET_PARCELED, asSet(mParcel.defaultRouters));
- }
-
- @Test
- public void testSetDnsServers() {
- mParcel.setDnsServers(TEST_ADDRESS_SET);
- assertEquals(TEST_ADDRESS_SET_PARCELED, asSet(mParcel.dnsServers));
- }
-
- @Test
- public void testSetExcludedAddrs() {
- mParcel.setExcludedAddrs(TEST_ADDRESS_SET);
- assertEquals(TEST_ADDRESS_SET_PARCELED, asSet(mParcel.excludedAddrs));
- }
-
- @Test
- public void testSetDhcpLeaseTimeSecs() {
- mParcel.setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS);
- assertEquals(TEST_LEASE_TIME_SECS, mParcel.dhcpLeaseTimeSecs);
- }
-
- @Test
- public void testSetLinkMtu() {
- mParcel.setLinkMtu(TEST_MTU);
- assertEquals(TEST_MTU, mParcel.linkMtu);
- }
-
- @Test
- public void testSetMetered() {
- mParcel.setMetered(true);
- assertTrue(mParcel.metered);
- mParcel.setMetered(false);
- assertFalse(mParcel.metered);
- }
-
- @Test
- public void testSetClientAddr() {
- mParcel.setSingleClientAddr(TEST_CLIENT_ADDRESS);
- assertEquals(TEST_CLIENT_ADDRESS_PARCELED, mParcel.singleClientAddr);
- }
-
- private static Inet4Address inet4Addr(String addr) {
- return (Inet4Address) parseNumericAddress(addr);
- }
-
- private static Set<Integer> asSet(int[] ints) {
- return IntStream.of(ints).boxed().collect(Collectors.toSet());
- }
-}
diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
deleted file mode 100644
index 30a9d22..0000000
--- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ /dev/null
@@ -1,1074 +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.net.ip;
-
-import static android.net.INetd.IF_STATE_UP;
-import static android.net.RouteInfo.RTN_UNICAST;
-import static android.net.TetheringManager.TETHERING_BLUETOOTH;
-import static android.net.TetheringManager.TETHERING_NCM;
-import static android.net.TetheringManager.TETHERING_USB;
-import static android.net.TetheringManager.TETHERING_WIFI;
-import static android.net.TetheringManager.TETHERING_WIFI_P2P;
-import static android.net.TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.ip.IpServer.STATE_AVAILABLE;
-import static android.net.ip.IpServer.STATE_LOCAL_ONLY;
-import static android.net.ip.IpServer.STATE_TETHERED;
-import static android.net.ip.IpServer.STATE_UNAVAILABLE;
-import static android.net.netlink.NetlinkConstants.RTM_DELNEIGH;
-import static android.net.netlink.NetlinkConstants.RTM_NEWNEIGH;
-import static android.net.netlink.StructNdMsg.NUD_FAILED;
-import static android.net.netlink.StructNdMsg.NUD_REACHABLE;
-import static android.net.netlink.StructNdMsg.NUD_STALE;
-
-import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.usage.NetworkStatsManager;
-import android.net.INetd;
-import android.net.InetAddresses;
-import android.net.InterfaceConfigurationParcel;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.MacAddress;
-import android.net.RouteInfo;
-import android.net.TetherOffloadRuleParcel;
-import android.net.TetherStatsParcel;
-import android.net.dhcp.DhcpServingParamsParcel;
-import android.net.dhcp.IDhcpEventCallbacks;
-import android.net.dhcp.IDhcpServer;
-import android.net.dhcp.IDhcpServerCallbacks;
-import android.net.ip.IpNeighborMonitor.NeighborEvent;
-import android.net.ip.IpNeighborMonitor.NeighborEventConsumer;
-import android.net.ip.RouterAdvertisementDaemon.RaParams;
-import android.net.util.InterfaceParams;
-import android.net.util.InterfaceSet;
-import android.net.util.PrefixUtils;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.test.TestLooper;
-import android.text.TextUtils;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.networkstack.tethering.BpfCoordinator;
-import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
-import com.android.networkstack.tethering.PrivateAddressCoordinator;
-import com.android.networkstack.tethering.TetheringConfiguration;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Captor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class IpServerTest {
- private static final String IFACE_NAME = "testnet1";
- private static final String UPSTREAM_IFACE = "upstream0";
- private static final String UPSTREAM_IFACE2 = "upstream1";
- private static final int UPSTREAM_IFINDEX = 101;
- private static final int UPSTREAM_IFINDEX2 = 102;
- private static final String BLUETOOTH_IFACE_ADDR = "192.168.44.1";
- private static final int BLUETOOTH_DHCP_PREFIX_LENGTH = 24;
- private static final int DHCP_LEASE_TIME_SECS = 3600;
- private static final boolean DEFAULT_USING_BPF_OFFLOAD = true;
-
- private static final InterfaceParams TEST_IFACE_PARAMS = new InterfaceParams(
- IFACE_NAME, 42 /* index */, MacAddress.ALL_ZEROS_ADDRESS, 1500 /* defaultMtu */);
-
- private static final int MAKE_DHCPSERVER_TIMEOUT_MS = 1000;
-
- private final LinkAddress mTestAddress = new LinkAddress("192.168.42.5/24");
- private final IpPrefix mBluetoothPrefix = new IpPrefix("192.168.44.0/24");
-
- @Mock private INetd mNetd;
- @Mock private IpServer.Callback mCallback;
- @Mock private SharedLog mSharedLog;
- @Mock private IDhcpServer mDhcpServer;
- @Mock private RouterAdvertisementDaemon mRaDaemon;
- @Mock private IpNeighborMonitor mIpNeighborMonitor;
- @Mock private IpServer.Dependencies mDependencies;
- @Mock private PrivateAddressCoordinator mAddressCoordinator;
- @Mock private NetworkStatsManager mStatsManager;
- @Mock private TetheringConfiguration mTetherConfig;
-
- @Captor private ArgumentCaptor<DhcpServingParamsParcel> mDhcpParamsCaptor;
-
- private final TestLooper mLooper = new TestLooper();
- private final ArgumentCaptor<LinkProperties> mLinkPropertiesCaptor =
- ArgumentCaptor.forClass(LinkProperties.class);
- private IpServer mIpServer;
- private InterfaceConfigurationParcel mInterfaceConfiguration;
- private NeighborEventConsumer mNeighborEventConsumer;
- private BpfCoordinator mBpfCoordinator;
-
- private void initStateMachine(int interfaceType) throws Exception {
- initStateMachine(interfaceType, false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD);
- }
-
- private void initStateMachine(int interfaceType, boolean usingLegacyDhcp,
- boolean usingBpfOffload) throws Exception {
- doAnswer(inv -> {
- final IDhcpServerCallbacks cb = inv.getArgument(2);
- new Thread(() -> {
- try {
- cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
- } catch (RemoteException e) {
- fail(e.getMessage());
- }
- }).run();
- return null;
- }).when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(), any());
- when(mDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon);
- when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS);
-
- when(mDependencies.getIfindex(eq(UPSTREAM_IFACE))).thenReturn(UPSTREAM_IFINDEX);
- when(mDependencies.getIfindex(eq(UPSTREAM_IFACE2))).thenReturn(UPSTREAM_IFINDEX2);
-
- mInterfaceConfiguration = new InterfaceConfigurationParcel();
- mInterfaceConfiguration.flags = new String[0];
- if (interfaceType == TETHERING_BLUETOOTH) {
- mInterfaceConfiguration.ipv4Addr = BLUETOOTH_IFACE_ADDR;
- mInterfaceConfiguration.prefixLength = BLUETOOTH_DHCP_PREFIX_LENGTH;
- }
-
- ArgumentCaptor<NeighborEventConsumer> neighborCaptor =
- ArgumentCaptor.forClass(NeighborEventConsumer.class);
- doReturn(mIpNeighborMonitor).when(mDependencies).getIpNeighborMonitor(any(), any(),
- neighborCaptor.capture());
-
- mIpServer = new IpServer(
- IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd, mBpfCoordinator,
- mCallback, usingLegacyDhcp, usingBpfOffload, mAddressCoordinator, mDependencies);
- mIpServer.start();
- mNeighborEventConsumer = neighborCaptor.getValue();
-
- // Starting the state machine always puts us in a consistent state and notifies
- // the rest of the world that we've changed from an unknown to available state.
- mLooper.dispatchAll();
- reset(mNetd, mCallback);
-
- when(mRaDaemon.start()).thenReturn(true);
- }
-
- private void initTetheredStateMachine(int interfaceType, String upstreamIface)
- throws Exception {
- initTetheredStateMachine(interfaceType, upstreamIface, false,
- DEFAULT_USING_BPF_OFFLOAD);
- }
-
- private void initTetheredStateMachine(int interfaceType, String upstreamIface,
- boolean usingLegacyDhcp, boolean usingBpfOffload) throws Exception {
- initStateMachine(interfaceType, usingLegacyDhcp, usingBpfOffload);
- dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
- if (upstreamIface != null) {
- LinkProperties lp = new LinkProperties();
- lp.setInterfaceName(upstreamIface);
- dispatchTetherConnectionChanged(upstreamIface, lp, 0);
- }
- reset(mNetd, mCallback, mAddressCoordinator);
- when(mAddressCoordinator.requestDownstreamAddress(any())).thenReturn(mTestAddress);
- }
-
- @Before public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- when(mSharedLog.forSubComponent(anyString())).thenReturn(mSharedLog);
- when(mAddressCoordinator.requestDownstreamAddress(any())).thenReturn(mTestAddress);
- when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(true /* default value */);
-
- mBpfCoordinator = spy(new BpfCoordinator(
- new BpfCoordinator.Dependencies() {
- @NonNull
- public Handler getHandler() {
- return new Handler(mLooper.getLooper());
- }
-
- @NonNull
- public INetd getNetd() {
- return mNetd;
- }
-
- @NonNull
- public NetworkStatsManager getNetworkStatsManager() {
- return mStatsManager;
- }
-
- @NonNull
- public SharedLog getSharedLog() {
- return mSharedLog;
- }
-
- @Nullable
- public TetheringConfiguration getTetherConfig() {
- return mTetherConfig;
- }
- }));
- }
-
- @Test
- public void startsOutAvailable() {
- when(mDependencies.getIpNeighborMonitor(any(), any(), any()))
- .thenReturn(mIpNeighborMonitor);
- mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), TETHERING_BLUETOOTH, mSharedLog,
- mNetd, mBpfCoordinator, mCallback, false /* usingLegacyDhcp */,
- DEFAULT_USING_BPF_OFFLOAD, mAddressCoordinator, mDependencies);
- mIpServer.start();
- mLooper.dispatchAll();
- verify(mCallback).updateInterfaceState(
- mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
- verify(mCallback).updateLinkProperties(eq(mIpServer), any(LinkProperties.class));
- verifyNoMoreInteractions(mCallback, mNetd);
- }
-
- @Test
- public void shouldDoNothingUntilRequested() throws Exception {
- initStateMachine(TETHERING_BLUETOOTH);
- final int [] noOp_commands = {
- IpServer.CMD_TETHER_UNREQUESTED,
- IpServer.CMD_IP_FORWARDING_ENABLE_ERROR,
- IpServer.CMD_IP_FORWARDING_DISABLE_ERROR,
- IpServer.CMD_START_TETHERING_ERROR,
- IpServer.CMD_STOP_TETHERING_ERROR,
- IpServer.CMD_SET_DNS_FORWARDERS_ERROR,
- IpServer.CMD_TETHER_CONNECTION_CHANGED
- };
- for (int command : noOp_commands) {
- // None of these commands should trigger us to request action from
- // the rest of the system.
- dispatchCommand(command);
- verifyNoMoreInteractions(mNetd, mCallback);
- }
- }
-
- @Test
- public void handlesImmediateInterfaceDown() throws Exception {
- initStateMachine(TETHERING_BLUETOOTH);
-
- dispatchCommand(IpServer.CMD_INTERFACE_DOWN);
- verify(mCallback).updateInterfaceState(
- mIpServer, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR);
- verify(mCallback).updateLinkProperties(eq(mIpServer), any(LinkProperties.class));
- verifyNoMoreInteractions(mNetd, mCallback);
- }
-
- @Test
- public void canBeTethered() throws Exception {
- initStateMachine(TETHERING_BLUETOOTH);
-
- dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
- InOrder inOrder = inOrder(mCallback, mNetd);
- inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
- inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
- // One for ipv4 route, one for ipv6 link local route.
- inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
- any(), any());
- inOrder.verify(mCallback).updateInterfaceState(
- mIpServer, STATE_TETHERED, TETHER_ERROR_NO_ERROR);
- inOrder.verify(mCallback).updateLinkProperties(
- eq(mIpServer), any(LinkProperties.class));
- verifyNoMoreInteractions(mNetd, mCallback);
- }
-
- @Test
- public void canUnrequestTethering() throws Exception {
- initTetheredStateMachine(TETHERING_BLUETOOTH, null);
-
- dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED);
- InOrder inOrder = inOrder(mCallback, mNetd, mAddressCoordinator);
- inOrder.verify(mNetd).tetherApplyDnsInterfaces();
- inOrder.verify(mNetd).tetherInterfaceRemove(IFACE_NAME);
- inOrder.verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
- inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
- inOrder.verify(mAddressCoordinator).releaseDownstream(any());
- inOrder.verify(mCallback).updateInterfaceState(
- mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
- inOrder.verify(mCallback).updateLinkProperties(
- eq(mIpServer), any(LinkProperties.class));
- verifyNoMoreInteractions(mNetd, mCallback, mAddressCoordinator);
- }
-
- @Test
- public void canBeTetheredAsUsb() throws Exception {
- initStateMachine(TETHERING_USB);
-
- dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
- InOrder inOrder = inOrder(mCallback, mNetd, mAddressCoordinator);
- inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any());
- inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
- IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
- inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
- inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
- inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
- any(), any());
- inOrder.verify(mCallback).updateInterfaceState(
- mIpServer, STATE_TETHERED, TETHER_ERROR_NO_ERROR);
- inOrder.verify(mCallback).updateLinkProperties(
- eq(mIpServer), mLinkPropertiesCaptor.capture());
- assertIPv4AddressAndDirectlyConnectedRoute(mLinkPropertiesCaptor.getValue());
- verifyNoMoreInteractions(mNetd, mCallback, mAddressCoordinator);
- }
-
- @Test
- public void canBeTetheredAsWifiP2p() throws Exception {
- initStateMachine(TETHERING_WIFI_P2P);
-
- dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
- InOrder inOrder = inOrder(mCallback, mNetd, mAddressCoordinator);
- inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any());
- inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
- IFACE_NAME.equals(cfg.ifName) && assertNotContainsFlag(cfg.flags, IF_STATE_UP)));
- inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
- inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
- inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
- any(), any());
- inOrder.verify(mCallback).updateInterfaceState(
- mIpServer, STATE_LOCAL_ONLY, TETHER_ERROR_NO_ERROR);
- inOrder.verify(mCallback).updateLinkProperties(
- eq(mIpServer), mLinkPropertiesCaptor.capture());
- assertIPv4AddressAndDirectlyConnectedRoute(mLinkPropertiesCaptor.getValue());
- verifyNoMoreInteractions(mNetd, mCallback, mAddressCoordinator);
- }
-
- @Test
- public void handlesFirstUpstreamChange() throws Exception {
- initTetheredStateMachine(TETHERING_BLUETOOTH, null);
-
- // Telling the state machine about its upstream interface triggers
- // a little more configuration.
- dispatchTetherConnectionChanged(UPSTREAM_IFACE);
- InOrder inOrder = inOrder(mNetd);
- inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE);
- inOrder.verify(mNetd).ipfwdAddInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
- verifyNoMoreInteractions(mNetd, mCallback);
- }
-
- @Test
- public void handlesChangingUpstream() throws Exception {
- initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
-
- dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
- InOrder inOrder = inOrder(mNetd);
- inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
- inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE);
- inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
- inOrder.verify(mNetd).ipfwdAddInterfaceForward(IFACE_NAME, UPSTREAM_IFACE2);
- verifyNoMoreInteractions(mNetd, mCallback);
- }
-
- @Test
- public void handlesChangingUpstreamNatFailure() throws Exception {
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
-
- doThrow(RemoteException.class).when(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
-
- dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
- InOrder inOrder = inOrder(mNetd);
- inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
- inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE);
- inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
- inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE2);
- inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE2);
- }
-
- @Test
- public void handlesChangingUpstreamInterfaceForwardingFailure() throws Exception {
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
-
- doThrow(RemoteException.class).when(mNetd).ipfwdAddInterfaceForward(
- IFACE_NAME, UPSTREAM_IFACE2);
-
- dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
- InOrder inOrder = inOrder(mNetd);
- inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
- inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE);
- inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
- inOrder.verify(mNetd).ipfwdAddInterfaceForward(IFACE_NAME, UPSTREAM_IFACE2);
- inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE2);
- inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE2);
- }
-
- @Test
- public void canUnrequestTetheringWithUpstream() throws Exception {
- initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
-
- dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED);
- InOrder inOrder = inOrder(mNetd, mCallback, mAddressCoordinator);
- inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
- inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE);
- inOrder.verify(mNetd).tetherApplyDnsInterfaces();
- inOrder.verify(mNetd).tetherInterfaceRemove(IFACE_NAME);
- inOrder.verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
- inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
- inOrder.verify(mAddressCoordinator).releaseDownstream(any());
- inOrder.verify(mCallback).updateInterfaceState(
- mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
- inOrder.verify(mCallback).updateLinkProperties(
- eq(mIpServer), any(LinkProperties.class));
- verifyNoMoreInteractions(mNetd, mCallback, mAddressCoordinator);
- }
-
- @Test
- public void interfaceDownLeadsToUnavailable() throws Exception {
- for (boolean shouldThrow : new boolean[]{true, false}) {
- initTetheredStateMachine(TETHERING_USB, null);
-
- if (shouldThrow) {
- doThrow(RemoteException.class).when(mNetd).tetherInterfaceRemove(IFACE_NAME);
- }
- dispatchCommand(IpServer.CMD_INTERFACE_DOWN);
- InOrder usbTeardownOrder = inOrder(mNetd, mCallback);
- // Currently IpServer interfaceSetCfg twice to stop IPv4. One just set interface down
- // Another one is set IPv4 to 0.0.0.0/0 as clearng ipv4 address.
- usbTeardownOrder.verify(mNetd, times(2)).interfaceSetCfg(
- argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
- usbTeardownOrder.verify(mCallback).updateInterfaceState(
- mIpServer, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR);
- usbTeardownOrder.verify(mCallback).updateLinkProperties(
- eq(mIpServer), mLinkPropertiesCaptor.capture());
- assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue());
- }
- }
-
- @Test
- public void usbShouldBeTornDownOnTetherError() throws Exception {
- initStateMachine(TETHERING_USB);
-
- doThrow(RemoteException.class).when(mNetd).tetherInterfaceAdd(IFACE_NAME);
- dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
- InOrder usbTeardownOrder = inOrder(mNetd, mCallback);
- usbTeardownOrder.verify(mNetd).interfaceSetCfg(
- argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
- usbTeardownOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
-
- usbTeardownOrder.verify(mNetd, times(2)).interfaceSetCfg(
- argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
- usbTeardownOrder.verify(mCallback).updateInterfaceState(
- mIpServer, STATE_AVAILABLE, TETHER_ERROR_TETHER_IFACE_ERROR);
- usbTeardownOrder.verify(mCallback).updateLinkProperties(
- eq(mIpServer), mLinkPropertiesCaptor.capture());
- assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue());
- }
-
- @Test
- public void shouldTearDownUsbOnUpstreamError() throws Exception {
- initTetheredStateMachine(TETHERING_USB, null);
-
- doThrow(RemoteException.class).when(mNetd).tetherAddForward(anyString(), anyString());
- dispatchTetherConnectionChanged(UPSTREAM_IFACE);
- InOrder usbTeardownOrder = inOrder(mNetd, mCallback);
- usbTeardownOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE);
-
- usbTeardownOrder.verify(mNetd, times(2)).interfaceSetCfg(
- argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
- usbTeardownOrder.verify(mCallback).updateInterfaceState(
- mIpServer, STATE_AVAILABLE, TETHER_ERROR_ENABLE_FORWARDING_ERROR);
- usbTeardownOrder.verify(mCallback).updateLinkProperties(
- eq(mIpServer), mLinkPropertiesCaptor.capture());
- assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue());
- }
-
- @Test
- public void ignoresDuplicateUpstreamNotifications() throws Exception {
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
-
- verifyNoMoreInteractions(mNetd, mCallback);
-
- for (int i = 0; i < 5; i++) {
- dispatchTetherConnectionChanged(UPSTREAM_IFACE);
- verifyNoMoreInteractions(mNetd, mCallback);
- }
- }
-
- @Test
- public void startsDhcpServer() throws Exception {
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE);
-
- assertDhcpStarted(PrefixUtils.asIpPrefix(mTestAddress));
- }
-
- @Test
- public void startsDhcpServerOnBluetooth() throws Exception {
- initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE);
-
- assertDhcpStarted(mBluetoothPrefix);
- }
-
- @Test
- public void startsDhcpServerOnWifiP2p() throws Exception {
- initTetheredStateMachine(TETHERING_WIFI_P2P, UPSTREAM_IFACE);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE);
-
- assertDhcpStarted(PrefixUtils.asIpPrefix(mTestAddress));
- }
-
- @Test
- public void startsDhcpServerOnNcm() throws Exception {
- initStateMachine(TETHERING_NCM);
- dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE);
-
- assertDhcpStarted(new IpPrefix("192.168.42.0/24"));
- }
-
- @Test
- public void testOnNewPrefixRequest() throws Exception {
- initStateMachine(TETHERING_NCM);
- dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
-
- final IDhcpEventCallbacks eventCallbacks;
- final ArgumentCaptor<IDhcpEventCallbacks> dhcpEventCbsCaptor =
- ArgumentCaptor.forClass(IDhcpEventCallbacks.class);
- verify(mDhcpServer, timeout(MAKE_DHCPSERVER_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), dhcpEventCbsCaptor.capture());
- eventCallbacks = dhcpEventCbsCaptor.getValue();
- assertDhcpStarted(new IpPrefix("192.168.42.0/24"));
-
- final ArgumentCaptor<LinkProperties> lpCaptor =
- ArgumentCaptor.forClass(LinkProperties.class);
- InOrder inOrder = inOrder(mNetd, mCallback, mAddressCoordinator);
- inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any());
- inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
- // One for ipv4 route, one for ipv6 link local route.
- inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
- any(), any());
- inOrder.verify(mCallback).updateInterfaceState(
- mIpServer, STATE_LOCAL_ONLY, TETHER_ERROR_NO_ERROR);
- inOrder.verify(mCallback).updateLinkProperties(eq(mIpServer), lpCaptor.capture());
- verifyNoMoreInteractions(mCallback, mAddressCoordinator);
-
- // Simulate the DHCP server receives DHCPDECLINE on MirrorLink and then signals
- // onNewPrefixRequest callback.
- final LinkAddress newAddress = new LinkAddress("192.168.100.125/24");
- when(mAddressCoordinator.requestDownstreamAddress(any())).thenReturn(newAddress);
- eventCallbacks.onNewPrefixRequest(new IpPrefix("192.168.42.0/24"));
- mLooper.dispatchAll();
-
- inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any());
- inOrder.verify(mNetd).tetherApplyDnsInterfaces();
- inOrder.verify(mCallback).updateLinkProperties(eq(mIpServer), lpCaptor.capture());
- verifyNoMoreInteractions(mCallback);
-
- final LinkProperties linkProperties = lpCaptor.getValue();
- final List<LinkAddress> linkAddresses = linkProperties.getLinkAddresses();
- assertEquals(1, linkProperties.getLinkAddresses().size());
- assertEquals(1, linkProperties.getRoutes().size());
- final IpPrefix prefix = new IpPrefix(linkAddresses.get(0).getAddress(),
- linkAddresses.get(0).getPrefixLength());
- assertNotEquals(prefix, new IpPrefix("192.168.42.0/24"));
-
- verify(mDhcpServer).updateParams(mDhcpParamsCaptor.capture(), any());
- assertDhcpServingParams(mDhcpParamsCaptor.getValue(), prefix);
- }
-
- @Test
- public void doesNotStartDhcpServerIfDisabled() throws Exception {
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, true /* usingLegacyDhcp */,
- DEFAULT_USING_BPF_OFFLOAD);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE);
-
- verify(mDependencies, never()).makeDhcpServer(any(), any(), any());
- }
-
- private InetAddress addr(String addr) throws Exception {
- return InetAddresses.parseNumericAddress(addr);
- }
-
- private void recvNewNeigh(int ifindex, InetAddress addr, short nudState, MacAddress mac) {
- mNeighborEventConsumer.accept(new NeighborEvent(0, RTM_NEWNEIGH, ifindex, addr,
- nudState, mac));
- mLooper.dispatchAll();
- }
-
- private void recvDelNeigh(int ifindex, InetAddress addr, short nudState, MacAddress mac) {
- mNeighborEventConsumer.accept(new NeighborEvent(0, RTM_DELNEIGH, ifindex, addr,
- nudState, mac));
- mLooper.dispatchAll();
- }
-
- /**
- * Custom ArgumentMatcher for TetherOffloadRuleParcel. This is needed because generated stable
- * AIDL classes don't have equals(), so we cannot just use eq(). A custom assert, such as:
- *
- * private void checkFooCalled(StableParcelable p, ...) {
- * ArgumentCaptor<FooParam> captor = ArgumentCaptor.forClass(FooParam.class);
- * verify(mMock).foo(captor.capture());
- * Foo foo = captor.getValue();
- * assertFooMatchesExpectations(foo);
- * }
- *
- * almost works, but not quite. This is because if the code under test calls foo() twice, the
- * first call to checkFooCalled() matches both the calls, putting both calls into the captor,
- * and then fails with TooManyActualInvocations. It also makes it harder to use other mockito
- * features such as never(), inOrder(), etc.
- *
- * This approach isn't great because if the match fails, the error message is unhelpful
- * (actual: "android.net.TetherOffloadRuleParcel@8c827b0" or some such), but at least it does
- * work.
- *
- * TODO: consider making the error message more readable by adding a method that catching the
- * AssertionFailedError and throwing a new assertion with more details. See
- * NetworkMonitorTest#verifyNetworkTested.
- *
- * See ConnectivityServiceTest#assertRoutesAdded for an alternative approach which solves the
- * TooManyActualInvocations problem described above by forcing the caller of the custom assert
- * method to specify all expected invocations in one call. This is useful when the stable
- * parcelable class being asserted on has a corresponding Java object (eg., RouteInfo and
- * RouteInfoParcelable), and the caller can just pass in a list of them. It not useful here
- * because there is no such object.
- */
- private static class TetherOffloadRuleParcelMatcher implements
- ArgumentMatcher<TetherOffloadRuleParcel> {
- public final int upstreamIfindex;
- public final InetAddress dst;
- public final MacAddress dstMac;
-
- TetherOffloadRuleParcelMatcher(int upstreamIfindex, InetAddress dst, MacAddress dstMac) {
- this.upstreamIfindex = upstreamIfindex;
- this.dst = dst;
- this.dstMac = dstMac;
- }
-
- public boolean matches(TetherOffloadRuleParcel parcel) {
- return upstreamIfindex == parcel.inputInterfaceIndex
- && (TEST_IFACE_PARAMS.index == parcel.outputInterfaceIndex)
- && Arrays.equals(dst.getAddress(), parcel.destination)
- && (128 == parcel.prefixLength)
- && Arrays.equals(TEST_IFACE_PARAMS.macAddr.toByteArray(), parcel.srcL2Address)
- && Arrays.equals(dstMac.toByteArray(), parcel.dstL2Address);
- }
-
- public String toString() {
- return String.format("TetherOffloadRuleParcelMatcher(%d, %s, %s",
- upstreamIfindex, dst.getHostAddress(), dstMac);
- }
- }
-
- @NonNull
- private static TetherOffloadRuleParcel matches(
- int upstreamIfindex, InetAddress dst, MacAddress dstMac) {
- return argThat(new TetherOffloadRuleParcelMatcher(upstreamIfindex, dst, dstMac));
- }
-
- @NonNull
- private static Ipv6ForwardingRule makeForwardingRule(
- int upstreamIfindex, @NonNull InetAddress dst, @NonNull MacAddress dstMac) {
- return new Ipv6ForwardingRule(upstreamIfindex, TEST_IFACE_PARAMS.index,
- (Inet6Address) dst, TEST_IFACE_PARAMS.macAddr, dstMac);
- }
-
- @NonNull
- private static TetherStatsParcel buildEmptyTetherStatsParcel(int ifIndex) {
- TetherStatsParcel parcel = new TetherStatsParcel();
- parcel.ifIndex = ifIndex;
- return parcel;
- }
-
- private void resetNetdAndBpfCoordinator() throws Exception {
- reset(mNetd, mBpfCoordinator);
- when(mNetd.tetherOffloadGetStats()).thenReturn(new TetherStatsParcel[0]);
- when(mNetd.tetherOffloadGetAndClearStats(UPSTREAM_IFINDEX))
- .thenReturn(buildEmptyTetherStatsParcel(UPSTREAM_IFINDEX));
- when(mNetd.tetherOffloadGetAndClearStats(UPSTREAM_IFINDEX2))
- .thenReturn(buildEmptyTetherStatsParcel(UPSTREAM_IFINDEX2));
- }
-
- @Test
- public void addRemoveipv6ForwardingRules() throws Exception {
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
- DEFAULT_USING_BPF_OFFLOAD);
-
- final int myIfindex = TEST_IFACE_PARAMS.index;
- final int notMyIfindex = myIfindex - 1;
-
- final MacAddress myMac = TEST_IFACE_PARAMS.macAddr;
- final InetAddress neighA = InetAddresses.parseNumericAddress("2001:db8::1");
- final InetAddress neighB = InetAddresses.parseNumericAddress("2001:db8::2");
- final InetAddress neighLL = InetAddresses.parseNumericAddress("fe80::1");
- final InetAddress neighMC = InetAddresses.parseNumericAddress("ff02::1234");
- final MacAddress macNull = MacAddress.fromString("00:00:00:00:00:00");
- final MacAddress macA = MacAddress.fromString("00:00:00:00:00:0a");
- final MacAddress macB = MacAddress.fromString("11:22:33:00:00:0b");
-
- resetNetdAndBpfCoordinator();
- verifyNoMoreInteractions(mBpfCoordinator, mNetd);
-
- // TODO: Perhaps verify the interaction of tetherOffloadSetInterfaceQuota and
- // tetherOffloadGetAndClearStats in netd while the rules are changed.
-
- // Events on other interfaces are ignored.
- recvNewNeigh(notMyIfindex, neighA, NUD_REACHABLE, macA);
- verifyNoMoreInteractions(mBpfCoordinator, mNetd);
-
- // Events on this interface are received and sent to netd.
- recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
- verify(mBpfCoordinator).tetherOffloadRuleAdd(
- mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macA));
- verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighA, macA));
- resetNetdAndBpfCoordinator();
-
- recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
- verify(mBpfCoordinator).tetherOffloadRuleAdd(
- mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macB));
- verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighB, macB));
- resetNetdAndBpfCoordinator();
-
- // Link-local and multicast neighbors are ignored.
- recvNewNeigh(myIfindex, neighLL, NUD_REACHABLE, macA);
- verifyNoMoreInteractions(mBpfCoordinator, mNetd);
- recvNewNeigh(myIfindex, neighMC, NUD_REACHABLE, macA);
- verifyNoMoreInteractions(mBpfCoordinator, mNetd);
-
- // A neighbor that is no longer valid causes the rule to be removed.
- // NUD_FAILED events do not have a MAC address.
- recvNewNeigh(myIfindex, neighA, NUD_FAILED, null);
- verify(mBpfCoordinator).tetherOffloadRuleRemove(
- mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macNull));
- verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighA, macNull));
- resetNetdAndBpfCoordinator();
-
- // A neighbor that is deleted causes the rule to be removed.
- recvDelNeigh(myIfindex, neighB, NUD_STALE, macB);
- verify(mBpfCoordinator).tetherOffloadRuleRemove(
- mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macNull));
- verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macNull));
- resetNetdAndBpfCoordinator();
-
- // Upstream changes result in updating the rules.
- recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
- recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
- resetNetdAndBpfCoordinator();
-
- InOrder inOrder = inOrder(mNetd);
- LinkProperties lp = new LinkProperties();
- lp.setInterfaceName(UPSTREAM_IFACE2);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp, -1);
- verify(mBpfCoordinator).tetherOffloadRuleUpdate(mIpServer, UPSTREAM_IFINDEX2);
- inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighA, macA));
- inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX2, neighA, macA));
- inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macB));
- inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX2, neighB, macB));
- resetNetdAndBpfCoordinator();
-
- // When the upstream is lost, rules are removed.
- dispatchTetherConnectionChanged(null, null, 0);
- // Clear function is called two times by:
- // - processMessage CMD_TETHER_CONNECTION_CHANGED for the upstream is lost.
- // - processMessage CMD_IPV6_TETHER_UPDATE for the IPv6 upstream is lost.
- // See dispatchTetherConnectionChanged.
- verify(mBpfCoordinator, times(2)).tetherOffloadRuleClear(mIpServer);
- verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX2, neighA, macA));
- verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX2, neighB, macB));
- resetNetdAndBpfCoordinator();
-
- // If the upstream is IPv4-only, no rules are added.
- dispatchTetherConnectionChanged(UPSTREAM_IFACE);
- resetNetdAndBpfCoordinator();
- recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
- // Clear function is called by #updateIpv6ForwardingRules for the IPv6 upstream is lost.
- verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
- verifyNoMoreInteractions(mBpfCoordinator, mNetd);
-
- // Rules can be added again once upstream IPv6 connectivity is available.
- lp.setInterfaceName(UPSTREAM_IFACE);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, -1);
- recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
- verify(mBpfCoordinator).tetherOffloadRuleAdd(
- mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macB));
- verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighB, macB));
- verify(mBpfCoordinator, never()).tetherOffloadRuleAdd(
- mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macA));
- verify(mNetd, never()).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighA, macA));
-
- // If upstream IPv6 connectivity is lost, rules are removed.
- resetNetdAndBpfCoordinator();
- dispatchTetherConnectionChanged(UPSTREAM_IFACE, null, 0);
- verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
- verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macB));
-
- // When the interface goes down, rules are removed.
- lp.setInterfaceName(UPSTREAM_IFACE);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, -1);
- recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
- recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
- verify(mBpfCoordinator).tetherOffloadRuleAdd(
- mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macA));
- verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighA, macA));
- verify(mBpfCoordinator).tetherOffloadRuleAdd(
- mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macB));
- verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighB, macB));
- resetNetdAndBpfCoordinator();
-
- mIpServer.stop();
- mLooper.dispatchAll();
- verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
- verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighA, macA));
- verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macB));
- verify(mIpNeighborMonitor).stop();
- resetNetdAndBpfCoordinator();
- }
-
- @Test
- public void enableDisableUsingBpfOffload() throws Exception {
- final int myIfindex = TEST_IFACE_PARAMS.index;
- final InetAddress neigh = InetAddresses.parseNumericAddress("2001:db8::1");
- final MacAddress macA = MacAddress.fromString("00:00:00:00:00:0a");
- final MacAddress macNull = MacAddress.fromString("00:00:00:00:00:00");
-
- // Expect that rules can be only added/removed when the BPF offload config is enabled.
- // Note that the BPF offload disabled case is not a realistic test case. Because IP
- // neighbor monitor doesn't start if BPF offload is disabled, there should have no
- // neighbor event listening. This is used for testing the protection check just in case.
- // TODO: Perhaps remove the BPF offload disabled case test once this check isn't needed
- // anymore.
-
- // [1] Enable BPF offload.
- // A neighbor that is added or deleted causes the rule to be added or removed.
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
- true /* usingBpfOffload */);
- resetNetdAndBpfCoordinator();
-
- recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, macA);
- verify(mBpfCoordinator).tetherOffloadRuleAdd(
- mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neigh, macA));
- verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neigh, macA));
- resetNetdAndBpfCoordinator();
-
- recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
- verify(mBpfCoordinator).tetherOffloadRuleRemove(
- mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neigh, macNull));
- verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neigh, macNull));
- resetNetdAndBpfCoordinator();
-
- // [2] Disable BPF offload.
- // A neighbor that is added or deleted doesn’t cause the rule to be added or removed.
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
- false /* usingBpfOffload */);
- resetNetdAndBpfCoordinator();
-
- recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, macA);
- verify(mBpfCoordinator, never()).tetherOffloadRuleAdd(any(), any());
- verify(mNetd, never()).tetherOffloadRuleAdd(any());
- resetNetdAndBpfCoordinator();
-
- recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
- verify(mBpfCoordinator, never()).tetherOffloadRuleRemove(any(), any());
- verify(mNetd, never()).tetherOffloadRuleRemove(any());
- resetNetdAndBpfCoordinator();
- }
-
- @Test
- public void doesNotStartIpNeighborMonitorIfBpfOffloadDisabled() throws Exception {
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
- false /* usingBpfOffload */);
-
- // IP neighbor monitor doesn't start if BPF offload is disabled.
- verify(mIpNeighborMonitor, never()).start();
- }
-
- private LinkProperties buildIpv6OnlyLinkProperties(final String iface) {
- final LinkProperties linkProp = new LinkProperties();
- linkProp.setInterfaceName(iface);
- linkProp.addLinkAddress(new LinkAddress("2001:db8::1/64"));
- linkProp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, iface, RTN_UNICAST));
- final InetAddress dns = InetAddresses.parseNumericAddress("2001:4860:4860::8888");
- linkProp.addDnsServer(dns);
-
- return linkProp;
- }
-
- @Test
- public void testAdjustTtlValue() throws Exception {
- final ArgumentCaptor<RaParams> raParamsCaptor =
- ArgumentCaptor.forClass(RaParams.class);
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
- verify(mRaDaemon).buildNewRa(any(), raParamsCaptor.capture());
- final RaParams noV6Params = raParamsCaptor.getValue();
- assertEquals(65, noV6Params.hopLimit);
- reset(mRaDaemon);
-
- when(mNetd.getProcSysNet(
- INetd.IPV6, INetd.CONF, UPSTREAM_IFACE, "hop_limit")).thenReturn("64");
- final LinkProperties lp = buildIpv6OnlyLinkProperties(UPSTREAM_IFACE);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, 1);
- verify(mRaDaemon).buildNewRa(any(), raParamsCaptor.capture());
- final RaParams nonCellularParams = raParamsCaptor.getValue();
- assertEquals(65, nonCellularParams.hopLimit);
- reset(mRaDaemon);
-
- dispatchTetherConnectionChanged(UPSTREAM_IFACE, null, 0);
- verify(mRaDaemon).buildNewRa(any(), raParamsCaptor.capture());
- final RaParams noUpstream = raParamsCaptor.getValue();
- assertEquals(65, nonCellularParams.hopLimit);
- reset(mRaDaemon);
-
- dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, -1);
- verify(mRaDaemon).buildNewRa(any(), raParamsCaptor.capture());
- final RaParams cellularParams = raParamsCaptor.getValue();
- assertEquals(63, cellularParams.hopLimit);
- reset(mRaDaemon);
- }
-
- private void assertDhcpServingParams(final DhcpServingParamsParcel params,
- final IpPrefix prefix) {
- // Last address byte is random
- assertTrue(prefix.contains(intToInet4AddressHTH(params.serverAddr)));
- assertEquals(prefix.getPrefixLength(), params.serverAddrPrefixLength);
- assertEquals(1, params.defaultRouters.length);
- assertEquals(params.serverAddr, params.defaultRouters[0]);
- assertEquals(1, params.dnsServers.length);
- assertEquals(params.serverAddr, params.dnsServers[0]);
- assertEquals(DHCP_LEASE_TIME_SECS, params.dhcpLeaseTimeSecs);
- if (mIpServer.interfaceType() == TETHERING_NCM) {
- assertTrue(params.changePrefixOnDecline);
- }
- }
-
- private void assertDhcpStarted(IpPrefix expectedPrefix) throws Exception {
- verify(mDependencies, times(1)).makeDhcpServer(eq(IFACE_NAME), any(), any());
- verify(mDhcpServer, timeout(MAKE_DHCPSERVER_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
- assertDhcpServingParams(mDhcpParamsCaptor.getValue(), expectedPrefix);
- }
-
- /**
- * Send a command to the state machine under test, and run the event loop to idle.
- *
- * @param command One of the IpServer.CMD_* constants.
- * @param arg1 An additional argument to pass.
- */
- private void dispatchCommand(int command, int arg1) {
- mIpServer.sendMessage(command, arg1);
- mLooper.dispatchAll();
- }
-
- /**
- * Send a command to the state machine under test, and run the event loop to idle.
- *
- * @param command One of the IpServer.CMD_* constants.
- */
- private void dispatchCommand(int command) {
- mIpServer.sendMessage(command);
- mLooper.dispatchAll();
- }
-
- /**
- * Special override to tell the state machine that the upstream interface has changed.
- *
- * @see #dispatchCommand(int)
- * @param upstreamIface String name of upstream interface (or null)
- * @param v6lp IPv6 LinkProperties of the upstream interface, or null for an IPv4-only upstream.
- */
- private void dispatchTetherConnectionChanged(String upstreamIface, LinkProperties v6lp,
- int ttlAdjustment) {
- dispatchTetherConnectionChanged(upstreamIface);
- mIpServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, ttlAdjustment, 0, v6lp);
- mLooper.dispatchAll();
- }
-
- private void dispatchTetherConnectionChanged(String upstreamIface) {
- final InterfaceSet ifs = (upstreamIface != null) ? new InterfaceSet(upstreamIface) : null;
- mIpServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifs);
- mLooper.dispatchAll();
- }
-
- private void assertIPv4AddressAndDirectlyConnectedRoute(LinkProperties lp) {
- // Find the first IPv4 LinkAddress.
- LinkAddress addr4 = null;
- for (LinkAddress addr : lp.getLinkAddresses()) {
- if (!(addr.getAddress() instanceof Inet4Address)) continue;
- addr4 = addr;
- break;
- }
- assertNotNull("missing IPv4 address", addr4);
-
- final IpPrefix destination = new IpPrefix(addr4.getAddress(), addr4.getPrefixLength());
- // Assert the presence of the associated directly connected route.
- final RouteInfo directlyConnected = new RouteInfo(destination, null, lp.getInterfaceName(),
- RouteInfo.RTN_UNICAST);
- assertTrue("missing directly connected route: '" + directlyConnected.toString() + "'",
- lp.getRoutes().contains(directlyConnected));
- }
-
- private void assertNoAddressesNorRoutes(LinkProperties lp) {
- assertTrue(lp.getLinkAddresses().isEmpty());
- assertTrue(lp.getRoutes().isEmpty());
- // We also check that interface name is non-empty, because we should
- // never see an empty interface name in any LinkProperties update.
- assertFalse(TextUtils.isEmpty(lp.getInterfaceName()));
- }
-
- private boolean assertContainsFlag(String[] flags, String match) {
- for (String flag : flags) {
- if (flag.equals(match)) return true;
- }
- fail("Missing flag: " + match);
- return false;
- }
-
- private boolean assertNotContainsFlag(String[] flags, String match) {
- for (String flag : flags) {
- if (flag.equals(match)) {
- fail("Unexpected flag: " + match);
- return false;
- }
- }
- return true;
- }
-}
diff --git a/packages/Tethering/tests/unit/src/android/net/util/InterfaceSetTest.java b/packages/Tethering/tests/unit/src/android/net/util/InterfaceSetTest.java
deleted file mode 100644
index ea084b6..0000000
--- a/packages/Tethering/tests/unit/src/android/net/util/InterfaceSetTest.java
+++ /dev/null
@@ -1,61 +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.net.util;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class InterfaceSetTest {
- @Test
- public void testNullNamesIgnored() {
- final InterfaceSet set = new InterfaceSet(null, "if1", null, "if2", null);
- assertEquals(2, set.ifnames.size());
- assertTrue(set.ifnames.contains("if1"));
- assertTrue(set.ifnames.contains("if2"));
- }
-
- @Test
- public void testToString() {
- final InterfaceSet set = new InterfaceSet("if1", "if2");
- final String setString = set.toString();
- assertTrue(setString.equals("[if1,if2]") || setString.equals("[if2,if1]"));
- }
-
- @Test
- public void testToString_Empty() {
- final InterfaceSet set = new InterfaceSet(null, null);
- assertEquals("[]", set.toString());
- }
-
- @Test
- public void testEquals() {
- assertEquals(new InterfaceSet(null, "if1", "if2"), new InterfaceSet("if2", "if1"));
- assertEquals(new InterfaceSet(null, null), new InterfaceSet());
- assertFalse(new InterfaceSet("if1", "if3").equals(new InterfaceSet("if1", "if2")));
- assertFalse(new InterfaceSet("if1", "if2").equals(new InterfaceSet("if1")));
- assertFalse(new InterfaceSet().equals(null));
- }
-}
diff --git a/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java b/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java
deleted file mode 100644
index 1499f3b..0000000
--- a/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.util;
-
-import static android.net.TetheringManager.TETHERING_USB;
-import static android.net.TetheringManager.TETHERING_WIFI;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.net.LinkAddress;
-import android.net.TetheringRequestParcel;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.testutils.MiscAssertsKt;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class TetheringUtilsTest {
- private static final LinkAddress TEST_SERVER_ADDR = new LinkAddress("192.168.43.1/24");
- private static final LinkAddress TEST_CLIENT_ADDR = new LinkAddress("192.168.43.5/24");
- private TetheringRequestParcel mTetheringRequest;
-
- @Before
- public void setUp() {
- mTetheringRequest = makeTetheringRequestParcel();
- }
-
- public TetheringRequestParcel makeTetheringRequestParcel() {
- final TetheringRequestParcel request = new TetheringRequestParcel();
- request.tetheringType = TETHERING_WIFI;
- request.localIPv4Address = TEST_SERVER_ADDR;
- request.staticClientAddress = TEST_CLIENT_ADDR;
- request.exemptFromEntitlementCheck = false;
- request.showProvisioningUi = true;
- return request;
- }
-
- @Test
- public void testIsTetheringRequestEquals() throws Exception {
- TetheringRequestParcel request = makeTetheringRequestParcel();
-
- assertTrue(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, mTetheringRequest));
- assertTrue(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
- assertTrue(TetheringUtils.isTetheringRequestEquals(null, null));
- assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, null));
- assertFalse(TetheringUtils.isTetheringRequestEquals(null, mTetheringRequest));
-
- request = makeTetheringRequestParcel();
- request.tetheringType = TETHERING_USB;
- assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
-
- request = makeTetheringRequestParcel();
- request.localIPv4Address = null;
- request.staticClientAddress = null;
- assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
-
- request = makeTetheringRequestParcel();
- request.exemptFromEntitlementCheck = true;
- assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
-
- request = makeTetheringRequestParcel();
- request.showProvisioningUi = false;
- assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
-
- MiscAssertsKt.assertFieldCountEquals(5, TetheringRequestParcel.class);
- }
-}
diff --git a/packages/Tethering/tests/unit/src/android/net/util/VersionedBroadcastListenerTest.java b/packages/Tethering/tests/unit/src/android/net/util/VersionedBroadcastListenerTest.java
deleted file mode 100644
index 5a9b6e3..0000000
--- a/packages/Tethering/tests/unit/src/android/net/util/VersionedBroadcastListenerTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.reset;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.test.BroadcastInterceptingContext;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VersionedBroadcastListenerTest {
- private static final String TAG = VersionedBroadcastListenerTest.class.getSimpleName();
- private static final String ACTION_TEST = "action.test.happy.broadcasts";
-
- @Mock private Context mContext;
- private BroadcastInterceptingContext mServiceContext;
- private Handler mHandler;
- private VersionedBroadcastListener mListener;
- private int mCallbackCount;
-
- private void doCallback() {
- mCallbackCount++;
- }
-
- private class MockContext extends BroadcastInterceptingContext {
- MockContext(Context base) {
- super(base);
- }
- }
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- }
-
- @Before public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- reset(mContext);
- mServiceContext = new MockContext(mContext);
- mHandler = new Handler(Looper.myLooper());
- mCallbackCount = 0;
- final IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_TEST);
- mListener = new VersionedBroadcastListener(
- TAG, mServiceContext, mHandler, filter, (Intent intent) -> doCallback());
- }
-
- @After public void tearDown() throws Exception {
- if (mListener != null) {
- mListener.stopListening();
- mListener = null;
- }
- }
-
- private void sendBroadcast() {
- final Intent intent = new Intent(ACTION_TEST);
- mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
-
- @Test
- public void testBasicListening() {
- assertEquals(0, mCallbackCount);
- mListener.startListening();
- for (int i = 0; i < 5; i++) {
- sendBroadcast();
- assertEquals(i + 1, mCallbackCount);
- }
- mListener.stopListening();
- }
-
- @Test
- public void testBroadcastsBeforeStartAreIgnored() {
- assertEquals(0, mCallbackCount);
- for (int i = 0; i < 5; i++) {
- sendBroadcast();
- assertEquals(0, mCallbackCount);
- }
-
- mListener.startListening();
- sendBroadcast();
- assertEquals(1, mCallbackCount);
- }
-
- @Test
- public void testBroadcastsAfterStopAreIgnored() {
- mListener.startListening();
- sendBroadcast();
- assertEquals(1, mCallbackCount);
- mListener.stopListening();
-
- for (int i = 0; i < 5; i++) {
- sendBroadcast();
- assertEquals(1, mCallbackCount);
- }
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
deleted file mode 100644
index 64242ae..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ /dev/null
@@ -1,607 +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.networkstack.tethering;
-
-import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
-import static android.net.NetworkStats.METERED_NO;
-import static android.net.NetworkStats.ROAMING_NO;
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-import static android.net.NetworkStats.UID_TETHERING;
-import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
-
-import static com.android.networkstack.tethering.BpfCoordinator.StatsType;
-import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_IFACE;
-import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_UID;
-import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.argThat;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.usage.NetworkStatsManager;
-import android.net.INetd;
-import android.net.InetAddresses;
-import android.net.MacAddress;
-import android.net.NetworkStats;
-import android.net.TetherOffloadRuleParcel;
-import android.net.TetherStatsParcel;
-import android.net.ip.IpServer;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.test.TestLooper;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
-import com.android.testutils.TestableNetworkStatsProviderCbBinder;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class BpfCoordinatorTest {
- private static final int DOWNSTREAM_IFINDEX = 10;
- private static final MacAddress DOWNSTREAM_MAC = MacAddress.ALL_ZEROS_ADDRESS;
- private static final InetAddress NEIGH_A = InetAddresses.parseNumericAddress("2001:db8::1");
- private static final InetAddress NEIGH_B = InetAddresses.parseNumericAddress("2001:db8::2");
- private static final MacAddress MAC_A = MacAddress.fromString("00:00:00:00:00:0a");
- private static final MacAddress MAC_B = MacAddress.fromString("11:22:33:00:00:0b");
-
- @Mock private NetworkStatsManager mStatsManager;
- @Mock private INetd mNetd;
- @Mock private IpServer mIpServer;
- @Mock private TetheringConfiguration mTetherConfig;
-
- // Late init since methods must be called by the thread that created this object.
- private TestableNetworkStatsProviderCbBinder mTetherStatsProviderCb;
- private BpfCoordinator.BpfTetherStatsProvider mTetherStatsProvider;
- private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
- ArgumentCaptor.forClass(ArrayList.class);
- private final TestLooper mTestLooper = new TestLooper();
- private BpfCoordinator.Dependencies mDeps =
- new BpfCoordinator.Dependencies() {
- @NonNull
- public Handler getHandler() {
- return new Handler(mTestLooper.getLooper());
- }
-
- @NonNull
- public INetd getNetd() {
- return mNetd;
- }
-
- @NonNull
- public NetworkStatsManager getNetworkStatsManager() {
- return mStatsManager;
- }
-
- @NonNull
- public SharedLog getSharedLog() {
- return new SharedLog("test");
- }
-
- @Nullable
- public TetheringConfiguration getTetherConfig() {
- return mTetherConfig;
- }
- };
-
- @Before public void setUp() {
- MockitoAnnotations.initMocks(this);
- when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(true /* default value */);
- }
-
- private void waitForIdle() {
- mTestLooper.dispatchAll();
- }
-
- private void setupFunctioningNetdInterface() throws Exception {
- when(mNetd.tetherOffloadGetStats()).thenReturn(new TetherStatsParcel[0]);
- }
-
- @NonNull
- private BpfCoordinator makeBpfCoordinator() throws Exception {
- final BpfCoordinator coordinator = new BpfCoordinator(mDeps);
- final ArgumentCaptor<BpfCoordinator.BpfTetherStatsProvider>
- tetherStatsProviderCaptor =
- ArgumentCaptor.forClass(BpfCoordinator.BpfTetherStatsProvider.class);
- verify(mStatsManager).registerNetworkStatsProvider(anyString(),
- tetherStatsProviderCaptor.capture());
- mTetherStatsProvider = tetherStatsProviderCaptor.getValue();
- assertNotNull(mTetherStatsProvider);
- mTetherStatsProviderCb = new TestableNetworkStatsProviderCbBinder();
- mTetherStatsProvider.setProviderCallbackBinder(mTetherStatsProviderCb);
- return coordinator;
- }
-
- @NonNull
- private static NetworkStats.Entry buildTestEntry(@NonNull StatsType how,
- @NonNull String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) {
- return new NetworkStats.Entry(iface, how == STATS_PER_IFACE ? UID_ALL : UID_TETHERING,
- SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, rxBytes,
- rxPackets, txBytes, txPackets, 0L);
- }
-
- @NonNull
- private static TetherStatsParcel buildTestTetherStatsParcel(@NonNull Integer ifIndex,
- long rxBytes, long rxPackets, long txBytes, long txPackets) {
- final TetherStatsParcel parcel = new TetherStatsParcel();
- parcel.ifIndex = ifIndex;
- parcel.rxBytes = rxBytes;
- parcel.rxPackets = rxPackets;
- parcel.txBytes = txBytes;
- parcel.txPackets = txPackets;
- return parcel;
- }
-
- // Set up specific tether stats list and wait for the stats cache is updated by polling thread
- // in the coordinator. Beware of that it is only used for the default polling interval.
- private void setTetherOffloadStatsList(TetherStatsParcel[] tetherStatsList) throws Exception {
- when(mNetd.tetherOffloadGetStats()).thenReturn(tetherStatsList);
- mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- waitForIdle();
- }
-
- @Test
- public void testGetForwardedStats() throws Exception {
- setupFunctioningNetdInterface();
-
- final BpfCoordinator coordinator = makeBpfCoordinator();
- coordinator.startPolling();
-
- final String wlanIface = "wlan0";
- final Integer wlanIfIndex = 100;
- final String mobileIface = "rmnet_data0";
- final Integer mobileIfIndex = 101;
-
- // Add interface name to lookup table. In realistic case, the upstream interface name will
- // be added by IpServer when IpServer has received with a new IPv6 upstream update event.
- coordinator.addUpstreamNameToLookupTable(wlanIfIndex, wlanIface);
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
-
- // [1] Both interface stats are changed.
- // Setup the tether stats of wlan and mobile interface. Note that move forward the time of
- // the looper to make sure the new tether stats has been updated by polling update thread.
- setTetherOffloadStatsList(new TetherStatsParcel[] {
- buildTestTetherStatsParcel(wlanIfIndex, 1000, 100, 2000, 200),
- buildTestTetherStatsParcel(mobileIfIndex, 3000, 300, 4000, 400)});
-
- final NetworkStats expectedIfaceStats = new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_IFACE, wlanIface, 1000, 100, 2000, 200))
- .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 3000, 300, 4000, 400));
-
- final NetworkStats expectedUidStats = new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_UID, wlanIface, 1000, 100, 2000, 200))
- .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 3000, 300, 4000, 400));
-
- // Force pushing stats update to verify the stats reported.
- // TODO: Perhaps make #expectNotifyStatsUpdated to use test TetherStatsParcel object for
- // verifying the notification.
- mTetherStatsProvider.pushTetherStats();
- mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStats, expectedUidStats);
-
- // [2] Only one interface stats is changed.
- // The tether stats of mobile interface is accumulated and The tether stats of wlan
- // interface is the same.
- setTetherOffloadStatsList(new TetherStatsParcel[] {
- buildTestTetherStatsParcel(wlanIfIndex, 1000, 100, 2000, 200),
- buildTestTetherStatsParcel(mobileIfIndex, 3010, 320, 4030, 440)});
-
- final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_IFACE, wlanIface, 0, 0, 0, 0))
- .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 10, 20, 30, 40));
-
- final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_UID, wlanIface, 0, 0, 0, 0))
- .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 10, 20, 30, 40));
-
- // Force pushing stats update to verify that only diff of stats is reported.
- mTetherStatsProvider.pushTetherStats();
- mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStatsDiff,
- expectedUidStatsDiff);
-
- // [3] Stop coordinator.
- // Shutdown the coordinator and clear the invocation history, especially the
- // tetherOffloadGetStats() calls.
- coordinator.stopPolling();
- clearInvocations(mNetd);
-
- // Verify the polling update thread stopped.
- mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- waitForIdle();
- verify(mNetd, never()).tetherOffloadGetStats();
- }
-
- @Test
- public void testOnSetAlert() throws Exception {
- setupFunctioningNetdInterface();
-
- final BpfCoordinator coordinator = makeBpfCoordinator();
- coordinator.startPolling();
-
- final String mobileIface = "rmnet_data0";
- final Integer mobileIfIndex = 100;
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
-
- // Verify that set quota to 0 will immediately triggers a callback.
- mTetherStatsProvider.onSetAlert(0);
- waitForIdle();
- mTetherStatsProviderCb.expectNotifyAlertReached();
-
- // Verify that notifyAlertReached never fired if quota is not yet reached.
- when(mNetd.tetherOffloadGetStats()).thenReturn(
- new TetherStatsParcel[] {buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0)});
- mTetherStatsProvider.onSetAlert(100);
- mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- waitForIdle();
- mTetherStatsProviderCb.assertNoCallback();
-
- // Verify that notifyAlertReached fired when quota is reached.
- when(mNetd.tetherOffloadGetStats()).thenReturn(
- new TetherStatsParcel[] {buildTestTetherStatsParcel(mobileIfIndex, 50, 0, 50, 0)});
- mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- waitForIdle();
- mTetherStatsProviderCb.expectNotifyAlertReached();
-
- // Verify that set quota with UNLIMITED won't trigger any callback.
- mTetherStatsProvider.onSetAlert(QUOTA_UNLIMITED);
- mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- waitForIdle();
- mTetherStatsProviderCb.assertNoCallback();
- }
-
- // The custom ArgumentMatcher simply comes from IpServerTest.
- // TODO: move both of them into a common utility class for reusing the code.
- private static class TetherOffloadRuleParcelMatcher implements
- ArgumentMatcher<TetherOffloadRuleParcel> {
- public final int upstreamIfindex;
- public final int downstreamIfindex;
- public final Inet6Address address;
- public final MacAddress srcMac;
- public final MacAddress dstMac;
-
- TetherOffloadRuleParcelMatcher(@NonNull Ipv6ForwardingRule rule) {
- upstreamIfindex = rule.upstreamIfindex;
- downstreamIfindex = rule.downstreamIfindex;
- address = rule.address;
- srcMac = rule.srcMac;
- dstMac = rule.dstMac;
- }
-
- public boolean matches(@NonNull TetherOffloadRuleParcel parcel) {
- return upstreamIfindex == parcel.inputInterfaceIndex
- && (downstreamIfindex == parcel.outputInterfaceIndex)
- && Arrays.equals(address.getAddress(), parcel.destination)
- && (128 == parcel.prefixLength)
- && Arrays.equals(srcMac.toByteArray(), parcel.srcL2Address)
- && Arrays.equals(dstMac.toByteArray(), parcel.dstL2Address);
- }
-
- public String toString() {
- return String.format("TetherOffloadRuleParcelMatcher(%d, %d, %s, %s, %s",
- upstreamIfindex, downstreamIfindex, address.getHostAddress(), srcMac, dstMac);
- }
- }
-
- @NonNull
- private TetherOffloadRuleParcel matches(@NonNull Ipv6ForwardingRule rule) {
- return argThat(new TetherOffloadRuleParcelMatcher(rule));
- }
-
- @NonNull
- private static Ipv6ForwardingRule buildTestForwardingRule(
- int upstreamIfindex, @NonNull InetAddress address, @NonNull MacAddress dstMac) {
- return new Ipv6ForwardingRule(upstreamIfindex, DOWNSTREAM_IFINDEX, (Inet6Address) address,
- DOWNSTREAM_MAC, dstMac);
- }
-
- @Test
- public void testSetDataLimit() throws Exception {
- setupFunctioningNetdInterface();
-
- final BpfCoordinator coordinator = makeBpfCoordinator();
-
- final String mobileIface = "rmnet_data0";
- final Integer mobileIfIndex = 100;
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
-
- // [1] Default limit.
- // Set the unlimited quota as default if the service has never applied a data limit for a
- // given upstream. Note that the data limit only be applied on an upstream which has rules.
- final Ipv6ForwardingRule rule = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
- final InOrder inOrder = inOrder(mNetd);
- coordinator.tetherOffloadRuleAdd(mIpServer, rule);
- inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(rule));
- inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, QUOTA_UNLIMITED);
- inOrder.verifyNoMoreInteractions();
-
- // [2] Specific limit.
- // Applying the data limit boundary {min, 1gb, max, infinity} on current upstream.
- for (final long quota : new long[] {0, 1048576000, Long.MAX_VALUE, QUOTA_UNLIMITED}) {
- mTetherStatsProvider.onSetLimit(mobileIface, quota);
- waitForIdle();
- inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, quota);
- inOrder.verifyNoMoreInteractions();
- }
-
- // [3] Invalid limit.
- // The valid range of quota is 0..max_int64 or -1 (unlimited).
- final long invalidLimit = Long.MIN_VALUE;
- try {
- mTetherStatsProvider.onSetLimit(mobileIface, invalidLimit);
- waitForIdle();
- fail("No exception thrown for invalid limit " + invalidLimit + ".");
- } catch (IllegalArgumentException expected) {
- assertEquals(expected.getMessage(), "invalid quota value " + invalidLimit);
- }
- }
-
- // TODO: Test the case in which the rules are changed from different IpServer objects.
- @Test
- public void testSetDataLimitOnRuleChange() throws Exception {
- setupFunctioningNetdInterface();
-
- final BpfCoordinator coordinator = makeBpfCoordinator();
-
- final String mobileIface = "rmnet_data0";
- final Integer mobileIfIndex = 100;
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
-
- // Applying a data limit to the current upstream does not take any immediate action.
- // The data limit could be only set on an upstream which has rules.
- final long limit = 12345;
- final InOrder inOrder = inOrder(mNetd);
- mTetherStatsProvider.onSetLimit(mobileIface, limit);
- waitForIdle();
- inOrder.verify(mNetd, never()).tetherOffloadSetInterfaceQuota(anyInt(), anyLong());
-
- // Adding the first rule on current upstream immediately sends the quota to netd.
- final Ipv6ForwardingRule ruleA = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
- coordinator.tetherOffloadRuleAdd(mIpServer, ruleA);
- inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ruleA));
- inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, limit);
- inOrder.verifyNoMoreInteractions();
-
- // Adding the second rule on current upstream does not send the quota to netd.
- final Ipv6ForwardingRule ruleB = buildTestForwardingRule(mobileIfIndex, NEIGH_B, MAC_B);
- coordinator.tetherOffloadRuleAdd(mIpServer, ruleB);
- inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ruleB));
- inOrder.verify(mNetd, never()).tetherOffloadSetInterfaceQuota(anyInt(), anyLong());
-
- // Removing the second rule on current upstream does not send the quota to netd.
- coordinator.tetherOffloadRuleRemove(mIpServer, ruleB);
- inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ruleB));
- inOrder.verify(mNetd, never()).tetherOffloadSetInterfaceQuota(anyInt(), anyLong());
-
- // Removing the last rule on current upstream immediately sends the cleanup stuff to netd.
- when(mNetd.tetherOffloadGetAndClearStats(mobileIfIndex))
- .thenReturn(buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0));
- coordinator.tetherOffloadRuleRemove(mIpServer, ruleA);
- inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ruleA));
- inOrder.verify(mNetd).tetherOffloadGetAndClearStats(mobileIfIndex);
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void testTetherOffloadRuleUpdateAndClear() throws Exception {
- setupFunctioningNetdInterface();
-
- final BpfCoordinator coordinator = makeBpfCoordinator();
-
- final String ethIface = "eth1";
- final String mobileIface = "rmnet_data0";
- final Integer ethIfIndex = 100;
- final Integer mobileIfIndex = 101;
- coordinator.addUpstreamNameToLookupTable(ethIfIndex, ethIface);
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
-
- final InOrder inOrder = inOrder(mNetd);
-
- // Before the rule test, here are the additional actions while the rules are changed.
- // - After adding the first rule on a given upstream, the coordinator adds a data limit.
- // If the service has never applied the data limit, set an unlimited quota as default.
- // - After removing the last rule on a given upstream, the coordinator gets the last stats.
- // Then, it clears the stats and the limit entry from BPF maps.
- // See tetherOffloadRule{Add, Remove, Clear, Clean}.
-
- // [1] Adding rules on the upstream Ethernet.
- // Note that the default data limit is applied after the first rule is added.
- final Ipv6ForwardingRule ethernetRuleA = buildTestForwardingRule(
- ethIfIndex, NEIGH_A, MAC_A);
- final Ipv6ForwardingRule ethernetRuleB = buildTestForwardingRule(
- ethIfIndex, NEIGH_B, MAC_B);
-
- coordinator.tetherOffloadRuleAdd(mIpServer, ethernetRuleA);
- inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ethernetRuleA));
- inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(ethIfIndex, QUOTA_UNLIMITED);
-
- coordinator.tetherOffloadRuleAdd(mIpServer, ethernetRuleB);
- inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ethernetRuleB));
-
- // [2] Update the existing rules from Ethernet to cellular.
- final Ipv6ForwardingRule mobileRuleA = buildTestForwardingRule(
- mobileIfIndex, NEIGH_A, MAC_A);
- final Ipv6ForwardingRule mobileRuleB = buildTestForwardingRule(
- mobileIfIndex, NEIGH_B, MAC_B);
- when(mNetd.tetherOffloadGetAndClearStats(ethIfIndex))
- .thenReturn(buildTestTetherStatsParcel(ethIfIndex, 10, 20, 30, 40));
-
- // Update the existing rules for upstream changes. The rules are removed and re-added one
- // by one for updating upstream interface index by #tetherOffloadRuleUpdate.
- coordinator.tetherOffloadRuleUpdate(mIpServer, mobileIfIndex);
- inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ethernetRuleA));
- inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(mobileRuleA));
- inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, QUOTA_UNLIMITED);
- inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ethernetRuleB));
- inOrder.verify(mNetd).tetherOffloadGetAndClearStats(ethIfIndex);
- inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(mobileRuleB));
-
- // [3] Clear all rules for a given IpServer.
- when(mNetd.tetherOffloadGetAndClearStats(mobileIfIndex))
- .thenReturn(buildTestTetherStatsParcel(mobileIfIndex, 50, 60, 70, 80));
- coordinator.tetherOffloadRuleClear(mIpServer);
- inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(mobileRuleA));
- inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(mobileRuleB));
- inOrder.verify(mNetd).tetherOffloadGetAndClearStats(mobileIfIndex);
-
- // [4] Force pushing stats update to verify that the last diff of stats is reported on all
- // upstreams.
- mTetherStatsProvider.pushTetherStats();
- mTetherStatsProviderCb.expectNotifyStatsUpdated(
- new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_IFACE, ethIface, 10, 20, 30, 40))
- .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 50, 60, 70, 80)),
- new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_UID, ethIface, 10, 20, 30, 40))
- .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 50, 60, 70, 80)));
- }
-
- @Test
- public void testTetheringConfigDisable() throws Exception {
- setupFunctioningNetdInterface();
- when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(false);
-
- final BpfCoordinator coordinator = makeBpfCoordinator();
- coordinator.startPolling();
-
- // The tether stats polling task should not be scheduled.
- mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- waitForIdle();
- verify(mNetd, never()).tetherOffloadGetStats();
-
- // The interface name lookup table can't be added.
- final String iface = "rmnet_data0";
- final Integer ifIndex = 100;
- coordinator.addUpstreamNameToLookupTable(ifIndex, iface);
- assertEquals(0, coordinator.getInterfaceNamesForTesting().size());
-
- // The rule can't be added.
- final InetAddress neigh = InetAddresses.parseNumericAddress("2001:db8::1");
- final MacAddress mac = MacAddress.fromString("00:00:00:00:00:0a");
- final Ipv6ForwardingRule rule = buildTestForwardingRule(ifIndex, neigh, mac);
- coordinator.tetherOffloadRuleAdd(mIpServer, rule);
- verify(mNetd, never()).tetherOffloadRuleAdd(any());
- LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules =
- coordinator.getForwardingRulesForTesting().get(mIpServer);
- assertNull(rules);
-
- // The rule can't be removed. This is not a realistic case because adding rule is not
- // allowed. That implies no rule could be removed, cleared or updated. Verify these
- // cases just in case.
- rules = new LinkedHashMap<Inet6Address, Ipv6ForwardingRule>();
- rules.put(rule.address, rule);
- coordinator.getForwardingRulesForTesting().put(mIpServer, rules);
- coordinator.tetherOffloadRuleRemove(mIpServer, rule);
- verify(mNetd, never()).tetherOffloadRuleRemove(any());
- rules = coordinator.getForwardingRulesForTesting().get(mIpServer);
- assertNotNull(rules);
- assertEquals(1, rules.size());
-
- // The rule can't be cleared.
- coordinator.tetherOffloadRuleClear(mIpServer);
- verify(mNetd, never()).tetherOffloadRuleRemove(any());
- rules = coordinator.getForwardingRulesForTesting().get(mIpServer);
- assertNotNull(rules);
- assertEquals(1, rules.size());
-
- // The rule can't be updated.
- coordinator.tetherOffloadRuleUpdate(mIpServer, rule.upstreamIfindex + 1 /* new */);
- verify(mNetd, never()).tetherOffloadRuleRemove(any());
- verify(mNetd, never()).tetherOffloadRuleAdd(any());
- rules = coordinator.getForwardingRulesForTesting().get(mIpServer);
- assertNotNull(rules);
- assertEquals(1, rules.size());
- }
-
- @Test
- public void testTetheringConfigSetPollingInterval() throws Exception {
- setupFunctioningNetdInterface();
-
- final BpfCoordinator coordinator = makeBpfCoordinator();
-
- // [1] The default polling interval.
- coordinator.startPolling();
- assertEquals(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS, coordinator.getPollingInterval());
- coordinator.stopPolling();
-
- // [2] Expect the invalid polling interval isn't applied. The valid range of interval is
- // DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS..max_long.
- for (final int interval
- : new int[] {0, 100, DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS - 1}) {
- when(mTetherConfig.getOffloadPollInterval()).thenReturn(interval);
- coordinator.startPolling();
- assertEquals(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS, coordinator.getPollingInterval());
- coordinator.stopPolling();
- }
-
- // [3] Set a specific polling interval which is larger than default value.
- // Use a large polling interval to avoid flaky test because the time forwarding
- // approximation is used to verify the scheduled time of the polling thread.
- final int pollingInterval = 100_000;
- when(mTetherConfig.getOffloadPollInterval()).thenReturn(pollingInterval);
- coordinator.startPolling();
-
- // Expect the specific polling interval to be applied.
- assertEquals(pollingInterval, coordinator.getPollingInterval());
-
- // Start on a new polling time slot.
- mTestLooper.moveTimeForward(pollingInterval);
- waitForIdle();
- clearInvocations(mNetd);
-
- // Move time forward to 90% polling interval time. Expect that the polling thread has not
- // scheduled yet.
- mTestLooper.moveTimeForward((long) (pollingInterval * 0.9));
- waitForIdle();
- verify(mNetd, never()).tetherOffloadGetStats();
-
- // Move time forward to the remaining 10% polling interval time. Expect that the polling
- // thread has scheduled.
- mTestLooper.moveTimeForward((long) (pollingInterval * 0.1));
- waitForIdle();
- verify(mNetd).tetherOffloadGetStats();
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/ConnectedClientsTrackerTest.kt b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/ConnectedClientsTrackerTest.kt
deleted file mode 100644
index d915354..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/ConnectedClientsTrackerTest.kt
+++ /dev/null
@@ -1,162 +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.networkstack.tethering
-
-import android.net.LinkAddress
-import android.net.MacAddress
-import android.net.TetheredClient
-import android.net.TetheredClient.AddressInfo
-import android.net.TetheringManager.TETHERING_USB
-import android.net.TetheringManager.TETHERING_WIFI
-import android.net.ip.IpServer
-import android.net.wifi.WifiClient
-import androidx.test.filters.SmallTest
-import androidx.test.runner.AndroidJUnit4
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mockito.doReturn
-import org.mockito.Mockito.mock
-import kotlin.test.assertEquals
-import kotlin.test.assertFalse
-import kotlin.test.assertTrue
-
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-class ConnectedClientsTrackerTest {
-
- private val server1 = mock(IpServer::class.java)
- private val server2 = mock(IpServer::class.java)
- private val servers = listOf(server1, server2)
-
- private val clock = TestClock(1324L)
-
- private val client1Addr = MacAddress.fromString("01:23:45:67:89:0A")
- private val client1 = TetheredClient(client1Addr, listOf(
- makeAddrInfo("192.168.43.44/32", null /* hostname */, clock.time + 20)),
- TETHERING_WIFI)
- private val wifiClient1 = makeWifiClient(client1Addr)
- private val client2Addr = MacAddress.fromString("02:34:56:78:90:AB")
- private val client2Exp30AddrInfo = makeAddrInfo(
- "192.168.43.45/32", "my_hostname", clock.time + 30)
- private val client2 = TetheredClient(client2Addr, listOf(
- client2Exp30AddrInfo,
- makeAddrInfo("2001:db8:12::34/72", "other_hostname", clock.time + 10)),
- TETHERING_WIFI)
- private val wifiClient2 = makeWifiClient(client2Addr)
- private val client3Addr = MacAddress.fromString("03:45:67:89:0A:BC")
- private val client3 = TetheredClient(client3Addr,
- listOf(makeAddrInfo("2001:db8:34::34/72", "other_other_hostname", clock.time + 10)),
- TETHERING_USB)
-
- private fun makeAddrInfo(addr: String, hostname: String?, expTime: Long) =
- LinkAddress(addr).let {
- AddressInfo(LinkAddress(it.address, it.prefixLength, it.flags, it.scope,
- expTime /* deprecationTime */, expTime /* expirationTime */), hostname)
- }
-
- @Test
- fun testUpdateConnectedClients() {
- doReturn(emptyList<TetheredClient>()).`when`(server1).allLeases
- doReturn(emptyList<TetheredClient>()).`when`(server2).allLeases
-
- val tracker = ConnectedClientsTracker(clock)
- assertFalse(tracker.updateConnectedClients(servers, null))
-
- // Obtain a lease for client 1
- doReturn(listOf(client1)).`when`(server1).allLeases
- assertSameClients(listOf(client1), assertNewClients(tracker, servers, listOf(wifiClient1)))
-
- // Client 2 L2-connected, no lease yet
- val client2WithoutAddr = TetheredClient(client2Addr, emptyList(), TETHERING_WIFI)
- assertSameClients(listOf(client1, client2WithoutAddr),
- assertNewClients(tracker, servers, listOf(wifiClient1, wifiClient2)))
-
- // Client 2 lease obtained
- doReturn(listOf(client1, client2)).`when`(server1).allLeases
- assertSameClients(listOf(client1, client2), assertNewClients(tracker, servers, null))
-
- // Client 3 lease obtained
- doReturn(listOf(client3)).`when`(server2).allLeases
- assertSameClients(listOf(client1, client2, client3),
- assertNewClients(tracker, servers, null))
-
- // Client 2 L2-disconnected
- assertSameClients(listOf(client1, client3),
- assertNewClients(tracker, servers, listOf(wifiClient1)))
-
- // Client 1 L2-disconnected
- assertSameClients(listOf(client3), assertNewClients(tracker, servers, emptyList()))
-
- // Client 1 comes back
- assertSameClients(listOf(client1, client3),
- assertNewClients(tracker, servers, listOf(wifiClient1)))
-
- // Leases lost, client 1 still L2-connected
- doReturn(emptyList<TetheredClient>()).`when`(server1).allLeases
- doReturn(emptyList<TetheredClient>()).`when`(server2).allLeases
- assertSameClients(listOf(TetheredClient(client1Addr, emptyList(), TETHERING_WIFI)),
- assertNewClients(tracker, servers, null))
- }
-
- @Test
- fun testUpdateConnectedClients_LeaseExpiration() {
- val tracker = ConnectedClientsTracker(clock)
- doReturn(listOf(client1, client2)).`when`(server1).allLeases
- doReturn(listOf(client3)).`when`(server2).allLeases
- assertSameClients(listOf(client1, client2, client3), assertNewClients(
- tracker, servers, listOf(wifiClient1, wifiClient2)))
-
- clock.time += 20
- // Client 3 has no remaining lease: removed
- val expectedClients = listOf(
- // Client 1 has no remaining lease but is L2-connected
- TetheredClient(client1Addr, emptyList(), TETHERING_WIFI),
- // Client 2 has some expired leases
- TetheredClient(
- client2Addr,
- // Only the "t + 30" address is left, the "t + 10" address expired
- listOf(client2Exp30AddrInfo),
- TETHERING_WIFI))
- assertSameClients(expectedClients, assertNewClients(tracker, servers, null))
- }
-
- private fun assertNewClients(
- tracker: ConnectedClientsTracker,
- ipServers: Iterable<IpServer>,
- wifiClients: List<WifiClient>?
- ): List<TetheredClient> {
- assertTrue(tracker.updateConnectedClients(ipServers, wifiClients))
- return tracker.lastTetheredClients
- }
-
- private fun assertSameClients(expected: List<TetheredClient>, actual: List<TetheredClient>) {
- val expectedSet = HashSet(expected)
- assertEquals(expected.size, expectedSet.size)
- assertEquals(expectedSet, HashSet(actual))
- }
-
- private fun makeWifiClient(macAddr: MacAddress): WifiClient {
- // Use a mock WifiClient as the constructor is not part of the WiFi module exported API.
- return mock(WifiClient::class.java).apply { doReturn(macAddr).`when`(this).macAddress }
- }
-
- private class TestClock(var time: Long) : ConnectedClientsTracker.Clock() {
- override fun elapsedRealtime(): Long {
- return time
- }
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
deleted file mode 100644
index 354e753..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
+++ /dev/null
@@ -1,623 +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.networkstack.tethering;
-
-import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
-import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
-import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
-import static android.net.TetheringConstants.EXTRA_TETHER_PROVISIONING_RESPONSE;
-import static android.net.TetheringConstants.EXTRA_TETHER_SILENT_PROVISIONING_ACTION;
-import static android.net.TetheringConstants.EXTRA_TETHER_SUBID;
-import static android.net.TetheringConstants.EXTRA_TETHER_UI_PROVISIONING_APP_NAME;
-import static android.net.TetheringManager.TETHERING_BLUETOOTH;
-import static android.net.TetheringManager.TETHERING_ETHERNET;
-import static android.net.TetheringManager.TETHERING_INVALID;
-import static android.net.TetheringManager.TETHERING_USB;
-import static android.net.TetheringManager.TETHERING_WIFI;
-import static android.net.TetheringManager.TETHERING_WIFI_P2P;
-import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
-import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.net.util.SharedLog;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.PersistableBundle;
-import android.os.ResultReceiver;
-import android.os.SystemProperties;
-import android.os.test.TestLooper;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.telephony.CarrierConfigManager;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.test.BroadcastInterceptingContext;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class EntitlementManagerTest {
-
- private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
- private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
- private static final String PROVISIONING_APP_RESPONSE = "app_response";
-
- @Mock private CarrierConfigManager mCarrierConfigManager;
- @Mock private Context mContext;
- @Mock private Resources mResources;
- @Mock private SharedLog mLog;
- @Mock private EntitlementManager.OnUiEntitlementFailedListener mEntitlementFailedListener;
-
- // Like so many Android system APIs, these cannot be mocked because it is marked final.
- // We have to use the real versions.
- private final PersistableBundle mCarrierConfig = new PersistableBundle();
- private final TestLooper mLooper = new TestLooper();
- private Context mMockContext;
- private Runnable mPermissionChangeCallback;
-
- private WrappedEntitlementManager mEnMgr;
- private TetheringConfiguration mConfig;
- private MockitoSession mMockingSession;
-
- private class MockContext extends BroadcastInterceptingContext {
- MockContext(Context base) {
- super(base);
- }
-
- @Override
- public Resources getResources() {
- return mResources;
- }
- }
-
- public class WrappedEntitlementManager extends EntitlementManager {
- public int fakeEntitlementResult = TETHER_ERROR_ENTITLEMENT_UNKNOWN;
- public int uiProvisionCount = 0;
- public int silentProvisionCount = 0;
-
- public WrappedEntitlementManager(Context ctx, Handler h, SharedLog log,
- Runnable callback) {
- super(ctx, h, log, callback);
- }
-
- public void reset() {
- fakeEntitlementResult = TETHER_ERROR_ENTITLEMENT_UNKNOWN;
- uiProvisionCount = 0;
- silentProvisionCount = 0;
- }
-
- @Override
- protected Intent runUiTetherProvisioning(int type,
- final TetheringConfiguration config, final ResultReceiver receiver) {
- Intent intent = super.runUiTetherProvisioning(type, config, receiver);
- assertUiTetherProvisioningIntent(type, config, receiver, intent);
- uiProvisionCount++;
- receiver.send(fakeEntitlementResult, null);
- return intent;
- }
-
- private void assertUiTetherProvisioningIntent(int type, final TetheringConfiguration config,
- final ResultReceiver receiver, final Intent intent) {
- assertEquals(Settings.ACTION_TETHER_PROVISIONING_UI, intent.getAction());
- assertEquals(type, intent.getIntExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_INVALID));
- final String[] appName = intent.getStringArrayExtra(
- EXTRA_TETHER_UI_PROVISIONING_APP_NAME);
- assertEquals(PROVISIONING_APP_NAME.length, appName.length);
- for (int i = 0; i < PROVISIONING_APP_NAME.length; i++) {
- assertEquals(PROVISIONING_APP_NAME[i], appName[i]);
- }
- assertEquals(receiver, intent.getParcelableExtra(EXTRA_PROVISION_CALLBACK));
- assertEquals(config.activeDataSubId,
- intent.getIntExtra(EXTRA_TETHER_SUBID, INVALID_SUBSCRIPTION_ID));
- }
-
- @Override
- protected Intent runSilentTetherProvisioning(int type,
- final TetheringConfiguration config) {
- Intent intent = super.runSilentTetherProvisioning(type, config);
- assertSilentTetherProvisioning(type, config, intent);
- silentProvisionCount++;
- addDownstreamMapping(type, fakeEntitlementResult);
- return intent;
- }
-
- private void assertSilentTetherProvisioning(int type, final TetheringConfiguration config,
- final Intent intent) {
- assertEquals(type, intent.getIntExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_INVALID));
- assertEquals(true, intent.getBooleanExtra(EXTRA_RUN_PROVISION, false));
- assertEquals(PROVISIONING_NO_UI_APP_NAME,
- intent.getStringExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION));
- assertEquals(PROVISIONING_APP_RESPONSE,
- intent.getStringExtra(EXTRA_TETHER_PROVISIONING_RESPONSE));
- assertTrue(intent.hasExtra(EXTRA_PROVISION_CALLBACK));
- assertEquals(config.activeDataSubId,
- intent.getIntExtra(EXTRA_TETHER_SUBID, INVALID_SUBSCRIPTION_ID));
- }
- }
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mMockingSession = mockitoSession()
- .initMocks(this)
- .mockStatic(SystemProperties.class)
- .mockStatic(DeviceConfig.class)
- .strictness(Strictness.WARN)
- .startMocking();
- // Don't disable tethering provisioning unless requested.
- doReturn(false).when(
- () -> SystemProperties.getBoolean(
- eq(EntitlementManager.DISABLE_PROVISIONING_SYSPROP_KEY), anyBoolean()));
- doReturn(null).when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY), anyString()));
-
- when(mResources.getStringArray(R.array.config_tether_dhcp_range))
- .thenReturn(new String[0]);
- when(mResources.getStringArray(R.array.config_tether_usb_regexs))
- .thenReturn(new String[0]);
- when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
- .thenReturn(new String[0]);
- when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
- .thenReturn(new String[0]);
- when(mResources.getIntArray(R.array.config_tether_upstream_types))
- .thenReturn(new int[0]);
- when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
- false);
- when(mResources.getString(R.string.config_wifi_tether_enable)).thenReturn("");
- when(mLog.forSubComponent(anyString())).thenReturn(mLog);
-
- mMockContext = new MockContext(mContext);
- mPermissionChangeCallback = spy(() -> { });
- mEnMgr = new WrappedEntitlementManager(mMockContext, new Handler(mLooper.getLooper()), mLog,
- mPermissionChangeCallback);
- mEnMgr.setOnUiEntitlementFailedListener(mEntitlementFailedListener);
- mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- mEnMgr.setTetheringConfigurationFetcher(() -> {
- return mConfig;
- });
- }
-
- @After
- public void tearDown() throws Exception {
- mMockingSession.finishMocking();
- }
-
- private void setupForRequiredProvisioning() {
- // Produce some acceptable looking provision app setting if requested.
- when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
- .thenReturn(PROVISIONING_APP_NAME);
- when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
- .thenReturn(PROVISIONING_NO_UI_APP_NAME);
- when(mResources.getString(R.string.config_mobile_hotspot_provision_response)).thenReturn(
- PROVISIONING_APP_RESPONSE);
- // Act like the CarrierConfigManager is present and ready unless told otherwise.
- when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
- .thenReturn(mCarrierConfigManager);
- when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig);
- mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
- mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
- mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- }
-
- @Test
- public void canRequireProvisioning() {
- setupForRequiredProvisioning();
- assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
- }
-
- @Test
- public void toleratesCarrierConfigManagerMissing() {
- setupForRequiredProvisioning();
- when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
- .thenReturn(null);
- mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- // Couldn't get the CarrierConfigManager, but still had a declared provisioning app.
- // Therefore provisioning still be required.
- assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
- }
-
- @Test
- public void toleratesCarrierConfigMissing() {
- setupForRequiredProvisioning();
- when(mCarrierConfigManager.getConfig()).thenReturn(null);
- mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- // We still have a provisioning app configured, so still require provisioning.
- assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
- }
-
- @Test
- public void toleratesCarrierConfigNotLoaded() {
- setupForRequiredProvisioning();
- mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
- // We still have a provisioning app configured, so still require provisioning.
- assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
- }
-
- @Test
- public void provisioningNotRequiredWhenAppNotFound() {
- setupForRequiredProvisioning();
- when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
- .thenReturn(null);
- mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertFalse(mEnMgr.isTetherProvisioningRequired(mConfig));
- when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
- .thenReturn(new String[] {"malformedApp"});
- mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertFalse(mEnMgr.isTetherProvisioningRequired(mConfig));
- }
-
- @Test
- public void testRequestLastEntitlementCacheValue() throws Exception {
- // 1. Entitlement check is not required.
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- ResultReceiver receiver = new ResultReceiver(null) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- assertEquals(TETHER_ERROR_NO_ERROR, resultCode);
- }
- };
- mEnMgr.requestLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
- mLooper.dispatchAll();
- assertEquals(0, mEnMgr.uiProvisionCount);
- mEnMgr.reset();
-
- setupForRequiredProvisioning();
- // 2. No cache value and don't need to run entitlement check.
- receiver = new ResultReceiver(null) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- assertEquals(TETHER_ERROR_ENTITLEMENT_UNKNOWN, resultCode);
- }
- };
- mEnMgr.requestLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false);
- mLooper.dispatchAll();
- assertEquals(0, mEnMgr.uiProvisionCount);
- mEnMgr.reset();
- // 3. No cache value and ui entitlement check is needed.
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
- receiver = new ResultReceiver(null) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- assertEquals(TETHER_ERROR_PROVISIONING_FAILED, resultCode);
- }
- };
- mEnMgr.requestLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
- mLooper.dispatchAll();
- assertEquals(1, mEnMgr.uiProvisionCount);
- mEnMgr.reset();
- // 4. Cache value is TETHER_ERROR_PROVISIONING_FAILED and don't need to run entitlement
- // check.
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- receiver = new ResultReceiver(null) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- assertEquals(TETHER_ERROR_PROVISIONING_FAILED, resultCode);
- }
- };
- mEnMgr.requestLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false);
- mLooper.dispatchAll();
- assertEquals(0, mEnMgr.uiProvisionCount);
- mEnMgr.reset();
- // 5. Cache value is TETHER_ERROR_PROVISIONING_FAILED and ui entitlement check is needed.
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- receiver = new ResultReceiver(null) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- assertEquals(TETHER_ERROR_NO_ERROR, resultCode);
- }
- };
- mEnMgr.requestLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
- mLooper.dispatchAll();
- assertEquals(1, mEnMgr.uiProvisionCount);
- mEnMgr.reset();
- // 6. Cache value is TETHER_ERROR_NO_ERROR.
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- receiver = new ResultReceiver(null) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- assertEquals(TETHER_ERROR_NO_ERROR, resultCode);
- }
- };
- mEnMgr.requestLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
- mLooper.dispatchAll();
- assertEquals(0, mEnMgr.uiProvisionCount);
- mEnMgr.reset();
- // 7. Test get value for other downstream type.
- receiver = new ResultReceiver(null) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- assertEquals(TETHER_ERROR_ENTITLEMENT_UNKNOWN, resultCode);
- }
- };
- mEnMgr.requestLatestTetheringEntitlementResult(TETHERING_USB, receiver, false);
- mLooper.dispatchAll();
- assertEquals(0, mEnMgr.uiProvisionCount);
- mEnMgr.reset();
- // 8. Test get value for invalid downstream type.
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- receiver = new ResultReceiver(null) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- assertEquals(TETHER_ERROR_ENTITLEMENT_UNKNOWN, resultCode);
- }
- };
- mEnMgr.requestLatestTetheringEntitlementResult(TETHERING_WIFI_P2P, receiver, true);
- mLooper.dispatchAll();
- assertEquals(0, mEnMgr.uiProvisionCount);
- mEnMgr.reset();
- }
-
- private void assertPermissionChangeCallback(InOrder inOrder) {
- inOrder.verify(mPermissionChangeCallback, times(1)).run();
- }
-
- private void assertNoPermissionChange(InOrder inOrder) {
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void verifyPermissionResult() {
- final InOrder inOrder = inOrder(mPermissionChangeCallback);
- setupForRequiredProvisioning();
- mEnMgr.notifyUpstream(true);
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
- mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
- mLooper.dispatchAll();
- // Permitted: true -> false
- assertPermissionChangeCallback(inOrder);
- assertFalse(mEnMgr.isCellularUpstreamPermitted());
-
- mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
- mLooper.dispatchAll();
- // Permitted: false -> false
- assertNoPermissionChange(inOrder);
-
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
- mLooper.dispatchAll();
- // Permitted: false -> true
- assertPermissionChangeCallback(inOrder);
- assertTrue(mEnMgr.isCellularUpstreamPermitted());
- }
-
- @Test
- public void verifyPermissionIfAllNotApproved() {
- final InOrder inOrder = inOrder(mPermissionChangeCallback);
- setupForRequiredProvisioning();
- mEnMgr.notifyUpstream(true);
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
- mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
- mLooper.dispatchAll();
- // Permitted: true -> false
- assertPermissionChangeCallback(inOrder);
- assertFalse(mEnMgr.isCellularUpstreamPermitted());
-
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
- mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
- mLooper.dispatchAll();
- // Permitted: false -> false
- assertNoPermissionChange(inOrder);
- assertFalse(mEnMgr.isCellularUpstreamPermitted());
-
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
- mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
- mLooper.dispatchAll();
- // Permitted: false -> false
- assertNoPermissionChange(inOrder);
- assertFalse(mEnMgr.isCellularUpstreamPermitted());
- }
-
- @Test
- public void verifyPermissionIfAnyApproved() {
- final InOrder inOrder = inOrder(mPermissionChangeCallback);
- setupForRequiredProvisioning();
- mEnMgr.notifyUpstream(true);
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
- mLooper.dispatchAll();
- // Permitted: true -> true
- assertNoPermissionChange(inOrder);
- assertTrue(mEnMgr.isCellularUpstreamPermitted());
-
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
- mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
- mLooper.dispatchAll();
- // Permitted: true -> true
- assertNoPermissionChange(inOrder);
- assertTrue(mEnMgr.isCellularUpstreamPermitted());
-
- mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
- mLooper.dispatchAll();
- // Permitted: true -> false
- assertPermissionChangeCallback(inOrder);
- assertFalse(mEnMgr.isCellularUpstreamPermitted());
- }
-
- @Test
- public void verifyPermissionWhenProvisioningNotStarted() {
- final InOrder inOrder = inOrder(mPermissionChangeCallback);
- assertTrue(mEnMgr.isCellularUpstreamPermitted());
- assertNoPermissionChange(inOrder);
- setupForRequiredProvisioning();
- assertFalse(mEnMgr.isCellularUpstreamPermitted());
- assertNoPermissionChange(inOrder);
- }
-
- @Test
- public void testRunTetherProvisioning() {
- final InOrder inOrder = inOrder(mPermissionChangeCallback);
- setupForRequiredProvisioning();
- // 1. start ui provisioning, upstream is mobile
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.notifyUpstream(true);
- mLooper.dispatchAll();
- mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
- mLooper.dispatchAll();
- assertEquals(1, mEnMgr.uiProvisionCount);
- assertEquals(0, mEnMgr.silentProvisionCount);
- // Permitted: true -> true
- assertNoPermissionChange(inOrder);
- assertTrue(mEnMgr.isCellularUpstreamPermitted());
- mEnMgr.reset();
-
- // 2. start no-ui provisioning
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, false);
- mLooper.dispatchAll();
- assertEquals(0, mEnMgr.uiProvisionCount);
- assertEquals(1, mEnMgr.silentProvisionCount);
- // Permitted: true -> true
- assertNoPermissionChange(inOrder);
- assertTrue(mEnMgr.isCellularUpstreamPermitted());
- mEnMgr.reset();
-
- // 3. tear down mobile, then start ui provisioning
- mEnMgr.notifyUpstream(false);
- mLooper.dispatchAll();
- mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
- mLooper.dispatchAll();
- assertEquals(0, mEnMgr.uiProvisionCount);
- assertEquals(0, mEnMgr.silentProvisionCount);
- assertNoPermissionChange(inOrder);
- mEnMgr.reset();
-
- // 4. switch upstream back to mobile
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.notifyUpstream(true);
- mLooper.dispatchAll();
- assertEquals(1, mEnMgr.uiProvisionCount);
- assertEquals(0, mEnMgr.silentProvisionCount);
- // Permitted: true -> true
- assertNoPermissionChange(inOrder);
- assertTrue(mEnMgr.isCellularUpstreamPermitted());
- mEnMgr.reset();
-
- // 5. tear down mobile, then switch SIM
- mEnMgr.notifyUpstream(false);
- mLooper.dispatchAll();
- mEnMgr.reevaluateSimCardProvisioning(mConfig);
- assertEquals(0, mEnMgr.uiProvisionCount);
- assertEquals(0, mEnMgr.silentProvisionCount);
- assertNoPermissionChange(inOrder);
- mEnMgr.reset();
-
- // 6. switch upstream back to mobile again
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
- mEnMgr.notifyUpstream(true);
- mLooper.dispatchAll();
- assertEquals(0, mEnMgr.uiProvisionCount);
- assertEquals(3, mEnMgr.silentProvisionCount);
- // Permitted: true -> false
- assertPermissionChangeCallback(inOrder);
- assertFalse(mEnMgr.isCellularUpstreamPermitted());
- mEnMgr.reset();
-
- // 7. start ui provisioning, upstream is mobile, downstream is ethernet
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.startProvisioningIfNeeded(TETHERING_ETHERNET, true);
- mLooper.dispatchAll();
- assertEquals(1, mEnMgr.uiProvisionCount);
- assertEquals(0, mEnMgr.silentProvisionCount);
- // Permitted: false -> true
- assertPermissionChangeCallback(inOrder);
- assertTrue(mEnMgr.isCellularUpstreamPermitted());
- mEnMgr.reset();
-
- // 8. downstream is invalid
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI_P2P, true);
- mLooper.dispatchAll();
- assertEquals(0, mEnMgr.uiProvisionCount);
- assertEquals(0, mEnMgr.silentProvisionCount);
- assertNoPermissionChange(inOrder);
- mEnMgr.reset();
- }
-
- @Test
- public void testCallStopTetheringWhenUiProvisioningFail() {
- setupForRequiredProvisioning();
- verify(mEntitlementFailedListener, times(0)).onUiEntitlementFailed(TETHERING_WIFI);
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
- mEnMgr.notifyUpstream(true);
- mLooper.dispatchAll();
- mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
- mLooper.dispatchAll();
- assertEquals(1, mEnMgr.uiProvisionCount);
- verify(mEntitlementFailedListener, times(1)).onUiEntitlementFailed(TETHERING_WIFI);
- }
-
- @Test
- public void testsetExemptedDownstreamType() throws Exception {
- setupForRequiredProvisioning();
- // Cellular upstream is not permitted when no entitlement result.
- assertFalse(mEnMgr.isCellularUpstreamPermitted());
-
- // If there is exempted downstream and no other non-exempted downstreams, cellular is
- // permitted.
- mEnMgr.setExemptedDownstreamType(TETHERING_WIFI);
- assertTrue(mEnMgr.isCellularUpstreamPermitted());
-
- // If second downstream run entitlement check fail, cellular upstream is not permitted.
- mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
- mEnMgr.notifyUpstream(true);
- mLooper.dispatchAll();
- mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
- mLooper.dispatchAll();
- assertFalse(mEnMgr.isCellularUpstreamPermitted());
-
- // When second downstream is down, exempted downstream can use cellular upstream.
- assertEquals(1, mEnMgr.uiProvisionCount);
- verify(mEntitlementFailedListener).onUiEntitlementFailed(TETHERING_USB);
- mEnMgr.stopProvisioningIfNeeded(TETHERING_USB);
- assertTrue(mEnMgr.isCellularUpstreamPermitted());
-
- mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
- assertFalse(mEnMgr.isCellularUpstreamPermitted());
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/IPv6TetheringCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/IPv6TetheringCoordinatorTest.java
deleted file mode 100644
index f2b5314..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/IPv6TetheringCoordinatorTest.java
+++ /dev/null
@@ -1,156 +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.networkstack.tethering;
-
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.RouteInfo.RTN_UNICAST;
-import static android.net.ip.IpServer.STATE_LOCAL_ONLY;
-import static android.net.ip.IpServer.STATE_TETHERED;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.net.InetAddresses;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.RouteInfo;
-import android.net.ip.IpServer;
-import android.net.util.SharedLog;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class IPv6TetheringCoordinatorTest {
- private static final String TEST_DNS_SERVER = "2001:4860:4860::8888";
- private static final String TEST_INTERFACE = "test_rmnet0";
- private static final String TEST_IPV6_ADDRESS = "2001:db8::1/64";
- private static final String TEST_IPV4_ADDRESS = "192.168.100.1/24";
-
- private IPv6TetheringCoordinator mIPv6TetheringCoordinator;
- private ArrayList<IpServer> mNotifyList;
-
- @Mock private SharedLog mSharedLog;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- when(mSharedLog.forSubComponent(anyString())).thenReturn(mSharedLog);
- mNotifyList = new ArrayList<IpServer>();
- mIPv6TetheringCoordinator = new IPv6TetheringCoordinator(mNotifyList, mSharedLog);
- }
-
- private UpstreamNetworkState createDualStackUpstream(final int transportType) {
- final Network network = mock(Network.class);
- final NetworkCapabilities netCap =
- new NetworkCapabilities.Builder().addTransportType(transportType).build();
- final InetAddress dns = InetAddresses.parseNumericAddress(TEST_DNS_SERVER);
- final LinkProperties linkProp = new LinkProperties();
- linkProp.setInterfaceName(TEST_INTERFACE);
- linkProp.addLinkAddress(new LinkAddress(TEST_IPV6_ADDRESS));
- linkProp.addLinkAddress(new LinkAddress(TEST_IPV4_ADDRESS));
- linkProp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, TEST_INTERFACE, RTN_UNICAST));
- linkProp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, TEST_INTERFACE,
- RTN_UNICAST));
- linkProp.addDnsServer(dns);
- return new UpstreamNetworkState(linkProp, netCap, network);
- }
-
- private void assertOnlyOneV6AddressAndNoV4(LinkProperties lp) {
- assertEquals(lp.getInterfaceName(), TEST_INTERFACE);
- assertFalse(lp.hasIpv4Address());
- final List<LinkAddress> addresses = lp.getLinkAddresses();
- assertEquals(addresses.size(), 1);
- final LinkAddress v6Address = addresses.get(0);
- assertEquals(v6Address, new LinkAddress(TEST_IPV6_ADDRESS));
- }
-
- @Test
- public void testUpdateIpv6Upstream() throws Exception {
- // 1. Add first IpServer.
- final IpServer firstServer = mock(IpServer.class);
- mNotifyList.add(firstServer);
- mIPv6TetheringCoordinator.addActiveDownstream(firstServer, STATE_TETHERED);
- verify(firstServer).sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
- verifyNoMoreInteractions(firstServer);
-
- // 2. Add second IpServer and it would not have ipv6 tethering.
- final IpServer secondServer = mock(IpServer.class);
- mNotifyList.add(secondServer);
- mIPv6TetheringCoordinator.addActiveDownstream(secondServer, STATE_LOCAL_ONLY);
- verifyNoMoreInteractions(secondServer);
- reset(firstServer, secondServer);
-
- // 3. No upstream.
- mIPv6TetheringCoordinator.updateUpstreamNetworkState(null);
- verify(secondServer).sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
- reset(firstServer, secondServer);
-
- // 4. Update ipv6 mobile upstream.
- final UpstreamNetworkState mobileUpstream = createDualStackUpstream(TRANSPORT_CELLULAR);
- final ArgumentCaptor<LinkProperties> lp = ArgumentCaptor.forClass(LinkProperties.class);
- mIPv6TetheringCoordinator.updateUpstreamNetworkState(mobileUpstream);
- verify(firstServer).sendMessage(eq(IpServer.CMD_IPV6_TETHER_UPDATE), eq(-1), eq(0),
- lp.capture());
- final LinkProperties v6OnlyLink = lp.getValue();
- assertOnlyOneV6AddressAndNoV4(v6OnlyLink);
- verifyNoMoreInteractions(firstServer);
- verifyNoMoreInteractions(secondServer);
- reset(firstServer, secondServer);
-
- // 5. Remove first IpServer.
- mNotifyList.remove(firstServer);
- mIPv6TetheringCoordinator.removeActiveDownstream(firstServer);
- verify(firstServer).sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
- verify(secondServer).sendMessage(eq(IpServer.CMD_IPV6_TETHER_UPDATE), eq(-1), eq(0),
- lp.capture());
- final LinkProperties localOnlyLink = lp.getValue();
- assertNotNull(localOnlyLink);
- assertNotEquals(localOnlyLink, v6OnlyLink);
- reset(firstServer, secondServer);
-
- // 6. Remove second IpServer.
- mNotifyList.remove(secondServer);
- mIPv6TetheringCoordinator.removeActiveDownstream(secondServer);
- verifyNoMoreInteractions(firstServer);
- verify(secondServer).sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java
deleted file mode 100644
index f4d24891..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java
+++ /dev/null
@@ -1,70 +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.networkstack.tethering;
-
-import static android.Manifest.permission.WRITE_SETTINGS;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
-import static org.mockito.Mockito.mock;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.ITetheringConnector;
-import android.os.Binder;
-import android.os.IBinder;
-
-import androidx.annotation.NonNull;
-
-public class MockTetheringService extends TetheringService {
- private final Tethering mTethering = mock(Tethering.class);
-
- @Override
- public IBinder onBind(Intent intent) {
- return new MockTetheringConnector(super.onBind(intent));
- }
-
- @Override
- public Tethering makeTethering(TetheringDependencies deps) {
- return mTethering;
- }
-
- @Override
- boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid,
- @NonNull String callingPackage, boolean throwException) {
- // Test this does not verify the calling package / UID, as calling package could be shell
- // and not match the UID.
- return context.checkCallingOrSelfPermission(WRITE_SETTINGS) == PERMISSION_GRANTED;
- }
-
- public Tethering getTethering() {
- return mTethering;
- }
-
- public class MockTetheringConnector extends Binder {
- final IBinder mBase;
- MockTetheringConnector(IBinder base) {
- mBase = base;
- }
-
- public ITetheringConnector getTetheringConnector() {
- return ITetheringConnector.Stub.asInterface(mBase);
- }
-
- public MockTetheringService getService() {
- return MockTetheringService.this;
- }
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
deleted file mode 100644
index b291438..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
+++ /dev/null
@@ -1,827 +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.networkstack.tethering;
-
-import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
-import static android.net.NetworkStats.METERED_NO;
-import static android.net.NetworkStats.ROAMING_NO;
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-import static android.net.NetworkStats.UID_TETHERING;
-import static android.net.RouteInfo.RTN_UNICAST;
-import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
-
-import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_IFACE;
-import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_UID;
-import static com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
-import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
-import static com.android.testutils.MiscAssertsKt.assertContainsAll;
-import static com.android.testutils.MiscAssertsKt.assertThrows;
-import static com.android.testutils.NetworkStatsUtilsKt.assertNetworkStatsEquals;
-
-import static junit.framework.Assert.assertNotNull;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.app.usage.NetworkStatsManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.net.ITetheringStatsProvider;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkStats;
-import android.net.NetworkStats.Entry;
-import android.net.RouteInfo;
-import android.net.netstats.provider.NetworkStatsProvider;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.test.TestLooper;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.test.mock.MockContentResolver;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.testutils.TestableNetworkStatsProviderCbBinder;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class OffloadControllerTest {
- private static final String RNDIS0 = "test_rndis0";
- private static final String RMNET0 = "test_rmnet_data0";
- private static final String WLAN0 = "test_wlan0";
-
- private static final String IPV6_LINKLOCAL = "fe80::/64";
- private static final String IPV6_DOC_PREFIX = "2001:db8::/64";
- private static final String IPV6_DISCARD_PREFIX = "100::/64";
- private static final String USB_PREFIX = "192.168.42.0/24";
- private static final String WIFI_PREFIX = "192.168.43.0/24";
- private static final long WAIT_FOR_IDLE_TIMEOUT = 2 * 1000;
-
- @Mock private OffloadHardwareInterface mHardware;
- @Mock private ApplicationInfo mApplicationInfo;
- @Mock private Context mContext;
- @Mock private NetworkStatsManager mStatsManager;
- @Mock private TetheringConfiguration mTetherConfig;
- // Late init since methods must be called by the thread that created this object.
- private TestableNetworkStatsProviderCbBinder mTetherStatsProviderCb;
- private OffloadController.OffloadTetheringStatsProvider mTetherStatsProvider;
- private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
- ArgumentCaptor.forClass(ArrayList.class);
- private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor =
- ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class);
- private MockContentResolver mContentResolver;
- private final TestLooper mTestLooper = new TestLooper();
- private OffloadController.Dependencies mDeps = new OffloadController.Dependencies() {
- @Override
- public TetheringConfiguration getTetherConfig() {
- return mTetherConfig;
- }
- };
-
- @Before public void setUp() {
- MockitoAnnotations.initMocks(this);
- when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
- when(mContext.getPackageName()).thenReturn("OffloadControllerTest");
- mContentResolver = new MockContentResolver(mContext);
- mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
- when(mContext.getContentResolver()).thenReturn(mContentResolver);
- FakeSettingsProvider.clearSettingsProvider();
- when(mTetherConfig.getOffloadPollInterval()).thenReturn(-1); // Disabled.
- }
-
- @After public void tearDown() throws Exception {
- FakeSettingsProvider.clearSettingsProvider();
- }
-
- private void setupFunctioningHardwareInterface() {
- when(mHardware.initOffloadConfig()).thenReturn(true);
- when(mHardware.initOffloadControl(mControlCallbackCaptor.capture()))
- .thenReturn(true);
- when(mHardware.setUpstreamParameters(anyString(), any(), any(), any())).thenReturn(true);
- when(mHardware.getForwardedStats(any())).thenReturn(new ForwardedStats());
- when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(true);
- }
-
- private void enableOffload() {
- Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 0);
- }
-
- private void setOffloadPollInterval(int interval) {
- when(mTetherConfig.getOffloadPollInterval()).thenReturn(interval);
- }
-
- private void waitForIdle() {
- mTestLooper.dispatchAll();
- }
-
- private OffloadController makeOffloadController() throws Exception {
- OffloadController offload = new OffloadController(new Handler(mTestLooper.getLooper()),
- mHardware, mContentResolver, mStatsManager, new SharedLog("test"), mDeps);
- final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider>
- tetherStatsProviderCaptor =
- ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class);
- verify(mStatsManager).registerNetworkStatsProvider(anyString(),
- tetherStatsProviderCaptor.capture());
- mTetherStatsProvider = tetherStatsProviderCaptor.getValue();
- assertNotNull(mTetherStatsProvider);
- mTetherStatsProviderCb = new TestableNetworkStatsProviderCbBinder();
- mTetherStatsProvider.setProviderCallbackBinder(mTetherStatsProviderCb);
- return offload;
- }
-
- @Test
- public void testNoSettingsValueDefaultDisabledDoesNotStart() throws Exception {
- setupFunctioningHardwareInterface();
- when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(1);
- assertThrows(SettingNotFoundException.class, () ->
- Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED));
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
- inOrder.verify(mHardware, never()).initOffloadConfig();
- inOrder.verify(mHardware, never()).initOffloadControl(
- any(OffloadHardwareInterface.ControlCallback.class));
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void testNoSettingsValueDefaultEnabledDoesStart() throws Exception {
- setupFunctioningHardwareInterface();
- when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(0);
- assertThrows(SettingNotFoundException.class, () ->
- Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED));
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
- inOrder.verify(mHardware, times(1)).initOffloadConfig();
- inOrder.verify(mHardware, times(1)).initOffloadControl(
- any(OffloadHardwareInterface.ControlCallback.class));
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void testSettingsAllowsStart() throws Exception {
- setupFunctioningHardwareInterface();
- Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 0);
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
- inOrder.verify(mHardware, times(1)).initOffloadConfig();
- inOrder.verify(mHardware, times(1)).initOffloadControl(
- any(OffloadHardwareInterface.ControlCallback.class));
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void testSettingsDisablesStart() throws Exception {
- setupFunctioningHardwareInterface();
- Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 1);
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
- inOrder.verify(mHardware, never()).initOffloadConfig();
- inOrder.verify(mHardware, never()).initOffloadControl(anyObject());
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void testSetUpstreamLinkPropertiesWorking() throws Exception {
- setupFunctioningHardwareInterface();
- enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
- inOrder.verify(mHardware, times(1)).initOffloadConfig();
- inOrder.verify(mHardware, times(1)).initOffloadControl(
- any(OffloadHardwareInterface.ControlCallback.class));
- inOrder.verifyNoMoreInteractions();
-
- // In reality, the UpstreamNetworkMonitor would have passed down to us
- // a covering set of local prefixes representing a minimum essential
- // set plus all the prefixes on networks with network agents.
- //
- // We simulate that there, and then add upstream elements one by one
- // and watch what happens.
- final Set<IpPrefix> minimumLocalPrefixes = new HashSet<>();
- for (String s : new String[]{
- "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64"}) {
- minimumLocalPrefixes.add(new IpPrefix(s));
- }
- offload.setLocalPrefixes(minimumLocalPrefixes);
- inOrder.verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
- ArrayList<String> localPrefixes = mStringArrayCaptor.getValue();
- assertEquals(4, localPrefixes.size());
- assertContainsAll(localPrefixes,
- "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64");
- inOrder.verifyNoMoreInteractions();
-
- offload.setUpstreamLinkProperties(null);
- // No change in local addresses means no call to setLocalPrefixes().
- inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture());
- // This LinkProperties value does not differ from the default upstream.
- // There should be no extraneous call to setUpstreamParameters().
- inOrder.verify(mHardware, never()).setUpstreamParameters(
- anyObject(), anyObject(), anyObject(), anyObject());
- inOrder.verifyNoMoreInteractions();
-
- final LinkProperties lp = new LinkProperties();
-
- final String testIfName = "rmnet_data17";
- lp.setInterfaceName(testIfName);
- offload.setUpstreamLinkProperties(lp);
- // No change in local addresses means no call to setLocalPrefixes().
- inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture());
- inOrder.verify(mHardware, times(1)).setUpstreamParameters(
- eq(testIfName), eq(null), eq(null), eq(null));
- inOrder.verify(mHardware, times(1)).setDataLimit(eq(testIfName), eq(Long.MAX_VALUE));
- inOrder.verifyNoMoreInteractions();
-
- final String ipv4Addr = "192.0.2.5";
- final String linkAddr = ipv4Addr + "/24";
- lp.addLinkAddress(new LinkAddress(linkAddr));
- lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, null, RTN_UNICAST));
- offload.setUpstreamLinkProperties(lp);
- // IPv4 prefixes and addresses on the upstream are simply left as whole
- // prefixes (already passed in from UpstreamNetworkMonitor code). If a
- // tethering client sends traffic to the IPv4 default router or other
- // clients on the upstream this will not be hardware-forwarded, and that
- // should be fine for now. Ergo: no change in local addresses, no call
- // to setLocalPrefixes().
- inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture());
- inOrder.verify(mHardware, times(1)).setUpstreamParameters(
- eq(testIfName), eq(ipv4Addr), eq(null), eq(null));
- inOrder.verify(mHardware, times(1)).getForwardedStats(eq(testIfName));
- inOrder.verify(mHardware, times(1)).setDataLimit(eq(testIfName), eq(Long.MAX_VALUE));
- inOrder.verifyNoMoreInteractions();
-
- final String ipv4Gateway = "192.0.2.1";
- lp.addRoute(new RouteInfo(null, InetAddress.getByName(ipv4Gateway), null, RTN_UNICAST));
- offload.setUpstreamLinkProperties(lp);
- // No change in local addresses means no call to setLocalPrefixes().
- inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture());
- inOrder.verify(mHardware, times(1)).setUpstreamParameters(
- eq(testIfName), eq(ipv4Addr), eq(ipv4Gateway), eq(null));
- inOrder.verify(mHardware, times(1)).getForwardedStats(eq(testIfName));
- inOrder.verify(mHardware, times(1)).setDataLimit(eq(testIfName), eq(Long.MAX_VALUE));
- inOrder.verifyNoMoreInteractions();
-
- final String ipv6Gw1 = "fe80::cafe";
- lp.addRoute(new RouteInfo(null, InetAddress.getByName(ipv6Gw1), null, RTN_UNICAST));
- offload.setUpstreamLinkProperties(lp);
- // No change in local addresses means no call to setLocalPrefixes().
- inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture());
- inOrder.verify(mHardware, times(1)).setUpstreamParameters(
- eq(testIfName), eq(ipv4Addr), eq(ipv4Gateway), mStringArrayCaptor.capture());
- inOrder.verify(mHardware, times(1)).getForwardedStats(eq(testIfName));
- ArrayList<String> v6gws = mStringArrayCaptor.getValue();
- assertEquals(1, v6gws.size());
- assertTrue(v6gws.contains(ipv6Gw1));
- inOrder.verify(mHardware, times(1)).setDataLimit(eq(testIfName), eq(Long.MAX_VALUE));
- inOrder.verifyNoMoreInteractions();
-
- final String ipv6Gw2 = "fe80::d00d";
- lp.addRoute(new RouteInfo(null, InetAddress.getByName(ipv6Gw2), null, RTN_UNICAST));
- offload.setUpstreamLinkProperties(lp);
- // No change in local addresses means no call to setLocalPrefixes().
- inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture());
- inOrder.verify(mHardware, times(1)).setUpstreamParameters(
- eq(testIfName), eq(ipv4Addr), eq(ipv4Gateway), mStringArrayCaptor.capture());
- inOrder.verify(mHardware, times(1)).getForwardedStats(eq(testIfName));
- v6gws = mStringArrayCaptor.getValue();
- assertEquals(2, v6gws.size());
- assertTrue(v6gws.contains(ipv6Gw1));
- assertTrue(v6gws.contains(ipv6Gw2));
- inOrder.verify(mHardware, times(1)).setDataLimit(eq(testIfName), eq(Long.MAX_VALUE));
- inOrder.verifyNoMoreInteractions();
-
- final LinkProperties stacked = new LinkProperties();
- stacked.setInterfaceName("stacked");
- stacked.addLinkAddress(new LinkAddress("192.0.2.129/25"));
- stacked.addRoute(new RouteInfo(null, InetAddress.getByName("192.0.2.254"), null,
- RTN_UNICAST));
- stacked.addRoute(new RouteInfo(null, InetAddress.getByName("fe80::bad:f00"), null,
- RTN_UNICAST));
- assertTrue(lp.addStackedLink(stacked));
- offload.setUpstreamLinkProperties(lp);
- // No change in local addresses means no call to setLocalPrefixes().
- inOrder.verify(mHardware, never()).setLocalPrefixes(mStringArrayCaptor.capture());
- inOrder.verify(mHardware, times(1)).setUpstreamParameters(
- eq(testIfName), eq(ipv4Addr), eq(ipv4Gateway), mStringArrayCaptor.capture());
- inOrder.verify(mHardware, times(1)).getForwardedStats(eq(testIfName));
- v6gws = mStringArrayCaptor.getValue();
- assertEquals(2, v6gws.size());
- assertTrue(v6gws.contains(ipv6Gw1));
- assertTrue(v6gws.contains(ipv6Gw2));
- inOrder.verify(mHardware, times(1)).setDataLimit(eq(testIfName), eq(Long.MAX_VALUE));
- inOrder.verifyNoMoreInteractions();
-
- // Add in some IPv6 upstream info. When there is a tethered downstream
- // making use of the IPv6 prefix we would expect to see the /64 route
- // removed from "local prefixes" and /128s added for the upstream IPv6
- // addresses. This is not yet implemented, and for now we simply
- // expect to see these /128s.
- lp.addRoute(new RouteInfo(new IpPrefix("2001:db8::/64"), null, null, RTN_UNICAST));
- // "2001:db8::/64" plus "assigned" ASCII in hex
- lp.addLinkAddress(new LinkAddress("2001:db8::6173:7369:676e:6564/64"));
- // "2001:db8::/64" plus "random" ASCII in hex
- lp.addLinkAddress(new LinkAddress("2001:db8::7261:6e64:6f6d/64"));
- offload.setUpstreamLinkProperties(lp);
- inOrder.verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
- localPrefixes = mStringArrayCaptor.getValue();
- assertEquals(6, localPrefixes.size());
- assertContainsAll(localPrefixes,
- "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64",
- "2001:db8::6173:7369:676e:6564/128", "2001:db8::7261:6e64:6f6d/128");
- // The relevant parts of the LinkProperties have not changed, but at the
- // moment we do not de-dup upstream LinkProperties this carefully.
- inOrder.verify(mHardware, times(1)).setUpstreamParameters(
- eq(testIfName), eq(ipv4Addr), eq(ipv4Gateway), mStringArrayCaptor.capture());
- v6gws = mStringArrayCaptor.getValue();
- assertEquals(2, v6gws.size());
- assertTrue(v6gws.contains(ipv6Gw1));
- assertTrue(v6gws.contains(ipv6Gw2));
- inOrder.verify(mHardware, times(1)).getForwardedStats(eq(testIfName));
- inOrder.verify(mHardware, times(1)).setDataLimit(eq(testIfName), eq(Long.MAX_VALUE));
- inOrder.verifyNoMoreInteractions();
-
- // Completely identical LinkProperties updates are de-duped.
- offload.setUpstreamLinkProperties(lp);
- // This LinkProperties value does not differ from the default upstream.
- // There should be no extraneous call to setUpstreamParameters().
- inOrder.verify(mHardware, never()).setUpstreamParameters(
- anyObject(), anyObject(), anyObject(), anyObject());
- inOrder.verifyNoMoreInteractions();
- }
-
- private static @NonNull Entry buildTestEntry(@NonNull OffloadController.StatsType how,
- @NonNull String iface, long rxBytes, long txBytes) {
- return new Entry(iface, how == STATS_PER_IFACE ? UID_ALL : UID_TETHERING, SET_DEFAULT,
- TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, rxBytes, 0L,
- txBytes, 0L, 0L);
- }
-
- @Test
- public void testGetForwardedStats() throws Exception {
- setupFunctioningHardwareInterface();
- enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final String ethernetIface = "eth1";
- final String mobileIface = "rmnet_data0";
-
- when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
- new ForwardedStats(12345, 54321));
- when(mHardware.getForwardedStats(eq(mobileIface))).thenReturn(
- new ForwardedStats(999, 99999));
-
- InOrder inOrder = inOrder(mHardware);
-
- final LinkProperties lp = new LinkProperties();
- lp.setInterfaceName(ethernetIface);
- offload.setUpstreamLinkProperties(lp);
- // Previous upstream was null, so no stats are fetched.
- inOrder.verify(mHardware, never()).getForwardedStats(any());
-
- lp.setInterfaceName(mobileIface);
- offload.setUpstreamLinkProperties(lp);
- // Expect that we fetch stats from the previous upstream.
- inOrder.verify(mHardware, times(1)).getForwardedStats(eq(ethernetIface));
-
- lp.setInterfaceName(ethernetIface);
- offload.setUpstreamLinkProperties(lp);
- // Expect that we fetch stats from the previous upstream.
- inOrder.verify(mHardware, times(1)).getForwardedStats(eq(mobileIface));
-
- // Verify that the fetched stats are stored.
- final NetworkStats ifaceStats = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE);
- final NetworkStats uidStats = mTetherStatsProvider.getTetherStats(STATS_PER_UID);
- final NetworkStats expectedIfaceStats = new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
- .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321));
-
- final NetworkStats expectedUidStats = new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
- .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321));
-
- assertNetworkStatsEquals(expectedIfaceStats, ifaceStats);
- assertNetworkStatsEquals(expectedUidStats, uidStats);
-
- // Force pushing stats update to verify the stats reported.
- mTetherStatsProvider.pushTetherStats();
- mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStats, expectedUidStats);
-
- when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
- new ForwardedStats(100000, 100000));
- offload.setUpstreamLinkProperties(null);
- // Expect that we first clear the HAL's upstream parameters.
- inOrder.verify(mHardware, times(1)).setUpstreamParameters(
- eq(""), eq("0.0.0.0"), eq("0.0.0.0"), eq(null));
- // Expect that we fetch stats from the previous upstream.
- inOrder.verify(mHardware, times(1)).getForwardedStats(eq(ethernetIface));
-
- // There is no current upstream, so no stats are fetched.
- inOrder.verify(mHardware, never()).getForwardedStats(any());
- inOrder.verifyNoMoreInteractions();
-
- // Verify that the stored stats is accumulated.
- final NetworkStats ifaceStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE);
- final NetworkStats uidStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_UID);
- final NetworkStats expectedIfaceStatsAccu = new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
- .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321));
-
- final NetworkStats expectedUidStatsAccu = new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
- .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321));
-
- assertNetworkStatsEquals(expectedIfaceStatsAccu, ifaceStatsAccu);
- assertNetworkStatsEquals(expectedUidStatsAccu, uidStatsAccu);
-
- // Verify that only diff of stats is reported.
- mTetherStatsProvider.pushTetherStats();
- final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0))
- .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000));
-
- final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2)
- .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0))
- .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000));
- mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStatsDiff,
- expectedUidStatsDiff);
- }
-
- @Test
- public void testSetInterfaceQuota() throws Exception {
- setupFunctioningHardwareInterface();
- enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final String ethernetIface = "eth1";
- final String mobileIface = "rmnet_data0";
- final long ethernetLimit = 12345;
- final long mobileLimit = 12345678;
-
- final LinkProperties lp = new LinkProperties();
- lp.setInterfaceName(ethernetIface);
- offload.setUpstreamLinkProperties(lp);
-
- final InOrder inOrder = inOrder(mHardware);
- when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(true);
- when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(true);
-
- // Applying an interface quota to the current upstream immediately sends it to the hardware.
- mTetherStatsProvider.onSetLimit(ethernetIface, ethernetLimit);
- waitForIdle();
- inOrder.verify(mHardware).setDataLimit(ethernetIface, ethernetLimit);
- inOrder.verifyNoMoreInteractions();
-
- // Applying an interface quota to another upstream does not take any immediate action.
- mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
- waitForIdle();
- inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong());
-
- // Switching to that upstream causes the quota to be applied if the parameters were applied
- // correctly.
- lp.setInterfaceName(mobileIface);
- offload.setUpstreamLinkProperties(lp);
- waitForIdle();
- inOrder.verify(mHardware).setDataLimit(mobileIface, mobileLimit);
-
- // Setting a limit of ITetheringStatsProvider.QUOTA_UNLIMITED causes the limit to be set
- // to Long.MAX_VALUE.
- mTetherStatsProvider.onSetLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED);
- waitForIdle();
- inOrder.verify(mHardware).setDataLimit(mobileIface, Long.MAX_VALUE);
-
- // If setting upstream parameters fails, then the data limit is not set.
- when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(false);
- lp.setInterfaceName(ethernetIface);
- offload.setUpstreamLinkProperties(lp);
- mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
- waitForIdle();
- inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong());
-
- // If setting the data limit fails while changing upstreams, offload is stopped.
- when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(true);
- when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(false);
- lp.setInterfaceName(mobileIface);
- offload.setUpstreamLinkProperties(lp);
- mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
- waitForIdle();
- inOrder.verify(mHardware).getForwardedStats(ethernetIface);
- inOrder.verify(mHardware).stopOffloadControl();
- }
-
- @Test
- public void testDataLimitCallback() throws Exception {
- setupFunctioningHardwareInterface();
- enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
- callback.onStoppedLimitReached();
- mTetherStatsProviderCb.expectNotifyStatsUpdated();
- }
-
- @Test
- public void testAddRemoveDownstreams() throws Exception {
- setupFunctioningHardwareInterface();
- enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).initOffloadConfig();
- inOrder.verify(mHardware, times(1)).initOffloadControl(
- any(OffloadHardwareInterface.ControlCallback.class));
- inOrder.verifyNoMoreInteractions();
-
- // Tethering makes several calls to setLocalPrefixes() before add/remove
- // downstream calls are made. This is not tested here; only the behavior
- // of notifyDownstreamLinkProperties() and removeDownstreamInterface()
- // are tested.
-
- // [1] USB tethering is started.
- final LinkProperties usbLinkProperties = new LinkProperties();
- usbLinkProperties.setInterfaceName(RNDIS0);
- usbLinkProperties.addLinkAddress(new LinkAddress("192.168.42.1/24"));
- usbLinkProperties.addRoute(
- new RouteInfo(new IpPrefix(USB_PREFIX), null, null, RTN_UNICAST));
- offload.notifyDownstreamLinkProperties(usbLinkProperties);
- inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, USB_PREFIX);
- inOrder.verifyNoMoreInteractions();
-
- // [2] Routes for IPv6 link-local prefixes should never be added.
- usbLinkProperties.addRoute(
- new RouteInfo(new IpPrefix(IPV6_LINKLOCAL), null, null, RTN_UNICAST));
- offload.notifyDownstreamLinkProperties(usbLinkProperties);
- inOrder.verify(mHardware, never()).addDownstreamPrefix(eq(RNDIS0), anyString());
- inOrder.verifyNoMoreInteractions();
-
- // [3] Add an IPv6 prefix for good measure. Only new offload-able
- // prefixes should be passed to the HAL.
- usbLinkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
- usbLinkProperties.addRoute(
- new RouteInfo(new IpPrefix(IPV6_DOC_PREFIX), null, null, RTN_UNICAST));
- offload.notifyDownstreamLinkProperties(usbLinkProperties);
- inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, IPV6_DOC_PREFIX);
- inOrder.verifyNoMoreInteractions();
-
- // [4] Adding addresses doesn't affect notifyDownstreamLinkProperties().
- // The address is passed in by a separate setLocalPrefixes() invocation.
- usbLinkProperties.addLinkAddress(new LinkAddress("2001:db8::2/64"));
- offload.notifyDownstreamLinkProperties(usbLinkProperties);
- inOrder.verify(mHardware, never()).addDownstreamPrefix(eq(RNDIS0), anyString());
-
- // [5] Differences in local routes are converted into addDownstream()
- // and removeDownstream() invocations accordingly.
- usbLinkProperties.removeRoute(
- new RouteInfo(new IpPrefix(IPV6_DOC_PREFIX), null, RNDIS0, RTN_UNICAST));
- usbLinkProperties.addRoute(
- new RouteInfo(new IpPrefix(IPV6_DISCARD_PREFIX), null, null, RTN_UNICAST));
- offload.notifyDownstreamLinkProperties(usbLinkProperties);
- inOrder.verify(mHardware, times(1)).removeDownstreamPrefix(RNDIS0, IPV6_DOC_PREFIX);
- inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, IPV6_DISCARD_PREFIX);
- inOrder.verifyNoMoreInteractions();
-
- // [6] Removing a downstream interface which was never added causes no
- // interactions with the HAL.
- offload.removeDownstreamInterface(WLAN0);
- inOrder.verifyNoMoreInteractions();
-
- // [7] Removing an active downstream removes all remaining prefixes.
- offload.removeDownstreamInterface(RNDIS0);
- inOrder.verify(mHardware, times(1)).removeDownstreamPrefix(RNDIS0, USB_PREFIX);
- inOrder.verify(mHardware, times(1)).removeDownstreamPrefix(RNDIS0, IPV6_DISCARD_PREFIX);
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void testControlCallbackOnStoppedUnsupportedFetchesAllStats() throws Exception {
- setupFunctioningHardwareInterface();
- enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- // Pretend to set a few different upstreams (only the interface name
- // matters for this test; we're ignoring IP and route information).
- final LinkProperties upstreamLp = new LinkProperties();
- for (String ifname : new String[]{RMNET0, WLAN0, RMNET0}) {
- upstreamLp.setInterfaceName(ifname);
- offload.setUpstreamLinkProperties(upstreamLp);
- }
-
- // Clear invocation history, especially the getForwardedStats() calls
- // that happen with setUpstreamParameters().
- clearInvocations(mHardware);
-
- OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
- callback.onStoppedUnsupported();
-
- // Verify forwarded stats behaviour.
- verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
- verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
- // TODO: verify the exact stats reported.
- mTetherStatsProviderCb.expectNotifyStatsUpdated();
- mTetherStatsProviderCb.assertNoCallback();
- verifyNoMoreInteractions(mHardware);
- }
-
- @Test
- public void testControlCallbackOnSupportAvailableFetchesAllStatsAndPushesAllParameters()
- throws Exception {
- setupFunctioningHardwareInterface();
- enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- // Pretend to set a few different upstreams (only the interface name
- // matters for this test; we're ignoring IP and route information).
- final LinkProperties upstreamLp = new LinkProperties();
- for (String ifname : new String[]{RMNET0, WLAN0, RMNET0}) {
- upstreamLp.setInterfaceName(ifname);
- offload.setUpstreamLinkProperties(upstreamLp);
- }
-
- // Pretend that some local prefixes and downstreams have been added
- // (and removed, for good measure).
- final Set<IpPrefix> minimumLocalPrefixes = new HashSet<>();
- for (String s : new String[]{
- "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64"}) {
- minimumLocalPrefixes.add(new IpPrefix(s));
- }
- offload.setLocalPrefixes(minimumLocalPrefixes);
-
- final LinkProperties usbLinkProperties = new LinkProperties();
- usbLinkProperties.setInterfaceName(RNDIS0);
- usbLinkProperties.addLinkAddress(new LinkAddress("192.168.42.1/24"));
- usbLinkProperties.addRoute(
- new RouteInfo(new IpPrefix(USB_PREFIX), null, null, RTN_UNICAST));
- offload.notifyDownstreamLinkProperties(usbLinkProperties);
-
- final LinkProperties wifiLinkProperties = new LinkProperties();
- wifiLinkProperties.setInterfaceName(WLAN0);
- wifiLinkProperties.addLinkAddress(new LinkAddress("192.168.43.1/24"));
- wifiLinkProperties.addRoute(
- new RouteInfo(new IpPrefix(WIFI_PREFIX), null, null, RTN_UNICAST));
- wifiLinkProperties.addRoute(
- new RouteInfo(new IpPrefix(IPV6_LINKLOCAL), null, null, RTN_UNICAST));
- // Use a benchmark prefix (RFC 5180 + erratum), since the documentation
- // prefix is included in the excluded prefix list.
- wifiLinkProperties.addLinkAddress(new LinkAddress("2001:2::1/64"));
- wifiLinkProperties.addLinkAddress(new LinkAddress("2001:2::2/64"));
- wifiLinkProperties.addRoute(
- new RouteInfo(new IpPrefix("2001:2::/64"), null, null, RTN_UNICAST));
- offload.notifyDownstreamLinkProperties(wifiLinkProperties);
-
- offload.removeDownstreamInterface(RNDIS0);
-
- // Clear invocation history, especially the getForwardedStats() calls
- // that happen with setUpstreamParameters().
- clearInvocations(mHardware);
-
- OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
- callback.onSupportAvailable();
-
- // Verify forwarded stats behaviour.
- verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
- verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
- mTetherStatsProviderCb.expectNotifyStatsUpdated();
- mTetherStatsProviderCb.assertNoCallback();
-
- // TODO: verify local prefixes and downstreams are also pushed to the HAL.
- verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
- ArrayList<String> localPrefixes = mStringArrayCaptor.getValue();
- assertEquals(4, localPrefixes.size());
- assertContainsAll(localPrefixes,
- // TODO: The logic to find and exclude downstream IP prefixes
- // is currently in Tethering's OffloadWrapper but must be moved
- // into OffloadController proper. After this, also check for:
- // "192.168.43.1/32", "2001:2::1/128", "2001:2::2/128"
- "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64");
- verify(mHardware, times(1)).addDownstreamPrefix(WLAN0, "192.168.43.0/24");
- verify(mHardware, times(1)).addDownstreamPrefix(WLAN0, "2001:2::/64");
- verify(mHardware, times(1)).setUpstreamParameters(eq(RMNET0), any(), any(), any());
- verify(mHardware, times(1)).setDataLimit(eq(RMNET0), anyLong());
- verifyNoMoreInteractions(mHardware);
- }
-
- @Test
- public void testOnSetAlert() throws Exception {
- setupFunctioningHardwareInterface();
- enableOffload();
- setOffloadPollInterval(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- // Initialize with fake eth upstream.
- final String ethernetIface = "eth1";
- InOrder inOrder = inOrder(mHardware);
- final LinkProperties lp = new LinkProperties();
- lp.setInterfaceName(ethernetIface);
- offload.setUpstreamLinkProperties(lp);
- // Previous upstream was null, so no stats are fetched.
- inOrder.verify(mHardware, never()).getForwardedStats(any());
-
- // Verify that set quota to 0 will immediately triggers an callback.
- mTetherStatsProvider.onSetAlert(0);
- waitForIdle();
- mTetherStatsProviderCb.expectNotifyAlertReached();
-
- // Verify that notifyAlertReached never fired if quota is not yet reached.
- when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
- new ForwardedStats(0, 0));
- mTetherStatsProvider.onSetAlert(100);
- mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- waitForIdle();
- mTetherStatsProviderCb.assertNoCallback();
-
- // Verify that notifyAlertReached fired when quota is reached.
- when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
- new ForwardedStats(50, 50));
- mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- waitForIdle();
- mTetherStatsProviderCb.expectNotifyAlertReached();
-
- // Verify that set quota with UNLIMITED won't trigger any callback, and won't fetch
- // any stats since the polling is stopped.
- reset(mHardware);
- mTetherStatsProvider.onSetAlert(NetworkStatsProvider.QUOTA_UNLIMITED);
- mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- waitForIdle();
- mTetherStatsProviderCb.assertNoCallback();
- verify(mHardware, never()).getForwardedStats(any());
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
deleted file mode 100644
index c543fad..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
+++ /dev/null
@@ -1,254 +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.networkstack.tethering;
-
-import static android.net.util.TetheringUtils.uint16;
-import static android.system.OsConstants.SOCK_STREAM;
-import static android.system.OsConstants.AF_UNIX;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
-import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
-import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
-import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
-import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
-import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
-import android.net.netlink.StructNlMsgHdr;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.NativeHandle;
-import android.os.test.TestLooper;
-import android.system.ErrnoException;
-import android.system.OsConstants;
-import android.system.Os;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.FileDescriptor;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class OffloadHardwareInterfaceTest {
- private static final String RMNET0 = "test_rmnet_data0";
-
- private final TestLooper mTestLooper = new TestLooper();
-
- private OffloadHardwareInterface mOffloadHw;
- private ITetheringOffloadCallback mTetheringOffloadCallback;
- private OffloadHardwareInterface.ControlCallback mControlCallback;
-
- @Mock private IOffloadConfig mIOffloadConfig;
- @Mock private IOffloadControl mIOffloadControl;
- @Mock private NativeHandle mNativeHandle;
-
- // Random values to test Netlink message.
- private static final short TEST_TYPE = 184;
- private static final short TEST_FLAGS = 263;
-
- class MyDependencies extends OffloadHardwareInterface.Dependencies {
- MyDependencies(SharedLog log) {
- super(log);
- }
-
- @Override
- public IOffloadConfig getOffloadConfig() {
- return mIOffloadConfig;
- }
-
- @Override
- public IOffloadControl getOffloadControl() {
- return mIOffloadControl;
- }
-
- @Override
- public NativeHandle createConntrackSocket(final int groups) {
- return mNativeHandle;
- }
- }
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- final SharedLog log = new SharedLog("test");
- mOffloadHw = new OffloadHardwareInterface(new Handler(mTestLooper.getLooper()), log,
- new MyDependencies(log));
- mControlCallback = spy(new OffloadHardwareInterface.ControlCallback());
- }
-
- private void startOffloadHardwareInterface() throws Exception {
- mOffloadHw.initOffloadConfig();
- mOffloadHw.initOffloadControl(mControlCallback);
- final ArgumentCaptor<ITetheringOffloadCallback> mOffloadCallbackCaptor =
- ArgumentCaptor.forClass(ITetheringOffloadCallback.class);
- verify(mIOffloadControl).initOffload(mOffloadCallbackCaptor.capture(), any());
- mTetheringOffloadCallback = mOffloadCallbackCaptor.getValue();
- }
-
- @Test
- public void testGetForwardedStats() throws Exception {
- startOffloadHardwareInterface();
- final OffloadHardwareInterface.ForwardedStats stats = mOffloadHw.getForwardedStats(RMNET0);
- verify(mIOffloadControl).getForwardedStats(eq(RMNET0), any());
- assertNotNull(stats);
- }
-
- @Test
- public void testSetLocalPrefixes() throws Exception {
- startOffloadHardwareInterface();
- final ArrayList<String> localPrefixes = new ArrayList<>();
- localPrefixes.add("127.0.0.0/8");
- localPrefixes.add("fe80::/64");
- mOffloadHw.setLocalPrefixes(localPrefixes);
- verify(mIOffloadControl).setLocalPrefixes(eq(localPrefixes), any());
- }
-
- @Test
- public void testSetDataLimit() throws Exception {
- startOffloadHardwareInterface();
- final long limit = 12345;
- mOffloadHw.setDataLimit(RMNET0, limit);
- verify(mIOffloadControl).setDataLimit(eq(RMNET0), eq(limit), any());
- }
-
- @Test
- public void testSetUpstreamParameters() throws Exception {
- startOffloadHardwareInterface();
- final String v4addr = "192.168.10.1";
- final String v4gateway = "192.168.10.255";
- final ArrayList<String> v6gws = new ArrayList<>(0);
- v6gws.add("2001:db8::1");
- mOffloadHw.setUpstreamParameters(RMNET0, v4addr, v4gateway, v6gws);
- verify(mIOffloadControl).setUpstreamParameters(eq(RMNET0), eq(v4addr), eq(v4gateway),
- eq(v6gws), any());
-
- final ArgumentCaptor<ArrayList<String>> mArrayListCaptor =
- ArgumentCaptor.forClass(ArrayList.class);
- mOffloadHw.setUpstreamParameters(null, null, null, null);
- verify(mIOffloadControl).setUpstreamParameters(eq(""), eq(""), eq(""),
- mArrayListCaptor.capture(), any());
- assertEquals(mArrayListCaptor.getValue().size(), 0);
- }
-
- @Test
- public void testUpdateDownstreamPrefix() throws Exception {
- startOffloadHardwareInterface();
- final String ifName = "wlan1";
- final String prefix = "192.168.43.0/24";
- mOffloadHw.addDownstreamPrefix(ifName, prefix);
- verify(mIOffloadControl).addDownstream(eq(ifName), eq(prefix), any());
-
- mOffloadHw.removeDownstreamPrefix(ifName, prefix);
- verify(mIOffloadControl).removeDownstream(eq(ifName), eq(prefix), any());
- }
-
- @Test
- public void testTetheringOffloadCallback() throws Exception {
- startOffloadHardwareInterface();
-
- mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED);
- mTestLooper.dispatchAll();
- verify(mControlCallback).onStarted();
-
- mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR);
- mTestLooper.dispatchAll();
- verify(mControlCallback).onStoppedError();
-
- mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED);
- mTestLooper.dispatchAll();
- verify(mControlCallback).onStoppedUnsupported();
-
- mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE);
- mTestLooper.dispatchAll();
- verify(mControlCallback).onSupportAvailable();
-
- mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED);
- mTestLooper.dispatchAll();
- verify(mControlCallback).onStoppedLimitReached();
-
- final NatTimeoutUpdate tcpParams = buildNatTimeoutUpdate(NetworkProtocol.TCP);
- mTetheringOffloadCallback.updateTimeout(tcpParams);
- mTestLooper.dispatchAll();
- verify(mControlCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_TCP),
- eq(tcpParams.src.addr),
- eq(uint16(tcpParams.src.port)),
- eq(tcpParams.dst.addr),
- eq(uint16(tcpParams.dst.port)));
-
- final NatTimeoutUpdate udpParams = buildNatTimeoutUpdate(NetworkProtocol.UDP);
- mTetheringOffloadCallback.updateTimeout(udpParams);
- mTestLooper.dispatchAll();
- verify(mControlCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_UDP),
- eq(udpParams.src.addr),
- eq(uint16(udpParams.src.port)),
- eq(udpParams.dst.addr),
- eq(uint16(udpParams.dst.port)));
- }
-
- @Test
- public void testNetlinkMessage() throws Exception {
- FileDescriptor writeSocket = new FileDescriptor();
- FileDescriptor readSocket = new FileDescriptor();
- try {
- Os.socketpair(AF_UNIX, SOCK_STREAM, 0, writeSocket, readSocket);
- } catch (ErrnoException e) {
- fail();
- return;
- }
- when(mNativeHandle.getFileDescriptor()).thenReturn(writeSocket);
-
- mOffloadHw.sendNetlinkMessage(mNativeHandle, TEST_TYPE, TEST_FLAGS);
-
- ByteBuffer buffer = ByteBuffer.allocate(StructNlMsgHdr.STRUCT_SIZE);
- int read = Os.read(readSocket, buffer);
-
- buffer.flip();
- assertEquals(StructNlMsgHdr.STRUCT_SIZE, buffer.getInt());
- assertEquals(TEST_TYPE, buffer.getShort());
- assertEquals(TEST_FLAGS, buffer.getShort());
- assertEquals(1 /* seq */, buffer.getInt());
- assertEquals(0 /* pid */, buffer.getInt());
- }
-
- private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) {
- final NatTimeoutUpdate params = new NatTimeoutUpdate();
- params.proto = proto;
- params.src.addr = "192.168.43.200";
- params.src.port = 100;
- params.dst.addr = "172.50.46.169";
- params.dst.port = 150;
- return params;
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java
deleted file mode 100644
index 93efd49..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java
+++ /dev/null
@@ -1,254 +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.networkstack.tethering;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.InetAddresses;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.ip.IpServer;
-import android.net.util.NetworkConstants;
-import android.net.util.PrefixUtils;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class PrivateAddressCoordinatorTest {
- private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0";
- private static final String TEST_WIFI_IFNAME = "test_wlan0";
-
- @Mock private IpServer mHotspotIpServer;
- @Mock private IpServer mUsbIpServer;
- @Mock private IpServer mEthernetIpServer;
- @Mock private Context mContext;
- @Mock private ConnectivityManager mConnectivityMgr;
-
- private PrivateAddressCoordinator mPrivateAddressCoordinator;
- private final IpPrefix mBluetoothPrefix = new IpPrefix("192.168.44.0/24");
- private final Network mWifiNetwork = new Network(1);
- private final Network mMobileNetwork = new Network(2);
- private final Network[] mAllNetworks = {mMobileNetwork, mWifiNetwork};
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mConnectivityMgr);
- when(mConnectivityMgr.getAllNetworks()).thenReturn(mAllNetworks);
- mPrivateAddressCoordinator = spy(new PrivateAddressCoordinator(mContext));
- }
-
- @Test
- public void testDownstreamPrefixRequest() throws Exception {
- LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress(
- mHotspotIpServer);
- final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(address);
- assertNotEquals(hotspotPrefix, mBluetoothPrefix);
-
- address = mPrivateAddressCoordinator.requestDownstreamAddress(
- mHotspotIpServer);
- final IpPrefix testDupRequest = PrefixUtils.asIpPrefix(address);
- assertNotEquals(hotspotPrefix, testDupRequest);
- assertNotEquals(mBluetoothPrefix, testDupRequest);
- mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
-
- address = mPrivateAddressCoordinator.requestDownstreamAddress(
- mUsbIpServer);
- final IpPrefix usbPrefix = PrefixUtils.asIpPrefix(address);
- assertNotEquals(usbPrefix, mBluetoothPrefix);
- assertNotEquals(usbPrefix, hotspotPrefix);
- mPrivateAddressCoordinator.releaseDownstream(mUsbIpServer);
- }
-
- @Test
- public void testRequestDownstreamAddress() throws Exception {
- LinkAddress expectedAddress = new LinkAddress("192.168.43.42/24");
- int fakeSubAddr = 0x2b00;
- when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr);
- LinkAddress actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress(
- mHotspotIpServer);
- assertEquals(actualAddress, expectedAddress);
- mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
-
- fakeSubAddr = 0x2b01;
- when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr);
- actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress(
- mHotspotIpServer);
- assertEquals(actualAddress, expectedAddress);
- mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
-
- fakeSubAddr = 0x2bff;
- when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr);
- actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress(
- mHotspotIpServer);
- assertEquals(actualAddress, expectedAddress);
- mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
-
- expectedAddress = new LinkAddress("192.168.43.5/24");
- fakeSubAddr = 0x2b05;
- when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr);
- actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress(
- mHotspotIpServer);
- assertEquals(actualAddress, expectedAddress);
- mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
- }
-
- @Test
- public void testReserveBluetoothPrefix() throws Exception {
- final int fakeSubAddr = 0x2c05;
- when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr);
- LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress(
- mHotspotIpServer);
- final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(address);
- assertNotEquals("Should not get reserved prefix: ", mBluetoothPrefix, hotspotPrefix);
- mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
- }
-
- @Test
- public void testNoConflictDownstreamPrefix() throws Exception {
- final int fakeHotspotSubAddr = 0x2b05;
- final IpPrefix predefinedPrefix = new IpPrefix("192.168.43.0/24");
- when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeHotspotSubAddr);
- LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress(
- mHotspotIpServer);
- final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(address);
- assertEquals("Wrong wifi perfix: ", predefinedPrefix, hotspotPrefix);
- when(mHotspotIpServer.getAddress()).thenReturn(address);
-
- address = mPrivateAddressCoordinator.requestDownstreamAddress(
- mUsbIpServer);
- final IpPrefix usbPrefix = PrefixUtils.asIpPrefix(address);
- assertNotEquals(predefinedPrefix, usbPrefix);
-
- mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
- mPrivateAddressCoordinator.releaseDownstream(mUsbIpServer);
- address = mPrivateAddressCoordinator.requestDownstreamAddress(
- mUsbIpServer);
- final IpPrefix allowUseFreePrefix = PrefixUtils.asIpPrefix(address);
- assertEquals("Fail to reselect available perfix: ", predefinedPrefix, allowUseFreePrefix);
- }
-
- private LinkProperties buildUpstreamLinkProperties(boolean withIPv4, boolean withIPv6,
- boolean isMobile) {
- final String testIface;
- final String testIpv4Address;
- if (isMobile) {
- testIface = TEST_MOBILE_IFNAME;
- testIpv4Address = "10.0.0.1";
- } else {
- testIface = TEST_WIFI_IFNAME;
- testIpv4Address = "192.168.43.5";
- }
-
- final LinkProperties prop = new LinkProperties();
- prop.setInterfaceName(testIface);
-
- if (withIPv4) {
- prop.addLinkAddress(
- new LinkAddress(InetAddresses.parseNumericAddress(testIpv4Address),
- NetworkConstants.IPV4_ADDR_BITS));
- }
-
- if (withIPv6) {
- prop.addLinkAddress(
- new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"),
- NetworkConstants.RFC7421_PREFIX_LENGTH));
- }
- return prop;
- }
-
- @Test
- public void testNoConflictUpstreamPrefix() throws Exception {
- final int fakeHotspotSubId = 43;
- final int fakeHotspotSubAddr = 0x2b05;
- final IpPrefix predefinedPrefix = new IpPrefix("192.168.43.0/24");
- // Force always get subAddress "43.5" for conflict testing.
- when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeHotspotSubAddr);
- // 1. Enable hotspot with prefix 192.168.43.0/24
- final LinkAddress hotspotAddr = mPrivateAddressCoordinator.requestDownstreamAddress(
- mHotspotIpServer);
- final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(hotspotAddr);
- assertEquals("Wrong wifi perfix: ", predefinedPrefix, hotspotPrefix);
- when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddr);
- // 2. Update v6 only mobile network, hotspot prefix should not be removed.
- List<String> testConflicts;
- final LinkProperties v6OnlyMobileProp = buildUpstreamLinkProperties(false, true, true);
- mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v6OnlyMobileProp);
- verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT);
- mPrivateAddressCoordinator.removeUpstreamPrefix(mMobileNetwork);
- // 3. Update v4 only mobile network, hotspot prefix should not be removed.
- final LinkProperties v4OnlyMobileProp = buildUpstreamLinkProperties(true, false, true);
- mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v4OnlyMobileProp);
- verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT);
- // 4. Update v4v6 mobile network, hotspot prefix should not be removed.
- final LinkProperties v4v6MobileProp = buildUpstreamLinkProperties(true, true, true);
- mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v4v6MobileProp);
- verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT);
- // 5. Update v6 only wifi network, hotspot prefix should not be removed.
- final LinkProperties v6OnlyWifiProp = buildUpstreamLinkProperties(false, true, false);
- mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v6OnlyWifiProp);
- verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT);
- mPrivateAddressCoordinator.removeUpstreamPrefix(mWifiNetwork);
- // 6. Update v4 only wifi network, it conflict with hotspot prefix.
- final LinkProperties v4OnlyWifiProp = buildUpstreamLinkProperties(true, false, false);
- mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v4OnlyWifiProp);
- verify(mHotspotIpServer).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT);
- reset(mHotspotIpServer);
- // 7. Restart hotspot again and its prefix is different previous.
- mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
- final LinkAddress hotspotAddr2 = mPrivateAddressCoordinator.requestDownstreamAddress(
- mHotspotIpServer);
- final IpPrefix hotspotPrefix2 = PrefixUtils.asIpPrefix(hotspotAddr2);
- assertNotEquals(hotspotPrefix, hotspotPrefix2);
- when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddr2);
- mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v4OnlyWifiProp);
- verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT);
- // 7. Usb tethering can be enabled and its prefix is different with conflict one.
- final LinkAddress usbAddr = mPrivateAddressCoordinator.requestDownstreamAddress(
- mUsbIpServer);
- final IpPrefix usbPrefix = PrefixUtils.asIpPrefix(usbAddr);
- assertNotEquals(predefinedPrefix, usbPrefix);
- assertNotEquals(hotspotPrefix2, usbPrefix);
- when(mUsbIpServer.getAddress()).thenReturn(usbAddr);
- // 8. Disable wifi upstream, then wifi's prefix can be selected again.
- mPrivateAddressCoordinator.removeUpstreamPrefix(mWifiNetwork);
- final LinkAddress ethAddr = mPrivateAddressCoordinator.requestDownstreamAddress(
- mEthernetIpServer);
- final IpPrefix ethPrefix = PrefixUtils.asIpPrefix(ethAddr);
- assertEquals(predefinedPrefix, ethPrefix);
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
deleted file mode 100644
index a9ac4e2..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.networkstack.tethering;
-
-import static android.net.ConnectivityManager.TYPE_ETHERNET;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
-import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.util.SharedLog;
-import android.provider.DeviceConfig;
-import android.telephony.TelephonyManager;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.test.BroadcastInterceptingContext;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class TetheringConfigurationTest {
- private final SharedLog mLog = new SharedLog("TetheringConfigurationTest");
-
- private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
- private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
- private static final String PROVISIONING_APP_RESPONSE = "app_response";
- @Mock private Context mContext;
- @Mock private TelephonyManager mTelephonyManager;
- @Mock private Resources mResources;
- @Mock private Resources mResourcesForSubId;
- private Context mMockContext;
- private boolean mHasTelephonyManager;
- private boolean mEnableLegacyDhcpServer;
- private MockitoSession mMockingSession;
-
- private class MockTetheringConfiguration extends TetheringConfiguration {
- MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
- super(ctx, log, id);
- }
-
- @Override
- protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
- return mResourcesForSubId;
- }
- }
-
- private class MockContext extends BroadcastInterceptingContext {
- MockContext(Context base) {
- super(base);
- }
-
- @Override
- public Resources getResources() {
- return mResources;
- }
-
- @Override
- public Object getSystemService(String name) {
- if (Context.TELEPHONY_SERVICE.equals(name)) {
- return mHasTelephonyManager ? mTelephonyManager : null;
- }
- return super.getSystemService(name);
- }
- }
-
- @Before
- public void setUp() throws Exception {
- // TODO: use a dependencies class instead of mock statics.
- mMockingSession = mockitoSession()
- .initMocks(this)
- .mockStatic(DeviceConfig.class)
- .strictness(Strictness.WARN)
- .startMocking();
- doReturn(null).when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
-
- when(mResources.getStringArray(R.array.config_tether_dhcp_range)).thenReturn(
- new String[0]);
- when(mResources.getInteger(R.integer.config_tether_offload_poll_interval)).thenReturn(
- TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- when(mResources.getStringArray(R.array.config_tether_usb_regexs)).thenReturn(new String[0]);
- when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
- .thenReturn(new String[]{ "test_wlan\\d" });
- when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs)).thenReturn(
- new String[0]);
- when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]);
- when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
- .thenReturn(new String[0]);
- when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
- false);
- initializeBpfOffloadConfiguration(true, null /* unset */);
-
- mHasTelephonyManager = true;
- mMockContext = new MockContext(mContext);
- mEnableLegacyDhcpServer = false;
- }
-
- @After
- public void tearDown() throws Exception {
- mMockingSession.finishMocking();
- }
-
- private TetheringConfiguration getTetheringConfiguration(int... legacyTetherUpstreamTypes) {
- when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(
- legacyTetherUpstreamTypes);
- return new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- }
-
- @Test
- public void testNoTelephonyManagerMeansNoDun() {
- mHasTelephonyManager = false;
- final TetheringConfiguration cfg = getTetheringConfiguration(
- new int[]{TYPE_MOBILE_DUN, TYPE_WIFI});
- assertFalse(cfg.isDunRequired);
- assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
- // Just to prove we haven't clobbered Wi-Fi:
- assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_WIFI));
- }
-
- @Test
- public void testDunFromTelephonyManagerMeansDun() {
- when(mTelephonyManager.isTetheringApnRequired()).thenReturn(true);
-
- final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
- final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
- TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI);
- final TetheringConfiguration cfgWifiDun = getTetheringConfiguration(
- TYPE_WIFI, TYPE_MOBILE_DUN);
- final TetheringConfiguration cfgMobileWifiHipriDun = getTetheringConfiguration(
- TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI, TYPE_MOBILE_DUN);
-
- for (TetheringConfiguration cfg : Arrays.asList(cfgWifi, cfgMobileWifiHipri,
- cfgWifiDun, cfgMobileWifiHipriDun)) {
- String msg = "config=" + cfg.toString();
- assertTrue(msg, cfg.isDunRequired);
- assertTrue(msg, cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
- assertFalse(msg, cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
- assertFalse(msg, cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_HIPRI));
- // Just to prove we haven't clobbered Wi-Fi:
- assertTrue(msg, cfg.preferredUpstreamIfaceTypes.contains(TYPE_WIFI));
- }
- }
-
- @Test
- public void testDunNotRequiredFromTelephonyManagerMeansNoDun() {
- when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
-
- final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
- final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
- TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI);
- final TetheringConfiguration cfgWifiDun = getTetheringConfiguration(
- TYPE_WIFI, TYPE_MOBILE_DUN);
- final TetheringConfiguration cfgWifiMobile = getTetheringConfiguration(
- TYPE_WIFI, TYPE_MOBILE);
- final TetheringConfiguration cfgWifiHipri = getTetheringConfiguration(
- TYPE_WIFI, TYPE_MOBILE_HIPRI);
- final TetheringConfiguration cfgMobileWifiHipriDun = getTetheringConfiguration(
- TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI, TYPE_MOBILE_DUN);
-
- String msg;
- // TYPE_MOBILE_DUN should be present in none of the combinations.
- // TYPE_WIFI should not be affected.
- for (TetheringConfiguration cfg : Arrays.asList(cfgWifi, cfgMobileWifiHipri, cfgWifiDun,
- cfgWifiMobile, cfgWifiHipri, cfgMobileWifiHipriDun)) {
- msg = "config=" + cfg.toString();
- assertFalse(msg, cfg.isDunRequired);
- assertFalse(msg, cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
- assertTrue(msg, cfg.preferredUpstreamIfaceTypes.contains(TYPE_WIFI));
- }
-
- for (TetheringConfiguration cfg : Arrays.asList(cfgWifi, cfgMobileWifiHipri, cfgWifiDun,
- cfgMobileWifiHipriDun)) {
- msg = "config=" + cfg.toString();
- assertTrue(msg, cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
- assertTrue(msg, cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_HIPRI));
- }
- msg = "config=" + cfgWifiMobile.toString();
- assertTrue(msg, cfgWifiMobile.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
- assertFalse(msg, cfgWifiMobile.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_HIPRI));
- msg = "config=" + cfgWifiHipri.toString();
- assertFalse(msg, cfgWifiHipri.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
- assertTrue(msg, cfgWifiHipri.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_HIPRI));
-
- }
-
- @Test
- public void testNoDefinedUpstreamTypesAddsEthernet() {
- when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[]{});
- when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
-
- final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
- assertTrue(upstreamIterator.hasNext());
- assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
- // The following is because the code always adds some kind of mobile
- // upstream, be it DUN or, in this case where DUN is NOT required,
- // make sure there is at least one of MOBILE or HIPRI. With the empty
- // list of the configuration in this test, it will always add both
- // MOBILE and HIPRI, in that order.
- assertTrue(upstreamIterator.hasNext());
- assertEquals(TYPE_MOBILE, upstreamIterator.next().intValue());
- assertTrue(upstreamIterator.hasNext());
- assertEquals(TYPE_MOBILE_HIPRI, upstreamIterator.next().intValue());
- assertFalse(upstreamIterator.hasNext());
- }
-
- @Test
- public void testDefinedUpstreamTypesSansEthernetAddsEthernet() {
- when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(
- new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI});
- when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
-
- final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
- assertTrue(upstreamIterator.hasNext());
- assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
- assertTrue(upstreamIterator.hasNext());
- assertEquals(TYPE_WIFI, upstreamIterator.next().intValue());
- assertTrue(upstreamIterator.hasNext());
- assertEquals(TYPE_MOBILE_HIPRI, upstreamIterator.next().intValue());
- assertFalse(upstreamIterator.hasNext());
- }
-
- @Test
- public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() {
- when(mResources.getIntArray(R.array.config_tether_upstream_types))
- .thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI});
- when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
-
- final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
- assertTrue(upstreamIterator.hasNext());
- assertEquals(TYPE_WIFI, upstreamIterator.next().intValue());
- assertTrue(upstreamIterator.hasNext());
- assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
- assertTrue(upstreamIterator.hasNext());
- assertEquals(TYPE_MOBILE_HIPRI, upstreamIterator.next().intValue());
- assertFalse(upstreamIterator.hasNext());
- }
-
- private void initializeBpfOffloadConfiguration(
- final boolean fromRes, final String fromDevConfig) {
- when(mResources.getBoolean(R.bool.config_tether_enable_bpf_offload)).thenReturn(fromRes);
- doReturn(fromDevConfig).when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD)));
- }
-
- @Test
- public void testBpfOffloadEnabledByResource() {
- initializeBpfOffloadConfiguration(true, null /* unset */);
- final TetheringConfiguration enableByRes =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(enableByRes.isBpfOffloadEnabled());
- }
-
- @Test
- public void testBpfOffloadEnabledByDeviceConfigOverride() {
- for (boolean res : new boolean[]{true, false}) {
- initializeBpfOffloadConfiguration(res, "true");
- final TetheringConfiguration enableByDevConOverride =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(enableByDevConOverride.isBpfOffloadEnabled());
- }
- }
-
- @Test
- public void testBpfOffloadDisabledByResource() {
- initializeBpfOffloadConfiguration(false, null /* unset */);
- final TetheringConfiguration disableByRes =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertFalse(disableByRes.isBpfOffloadEnabled());
- }
-
- @Test
- public void testBpfOffloadDisabledByDeviceConfigOverride() {
- for (boolean res : new boolean[]{true, false}) {
- initializeBpfOffloadConfiguration(res, "false");
- final TetheringConfiguration disableByDevConOverride =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertFalse(disableByDevConOverride.isBpfOffloadEnabled());
- }
- }
-
- @Test
- public void testNewDhcpServerDisabled() {
- when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
- true);
- doReturn("false").when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
-
- final TetheringConfiguration enableByRes =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(enableByRes.enableLegacyDhcpServer);
-
- when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
- false);
- doReturn("true").when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
-
- final TetheringConfiguration enableByDevConfig =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(enableByDevConfig.enableLegacyDhcpServer);
- }
-
- @Test
- public void testNewDhcpServerEnabled() {
- when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
- false);
- doReturn("false").when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
-
- final TetheringConfiguration cfg =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
-
- assertFalse(cfg.enableLegacyDhcpServer);
- }
-
- @Test
- public void testOffloadIntervalByResource() {
- final TetheringConfiguration intervalByDefault =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertEquals(TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS,
- intervalByDefault.getOffloadPollInterval());
-
- final int[] testOverrides = {0, 3000, -1};
- for (final int override : testOverrides) {
- when(mResources.getInteger(R.integer.config_tether_offload_poll_interval)).thenReturn(
- override);
- final TetheringConfiguration overrideByRes =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertEquals(override, overrideByRes.getOffloadPollInterval());
- }
- }
-
- @Test
- public void testGetResourcesBySubId() {
- setUpResourceForSubId();
- final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(cfg.provisioningApp.length == 0);
- final int anyValidSubId = 1;
- final MockTetheringConfiguration mockCfg =
- new MockTetheringConfiguration(mMockContext, mLog, anyValidSubId);
- assertEquals(mockCfg.provisioningApp[0], PROVISIONING_APP_NAME[0]);
- assertEquals(mockCfg.provisioningApp[1], PROVISIONING_APP_NAME[1]);
- assertEquals(mockCfg.provisioningAppNoUi, PROVISIONING_NO_UI_APP_NAME);
- assertEquals(mockCfg.provisioningResponse, PROVISIONING_APP_RESPONSE);
- }
-
- private void setUpResourceForSubId() {
- when(mResourcesForSubId.getStringArray(
- R.array.config_tether_dhcp_range)).thenReturn(new String[0]);
- when(mResourcesForSubId.getStringArray(
- R.array.config_tether_usb_regexs)).thenReturn(new String[0]);
- when(mResourcesForSubId.getStringArray(
- R.array.config_tether_wifi_regexs)).thenReturn(new String[]{ "test_wlan\\d" });
- when(mResourcesForSubId.getStringArray(
- R.array.config_tether_bluetooth_regexs)).thenReturn(new String[0]);
- when(mResourcesForSubId.getIntArray(R.array.config_tether_upstream_types)).thenReturn(
- new int[0]);
- when(mResourcesForSubId.getStringArray(
- R.array.config_mobile_hotspot_provision_app)).thenReturn(PROVISIONING_APP_NAME);
- when(mResourcesForSubId.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
- .thenReturn(PROVISIONING_NO_UI_APP_NAME);
- when(mResourcesForSubId.getString(
- R.string.config_mobile_hotspot_provision_response)).thenReturn(
- PROVISIONING_APP_RESPONSE);
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt
deleted file mode 100644
index 4b6bbac0..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt
+++ /dev/null
@@ -1,381 +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.networkstack.tethering
-
-import android.app.Notification
-import android.app.NotificationManager
-import android.content.Context
-import android.content.pm.ActivityInfo
-import android.content.pm.ApplicationInfo
-import android.content.pm.PackageManager
-import android.content.pm.ResolveInfo
-import android.content.res.Resources
-import android.net.ConnectivityManager.TETHERING_WIFI
-import android.os.Handler
-import android.os.HandlerThread
-import android.os.Looper
-import android.net.NetworkCapabilities
-import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING
-import android.os.UserHandle
-import android.telephony.TelephonyManager
-import androidx.test.filters.SmallTest
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.test.BroadcastInterceptingContext
-import com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE
-import com.android.networkstack.tethering.TetheringNotificationUpdater.EVENT_SHOW_NO_UPSTREAM
-import com.android.networkstack.tethering.TetheringNotificationUpdater.NO_UPSTREAM_NOTIFICATION_ID
-import com.android.networkstack.tethering.TetheringNotificationUpdater.RESTRICTED_NOTIFICATION_ID
-import com.android.networkstack.tethering.TetheringNotificationUpdater.ROAMING_NOTIFICATION_ID
-import com.android.networkstack.tethering.TetheringNotificationUpdater.VERIZON_CARRIER_ID
-import com.android.testutils.waitForIdle
-import org.junit.After
-import org.junit.Assert.assertEquals
-import org.junit.Assert.fail
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.eq
-import org.mockito.Mock
-import org.mockito.Mockito.doReturn
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.reset
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.MockitoAnnotations
-
-const val TEST_SUBID = 1
-const val WIFI_MASK = 1 shl TETHERING_WIFI
-const val TEST_DISALLOW_TITLE = "Tether function is disallowed"
-const val TEST_DISALLOW_MESSAGE = "Please contact your admin"
-const val TEST_NO_UPSTREAM_TITLE = "Hotspot has no internet access"
-const val TEST_NO_UPSTREAM_MESSAGE = "Device cannot connect to internet."
-const val TEST_NO_UPSTREAM_BUTTON = "Turn off hotspot"
-const val TEST_ROAMING_TITLE = "Hotspot is on"
-const val TEST_ROAMING_MESSAGE = "Additional charges may apply while roaming."
-
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-class TetheringNotificationUpdaterTest {
- // lateinit used here for mocks as they need to be reinitialized between each test and the test
- // should crash if they are used before being initialized.
- @Mock private lateinit var mockContext: Context
- @Mock private lateinit var notificationManager: NotificationManager
- @Mock private lateinit var telephonyManager: TelephonyManager
- @Mock private lateinit var testResources: Resources
-
- // lateinit for these classes under test, as they should be reset to a different instance for
- // every test but should always be initialized before use (or the test should crash).
- private lateinit var context: TestContext
- private lateinit var notificationUpdater: TetheringNotificationUpdater
- private lateinit var fakeTetheringThread: HandlerThread
-
- private val ROAMING_CAPABILITIES = NetworkCapabilities()
- private val HOME_CAPABILITIES = NetworkCapabilities().addCapability(NET_CAPABILITY_NOT_ROAMING)
- private val NOTIFICATION_ICON_ID = R.drawable.stat_sys_tether_general
- private val TIMEOUT_MS = 500L
-
- private inner class TestContext(c: Context) : BroadcastInterceptingContext(c) {
- override fun createContextAsUser(user: UserHandle, flags: Int) =
- if (user == UserHandle.ALL) mockContext else this
- override fun getSystemService(name: String) =
- if (name == Context.TELEPHONY_SERVICE) telephonyManager
- else super.getSystemService(name)
- }
-
- private inner class WrappedNotificationUpdater(c: Context, looper: Looper)
- : TetheringNotificationUpdater(c, looper) {
- override fun getResourcesForSubId(c: Context, subId: Int) =
- if (subId == TEST_SUBID) testResources else super.getResourcesForSubId(c, subId)
- }
-
- private fun setupResources() {
- doReturn(5).`when`(testResources)
- .getInteger(R.integer.delay_to_show_no_upstream_after_no_backhaul)
- doReturn(true).`when`(testResources)
- .getBoolean(R.bool.config_upstream_roaming_notification)
- doReturn(TEST_DISALLOW_TITLE).`when`(testResources)
- .getString(R.string.disable_tether_notification_title)
- doReturn(TEST_DISALLOW_MESSAGE).`when`(testResources)
- .getString(R.string.disable_tether_notification_message)
- doReturn(TEST_NO_UPSTREAM_TITLE).`when`(testResources)
- .getString(R.string.no_upstream_notification_title)
- doReturn(TEST_NO_UPSTREAM_MESSAGE).`when`(testResources)
- .getString(R.string.no_upstream_notification_message)
- doReturn(TEST_NO_UPSTREAM_BUTTON).`when`(testResources)
- .getString(R.string.no_upstream_notification_disable_button)
- doReturn(TEST_ROAMING_TITLE).`when`(testResources)
- .getString(R.string.upstream_roaming_notification_title)
- doReturn(TEST_ROAMING_MESSAGE).`when`(testResources)
- .getString(R.string.upstream_roaming_notification_message)
- }
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
- context = TestContext(InstrumentationRegistry.getInstrumentation().context)
- doReturn(notificationManager).`when`(mockContext)
- .getSystemService(Context.NOTIFICATION_SERVICE)
- fakeTetheringThread = HandlerThread(this::class.java.simpleName)
- fakeTetheringThread.start()
- notificationUpdater = WrappedNotificationUpdater(context, fakeTetheringThread.looper)
- setupResources()
- }
-
- @After
- fun tearDown() {
- fakeTetheringThread.quitSafely()
- }
-
- private fun Notification.title() = this.extras.getString(Notification.EXTRA_TITLE)
- private fun Notification.text() = this.extras.getString(Notification.EXTRA_TEXT)
-
- private fun verifyNotification(iconId: Int, title: String, text: String, id: Int) {
- verify(notificationManager, never()).cancel(any(), eq(id))
-
- val notificationCaptor = ArgumentCaptor.forClass(Notification::class.java)
- verify(notificationManager, times(1))
- .notify(any(), eq(id), notificationCaptor.capture())
-
- val notification = notificationCaptor.getValue()
- assertEquals(iconId, notification.smallIcon.resId)
- assertEquals(title, notification.title())
- assertEquals(text, notification.text())
-
- reset(notificationManager)
- }
-
- private fun verifyNotificationCancelled(
- notificationIds: List<Int>,
- resetAfterVerified: Boolean = true
- ) {
- notificationIds.forEach {
- verify(notificationManager, times(1)).cancel(any(), eq(it))
- }
- if (resetAfterVerified) reset(notificationManager)
- }
-
- @Test
- fun testRestrictedNotification() {
- // Set test sub id.
- notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
-
- // User restrictions on. Show restricted notification.
- notificationUpdater.notifyTetheringDisabledByRestriction()
- verifyNotification(NOTIFICATION_ICON_ID, TEST_DISALLOW_TITLE, TEST_DISALLOW_MESSAGE,
- RESTRICTED_NOTIFICATION_ID)
-
- // User restrictions off. Clear notification.
- notificationUpdater.tetheringRestrictionLifted()
- verifyNotificationCancelled(listOf(RESTRICTED_NOTIFICATION_ID))
-
- // No downstream.
- notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
- verifyZeroInteractions(notificationManager)
-
- // User restrictions on again. Show restricted notification.
- notificationUpdater.notifyTetheringDisabledByRestriction()
- verifyNotification(NOTIFICATION_ICON_ID, TEST_DISALLOW_TITLE, TEST_DISALLOW_MESSAGE,
- RESTRICTED_NOTIFICATION_ID)
- }
-
- val MAX_BACKOFF_MS = 200L
- /**
- * Waits for all messages, including delayed ones, to be processed.
- *
- * This will wait until the handler has no more messages to be processed including
- * delayed ones, or the timeout has expired. It uses an exponential backoff strategy
- * to wait longer and longer to consume less CPU, with the max granularity being
- * MAX_BACKOFF_MS.
- *
- * @return true if all messages have been processed including delayed ones, false if timeout
- *
- * TODO: Move this method to com.android.testutils.HandlerUtils.kt.
- */
- private fun Handler.waitForDelayedMessage(what: Int?, timeoutMs: Long) {
- fun hasMatchingMessages() =
- if (what == null) hasMessagesOrCallbacks() else hasMessages(what)
- val expiry = System.currentTimeMillis() + timeoutMs
- var delay = 5L
- while (System.currentTimeMillis() < expiry && hasMatchingMessages()) {
- // None of Handler, Looper, Message and MessageQueue expose any way to retrieve
- // the time when the next (let alone the last) message will be processed, so
- // short of examining the internals with reflection sleep() is the only solution.
- Thread.sleep(delay)
- delay = (delay * 2)
- .coerceAtMost(expiry - System.currentTimeMillis())
- .coerceAtMost(MAX_BACKOFF_MS)
- }
-
- val timeout = expiry - System.currentTimeMillis()
- if (timeout <= 0) fail("Delayed message did not process yet after ${timeoutMs}ms")
- waitForIdle(timeout)
- }
-
- @Test
- fun testNoUpstreamNotification() {
- // Set test sub id.
- notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
-
- // Wifi downstream.
- notificationUpdater.onDownstreamChanged(WIFI_MASK)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
-
- // There is no upstream. Show no upstream notification.
- notificationUpdater.onUpstreamCapabilitiesChanged(null)
- notificationUpdater.handler.waitForDelayedMessage(EVENT_SHOW_NO_UPSTREAM, TIMEOUT_MS)
- verifyNotification(NOTIFICATION_ICON_ID, TEST_NO_UPSTREAM_TITLE, TEST_NO_UPSTREAM_MESSAGE,
- NO_UPSTREAM_NOTIFICATION_ID)
-
- // Same capabilities changed. Nothing happened.
- notificationUpdater.onUpstreamCapabilitiesChanged(null)
- verifyZeroInteractions(notificationManager)
-
- // Upstream come back. Clear no upstream notification.
- notificationUpdater.onUpstreamCapabilitiesChanged(HOME_CAPABILITIES)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID))
-
- // No upstream again. Show no upstream notification.
- notificationUpdater.onUpstreamCapabilitiesChanged(null)
- notificationUpdater.handler.waitForDelayedMessage(EVENT_SHOW_NO_UPSTREAM, TIMEOUT_MS)
- verifyNotification(NOTIFICATION_ICON_ID, TEST_NO_UPSTREAM_TITLE, TEST_NO_UPSTREAM_MESSAGE,
- NO_UPSTREAM_NOTIFICATION_ID)
-
- // No downstream.
- notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
-
- // Wifi downstream and home capabilities.
- notificationUpdater.onDownstreamChanged(WIFI_MASK)
- notificationUpdater.onUpstreamCapabilitiesChanged(HOME_CAPABILITIES)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
-
- // Set R.integer.delay_to_show_no_upstream_after_no_backhaul to -1 and change to no upstream
- // again. Don't put up no upstream notification.
- doReturn(-1).`when`(testResources)
- .getInteger(R.integer.delay_to_show_no_upstream_after_no_backhaul)
- notificationUpdater.onUpstreamCapabilitiesChanged(null)
- notificationUpdater.handler.waitForDelayedMessage(EVENT_SHOW_NO_UPSTREAM, TIMEOUT_MS)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID))
- }
-
- @Test
- fun testGetResourcesForSubId() {
- doReturn(telephonyManager).`when`(telephonyManager).createForSubscriptionId(anyInt())
- doReturn(1234).`when`(telephonyManager).getSimCarrierId()
- doReturn("000000").`when`(telephonyManager).getSimOperator()
-
- val subId = -2 // Use invalid subId to avoid getting resource from cache or real subId.
- val config = context.resources.configuration
- var res = notificationUpdater.getResourcesForSubId(context, subId)
- assertEquals(config.mcc, res.configuration.mcc)
- assertEquals(config.mnc, res.configuration.mnc)
-
- doReturn(VERIZON_CARRIER_ID).`when`(telephonyManager).getSimCarrierId()
- res = notificationUpdater.getResourcesForSubId(context, subId)
- assertEquals(config.mcc, res.configuration.mcc)
- assertEquals(config.mnc, res.configuration.mnc)
-
- doReturn("20404").`when`(telephonyManager).getSimOperator()
- res = notificationUpdater.getResourcesForSubId(context, subId)
- assertEquals(311, res.configuration.mcc)
- assertEquals(480, res.configuration.mnc)
- }
-
- @Test
- fun testRoamingNotification() {
- // Set test sub id.
- notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
-
- // Wifi downstream.
- notificationUpdater.onDownstreamChanged(WIFI_MASK)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
-
- // Upstream capabilities changed to roaming state. Show roaming notification.
- notificationUpdater.onUpstreamCapabilitiesChanged(ROAMING_CAPABILITIES)
- verifyNotification(NOTIFICATION_ICON_ID, TEST_ROAMING_TITLE, TEST_ROAMING_MESSAGE,
- ROAMING_NOTIFICATION_ID)
-
- // Same capabilities change. Nothing happened.
- notificationUpdater.onUpstreamCapabilitiesChanged(ROAMING_CAPABILITIES)
- verifyZeroInteractions(notificationManager)
-
- // Upstream capabilities changed to home state. Clear roaming notification.
- notificationUpdater.onUpstreamCapabilitiesChanged(HOME_CAPABILITIES)
- verifyNotificationCancelled(listOf(ROAMING_NOTIFICATION_ID))
-
- // Upstream capabilities changed to roaming state again. Show roaming notification.
- notificationUpdater.onUpstreamCapabilitiesChanged(ROAMING_CAPABILITIES)
- verifyNotification(NOTIFICATION_ICON_ID, TEST_ROAMING_TITLE, TEST_ROAMING_MESSAGE,
- ROAMING_NOTIFICATION_ID)
-
- // No upstream. Clear roaming notification and show no upstream notification.
- notificationUpdater.onUpstreamCapabilitiesChanged(null)
- notificationUpdater.handler.waitForDelayedMessage(EVENT_SHOW_NO_UPSTREAM, TIMEOUT_MS)
- verifyNotificationCancelled(listOf(ROAMING_NOTIFICATION_ID), false)
- verifyNotification(NOTIFICATION_ICON_ID, TEST_NO_UPSTREAM_TITLE, TEST_NO_UPSTREAM_MESSAGE,
- NO_UPSTREAM_NOTIFICATION_ID)
-
- // No downstream.
- notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
-
- // Wifi downstream again.
- notificationUpdater.onDownstreamChanged(WIFI_MASK)
- notificationUpdater.handler.waitForDelayedMessage(EVENT_SHOW_NO_UPSTREAM, TIMEOUT_MS)
- verifyNotificationCancelled(listOf(ROAMING_NOTIFICATION_ID), false)
- verifyNotification(NOTIFICATION_ICON_ID, TEST_NO_UPSTREAM_TITLE, TEST_NO_UPSTREAM_MESSAGE,
- NO_UPSTREAM_NOTIFICATION_ID)
-
- // Set R.bool.config_upstream_roaming_notification to false and change upstream
- // network to roaming state again. No roaming notification.
- doReturn(false).`when`(testResources)
- .getBoolean(R.bool.config_upstream_roaming_notification)
- notificationUpdater.onUpstreamCapabilitiesChanged(ROAMING_CAPABILITIES)
- verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
- }
-
- @Test
- fun testGetSettingsPackageName() {
- val defaultSettingsPackageName = "com.android.settings"
- val testSettingsPackageName = "com.android.test.settings"
- val pm = mock(PackageManager::class.java)
- doReturn(null).`when`(pm).resolveActivity(any(), anyInt())
- assertEquals(defaultSettingsPackageName,
- TetheringNotificationUpdater.getSettingsPackageName(pm))
-
- val resolveInfo = ResolveInfo().apply {
- activityInfo = ActivityInfo().apply {
- name = "test"
- applicationInfo = ApplicationInfo().apply {
- packageName = testSettingsPackageName
- }
- }
- }
- doReturn(resolveInfo).`when`(pm).resolveActivity(any(), anyInt())
- assertEquals(testSettingsPackageName,
- TetheringNotificationUpdater.getSettingsPackageName(pm))
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
deleted file mode 100644
index 22d894b..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
+++ /dev/null
@@ -1,473 +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.networkstack.tethering;
-
-import static android.Manifest.permission.ACCESS_NETWORK_STATE;
-import static android.Manifest.permission.TETHER_PRIVILEGED;
-import static android.Manifest.permission.UPDATE_APP_OPS_STATS;
-import static android.Manifest.permission.WRITE_SETTINGS;
-import static android.net.TetheringManager.TETHERING_WIFI;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
-import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.UiAutomation;
-import android.content.Intent;
-import android.net.IIntResultListener;
-import android.net.ITetheringConnector;
-import android.net.ITetheringEventCallback;
-import android.net.TetheringRequestParcel;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.ResultReceiver;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.rule.ServiceTestRule;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.networkstack.tethering.MockTetheringService.MockTetheringConnector;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class TetheringServiceTest {
- private static final String TEST_IFACE_NAME = "test_wlan0";
- private static final String TEST_CALLER_PKG = "com.android.shell";
- @Mock private ITetheringEventCallback mITetheringEventCallback;
- @Rule public ServiceTestRule mServiceTestRule;
- private Tethering mTethering;
- private Intent mMockServiceIntent;
- private ITetheringConnector mTetheringConnector;
- private UiAutomation mUiAutomation;
-
- private class TestTetheringResult extends IIntResultListener.Stub {
- private int mResult = -1; // Default value that does not match any result code.
- @Override
- public void onResult(final int resultCode) {
- mResult = resultCode;
- }
-
- public void assertResult(final int expected) {
- assertEquals(expected, mResult);
- }
- }
-
- private class MyResultReceiver extends ResultReceiver {
- MyResultReceiver(Handler handler) {
- super(handler);
- }
- private int mResult = -1; // Default value that does not match any result code.
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- mResult = resultCode;
- }
-
- public void assertResult(int expected) {
- assertEquals(expected, mResult);
- }
- }
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mUiAutomation =
- InstrumentationRegistry.getInstrumentation().getUiAutomation();
- mServiceTestRule = new ServiceTestRule();
- mMockServiceIntent = new Intent(
- InstrumentationRegistry.getTargetContext(),
- MockTetheringService.class);
- final MockTetheringConnector mockConnector =
- (MockTetheringConnector) mServiceTestRule.bindService(mMockServiceIntent);
- mTetheringConnector = mockConnector.getTetheringConnector();
- final MockTetheringService service = mockConnector.getService();
- mTethering = service.getTethering();
- }
-
- @After
- public void tearDown() throws Exception {
- mServiceTestRule.unbindService();
- mUiAutomation.dropShellPermissionIdentity();
- }
-
- private interface TestTetheringCall {
- void runTetheringCall(TestTetheringResult result) throws Exception;
- }
-
- private void runAsNoPermission(final TestTetheringCall test) throws Exception {
- runTetheringCall(test, new String[0]);
- }
-
- private void runAsTetherPrivileged(final TestTetheringCall test) throws Exception {
- runTetheringCall(test, TETHER_PRIVILEGED);
- }
-
- private void runAsAccessNetworkState(final TestTetheringCall test) throws Exception {
- runTetheringCall(test, ACCESS_NETWORK_STATE);
- }
-
- private void runAsWriteSettings(final TestTetheringCall test) throws Exception {
- runTetheringCall(test, WRITE_SETTINGS, UPDATE_APP_OPS_STATS);
- }
-
- private void runTetheringCall(final TestTetheringCall test, String... permissions)
- throws Exception {
- if (permissions.length > 0) mUiAutomation.adoptShellPermissionIdentity(permissions);
- try {
- when(mTethering.isTetheringSupported()).thenReturn(true);
- test.runTetheringCall(new TestTetheringResult());
- } finally {
- mUiAutomation.dropShellPermissionIdentity();
- }
- }
-
- private void verifyNoMoreInteractionsForTethering() {
- verifyNoMoreInteractions(mTethering);
- verifyNoMoreInteractions(mITetheringEventCallback);
- reset(mTethering, mITetheringEventCallback);
- }
-
- private void runTether(final TestTetheringResult result) throws Exception {
- when(mTethering.tether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
- mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, result);
- verify(mTethering).isTetheringSupported();
- verify(mTethering).tether(TEST_IFACE_NAME);
- result.assertResult(TETHER_ERROR_NO_ERROR);
- }
-
- @Test
- public void testTether() throws Exception {
- runAsNoPermission((result) -> {
- mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, result);
- verify(mTethering).isTetherProvisioningRequired();
- result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsTetherPrivileged((result) -> {
- runTether(result);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsWriteSettings((result) -> {
- runTether(result);
- verify(mTethering).isTetherProvisioningRequired();
- verifyNoMoreInteractionsForTethering();
- });
- }
-
- private void runUnTether(final TestTetheringResult result) throws Exception {
- when(mTethering.untether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
- mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, result);
- verify(mTethering).isTetheringSupported();
- verify(mTethering).untether(TEST_IFACE_NAME);
- result.assertResult(TETHER_ERROR_NO_ERROR);
- }
-
- @Test
- public void testUntether() throws Exception {
- runAsNoPermission((result) -> {
- mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, result);
- verify(mTethering).isTetherProvisioningRequired();
- result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsTetherPrivileged((result) -> {
- runUnTether(result);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsWriteSettings((result) -> {
- runUnTether(result);
- verify(mTethering).isTetherProvisioningRequired();
- verifyNoMoreInteractionsForTethering();
- });
- }
-
- private void runSetUsbTethering(final TestTetheringResult result) throws Exception {
- when(mTethering.setUsbTethering(true /* enable */)).thenReturn(TETHER_ERROR_NO_ERROR);
- mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG, result);
- verify(mTethering).isTetheringSupported();
- verify(mTethering).setUsbTethering(true /* enable */);
- result.assertResult(TETHER_ERROR_NO_ERROR);
- }
-
- @Test
- public void testSetUsbTethering() throws Exception {
- runAsNoPermission((result) -> {
- mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG, result);
- verify(mTethering).isTetherProvisioningRequired();
- result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsTetherPrivileged((result) -> {
- runSetUsbTethering(result);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsWriteSettings((result) -> {
- runSetUsbTethering(result);
- verify(mTethering).isTetherProvisioningRequired();
- verifyNoMoreInteractionsForTethering();
- });
-
- }
-
- private void runStartTethering(final TestTetheringResult result,
- final TetheringRequestParcel request) throws Exception {
- mTetheringConnector.startTethering(request, TEST_CALLER_PKG, result);
- verify(mTethering).isTetheringSupported();
- verify(mTethering).startTethering(eq(request), eq(result));
- }
-
- @Test
- public void testStartTethering() throws Exception {
- final TetheringRequestParcel request = new TetheringRequestParcel();
- request.tetheringType = TETHERING_WIFI;
-
- runAsNoPermission((result) -> {
- mTetheringConnector.startTethering(request, TEST_CALLER_PKG, result);
- verify(mTethering).isTetherProvisioningRequired();
- result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsTetherPrivileged((result) -> {
- runStartTethering(result, request);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsWriteSettings((result) -> {
- runStartTethering(result, request);
- verify(mTethering).isTetherProvisioningRequired();
- verifyNoMoreInteractionsForTethering();
- });
- }
-
- private void runStartTetheringAndVerifyNoPermission(final TestTetheringResult result)
- throws Exception {
- final TetheringRequestParcel request = new TetheringRequestParcel();
- request.tetheringType = TETHERING_WIFI;
- request.exemptFromEntitlementCheck = true;
- mTetheringConnector.startTethering(request, TEST_CALLER_PKG, result);
- result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
- verifyNoMoreInteractionsForTethering();
- }
-
- @Test
- public void testFailToBypassEntitlementWithoutNeworkStackPermission() throws Exception {
- final TetheringRequestParcel request = new TetheringRequestParcel();
- request.tetheringType = TETHERING_WIFI;
- request.exemptFromEntitlementCheck = true;
-
- runAsNoPermission((result) -> {
- runStartTetheringAndVerifyNoPermission(result);
- });
-
- runAsTetherPrivileged((result) -> {
- runStartTetheringAndVerifyNoPermission(result);
- });
-
- runAsWriteSettings((result) -> {
- runStartTetheringAndVerifyNoPermission(result);
- });
- }
-
- private void runStopTethering(final TestTetheringResult result) throws Exception {
- mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, result);
- verify(mTethering).isTetheringSupported();
- verify(mTethering).stopTethering(TETHERING_WIFI);
- result.assertResult(TETHER_ERROR_NO_ERROR);
- }
-
- @Test
- public void testStopTethering() throws Exception {
- runAsNoPermission((result) -> {
- mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, result);
- verify(mTethering).isTetherProvisioningRequired();
- result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsTetherPrivileged((result) -> {
- runStopTethering(result);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsWriteSettings((result) -> {
- runStopTethering(result);
- verify(mTethering).isTetherProvisioningRequired();
- verifyNoMoreInteractionsForTethering();
- });
- }
-
- private void runRequestLatestTetheringEntitlementResult() throws Exception {
- final MyResultReceiver result = new MyResultReceiver(null);
- mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
- true /* showEntitlementUi */, TEST_CALLER_PKG);
- verify(mTethering).isTetheringSupported();
- verify(mTethering).requestLatestTetheringEntitlementResult(eq(TETHERING_WIFI),
- eq(result), eq(true) /* showEntitlementUi */);
- }
-
- @Test
- public void testRequestLatestTetheringEntitlementResult() throws Exception {
- // Run as no permission.
- final MyResultReceiver result = new MyResultReceiver(null);
- mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
- true /* showEntitlementUi */, TEST_CALLER_PKG);
- verify(mTethering).isTetherProvisioningRequired();
- result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
- verifyNoMoreInteractions(mTethering);
-
- runAsTetherPrivileged((none) -> {
- runRequestLatestTetheringEntitlementResult();
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsWriteSettings((none) -> {
- runRequestLatestTetheringEntitlementResult();
- verify(mTethering).isTetherProvisioningRequired();
- verifyNoMoreInteractionsForTethering();
- });
- }
-
- private void runRegisterTetheringEventCallback() throws Exception {
- mTetheringConnector.registerTetheringEventCallback(mITetheringEventCallback,
- TEST_CALLER_PKG);
- verify(mTethering).registerTetheringEventCallback(eq(mITetheringEventCallback));
- }
-
- @Test
- public void testRegisterTetheringEventCallback() throws Exception {
- runAsNoPermission((result) -> {
- mTetheringConnector.registerTetheringEventCallback(mITetheringEventCallback,
- TEST_CALLER_PKG);
- verify(mITetheringEventCallback).onCallbackStopped(
- TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsTetherPrivileged((none) -> {
- runRegisterTetheringEventCallback();
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsAccessNetworkState((none) -> {
- runRegisterTetheringEventCallback();
- verifyNoMoreInteractionsForTethering();
- });
- }
-
- private void runUnregisterTetheringEventCallback() throws Exception {
- mTetheringConnector.unregisterTetheringEventCallback(mITetheringEventCallback,
- TEST_CALLER_PKG);
- verify(mTethering).unregisterTetheringEventCallback(eq(mITetheringEventCallback));
- }
-
- @Test
- public void testUnregisterTetheringEventCallback() throws Exception {
- runAsNoPermission((result) -> {
- mTetheringConnector.unregisterTetheringEventCallback(mITetheringEventCallback,
- TEST_CALLER_PKG);
- verify(mITetheringEventCallback).onCallbackStopped(
- TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsTetherPrivileged((none) -> {
- runUnregisterTetheringEventCallback();
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsAccessNetworkState((none) -> {
- runUnregisterTetheringEventCallback();
- verifyNoMoreInteractionsForTethering();
- });
- }
-
- private void runStopAllTethering(final TestTetheringResult result) throws Exception {
- mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, result);
- verify(mTethering).isTetheringSupported();
- verify(mTethering).untetherAll();
- result.assertResult(TETHER_ERROR_NO_ERROR);
- }
-
- @Test
- public void testStopAllTethering() throws Exception {
- runAsNoPermission((result) -> {
- mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, result);
- verify(mTethering).isTetherProvisioningRequired();
- result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsTetherPrivileged((result) -> {
- runStopAllTethering(result);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsWriteSettings((result) -> {
- runStopAllTethering(result);
- verify(mTethering).isTetherProvisioningRequired();
- verifyNoMoreInteractionsForTethering();
- });
- }
-
- private void runIsTetheringSupported(final TestTetheringResult result) throws Exception {
- mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, result);
- verify(mTethering).isTetheringSupported();
- result.assertResult(TETHER_ERROR_NO_ERROR);
- }
-
- @Test
- public void testIsTetheringSupported() throws Exception {
- runAsNoPermission((result) -> {
- mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, result);
- verify(mTethering).isTetherProvisioningRequired();
- result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsTetherPrivileged((result) -> {
- runIsTetheringSupported(result);
- verifyNoMoreInteractionsForTethering();
- });
-
- runAsWriteSettings((result) -> {
- runIsTetheringSupported(result);
- verify(mTethering).isTetherProvisioningRequired();
- verifyNoMoreInteractionsForTethering();
- });
- }
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
deleted file mode 100644
index 64538c7..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ /dev/null
@@ -1,1986 +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 com.android.networkstack.tethering;
-
-import static android.content.pm.PackageManager.GET_ACTIVITIES;
-import static android.hardware.usb.UsbManager.USB_CONFIGURED;
-import static android.hardware.usb.UsbManager.USB_CONNECTED;
-import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM;
-import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
-import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
-import static android.net.RouteInfo.RTN_UNICAST;
-import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED;
-import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY;
-import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER;
-import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER;
-import static android.net.TetheringManager.TETHERING_ETHERNET;
-import static android.net.TetheringManager.TETHERING_NCM;
-import static android.net.TetheringManager.TETHERING_USB;
-import static android.net.TetheringManager.TETHERING_WIFI;
-import static android.net.TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
-import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
-import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
-import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
-import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
-import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
-import static com.android.networkstack.tethering.UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.notNull;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.usage.NetworkStatsManager;
-import android.bluetooth.BluetoothAdapter;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.hardware.usb.UsbManager;
-import android.net.ConnectivityManager;
-import android.net.EthernetManager;
-import android.net.EthernetManager.TetheredInterfaceCallback;
-import android.net.EthernetManager.TetheredInterfaceRequest;
-import android.net.IIntResultListener;
-import android.net.INetd;
-import android.net.ITetheringEventCallback;
-import android.net.InetAddresses;
-import android.net.InterfaceConfigurationParcel;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.MacAddress;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.RouteInfo;
-import android.net.TetherStatesParcel;
-import android.net.TetheredClient;
-import android.net.TetheringCallbackStartedParcel;
-import android.net.TetheringConfigurationParcel;
-import android.net.TetheringRequestParcel;
-import android.net.dhcp.DhcpServerCallbacks;
-import android.net.dhcp.DhcpServingParamsParcel;
-import android.net.dhcp.IDhcpServer;
-import android.net.ip.IpNeighborMonitor;
-import android.net.ip.IpServer;
-import android.net.ip.RouterAdvertisementDaemon;
-import android.net.util.InterfaceParams;
-import android.net.util.NetworkConstants;
-import android.net.util.SharedLog;
-import android.net.wifi.SoftApConfiguration;
-import android.net.wifi.WifiManager;
-import android.net.wifi.p2p.WifiP2pGroup;
-import android.net.wifi.p2p.WifiP2pInfo;
-import android.net.wifi.p2p.WifiP2pManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.test.TestLooper;
-import android.provider.Settings;
-import android.telephony.CarrierConfigManager;
-import android.telephony.PhoneStateListener;
-import android.telephony.TelephonyManager;
-import android.test.mock.MockContentResolver;
-
-import androidx.annotation.NonNull;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.test.BroadcastInterceptingContext;
-import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.testutils.MiscAssertsKt;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Vector;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class TetheringTest {
- private static final int IFINDEX_OFFSET = 100;
-
- private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0";
- private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0";
- private static final String TEST_USB_IFNAME = "test_rndis0";
- private static final String TEST_WIFI_IFNAME = "test_wlan0";
- private static final String TEST_WLAN_IFNAME = "test_wlan1";
- private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
- private static final String TEST_NCM_IFNAME = "test_ncm0";
- private static final String TEST_ETH_IFNAME = "test_eth0";
- private static final String TETHERING_NAME = "Tethering";
- private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
- private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
-
- private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
-
- @Mock private ApplicationInfo mApplicationInfo;
- @Mock private Context mContext;
- @Mock private NetworkStatsManager mStatsManager;
- @Mock private OffloadHardwareInterface mOffloadHardwareInterface;
- @Mock private OffloadHardwareInterface.ForwardedStats mForwardedStats;
- @Mock private Resources mResources;
- @Mock private TelephonyManager mTelephonyManager;
- @Mock private UsbManager mUsbManager;
- @Mock private WifiManager mWifiManager;
- @Mock private CarrierConfigManager mCarrierConfigManager;
- @Mock private UpstreamNetworkMonitor mUpstreamNetworkMonitor;
- @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator;
- @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon;
- @Mock private IpNeighborMonitor mIpNeighborMonitor;
- @Mock private IDhcpServer mDhcpServer;
- @Mock private INetd mNetd;
- @Mock private UserManager mUserManager;
- @Mock private NetworkRequest mNetworkRequest;
- @Mock private ConnectivityManager mCm;
- @Mock private EthernetManager mEm;
- @Mock private TetheringNotificationUpdater mNotificationUpdater;
- @Mock private BpfCoordinator mBpfCoordinator;
- @Mock private PackageManager mPackageManager;
-
- private final MockIpServerDependencies mIpServerDependencies =
- spy(new MockIpServerDependencies());
- private final MockTetheringDependencies mTetheringDependencies =
- new MockTetheringDependencies();
-
- // Like so many Android system APIs, these cannot be mocked because it is marked final.
- // We have to use the real versions.
- private final PersistableBundle mCarrierConfig = new PersistableBundle();
- private final TestLooper mLooper = new TestLooper();
-
- private Vector<Intent> mIntents;
- private BroadcastInterceptingContext mServiceContext;
- private MockContentResolver mContentResolver;
- private BroadcastReceiver mBroadcastReceiver;
- private Tethering mTethering;
- private PhoneStateListener mPhoneStateListener;
- private InterfaceConfigurationParcel mInterfaceConfiguration;
- private TetheringConfiguration mConfig;
- private EntitlementManager mEntitleMgr;
- private OffloadController mOffloadCtrl;
-
- private class TestContext extends BroadcastInterceptingContext {
- TestContext(Context base) {
- super(base);
- }
-
- @Override
- public ApplicationInfo getApplicationInfo() {
- return mApplicationInfo;
- }
-
- @Override
- public ContentResolver getContentResolver() {
- return mContentResolver;
- }
-
- @Override
- public String getPackageName() {
- return "TetheringTest";
- }
-
- @Override
- public Resources getResources() {
- return mResources;
- }
-
- @Override
- public Object getSystemService(String name) {
- if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
- if (Context.USB_SERVICE.equals(name)) return mUsbManager;
- if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
- if (Context.USER_SERVICE.equals(name)) return mUserManager;
- if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager;
- if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
- if (Context.ETHERNET_SERVICE.equals(name)) return mEm;
- return super.getSystemService(name);
- }
-
- @Override
- public PackageManager getPackageManager() {
- return mPackageManager;
- }
-
- @Override
- public String getSystemServiceName(Class<?> serviceClass) {
- if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
- return super.getSystemServiceName(serviceClass);
- }
- }
-
- public class MockIpServerDependencies extends IpServer.Dependencies {
- @Override
- public RouterAdvertisementDaemon getRouterAdvertisementDaemon(
- InterfaceParams ifParams) {
- return mRouterAdvertisementDaemon;
- }
-
- @Override
- public InterfaceParams getInterfaceParams(String ifName) {
- assertTrue("Non-mocked interface " + ifName,
- ifName.equals(TEST_USB_IFNAME)
- || ifName.equals(TEST_WLAN_IFNAME)
- || ifName.equals(TEST_MOBILE_IFNAME)
- || ifName.equals(TEST_P2P_IFNAME)
- || ifName.equals(TEST_NCM_IFNAME)
- || ifName.equals(TEST_ETH_IFNAME));
- final String[] ifaces = new String[] {
- TEST_USB_IFNAME, TEST_WLAN_IFNAME, TEST_MOBILE_IFNAME, TEST_P2P_IFNAME,
- TEST_NCM_IFNAME, TEST_ETH_IFNAME};
- return new InterfaceParams(ifName, ArrayUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET,
- MacAddress.ALL_ZEROS_ADDRESS);
- }
-
- @Override
- public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
- DhcpServerCallbacks cb) {
- new Thread(() -> {
- try {
- cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
- } catch (RemoteException e) {
- fail(e.getMessage());
- }
- }).run();
- }
-
- public IpNeighborMonitor getIpNeighborMonitor(Handler h, SharedLog l,
- IpNeighborMonitor.NeighborEventConsumer c) {
- return mIpNeighborMonitor;
- }
- }
-
- // MyTetheringConfiguration is used to override static method for testing.
- private class MyTetheringConfiguration extends TetheringConfiguration {
- MyTetheringConfiguration(Context ctx, SharedLog log, int id) {
- super(ctx, log, id);
- }
-
- @Override
- protected String getDeviceConfigProperty(final String name) {
- return null;
- }
-
- @Override
- protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
- return mResources;
- }
- }
-
- public class MockTetheringDependencies extends TetheringDependencies {
- StateMachine mUpstreamNetworkMonitorMasterSM;
- ArrayList<IpServer> mIpv6CoordinatorNotifyList;
-
- public void reset() {
- mUpstreamNetworkMonitorMasterSM = null;
- mIpv6CoordinatorNotifyList = null;
- }
-
- @Override
- public BpfCoordinator getBpfCoordinator(
- BpfCoordinator.Dependencies deps) {
- return mBpfCoordinator;
- }
-
- @Override
- public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
- return mOffloadHardwareInterface;
- }
-
- @Override
- public OffloadController getOffloadController(Handler h, SharedLog log,
- OffloadController.Dependencies deps) {
- mOffloadCtrl = spy(super.getOffloadController(h, log, deps));
- // Return real object here instead of mock because
- // testReportFailCallbackIfOffloadNotSupported depend on real OffloadController object.
- return mOffloadCtrl;
- }
-
- @Override
- public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
- StateMachine target, SharedLog log, int what) {
- mUpstreamNetworkMonitorMasterSM = target;
- return mUpstreamNetworkMonitor;
- }
-
- @Override
- public IPv6TetheringCoordinator getIPv6TetheringCoordinator(
- ArrayList<IpServer> notifyList, SharedLog log) {
- mIpv6CoordinatorNotifyList = notifyList;
- return mIPv6TetheringCoordinator;
- }
-
- @Override
- public IpServer.Dependencies getIpServerDependencies() {
- return mIpServerDependencies;
- }
-
- @Override
- public NetworkRequest getDefaultNetworkRequest() {
- return mNetworkRequest;
- }
-
- @Override
- public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log,
- Runnable callback) {
- mEntitleMgr = spy(super.getEntitlementManager(ctx, h, log, callback));
- return mEntitleMgr;
- }
-
- @Override
- public boolean isTetheringSupported() {
- return true;
- }
-
- @Override
- public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
- int subId) {
- mConfig = spy(new MyTetheringConfiguration(ctx, log, subId));
- return mConfig;
- }
-
- @Override
- public INetd getINetd(Context context) {
- return mNetd;
- }
-
- @Override
- public Looper getTetheringLooper() {
- return mLooper.getLooper();
- }
-
- @Override
- public Context getContext() {
- return mServiceContext;
- }
-
- @Override
- public BluetoothAdapter getBluetoothAdapter() {
- // TODO: add test for bluetooth tethering.
- return null;
- }
-
- @Override
- public TetheringNotificationUpdater getNotificationUpdater(Context ctx, Looper looper) {
- return mNotificationUpdater;
- }
-
- @Override
- public boolean isTetheringDenied() {
- return false;
- }
- }
-
- private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4,
- boolean withIPv6, boolean with464xlat) {
- final LinkProperties prop = new LinkProperties();
- prop.setInterfaceName(TEST_MOBILE_IFNAME);
-
- if (withIPv4) {
- prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
- InetAddresses.parseNumericAddress("10.0.0.1"),
- TEST_MOBILE_IFNAME, RTN_UNICAST));
- }
-
- if (withIPv6) {
- prop.addDnsServer(InetAddresses.parseNumericAddress("2001:db8::2"));
- prop.addLinkAddress(
- new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"),
- NetworkConstants.RFC7421_PREFIX_LENGTH));
- prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
- InetAddresses.parseNumericAddress("2001:db8::1"),
- TEST_MOBILE_IFNAME, RTN_UNICAST));
- }
-
- if (with464xlat) {
- final LinkProperties stackedLink = new LinkProperties();
- stackedLink.setInterfaceName(TEST_XLAT_MOBILE_IFNAME);
- stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
- InetAddresses.parseNumericAddress("192.0.0.1"),
- TEST_XLAT_MOBILE_IFNAME, RTN_UNICAST));
-
- prop.addStackedLink(stackedLink);
- }
-
-
- final NetworkCapabilities capabilities = new NetworkCapabilities()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- return new UpstreamNetworkState(prop, capabilities, new Network(100));
- }
-
- private static UpstreamNetworkState buildMobileIPv4UpstreamState() {
- return buildMobileUpstreamState(true, false, false);
- }
-
- private static UpstreamNetworkState buildMobileIPv6UpstreamState() {
- return buildMobileUpstreamState(false, true, false);
- }
-
- private static UpstreamNetworkState buildMobileDualStackUpstreamState() {
- return buildMobileUpstreamState(true, true, false);
- }
-
- private static UpstreamNetworkState buildMobile464xlatUpstreamState() {
- return buildMobileUpstreamState(false, true, true);
- }
-
- // See FakeSettingsProvider#clearSettingsProvider() that this needs to be called before and
- // after use.
- @BeforeClass
- public static void setupOnce() {
- FakeSettingsProvider.clearSettingsProvider();
- }
-
- @AfterClass
- public static void tearDownOnce() {
- FakeSettingsProvider.clearSettingsProvider();
- }
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- when(mResources.getStringArray(R.array.config_tether_dhcp_range))
- .thenReturn(new String[0]);
- when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
- false);
- when(mNetd.interfaceGetList())
- .thenReturn(new String[] {
- TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME, TEST_P2P_IFNAME,
- TEST_NCM_IFNAME, TEST_ETH_IFNAME});
- when(mResources.getString(R.string.config_wifi_tether_enable)).thenReturn("");
- mInterfaceConfiguration = new InterfaceConfigurationParcel();
- mInterfaceConfiguration.flags = new String[0];
- when(mRouterAdvertisementDaemon.start())
- .thenReturn(true);
- initOffloadConfiguration(true /* offloadConfig */, true /* offloadControl */,
- 0 /* defaultDisabled */);
- when(mOffloadHardwareInterface.getForwardedStats(any())).thenReturn(mForwardedStats);
-
- mServiceContext = new TestContext(mContext);
- mContentResolver = new MockContentResolver(mServiceContext);
- mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
- setTetheringSupported(true /* supported */);
- mIntents = new Vector<>();
- mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- mIntents.addElement(intent);
- }
- };
- mServiceContext.registerReceiver(mBroadcastReceiver,
- new IntentFilter(ACTION_TETHER_STATE_CHANGED));
- mTethering = makeTethering();
- verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
- verify(mNetd).registerUnsolicitedEventListener(any());
- final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
- ArgumentCaptor.forClass(PhoneStateListener.class);
- verify(mTelephonyManager).listen(phoneListenerCaptor.capture(),
- eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE));
- verify(mWifiManager).registerSoftApCallback(any(), any());
- mPhoneStateListener = phoneListenerCaptor.getValue();
- }
-
- private void setTetheringSupported(final boolean supported) {
- Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED,
- supported ? 1 : 0);
- when(mUserManager.hasUserRestriction(
- UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(!supported);
- // Setup tetherable configuration.
- when(mResources.getStringArray(R.array.config_tether_usb_regexs))
- .thenReturn(new String[] { "test_rndis\\d" });
- when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
- .thenReturn(new String[]{ "test_wlan\\d" });
- when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
- .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
- when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
- .thenReturn(new String[0]);
- when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
- .thenReturn(new String[] { "test_ncm\\d" });
- when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]);
- when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
- }
-
- private void initTetheringUpstream(UpstreamNetworkState upstreamState) {
- when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
- when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
- }
-
- private Tethering makeTethering() {
- mTetheringDependencies.reset();
- return new Tethering(mTetheringDependencies);
- }
-
- private TetheringRequestParcel createTetheringRequestParcel(final int type) {
- return createTetheringRequestParcel(type, null, null, false);
- }
-
- private TetheringRequestParcel createTetheringRequestParcel(final int type,
- final LinkAddress serverAddr, final LinkAddress clientAddr, final boolean exempt) {
- final TetheringRequestParcel request = new TetheringRequestParcel();
- request.tetheringType = type;
- request.localIPv4Address = serverAddr;
- request.staticClientAddress = clientAddr;
- request.exemptFromEntitlementCheck = exempt;
- request.showProvisioningUi = false;
-
- return request;
- }
-
- @After
- public void tearDown() {
- mServiceContext.unregisterReceiver(mBroadcastReceiver);
- }
-
- private void sendWifiApStateChanged(int state) {
- final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
- intent.putExtra(EXTRA_WIFI_AP_STATE, state);
- mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
-
- private void sendWifiApStateChanged(int state, String ifname, int ipmode) {
- final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
- intent.putExtra(EXTRA_WIFI_AP_STATE, state);
- intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname);
- intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode);
- mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
-
- private static final String[] P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST = {
- android.Manifest.permission.ACCESS_FINE_LOCATION,
- android.Manifest.permission.ACCESS_WIFI_STATE
- };
-
- private void sendWifiP2pConnectionChanged(
- boolean isGroupFormed, boolean isGroupOwner, String ifname) {
- WifiP2pGroup group = null;
- WifiP2pInfo p2pInfo = new WifiP2pInfo();
- p2pInfo.groupFormed = isGroupFormed;
- if (isGroupFormed) {
- p2pInfo.isGroupOwner = isGroupOwner;
- group = mock(WifiP2pGroup.class);
- when(group.isGroupOwner()).thenReturn(isGroupOwner);
- when(group.getInterface()).thenReturn(ifname);
- }
-
- final Intent intent = mock(Intent.class);
- when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
- when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO)).thenReturn(p2pInfo);
- when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP)).thenReturn(group);
-
- mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL,
- P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST);
- }
-
- private void sendUsbBroadcast(boolean connected, boolean configured, boolean function,
- int type) {
- final Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
- intent.putExtra(USB_CONNECTED, connected);
- intent.putExtra(USB_CONFIGURED, configured);
- if (type == TETHERING_USB) {
- intent.putExtra(USB_FUNCTION_RNDIS, function);
- } else {
- intent.putExtra(USB_FUNCTION_NCM, function);
- }
- mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
-
- private void sendConfigurationChanged() {
- final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
- mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
-
- private void verifyInterfaceServingModeStarted(String ifname) throws Exception {
- verify(mNetd, times(1)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
- verify(mNetd, times(1)).tetherInterfaceAdd(ifname);
- verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, ifname);
- verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(ifname),
- anyString(), anyString());
- }
-
- private void verifyTetheringBroadcast(String ifname, String whichExtra) {
- // Verify that ifname is in the whichExtra array of the tether state changed broadcast.
- final Intent bcast = mIntents.get(0);
- assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction());
- final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra);
- assertTrue(ifnames.contains(ifname));
- mIntents.remove(bcast);
- }
-
- public void failingLocalOnlyHotspotLegacyApBroadcast(
- boolean emulateInterfaceStatusChanged) throws Exception {
- // Emulate externally-visible WifiManager effects, causing the
- // per-interface state machine to start up, and telling us that
- // hotspot mode is to be started.
- if (emulateInterfaceStatusChanged) {
- mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
- }
- sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
- mLooper.dispatchAll();
-
- // If, and only if, Tethering received an interface status changed then
- // it creates a IpServer and sends out a broadcast indicating that the
- // interface is "available".
- if (emulateInterfaceStatusChanged) {
- // There is 1 IpServer state change event: STATE_AVAILABLE
- verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
- verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
- verify(mWifiManager).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- }
- verifyNoMoreInteractions(mNetd);
- verifyNoMoreInteractions(mWifiManager);
- }
-
- private void prepareNcmTethering() {
- // Emulate startTethering(TETHERING_NCM) called
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), null);
- mLooper.dispatchAll();
- verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
-
- mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true);
- }
-
- private void prepareUsbTethering(UpstreamNetworkState upstreamState) {
- initTetheringUpstream(upstreamState);
-
- // Emulate pressing the USB tethering button in Settings UI.
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null);
- mLooper.dispatchAll();
- verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
-
- mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
- }
-
- @Test
- public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
- UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
- prepareUsbTethering(upstreamState);
-
- // This should produce no activity of any kind.
- verifyNoMoreInteractions(mNetd);
-
- // Pretend we then receive USB configured broadcast.
- sendUsbBroadcast(true, true, true, TETHERING_USB);
- mLooper.dispatchAll();
- // Now we should see the start of tethering mechanics (in this case:
- // tetherMatchingInterfaces() which starts by fetching all interfaces).
- verify(mNetd, times(1)).interfaceGetList();
-
- // UpstreamNetworkMonitor should receive selected upstream
- verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
- verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
- }
-
- @Test
- public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception {
- failingLocalOnlyHotspotLegacyApBroadcast(true);
- }
-
- @Test
- public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception {
- failingLocalOnlyHotspotLegacyApBroadcast(false);
- }
-
- public void workingLocalOnlyHotspotEnrichedApBroadcast(
- boolean emulateInterfaceStatusChanged) throws Exception {
- // Emulate externally-visible WifiManager effects, causing the
- // per-interface state machine to start up, and telling us that
- // hotspot mode is to be started.
- if (emulateInterfaceStatusChanged) {
- mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
- }
- sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
- mLooper.dispatchAll();
-
- verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
- verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
- verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
- verify(mNetd, times(1)).tetherStartWithConfiguration(any());
- verifyNoMoreInteractions(mNetd);
- verify(mWifiManager).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- verify(mWifiManager).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
- verifyNoMoreInteractions(mWifiManager);
- verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
- verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
- // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY
- verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
-
- // Emulate externally-visible WifiManager effects, when hotspot mode
- // is being torn down.
- sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
- mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
- mLooper.dispatchAll();
-
- verify(mNetd, times(1)).tetherApplyDnsInterfaces();
- verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
- verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
- // interfaceSetCfg() called once for enabling and twice disabling IPv4.
- verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
- verify(mNetd, times(1)).tetherStop();
- verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
- verify(mWifiManager, times(3)).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- verifyNoMoreInteractions(mNetd);
- verifyNoMoreInteractions(mWifiManager);
- // Asking for the last error after the per-interface state machine
- // has been reaped yields an unknown interface error.
- assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
- }
-
- /**
- * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator.
- */
- private void sendIPv6TetherUpdates(UpstreamNetworkState upstreamState) {
- // IPv6TetheringCoordinator must have been notified of downstream
- verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream(
- argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)),
- eq(IpServer.STATE_TETHERED));
-
- for (IpServer ipSrv : mTetheringDependencies.mIpv6CoordinatorNotifyList) {
- UpstreamNetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false);
- ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0,
- upstreamState.linkProperties.isIpv6Provisioned()
- ? ipv6OnlyState.linkProperties
- : null);
- }
- mLooper.dispatchAll();
- }
-
- private void runUsbTethering(UpstreamNetworkState upstreamState) {
- prepareUsbTethering(upstreamState);
- sendUsbBroadcast(true, true, true, TETHERING_USB);
- mLooper.dispatchAll();
- }
-
- @Test
- public void workingMobileUsbTethering_IPv4() throws Exception {
- UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
- runUsbTethering(upstreamState);
-
- verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
- verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
-
- sendIPv6TetherUpdates(upstreamState);
- verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
- verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
- }
-
- @Test
- public void workingMobileUsbTethering_IPv4LegacyDhcp() {
- when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
- true);
- sendConfigurationChanged();
- final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
- runUsbTethering(upstreamState);
- sendIPv6TetherUpdates(upstreamState);
-
- verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
- }
-
- @Test
- public void workingMobileUsbTethering_IPv6() throws Exception {
- UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
- runUsbTethering(upstreamState);
-
- verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
- verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
-
- sendIPv6TetherUpdates(upstreamState);
- verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
- verify(mNetd, times(1)).tetherApplyDnsInterfaces();
- }
-
- @Test
- public void workingMobileUsbTethering_DualStack() throws Exception {
- UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
- runUsbTethering(upstreamState);
-
- verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
- verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
- verify(mRouterAdvertisementDaemon, times(1)).start();
- verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
-
- sendIPv6TetherUpdates(upstreamState);
- verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
- verify(mNetd, times(1)).tetherApplyDnsInterfaces();
- }
-
- @Test
- public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
- UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState();
- runUsbTethering(upstreamState);
-
- verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
- verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
- verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
- verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
- verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
-
- sendIPv6TetherUpdates(upstreamState);
- verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
- verify(mNetd, times(1)).tetherApplyDnsInterfaces();
- }
-
- @Test
- public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
- // Setup IPv6
- UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
- runUsbTethering(upstreamState);
-
- verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
- verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
- verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
-
- // Then 464xlat comes up
- upstreamState = buildMobile464xlatUpstreamState();
- initTetheringUpstream(upstreamState);
-
- // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
- mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
- Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
- UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
- 0,
- upstreamState);
- mLooper.dispatchAll();
-
- // Forwarding is added for 464xlat
- verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
- verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
- // Forwarding was not re-added for v6 (still times(1))
- verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
- verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
- // DHCP not restarted on downstream (still times(1))
- verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
- }
-
- @Test
- public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception {
- when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
- sendConfigurationChanged();
-
- // Setup IPv6
- final UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
- runUsbTethering(upstreamState);
-
- // UpstreamNetworkMonitor should choose upstream automatically
- // (in this specific case: choose the default network).
- verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
- verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
-
- verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
- }
-
- private void runNcmTethering() {
- prepareNcmTethering();
- sendUsbBroadcast(true, true, true, TETHERING_NCM);
- mLooper.dispatchAll();
- }
-
- @Test
- public void workingNcmTethering() throws Exception {
- runNcmTethering();
-
- verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
- }
-
- @Test
- public void workingNcmTethering_LegacyDhcp() {
- when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
- true);
- sendConfigurationChanged();
- runNcmTethering();
-
- verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
- }
-
- @Test
- public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception {
- workingLocalOnlyHotspotEnrichedApBroadcast(true);
- }
-
- @Test
- public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception {
- workingLocalOnlyHotspotEnrichedApBroadcast(false);
- }
-
- // TODO: Test with and without interfaceStatusChanged().
- @Test
- public void failingWifiTetheringLegacyApBroadcast() throws Exception {
- when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
-
- // Emulate pressing the WiFi tethering button.
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
- mLooper.dispatchAll();
- verify(mWifiManager, times(1)).startTetheredHotspot(null);
- verifyNoMoreInteractions(mWifiManager);
- verifyNoMoreInteractions(mNetd);
-
- // Emulate externally-visible WifiManager effects, causing the
- // per-interface state machine to start up, and telling us that
- // tethering mode is to be started.
- mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
- sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
- mLooper.dispatchAll();
-
- // There is 1 IpServer state change event: STATE_AVAILABLE
- verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
- verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
- verify(mWifiManager).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- verifyNoMoreInteractions(mNetd);
- verifyNoMoreInteractions(mWifiManager);
- }
-
- // TODO: Test with and without interfaceStatusChanged().
- @Test
- public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
- when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
-
- // Emulate pressing the WiFi tethering button.
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
- mLooper.dispatchAll();
- verify(mWifiManager, times(1)).startTetheredHotspot(null);
- verifyNoMoreInteractions(mWifiManager);
- verifyNoMoreInteractions(mNetd);
-
- // Emulate externally-visible WifiManager effects, causing the
- // per-interface state machine to start up, and telling us that
- // tethering mode is to be started.
- mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
- sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
- mLooper.dispatchAll();
-
- verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
- verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
- verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
- verify(mNetd, times(1)).tetherStartWithConfiguration(any());
- verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
- anyString(), anyString());
- verifyNoMoreInteractions(mNetd);
- verify(mWifiManager).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- verify(mWifiManager).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
- verifyNoMoreInteractions(mWifiManager);
- verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
- verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
- // In tethering mode, in the default configuration, an explicit request
- // for a mobile network is also made.
- verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest();
- // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_TETHERED
- verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
- verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI));
-
- /////
- // We do not currently emulate any upstream being found.
- //
- // This is why there are no calls to verify mNetd.tetherAddForward() or
- // mNetd.ipfwdAddInterfaceForward().
- /////
-
- // Emulate pressing the WiFi tethering button.
- mTethering.stopTethering(TETHERING_WIFI);
- mLooper.dispatchAll();
- verify(mWifiManager, times(1)).stopSoftAp();
- verifyNoMoreInteractions(mWifiManager);
- verifyNoMoreInteractions(mNetd);
-
- // Emulate externally-visible WifiManager effects, when tethering mode
- // is being torn down.
- sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
- mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
- mLooper.dispatchAll();
-
- verify(mNetd, times(1)).tetherApplyDnsInterfaces();
- verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
- verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
- // interfaceSetCfg() called once for enabling and twice for disabling IPv4.
- verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
- verify(mNetd, times(1)).tetherStop();
- verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
- verify(mWifiManager, times(3)).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- verifyNoMoreInteractions(mNetd);
- verifyNoMoreInteractions(mWifiManager);
- // Asking for the last error after the per-interface state machine
- // has been reaped yields an unknown interface error.
- assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
- }
-
- // TODO: Test with and without interfaceStatusChanged().
- @Test
- public void failureEnablingIpForwarding() throws Exception {
- when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
- doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
-
- // Emulate pressing the WiFi tethering button.
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
- mLooper.dispatchAll();
- verify(mWifiManager, times(1)).startTetheredHotspot(null);
- verifyNoMoreInteractions(mWifiManager);
- verifyNoMoreInteractions(mNetd);
-
- // Emulate externally-visible WifiManager effects, causing the
- // per-interface state machine to start up, and telling us that
- // tethering mode is to be started.
- mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
- sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
- mLooper.dispatchAll();
-
- // We verify get/set called three times here: twice for setup and once during
- // teardown because all events happen over the course of the single
- // dispatchAll() above. Note that once the IpServer IPv4 address config
- // code is refactored the two calls during shutdown will revert to one.
- verify(mNetd, times(3)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName)));
- verify(mNetd, times(1)).tetherInterfaceAdd(TEST_WLAN_IFNAME);
- verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
- verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
- anyString(), anyString());
- verify(mWifiManager).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- verify(mWifiManager).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
- // There are 3 IpServer state change event:
- // STATE_AVAILABLE -> STATE_TETHERED -> STATE_AVAILABLE.
- verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
- verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI));
- verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
- // This is called, but will throw.
- verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
- // This never gets called because of the exception thrown above.
- verify(mNetd, times(0)).tetherStartWithConfiguration(any());
- // When the master state machine transitions to an error state it tells
- // downstream interfaces, which causes us to tell Wi-Fi about the error
- // so it can take down AP mode.
- verify(mNetd, times(1)).tetherApplyDnsInterfaces();
- verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
- verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
- verify(mWifiManager).updateInterfaceIpState(
- TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
-
- verifyNoMoreInteractions(mWifiManager);
- verifyNoMoreInteractions(mNetd);
- }
-
- private void runUserRestrictionsChange(
- boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive,
- int expectedInteractionsWithShowNotification) throws Exception {
- final Bundle newRestrictions = new Bundle();
- newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
- final Tethering mockTethering = mock(Tethering.class);
- when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive);
- when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
-
- final Tethering.UserRestrictionActionListener ural =
- new Tethering.UserRestrictionActionListener(
- mUserManager, mockTethering, mNotificationUpdater);
- ural.mDisallowTethering = currentDisallow;
-
- ural.onUserRestrictionsChanged();
-
- verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification))
- .notifyTetheringDisabledByRestriction();
- verify(mockTethering, times(expectedInteractionsWithShowNotification)).untetherAll();
- }
-
- @Test
- public void testDisallowTetheringWhenTetheringIsNotActive() throws Exception {
- final boolean isTetheringActive = false;
- final boolean currDisallow = false;
- final boolean nextDisallow = true;
- final int expectedInteractionsWithShowNotification = 0;
-
- runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
- expectedInteractionsWithShowNotification);
- }
-
- @Test
- public void testDisallowTetheringWhenTetheringIsActive() throws Exception {
- final boolean isTetheringActive = true;
- final boolean currDisallow = false;
- final boolean nextDisallow = true;
- final int expectedInteractionsWithShowNotification = 1;
-
- runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
- expectedInteractionsWithShowNotification);
- }
-
- @Test
- public void testAllowTetheringWhenTetheringIsNotActive() throws Exception {
- final boolean isTetheringActive = false;
- final boolean currDisallow = true;
- final boolean nextDisallow = false;
- final int expectedInteractionsWithShowNotification = 0;
-
- runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
- expectedInteractionsWithShowNotification);
- }
-
- @Test
- public void testAllowTetheringWhenTetheringIsActive() throws Exception {
- final boolean isTetheringActive = true;
- final boolean currDisallow = true;
- final boolean nextDisallow = false;
- final int expectedInteractionsWithShowNotification = 0;
-
- runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
- expectedInteractionsWithShowNotification);
- }
-
- @Test
- public void testDisallowTetheringUnchanged() throws Exception {
- final boolean isTetheringActive = true;
- final int expectedInteractionsWithShowNotification = 0;
- boolean currDisallow = true;
- boolean nextDisallow = true;
-
- runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
- expectedInteractionsWithShowNotification);
-
- currDisallow = false;
- nextDisallow = false;
-
- runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
- expectedInteractionsWithShowNotification);
- }
-
- private class TestTetheringEventCallback extends ITetheringEventCallback.Stub {
- private final ArrayList<Network> mActualUpstreams = new ArrayList<>();
- private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs =
- new ArrayList<>();
- private final ArrayList<TetherStatesParcel> mTetherStates = new ArrayList<>();
- private final ArrayList<Integer> mOffloadStatus = new ArrayList<>();
-
- // This function will remove the recorded callbacks, so it must be called once for
- // each callback. If this is called after multiple callback, the order matters.
- // onCallbackCreated counts as the first call to expectUpstreamChanged with
- // @see onCallbackCreated.
- public void expectUpstreamChanged(Network... networks) {
- if (networks == null) {
- assertNoUpstreamChangeCallback();
- return;
- }
-
- final ArrayList<Network> expectedUpstreams =
- new ArrayList<Network>(Arrays.asList(networks));
- for (Network upstream : expectedUpstreams) {
- // throws OOB if no expectations
- assertEquals(mActualUpstreams.remove(0), upstream);
- }
- assertNoUpstreamChangeCallback();
- }
-
- // This function will remove the recorded callbacks, so it must be called once
- // for each callback. If this is called after multiple callback, the order matters.
- // onCallbackCreated counts as the first call to onConfigurationChanged with
- // @see onCallbackCreated.
- public void expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs) {
- final ArrayList<TetheringConfigurationParcel> expectedTetherConfig =
- new ArrayList<TetheringConfigurationParcel>(Arrays.asList(tetherConfigs));
- for (TetheringConfigurationParcel config : expectedTetherConfig) {
- // throws OOB if no expectations
- final TetheringConfigurationParcel actualConfig = mTetheringConfigs.remove(0);
- assertTetherConfigParcelEqual(actualConfig, config);
- }
- assertNoConfigChangeCallback();
- }
-
- public void expectOffloadStatusChanged(final int expectedStatus) {
- assertOffloadStatusChangedCallback();
- assertEquals(mOffloadStatus.remove(0), new Integer(expectedStatus));
- }
-
- public TetherStatesParcel pollTetherStatesChanged() {
- assertStateChangeCallback();
- return mTetherStates.remove(0);
- }
-
- @Override
- public void onUpstreamChanged(Network network) {
- mActualUpstreams.add(network);
- }
-
- @Override
- public void onConfigurationChanged(TetheringConfigurationParcel config) {
- mTetheringConfigs.add(config);
- }
-
- @Override
- public void onTetherStatesChanged(TetherStatesParcel states) {
- mTetherStates.add(states);
- }
-
- @Override
- public void onTetherClientsChanged(List<TetheredClient> clients) {
- // TODO: check this
- }
-
- @Override
- public void onOffloadStatusChanged(final int status) {
- mOffloadStatus.add(status);
- }
-
- @Override
- public void onCallbackStarted(TetheringCallbackStartedParcel parcel) {
- mActualUpstreams.add(parcel.upstreamNetwork);
- mTetheringConfigs.add(parcel.config);
- mTetherStates.add(parcel.states);
- mOffloadStatus.add(parcel.offloadStatus);
- }
-
- @Override
- public void onCallbackStopped(int errorCode) { }
-
- public void assertNoUpstreamChangeCallback() {
- assertTrue(mActualUpstreams.isEmpty());
- }
-
- public void assertNoConfigChangeCallback() {
- assertTrue(mTetheringConfigs.isEmpty());
- }
-
- public void assertNoStateChangeCallback() {
- assertTrue(mTetherStates.isEmpty());
- }
-
- public void assertStateChangeCallback() {
- assertFalse(mTetherStates.isEmpty());
- }
-
- public void assertOffloadStatusChangedCallback() {
- assertFalse(mOffloadStatus.isEmpty());
- }
-
- public void assertNoCallback() {
- assertNoUpstreamChangeCallback();
- assertNoConfigChangeCallback();
- assertNoStateChangeCallback();
- }
-
- private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual,
- @NonNull TetheringConfigurationParcel expect) {
- assertEquals(actual.subId, expect.subId);
- assertArrayEquals(actual.tetherableUsbRegexs, expect.tetherableUsbRegexs);
- assertArrayEquals(actual.tetherableWifiRegexs, expect.tetherableWifiRegexs);
- assertArrayEquals(actual.tetherableBluetoothRegexs, expect.tetherableBluetoothRegexs);
- assertEquals(actual.isDunRequired, expect.isDunRequired);
- assertEquals(actual.chooseUpstreamAutomatically, expect.chooseUpstreamAutomatically);
- assertArrayEquals(actual.preferredUpstreamIfaceTypes,
- expect.preferredUpstreamIfaceTypes);
- assertArrayEquals(actual.legacyDhcpRanges, expect.legacyDhcpRanges);
- assertArrayEquals(actual.defaultIPv4DNS, expect.defaultIPv4DNS);
- assertEquals(actual.enableLegacyDhcpServer, expect.enableLegacyDhcpServer);
- assertArrayEquals(actual.provisioningApp, expect.provisioningApp);
- assertEquals(actual.provisioningAppNoUi, expect.provisioningAppNoUi);
- assertEquals(actual.provisioningCheckPeriod, expect.provisioningCheckPeriod);
- }
- }
-
- private void assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel) {
- assertFalse(parcel == null);
- assertEquals(0, parcel.availableList.length);
- assertEquals(0, parcel.tetheredList.length);
- assertEquals(0, parcel.localOnlyList.length);
- assertEquals(0, parcel.erroredIfaceList.length);
- assertEquals(0, parcel.lastErrorList.length);
- MiscAssertsKt.assertFieldCountEquals(5, TetherStatesParcel.class);
- }
-
- @Test
- public void testRegisterTetheringEventCallback() throws Exception {
- TestTetheringEventCallback callback = new TestTetheringEventCallback();
- TestTetheringEventCallback callback2 = new TestTetheringEventCallback();
-
- // 1. Register one callback before running any tethering.
- mTethering.registerTetheringEventCallback(callback);
- mLooper.dispatchAll();
- callback.expectUpstreamChanged(new Network[] {null});
- callback.expectConfigurationChanged(
- mTethering.getTetheringConfiguration().toStableParcelable());
- TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
- assertTetherStatesNotNullButEmpty(tetherState);
- callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
- // 2. Enable wifi tethering.
- UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
- initTetheringUpstream(upstreamState);
- when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
- mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
- mLooper.dispatchAll();
- tetherState = callback.pollTetherStatesChanged();
- assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
-
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
- sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
- mLooper.dispatchAll();
- tetherState = callback.pollTetherStatesChanged();
- assertArrayEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME});
- callback.expectUpstreamChanged(upstreamState.network);
- callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
-
- // 3. Register second callback.
- mTethering.registerTetheringEventCallback(callback2);
- mLooper.dispatchAll();
- callback2.expectUpstreamChanged(upstreamState.network);
- callback2.expectConfigurationChanged(
- mTethering.getTetheringConfiguration().toStableParcelable());
- tetherState = callback2.pollTetherStatesChanged();
- assertEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME});
- callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
-
- // 4. Unregister first callback and disable wifi tethering
- mTethering.unregisterTetheringEventCallback(callback);
- mLooper.dispatchAll();
- mTethering.stopTethering(TETHERING_WIFI);
- sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
- mLooper.dispatchAll();
- tetherState = callback2.pollTetherStatesChanged();
- assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
- mLooper.dispatchAll();
- callback2.expectUpstreamChanged(new Network[] {null});
- callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
- callback.assertNoCallback();
- }
-
- @Test
- public void testReportFailCallbackIfOffloadNotSupported() throws Exception {
- final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
- TestTetheringEventCallback callback = new TestTetheringEventCallback();
- mTethering.registerTetheringEventCallback(callback);
- mLooper.dispatchAll();
- callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
-
- // 1. Offload fail if no OffloadConfig.
- initOffloadConfiguration(false /* offloadConfig */, true /* offloadControl */,
- 0 /* defaultDisabled */);
- runUsbTethering(upstreamState);
- callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
- runStopUSBTethering();
- callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
- reset(mUsbManager);
- // 2. Offload fail if no OffloadControl.
- initOffloadConfiguration(true /* offloadConfig */, false /* offloadControl */,
- 0 /* defaultDisabled */);
- runUsbTethering(upstreamState);
- callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
- runStopUSBTethering();
- callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
- reset(mUsbManager);
- // 3. Offload fail if disabled by settings.
- initOffloadConfiguration(true /* offloadConfig */, true /* offloadControl */,
- 1 /* defaultDisabled */);
- runUsbTethering(upstreamState);
- callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
- runStopUSBTethering();
- callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
- }
-
- private void runStopUSBTethering() {
- mTethering.stopTethering(TETHERING_USB);
- mLooper.dispatchAll();
- mTethering.interfaceRemoved(TEST_USB_IFNAME);
- mLooper.dispatchAll();
- }
-
- private void initOffloadConfiguration(final boolean offloadConfig,
- final boolean offloadControl, final int defaultDisabled) {
- when(mOffloadHardwareInterface.initOffloadConfig()).thenReturn(offloadConfig);
- when(mOffloadHardwareInterface.initOffloadControl(any())).thenReturn(offloadControl);
- when(mOffloadHardwareInterface.getDefaultTetherOffloadDisabled()).thenReturn(
- defaultDisabled);
- }
-
- @Test
- public void testMultiSimAware() throws Exception {
- final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
- assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.activeDataSubId);
-
- final int fakeSubId = 1234;
- mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
- final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
- assertEquals(fakeSubId, newConfig.activeDataSubId);
- verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId));
- }
-
- @Test
- public void testNoDuplicatedEthernetRequest() throws Exception {
- final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
- when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
- mLooper.dispatchAll();
- verify(mEm, times(1)).requestTetheredInterface(any(), any());
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
- mLooper.dispatchAll();
- verifyNoMoreInteractions(mEm);
- mTethering.stopTethering(TETHERING_ETHERNET);
- mLooper.dispatchAll();
- verify(mockRequest, times(1)).release();
- mTethering.stopTethering(TETHERING_ETHERNET);
- mLooper.dispatchAll();
- verifyNoMoreInteractions(mEm);
- }
-
- private void workingWifiP2pGroupOwner(
- boolean emulateInterfaceStatusChanged) throws Exception {
- if (emulateInterfaceStatusChanged) {
- mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
- }
- sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
- mLooper.dispatchAll();
-
- verifyInterfaceServingModeStarted(TEST_P2P_IFNAME);
- verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER);
- verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
- verify(mNetd, times(1)).tetherStartWithConfiguration(any());
- verifyNoMoreInteractions(mNetd);
- verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
- verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
- // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY
- verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
-
- assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastTetherError(TEST_P2P_IFNAME));
-
- // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
- // is being removed.
- sendWifiP2pConnectionChanged(false, true, TEST_P2P_IFNAME);
- mTethering.interfaceRemoved(TEST_P2P_IFNAME);
- mLooper.dispatchAll();
-
- verify(mNetd, times(1)).tetherApplyDnsInterfaces();
- verify(mNetd, times(1)).tetherInterfaceRemove(TEST_P2P_IFNAME);
- verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
- // interfaceSetCfg() called once for enabling and twice for disabling IPv4.
- verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
- verify(mNetd, times(1)).tetherStop();
- verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
- verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream();
- verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
- verifyNoMoreInteractions(mNetd);
- // Asking for the last error after the per-interface state machine
- // has been reaped yields an unknown interface error.
- assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
- }
-
- private void workingWifiP2pGroupClient(
- boolean emulateInterfaceStatusChanged) throws Exception {
- if (emulateInterfaceStatusChanged) {
- mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
- }
- sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME);
- mLooper.dispatchAll();
-
- verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
- verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
- verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
- verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
- verify(mNetd, never()).tetherStartWithConfiguration(any());
-
- // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
- // is being removed.
- sendWifiP2pConnectionChanged(false, false, TEST_P2P_IFNAME);
- mTethering.interfaceRemoved(TEST_P2P_IFNAME);
- mLooper.dispatchAll();
-
- verify(mNetd, never()).tetherApplyDnsInterfaces();
- verify(mNetd, never()).tetherInterfaceRemove(TEST_P2P_IFNAME);
- verify(mNetd, never()).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
- verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
- verify(mNetd, never()).tetherStop();
- verify(mNetd, never()).ipfwdDisableForwarding(TETHERING_NAME);
- verifyNoMoreInteractions(mNetd);
- // Asking for the last error after the per-interface state machine
- // has been reaped yields an unknown interface error.
- assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
- }
-
- @Test
- public void workingWifiP2pGroupOwnerWithIfaceChanged() throws Exception {
- workingWifiP2pGroupOwner(true);
- }
-
- @Test
- public void workingWifiP2pGroupOwnerSansIfaceChanged() throws Exception {
- workingWifiP2pGroupOwner(false);
- }
-
- private void workingWifiP2pGroupOwnerLegacyMode(
- boolean emulateInterfaceStatusChanged) throws Exception {
- // change to legacy mode and update tethering information by chaning SIM
- when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
- .thenReturn(new String[]{});
- final int fakeSubId = 1234;
- mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
-
- if (emulateInterfaceStatusChanged) {
- mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
- }
- sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
- mLooper.dispatchAll();
-
- verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
- verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
- verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
- verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
- verify(mNetd, never()).tetherStartWithConfiguration(any());
- assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
- }
- @Test
- public void workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged() throws Exception {
- workingWifiP2pGroupOwnerLegacyMode(true);
- }
-
- @Test
- public void workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged() throws Exception {
- workingWifiP2pGroupOwnerLegacyMode(false);
- }
-
- @Test
- public void workingWifiP2pGroupClientWithIfaceChanged() throws Exception {
- workingWifiP2pGroupClient(true);
- }
-
- @Test
- public void workingWifiP2pGroupClientSansIfaceChanged() throws Exception {
- workingWifiP2pGroupClient(false);
- }
-
- private void setDataSaverEnabled(boolean enabled) {
- final Intent intent = new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED);
- mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-
- final int status = enabled ? RESTRICT_BACKGROUND_STATUS_ENABLED
- : RESTRICT_BACKGROUND_STATUS_DISABLED;
- when(mCm.getRestrictBackgroundStatus()).thenReturn(status);
- mLooper.dispatchAll();
- }
-
- @Test
- public void testDataSaverChanged() {
- // Start Tethering.
- final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
- runUsbTethering(upstreamState);
- assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
- // Data saver is ON.
- setDataSaverEnabled(true);
- // Verify that tethering should be disabled.
- verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
- mTethering.interfaceRemoved(TEST_USB_IFNAME);
- mLooper.dispatchAll();
- assertEquals(mTethering.getTetheredIfaces(), new String[0]);
- reset(mUsbManager);
-
- runUsbTethering(upstreamState);
- // Verify that user can start tethering again without turning OFF data saver.
- assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
-
- // If data saver is keep ON with change event, tethering should not be OFF this time.
- setDataSaverEnabled(true);
- verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
- assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
-
- // If data saver is turned OFF, it should not change tethering.
- setDataSaverEnabled(false);
- verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
- assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
- }
-
- private static <T> void assertContains(Collection<T> collection, T element) {
- assertTrue(element + " not found in " + collection, collection.contains(element));
- }
-
- private class ResultListener extends IIntResultListener.Stub {
- private final int mExpectedResult;
- private boolean mHasResult = false;
- ResultListener(final int expectedResult) {
- mExpectedResult = expectedResult;
- }
-
- @Override
- public void onResult(final int resultCode) {
- mHasResult = true;
- if (resultCode != mExpectedResult) {
- fail("expected result: " + mExpectedResult + " but actual result: " + resultCode);
- }
- }
-
- public void assertHasResult() {
- if (!mHasResult) fail("No callback result");
- }
- }
-
- @Test
- public void testMultipleStartTethering() throws Exception {
- final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24");
- final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24");
- final String serverAddr = "192.168.20.1";
- final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR);
- final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR);
- final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR);
-
- // Enable USB tethering and check that Tethering starts USB.
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- null, null, false), firstResult);
- mLooper.dispatchAll();
- firstResult.assertHasResult();
- verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
- verifyNoMoreInteractions(mUsbManager);
-
- // Enable USB tethering again with the same request and expect no change to USB.
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- null, null, false), secondResult);
- mLooper.dispatchAll();
- secondResult.assertHasResult();
- verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
- reset(mUsbManager);
-
- // Enable USB tethering with a different request and expect that USB is stopped and
- // started.
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- serverLinkAddr, clientLinkAddr, false), thirdResult);
- mLooper.dispatchAll();
- thirdResult.assertHasResult();
- verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
- verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
-
- // Expect that when USB comes up, the DHCP server is configured with the requested address.
- mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
- sendUsbBroadcast(true, true, true, TETHERING_USB);
- mLooper.dispatchAll();
- verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
- verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
- }
-
- @Test
- public void testRequestStaticIp() throws Exception {
- final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24");
- final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24");
- final String serverAddr = "192.168.0.123";
- final int clientAddrParceled = 0xc0a8002a;
- final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
- ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- serverLinkAddr, clientLinkAddr, false), null);
- mLooper.dispatchAll();
- verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
- mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
- sendUsbBroadcast(true, true, true, TETHERING_USB);
- mLooper.dispatchAll();
- verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
- verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(),
- any());
- final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue();
- assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress());
- assertEquals(24, params.serverAddrPrefixLength);
- assertEquals(clientAddrParceled, params.singleClientAddr);
- }
-
- @Test
- public void testUpstreamNetworkChanged() {
- final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
- mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
- final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
- initTetheringUpstream(upstreamState);
- stateMachine.chooseUpstreamType(true);
-
- verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network));
- verify(mNotificationUpdater, times(1)).onUpstreamCapabilitiesChanged(any());
- }
-
- @Test
- public void testUpstreamCapabilitiesChanged() {
- final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
- mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
- final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
- initTetheringUpstream(upstreamState);
- stateMachine.chooseUpstreamType(true);
-
- stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState);
- // Should have two onUpstreamCapabilitiesChanged().
- // One is called by reportUpstreamChanged(). One is called by EVENT_ON_CAPABILITIES.
- verify(mNotificationUpdater, times(2)).onUpstreamCapabilitiesChanged(any());
- reset(mNotificationUpdater);
-
- // Verify that onUpstreamCapabilitiesChanged won't be called if not current upstream network
- // capabilities changed.
- final UpstreamNetworkState upstreamState2 = new UpstreamNetworkState(
- upstreamState.linkProperties, upstreamState.networkCapabilities, new Network(101));
- stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState2);
- verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any());
- }
-
- @Test
- public void testDumpTetheringLog() throws Exception {
- final FileDescriptor mockFd = mock(FileDescriptor.class);
- final PrintWriter mockPw = mock(PrintWriter.class);
- runUsbTethering(null);
- mLooper.startAutoDispatch();
- mTethering.dump(mockFd, mockPw, new String[0]);
- verify(mConfig).dump(any());
- verify(mEntitleMgr).dump(any());
- verify(mOffloadCtrl).dump(any());
- mLooper.stopAutoDispatch();
- }
-
- @Test
- public void testExemptFromEntitlementCheck() throws Exception {
- setupForRequiredProvisioning();
- final TetheringRequestParcel wifiNotExemptRequest =
- createTetheringRequestParcel(TETHERING_WIFI, null, null, false);
- mTethering.startTethering(wifiNotExemptRequest, null);
- mLooper.dispatchAll();
- verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
- verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
- assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
- mTethering.stopTethering(TETHERING_WIFI);
- mLooper.dispatchAll();
- verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
- reset(mEntitleMgr);
-
- setupForRequiredProvisioning();
- final TetheringRequestParcel wifiExemptRequest =
- createTetheringRequestParcel(TETHERING_WIFI, null, null, true);
- mTethering.startTethering(wifiExemptRequest, null);
- mLooper.dispatchAll();
- verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
- verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
- assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
- mTethering.stopTethering(TETHERING_WIFI);
- mLooper.dispatchAll();
- verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
- reset(mEntitleMgr);
-
- // If one app enables tethering without provisioning check first, then another app enables
- // tethering of the same type but does not disable the provisioning check.
- setupForRequiredProvisioning();
- mTethering.startTethering(wifiExemptRequest, null);
- mLooper.dispatchAll();
- verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
- verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
- assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
- reset(mEntitleMgr);
- setupForRequiredProvisioning();
- mTethering.startTethering(wifiNotExemptRequest, null);
- mLooper.dispatchAll();
- verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
- verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
- assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
- mTethering.stopTethering(TETHERING_WIFI);
- mLooper.dispatchAll();
- verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
- reset(mEntitleMgr);
- }
-
- private void setupForRequiredProvisioning() {
- // Produce some acceptable looking provision app setting if requested.
- when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
- .thenReturn(PROVISIONING_APP_NAME);
- when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
- .thenReturn(PROVISIONING_NO_UI_APP_NAME);
- // Act like the CarrierConfigManager is present and ready unless told otherwise.
- when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
- .thenReturn(mCarrierConfigManager);
- when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig);
- mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
- mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
- sendConfigurationChanged();
- }
-
- private static UpstreamNetworkState buildV4WifiUpstreamState(final String ipv4Address,
- final int prefixLength, final Network network) {
- final LinkProperties prop = new LinkProperties();
- prop.setInterfaceName(TEST_WIFI_IFNAME);
-
- prop.addLinkAddress(
- new LinkAddress(InetAddresses.parseNumericAddress(ipv4Address),
- prefixLength));
-
- final NetworkCapabilities capabilities = new NetworkCapabilities()
- .addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
- return new UpstreamNetworkState(prop, capabilities, network);
- }
-
- @Test
- public void testHandleIpConflict() throws Exception {
- final Network wifiNetwork = new Network(200);
- final Network[] allNetworks = { wifiNetwork };
- when(mCm.getAllNetworks()).thenReturn(allNetworks);
- UpstreamNetworkState upstreamNetwork = null;
- runUsbTethering(upstreamNetwork);
- final ArgumentCaptor<InterfaceConfigurationParcel> ifaceConfigCaptor =
- ArgumentCaptor.forClass(InterfaceConfigurationParcel.class);
- verify(mNetd).interfaceSetCfg(ifaceConfigCaptor.capture());
- final String ipv4Address = ifaceConfigCaptor.getValue().ipv4Addr;
- verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
- reset(mNetd, mUsbManager);
- upstreamNetwork = buildV4WifiUpstreamState(ipv4Address, 30, wifiNetwork);
- mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
- Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
- UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
- 0,
- upstreamNetwork);
- mLooper.dispatchAll();
- // verify trun off usb tethering
- verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE);
- mTethering.interfaceRemoved(TEST_USB_IFNAME);
- mLooper.dispatchAll();
- // verify restart usb tethering
- verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
- }
-
- @Test
- public void testNoAddressAvailable() throws Exception {
- final Network wifiNetwork = new Network(200);
- final Network[] allNetworks = { wifiNetwork };
- when(mCm.getAllNetworks()).thenReturn(allNetworks);
- final String upstreamAddress = "192.168.0.100";
- runUsbTethering(null);
- verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
- reset(mUsbManager);
- final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
- when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
- final ArgumentCaptor<TetheredInterfaceCallback> callbackCaptor =
- ArgumentCaptor.forClass(TetheredInterfaceCallback.class);
- mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
- mLooper.dispatchAll();
- verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture());
- TetheredInterfaceCallback ethCallback = callbackCaptor.getValue();
- ethCallback.onAvailable(TEST_ETH_IFNAME);
- mLooper.dispatchAll();
- reset(mUsbManager, mEm);
-
- final UpstreamNetworkState upstreamNetwork = buildV4WifiUpstreamState(
- upstreamAddress, 16, wifiNetwork);
- mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
- Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
- UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
- 0,
- upstreamNetwork);
- mLooper.dispatchAll();
- // verify trun off usb tethering
- verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE);
- // verify trun off ethernet tethering
- verify(mockRequest).release();
- mTethering.interfaceRemoved(TEST_USB_IFNAME);
- ethCallback.onUnavailable();
- mLooper.dispatchAll();
- // verify restart usb tethering
- verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
- // verify restart ethernet tethering
- verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture());
- ethCallback = callbackCaptor.getValue();
- ethCallback.onAvailable(TEST_ETH_IFNAME);
-
- reset(mUsbManager, mEm);
- when(mNetd.interfaceGetList())
- .thenReturn(new String[] {
- TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME, TEST_P2P_IFNAME,
- TEST_NCM_IFNAME, TEST_ETH_IFNAME});
-
- mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
- sendUsbBroadcast(true, true, true, TETHERING_USB);
- mLooper.dispatchAll();
- assertContains(Arrays.asList(mTethering.getTetherableIfaces()), TEST_USB_IFNAME);
- assertContains(Arrays.asList(mTethering.getTetherableIfaces()), TEST_ETH_IFNAME);
- assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastTetherError(TEST_USB_IFNAME));
- assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastTetherError(TEST_ETH_IFNAME));
- }
-
- @Test
- public void testProvisioningNeededButUnavailable() throws Exception {
- assertTrue(mTethering.isTetheringSupported());
- verify(mPackageManager, never()).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
-
- setupForRequiredProvisioning();
- assertTrue(mTethering.isTetheringSupported());
- verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
- reset(mPackageManager);
-
- doThrow(PackageManager.NameNotFoundException.class).when(mPackageManager).getPackageInfo(
- PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
- setupForRequiredProvisioning();
- assertFalse(mTethering.isTetheringSupported());
- verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
- }
-
- // TODO: Test that a request for hotspot mode doesn't interfere with an
- // already operating tethering mode interface.
-}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
deleted file mode 100644
index 232588c7..0000000
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
+++ /dev/null
@@ -1,800 +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.networkstack.tethering;
-
-import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
-import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-
-import static com.android.networkstack.tethering.UpstreamNetworkMonitor.TYPE_NONE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.IConnectivityManager;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.Message;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class UpstreamNetworkMonitorTest {
- private static final int EVENT_UNM_UPDATE = 1;
-
- private static final boolean INCLUDES = true;
- private static final boolean EXCLUDES = false;
-
- // Actual contents of the request don't matter for this test. The lack of
- // any specific TRANSPORT_* is sufficient to identify this request.
- private static final NetworkRequest sDefaultRequest = new NetworkRequest.Builder().build();
-
- @Mock private Context mContext;
- @Mock private EntitlementManager mEntitleMgr;
- @Mock private IConnectivityManager mCS;
- @Mock private SharedLog mLog;
-
- private TestStateMachine mSM;
- private TestConnectivityManager mCM;
- private UpstreamNetworkMonitor mUNM;
-
- @Before public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- reset(mContext);
- reset(mCS);
- reset(mLog);
- when(mLog.forSubComponent(anyString())).thenReturn(mLog);
- when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
-
- mCM = spy(new TestConnectivityManager(mContext, mCS));
- mSM = new TestStateMachine();
- mUNM = new UpstreamNetworkMonitor(
- (ConnectivityManager) mCM, mSM, mLog, EVENT_UNM_UPDATE);
- }
-
- @After public void tearDown() throws Exception {
- if (mSM != null) {
- mSM.quit();
- mSM = null;
- }
- }
-
- @Test
- public void testStopWithoutStartIsNonFatal() {
- mUNM.stop();
- mUNM.stop();
- mUNM.stop();
- }
-
- @Test
- public void testDoesNothingBeforeTrackDefaultAndStarted() throws Exception {
- assertTrue(mCM.hasNoCallbacks());
- assertFalse(mUNM.mobileNetworkRequested());
-
- mUNM.updateMobileRequiresDun(true);
- assertTrue(mCM.hasNoCallbacks());
- mUNM.updateMobileRequiresDun(false);
- assertTrue(mCM.hasNoCallbacks());
- }
-
- @Test
- public void testDefaultNetworkIsTracked() throws Exception {
- assertTrue(mCM.hasNoCallbacks());
- mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
-
- mUNM.startObserveAllNetworks();
- assertEquals(1, mCM.trackingDefault.size());
-
- mUNM.stop();
- assertTrue(mCM.onlyHasDefaultCallbacks());
- }
-
- @Test
- public void testListensForAllNetworks() throws Exception {
- assertTrue(mCM.listening.isEmpty());
-
- mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
- mUNM.startObserveAllNetworks();
- assertFalse(mCM.listening.isEmpty());
- assertTrue(mCM.isListeningForAll());
-
- mUNM.stop();
- assertTrue(mCM.onlyHasDefaultCallbacks());
- }
-
- @Test
- public void testCallbacksRegistered() {
- mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
- verify(mCM, times(1)).requestNetwork(
- eq(sDefaultRequest), any(NetworkCallback.class), any(Handler.class));
- mUNM.startObserveAllNetworks();
- verify(mCM, times(1)).registerNetworkCallback(
- any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class));
-
- mUNM.stop();
- verify(mCM, times(1)).unregisterNetworkCallback(any(NetworkCallback.class));
- }
-
- @Test
- public void testRequestsMobileNetwork() throws Exception {
- assertFalse(mUNM.mobileNetworkRequested());
- assertEquals(0, mCM.requested.size());
-
- mUNM.startObserveAllNetworks();
- assertFalse(mUNM.mobileNetworkRequested());
- assertEquals(0, mCM.requested.size());
-
- mUNM.updateMobileRequiresDun(false);
- assertFalse(mUNM.mobileNetworkRequested());
- assertEquals(0, mCM.requested.size());
-
- mUNM.registerMobileNetworkRequest();
- assertTrue(mUNM.mobileNetworkRequested());
- assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
- assertFalse(isDunRequested());
-
- mUNM.stop();
- assertFalse(mUNM.mobileNetworkRequested());
- assertTrue(mCM.hasNoCallbacks());
- }
-
- @Test
- public void testDuplicateMobileRequestsIgnored() throws Exception {
- assertFalse(mUNM.mobileNetworkRequested());
- assertEquals(0, mCM.requested.size());
-
- mUNM.startObserveAllNetworks();
- verify(mCM, times(1)).registerNetworkCallback(
- any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class));
- assertFalse(mUNM.mobileNetworkRequested());
- assertEquals(0, mCM.requested.size());
-
- mUNM.updateMobileRequiresDun(true);
- mUNM.registerMobileNetworkRequest();
- verify(mCM, times(1)).requestNetwork(
- any(NetworkRequest.class), anyInt(), anyInt(), any(Handler.class),
- any(NetworkCallback.class));
-
- assertTrue(mUNM.mobileNetworkRequested());
- assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(isDunRequested());
-
- // Try a few things that must not result in any state change.
- mUNM.registerMobileNetworkRequest();
- mUNM.updateMobileRequiresDun(true);
- mUNM.registerMobileNetworkRequest();
-
- assertTrue(mUNM.mobileNetworkRequested());
- assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(isDunRequested());
-
- mUNM.stop();
- verify(mCM, times(2)).unregisterNetworkCallback(any(NetworkCallback.class));
-
- verifyNoMoreInteractions(mCM);
- }
-
- @Test
- public void testRequestsDunNetwork() throws Exception {
- assertFalse(mUNM.mobileNetworkRequested());
- assertEquals(0, mCM.requested.size());
-
- mUNM.startObserveAllNetworks();
- assertFalse(mUNM.mobileNetworkRequested());
- assertEquals(0, mCM.requested.size());
-
- mUNM.updateMobileRequiresDun(true);
- assertFalse(mUNM.mobileNetworkRequested());
- assertEquals(0, mCM.requested.size());
-
- mUNM.registerMobileNetworkRequest();
- assertTrue(mUNM.mobileNetworkRequested());
- assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(isDunRequested());
-
- mUNM.stop();
- assertFalse(mUNM.mobileNetworkRequested());
- assertTrue(mCM.hasNoCallbacks());
- }
-
- @Test
- public void testUpdateMobileRequiresDun() throws Exception {
- mUNM.startObserveAllNetworks();
-
- // Test going from no-DUN to DUN correctly re-registers callbacks.
- mUNM.updateMobileRequiresDun(false);
- mUNM.registerMobileNetworkRequest();
- assertTrue(mUNM.mobileNetworkRequested());
- assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
- assertFalse(isDunRequested());
- mUNM.updateMobileRequiresDun(true);
- assertTrue(mUNM.mobileNetworkRequested());
- assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(isDunRequested());
-
- // Test going from DUN to no-DUN correctly re-registers callbacks.
- mUNM.updateMobileRequiresDun(false);
- assertTrue(mUNM.mobileNetworkRequested());
- assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
- assertFalse(isDunRequested());
-
- mUNM.stop();
- assertFalse(mUNM.mobileNetworkRequested());
- }
-
- @Test
- public void testSelectPreferredUpstreamType() throws Exception {
- final Collection<Integer> preferredTypes = new ArrayList<>();
- preferredTypes.add(TYPE_WIFI);
-
- mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
- mUNM.startObserveAllNetworks();
- // There are no networks, so there is nothing to select.
- assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
-
- final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
- wifiAgent.fakeConnect();
- // WiFi is up, we should prefer it.
- assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
- wifiAgent.fakeDisconnect();
- // There are no networks, so there is nothing to select.
- assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
-
- final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
- cellAgent.fakeConnect();
- assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
-
- preferredTypes.add(TYPE_MOBILE_DUN);
- // This is coupled with preferred types in TetheringConfiguration.
- mUNM.updateMobileRequiresDun(true);
- // DUN is available, but only use regular cell: no upstream selected.
- assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
- preferredTypes.remove(TYPE_MOBILE_DUN);
- // No WiFi, but our preferred flavour of cell is up.
- preferredTypes.add(TYPE_MOBILE_HIPRI);
- // This is coupled with preferred types in TetheringConfiguration.
- mUNM.updateMobileRequiresDun(false);
- assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
- mUNM.selectPreferredUpstreamType(preferredTypes));
- // Check to see we filed an explicit request.
- assertEquals(1, mCM.requested.size());
- NetworkRequest netReq = (NetworkRequest) mCM.requested.values().toArray()[0];
- assertTrue(netReq.networkCapabilities.hasTransport(TRANSPORT_CELLULAR));
- assertFalse(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN));
- // mobile is not permitted, we should not use HIPRI.
- when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
- assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
- assertEquals(0, mCM.requested.size());
- // mobile change back to permitted, HIRPI should come back
- when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
- assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
- mUNM.selectPreferredUpstreamType(preferredTypes));
-
- wifiAgent.fakeConnect();
- // WiFi is up, and we should prefer it over cell.
- assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
- assertEquals(0, mCM.requested.size());
-
- preferredTypes.remove(TYPE_MOBILE_HIPRI);
- preferredTypes.add(TYPE_MOBILE_DUN);
- // This is coupled with preferred types in TetheringConfiguration.
- mUNM.updateMobileRequiresDun(true);
- assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
-
- final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
- dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
- dunAgent.fakeConnect();
-
- // WiFi is still preferred.
- assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
-
- // WiFi goes down, cell and DUN are still up but only DUN is preferred.
- wifiAgent.fakeDisconnect();
- assertSatisfiesLegacyType(TYPE_MOBILE_DUN,
- mUNM.selectPreferredUpstreamType(preferredTypes));
- // Check to see we filed an explicit request.
- assertEquals(1, mCM.requested.size());
- netReq = (NetworkRequest) mCM.requested.values().toArray()[0];
- assertTrue(netReq.networkCapabilities.hasTransport(TRANSPORT_CELLULAR));
- assertTrue(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN));
- // mobile is not permitted, we should not use DUN.
- when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
- assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
- assertEquals(0, mCM.requested.size());
- // mobile change back to permitted, DUN should come back
- when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
- assertSatisfiesLegacyType(TYPE_MOBILE_DUN,
- mUNM.selectPreferredUpstreamType(preferredTypes));
- }
-
- @Test
- public void testGetCurrentPreferredUpstream() throws Exception {
- mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
- mUNM.startObserveAllNetworks();
- mUNM.updateMobileRequiresDun(false);
-
- // [0] Mobile connects, DUN not required -> mobile selected.
- final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
- cellAgent.fakeConnect();
- mCM.makeDefaultNetwork(cellAgent);
- assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
-
- // [1] Mobile connects but not permitted -> null selected
- when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
- assertEquals(null, mUNM.getCurrentPreferredUpstream());
- when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
-
- // [2] WiFi connects but not validated/promoted to default -> mobile selected.
- final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
- wifiAgent.fakeConnect();
- assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
-
- // [3] WiFi validates and is promoted to the default network -> WiFi selected.
- mCM.makeDefaultNetwork(wifiAgent);
- assertEquals(wifiAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
-
- // [4] DUN required, no other changes -> WiFi still selected
- mUNM.updateMobileRequiresDun(true);
- assertEquals(wifiAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
-
- // [5] WiFi no longer validated, mobile becomes default, DUN required -> null selected.
- mCM.makeDefaultNetwork(cellAgent);
- assertEquals(null, mUNM.getCurrentPreferredUpstream());
- // TODO: make sure that a DUN request has been filed. This is currently
- // triggered by code over in Tethering, but once that has been moved
- // into UNM we should test for this here.
-
- // [6] DUN network arrives -> DUN selected
- final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
- dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
- dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
- dunAgent.fakeConnect();
- assertEquals(dunAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
-
- // [7] Mobile is not permitted -> null selected
- when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
- assertEquals(null, mUNM.getCurrentPreferredUpstream());
- }
-
- @Test
- public void testLocalPrefixes() throws Exception {
- mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
- mUNM.startObserveAllNetworks();
-
- // [0] Test minimum set of local prefixes.
- Set<IpPrefix> local = mUNM.getLocalPrefixes();
- assertTrue(local.isEmpty());
-
- final Set<String> alreadySeen = new HashSet<>();
-
- // [1] Pretend Wi-Fi connects.
- final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
- final LinkProperties wifiLp = wifiAgent.linkProperties;
- wifiLp.setInterfaceName("wlan0");
- final String[] wifi_addrs = {
- "fe80::827a:bfff:fe6f:374d", "100.112.103.18",
- "2001:db8:4:fd00:827a:bfff:fe6f:374d",
- "2001:db8:4:fd00:6dea:325a:fdae:4ef4",
- "fd6a:a640:60bf:e985::123", // ULA address for good measure.
- };
- for (String addrStr : wifi_addrs) {
- final String cidr = addrStr.contains(":") ? "/64" : "/20";
- wifiLp.addLinkAddress(new LinkAddress(addrStr + cidr));
- }
- wifiAgent.fakeConnect();
- wifiAgent.sendLinkProperties();
-
- local = mUNM.getLocalPrefixes();
- assertPrefixSet(local, INCLUDES, alreadySeen);
- final String[] wifiLinkPrefixes = {
- // Link-local prefixes are excluded and dealt with elsewhere.
- "100.112.96.0/20", "2001:db8:4:fd00::/64", "fd6a:a640:60bf:e985::/64",
- };
- assertPrefixSet(local, INCLUDES, wifiLinkPrefixes);
- Collections.addAll(alreadySeen, wifiLinkPrefixes);
- assertEquals(alreadySeen.size(), local.size());
-
- // [2] Pretend mobile connects.
- final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
- final LinkProperties cellLp = cellAgent.linkProperties;
- cellLp.setInterfaceName("rmnet_data0");
- final String[] cell_addrs = {
- "10.102.211.48", "2001:db8:0:1:b50e:70d9:10c9:433d",
- };
- for (String addrStr : cell_addrs) {
- final String cidr = addrStr.contains(":") ? "/64" : "/27";
- cellLp.addLinkAddress(new LinkAddress(addrStr + cidr));
- }
- cellAgent.fakeConnect();
- cellAgent.sendLinkProperties();
-
- local = mUNM.getLocalPrefixes();
- assertPrefixSet(local, INCLUDES, alreadySeen);
- final String[] cellLinkPrefixes = { "10.102.211.32/27", "2001:db8:0:1::/64" };
- assertPrefixSet(local, INCLUDES, cellLinkPrefixes);
- Collections.addAll(alreadySeen, cellLinkPrefixes);
- assertEquals(alreadySeen.size(), local.size());
-
- // [3] Pretend DUN connects.
- final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
- dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
- dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
- final LinkProperties dunLp = dunAgent.linkProperties;
- dunLp.setInterfaceName("rmnet_data1");
- final String[] dun_addrs = {
- "192.0.2.48", "2001:db8:1:2:b50e:70d9:10c9:433d",
- };
- for (String addrStr : dun_addrs) {
- final String cidr = addrStr.contains(":") ? "/64" : "/27";
- dunLp.addLinkAddress(new LinkAddress(addrStr + cidr));
- }
- dunAgent.fakeConnect();
- dunAgent.sendLinkProperties();
-
- local = mUNM.getLocalPrefixes();
- assertPrefixSet(local, INCLUDES, alreadySeen);
- final String[] dunLinkPrefixes = { "192.0.2.32/27", "2001:db8:1:2::/64" };
- assertPrefixSet(local, INCLUDES, dunLinkPrefixes);
- Collections.addAll(alreadySeen, dunLinkPrefixes);
- assertEquals(alreadySeen.size(), local.size());
-
- // [4] Pretend Wi-Fi disconnected. It's addresses/prefixes should no
- // longer be included (should be properly removed).
- wifiAgent.fakeDisconnect();
- local = mUNM.getLocalPrefixes();
- assertPrefixSet(local, EXCLUDES, wifiLinkPrefixes);
- assertPrefixSet(local, INCLUDES, cellLinkPrefixes);
- assertPrefixSet(local, INCLUDES, dunLinkPrefixes);
-
- // [5] Pretend mobile disconnected.
- cellAgent.fakeDisconnect();
- local = mUNM.getLocalPrefixes();
- assertPrefixSet(local, EXCLUDES, wifiLinkPrefixes);
- assertPrefixSet(local, EXCLUDES, cellLinkPrefixes);
- assertPrefixSet(local, INCLUDES, dunLinkPrefixes);
-
- // [6] Pretend DUN disconnected.
- dunAgent.fakeDisconnect();
- local = mUNM.getLocalPrefixes();
- assertTrue(local.isEmpty());
- }
-
- @Test
- public void testSelectMobileWhenMobileIsNotDefault() {
- final Collection<Integer> preferredTypes = new ArrayList<>();
- // Mobile has higher pirority than wifi.
- preferredTypes.add(TYPE_MOBILE_HIPRI);
- preferredTypes.add(TYPE_WIFI);
- mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
- mUNM.startObserveAllNetworks();
- // Setup wifi and make wifi as default network.
- final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
- wifiAgent.fakeConnect();
- mCM.makeDefaultNetwork(wifiAgent);
- // Setup mobile network.
- final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
- cellAgent.fakeConnect();
-
- assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
- mUNM.selectPreferredUpstreamType(preferredTypes));
- verify(mEntitleMgr, times(1)).maybeRunProvisioning();
- }
-
- private void assertSatisfiesLegacyType(int legacyType, UpstreamNetworkState ns) {
- if (legacyType == TYPE_NONE) {
- assertTrue(ns == null);
- return;
- }
-
- final NetworkCapabilities nc =
- UpstreamNetworkMonitor.networkCapabilitiesForType(legacyType);
- assertTrue(nc.satisfiedByNetworkCapabilities(ns.networkCapabilities));
- }
-
- private void assertUpstreamTypeRequested(int upstreamType) throws Exception {
- assertEquals(1, mCM.requested.size());
- assertEquals(1, mCM.legacyTypeMap.size());
- assertEquals(Integer.valueOf(upstreamType),
- mCM.legacyTypeMap.values().iterator().next());
- }
-
- private boolean isDunRequested() {
- for (NetworkRequest req : mCM.requested.values()) {
- if (req.networkCapabilities.hasCapability(NET_CAPABILITY_DUN)) {
- return true;
- }
- }
- return false;
- }
-
- public static class TestConnectivityManager extends ConnectivityManager {
- public Map<NetworkCallback, Handler> allCallbacks = new HashMap<>();
- public Set<NetworkCallback> trackingDefault = new HashSet<>();
- public TestNetworkAgent defaultNetwork = null;
- public Map<NetworkCallback, NetworkRequest> listening = new HashMap<>();
- public Map<NetworkCallback, NetworkRequest> requested = new HashMap<>();
- public Map<NetworkCallback, Integer> legacyTypeMap = new HashMap<>();
-
- private int mNetworkId = 100;
-
- public TestConnectivityManager(Context ctx, IConnectivityManager svc) {
- super(ctx, svc);
- }
-
- boolean hasNoCallbacks() {
- return allCallbacks.isEmpty()
- && trackingDefault.isEmpty()
- && listening.isEmpty()
- && requested.isEmpty()
- && legacyTypeMap.isEmpty();
- }
-
- boolean onlyHasDefaultCallbacks() {
- return (allCallbacks.size() == 1)
- && (trackingDefault.size() == 1)
- && listening.isEmpty()
- && requested.isEmpty()
- && legacyTypeMap.isEmpty();
- }
-
- boolean isListeningForAll() {
- final NetworkCapabilities empty = new NetworkCapabilities();
- empty.clearAll();
-
- for (NetworkRequest req : listening.values()) {
- if (req.networkCapabilities.equalRequestableCapabilities(empty)) {
- return true;
- }
- }
- return false;
- }
-
- int getNetworkId() {
- return ++mNetworkId;
- }
-
- void makeDefaultNetwork(TestNetworkAgent agent) {
- if (Objects.equals(defaultNetwork, agent)) return;
-
- final TestNetworkAgent formerDefault = defaultNetwork;
- defaultNetwork = agent;
-
- for (NetworkCallback cb : trackingDefault) {
- if (defaultNetwork != null) {
- cb.onAvailable(defaultNetwork.networkId);
- cb.onCapabilitiesChanged(
- defaultNetwork.networkId, defaultNetwork.networkCapabilities);
- cb.onLinkPropertiesChanged(
- defaultNetwork.networkId, defaultNetwork.linkProperties);
- }
- }
- }
-
- @Override
- public void requestNetwork(NetworkRequest req, NetworkCallback cb, Handler h) {
- assertFalse(allCallbacks.containsKey(cb));
- allCallbacks.put(cb, h);
- if (sDefaultRequest.equals(req)) {
- assertFalse(trackingDefault.contains(cb));
- trackingDefault.add(cb);
- } else {
- assertFalse(requested.containsKey(cb));
- requested.put(cb, req);
- }
- }
-
- @Override
- public void requestNetwork(NetworkRequest req, NetworkCallback cb) {
- fail("Should never be called.");
- }
-
- @Override
- public void requestNetwork(NetworkRequest req,
- int timeoutMs, int legacyType, Handler h, NetworkCallback cb) {
- assertFalse(allCallbacks.containsKey(cb));
- allCallbacks.put(cb, h);
- assertFalse(requested.containsKey(cb));
- requested.put(cb, req);
- assertFalse(legacyTypeMap.containsKey(cb));
- if (legacyType != ConnectivityManager.TYPE_NONE) {
- legacyTypeMap.put(cb, legacyType);
- }
- }
-
- @Override
- public void registerNetworkCallback(NetworkRequest req, NetworkCallback cb, Handler h) {
- assertFalse(allCallbacks.containsKey(cb));
- allCallbacks.put(cb, h);
- assertFalse(listening.containsKey(cb));
- listening.put(cb, req);
- }
-
- @Override
- public void registerNetworkCallback(NetworkRequest req, NetworkCallback cb) {
- fail("Should never be called.");
- }
-
- @Override
- public void registerDefaultNetworkCallback(NetworkCallback cb, Handler h) {
- fail("Should never be called.");
- }
-
- @Override
- public void registerDefaultNetworkCallback(NetworkCallback cb) {
- fail("Should never be called.");
- }
-
- @Override
- public void unregisterNetworkCallback(NetworkCallback cb) {
- if (trackingDefault.contains(cb)) {
- trackingDefault.remove(cb);
- } else if (listening.containsKey(cb)) {
- listening.remove(cb);
- } else if (requested.containsKey(cb)) {
- requested.remove(cb);
- legacyTypeMap.remove(cb);
- } else {
- fail("Unexpected callback removed");
- }
- allCallbacks.remove(cb);
-
- assertFalse(allCallbacks.containsKey(cb));
- assertFalse(trackingDefault.contains(cb));
- assertFalse(listening.containsKey(cb));
- assertFalse(requested.containsKey(cb));
- }
- }
-
- public static class TestNetworkAgent {
- public final TestConnectivityManager cm;
- public final Network networkId;
- public final int transportType;
- public final NetworkCapabilities networkCapabilities;
- public final LinkProperties linkProperties;
-
- public TestNetworkAgent(TestConnectivityManager cm, int transportType) {
- this.cm = cm;
- this.networkId = new Network(cm.getNetworkId());
- this.transportType = transportType;
- networkCapabilities = new NetworkCapabilities();
- networkCapabilities.addTransportType(transportType);
- networkCapabilities.addCapability(NET_CAPABILITY_INTERNET);
- linkProperties = new LinkProperties();
- }
-
- public void fakeConnect() {
- for (NetworkCallback cb : cm.listening.keySet()) {
- cb.onAvailable(networkId);
- cb.onCapabilitiesChanged(networkId, copy(networkCapabilities));
- cb.onLinkPropertiesChanged(networkId, copy(linkProperties));
- }
- }
-
- public void fakeDisconnect() {
- for (NetworkCallback cb : cm.listening.keySet()) {
- cb.onLost(networkId);
- }
- }
-
- public void sendLinkProperties() {
- for (NetworkCallback cb : cm.listening.keySet()) {
- cb.onLinkPropertiesChanged(networkId, copy(linkProperties));
- }
- }
-
- @Override
- public String toString() {
- return String.format("TestNetworkAgent: %s %s", networkId, networkCapabilities);
- }
- }
-
- public static class TestStateMachine extends StateMachine {
- public final ArrayList<Message> messages = new ArrayList<>();
- private final State mLoggingState = new LoggingState();
-
- class LoggingState extends State {
- @Override public void enter() {
- messages.clear();
- }
-
- @Override public void exit() {
- messages.clear();
- }
-
- @Override public boolean processMessage(Message msg) {
- messages.add(msg);
- return true;
- }
- }
-
- public TestStateMachine() {
- super("UpstreamNetworkMonitor.TestStateMachine");
- addState(mLoggingState);
- setInitialState(mLoggingState);
- super.start();
- }
- }
-
- static NetworkCapabilities copy(NetworkCapabilities nc) {
- return new NetworkCapabilities(nc);
- }
-
- static LinkProperties copy(LinkProperties lp) {
- return new LinkProperties(lp);
- }
-
- static void assertPrefixSet(Set<IpPrefix> prefixes, boolean expectation, String... expected) {
- final Set<String> expectedSet = new HashSet<>();
- Collections.addAll(expectedSet, expected);
- assertPrefixSet(prefixes, expectation, expectedSet);
- }
-
- static void assertPrefixSet(Set<IpPrefix> prefixes, boolean expectation, Set<String> expected) {
- for (String expectedPrefix : expected) {
- final String errStr = expectation ? "did not find" : "found";
- assertEquals(
- String.format("Failed expectation: %s prefix: %s", errStr, expectedPrefix),
- expectation, prefixes.contains(new IpPrefix(expectedPrefix)));
- }
- }
-}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 77cd5d2..526c1ca 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -135,8 +135,6 @@
import android.net.metrics.NetworkEvent;
import android.net.netlink.InetDiagMessage;
import android.net.shared.PrivateDnsConfig;
-import android.net.util.LinkPropertiesUtils.CompareOrUpdateResult;
-import android.net.util.LinkPropertiesUtils.CompareResult;
import android.net.util.MultinetworkPolicyTracker;
import android.net.util.NetdService;
import android.os.Binder;
@@ -194,6 +192,8 @@
import com.android.internal.util.LocationPermissionChecker;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.XmlUtils;
+import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
+import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
import com.android.server.am.BatteryStatsService;
import com.android.server.connectivity.AutodestructReference;
import com.android.server.connectivity.DataConnectionStats;
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index 4a1820a..d907505 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -25,7 +25,6 @@
import android.net.nsd.INsdManager;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
-import android.net.util.nsd.DnsSdTxtRecord;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@@ -42,6 +41,7 @@
import com.android.internal.util.DumpUtils;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
+import com.android.net.module.util.DnsSdTxtRecord;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index a927fa2..3ab3fd5 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -38,6 +38,10 @@
"file_patterns": ["NotificationManagerService\\.java"]
},
{
+ "name": "CtsScopedStorageCoreHostTest",
+ "file_patterns": ["StorageManagerService\\.java"]
+ },
+ {
"name": "CtsScopedStorageHostTest",
"file_patterns": ["StorageManagerService\\.java"]
}
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index 103f659..7d8bed3 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -60,12 +60,12 @@
import android.net.ipsec.ike.TunnelModeChildSessionParams;
import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.net.util.IpRange;
import android.system.OsConstants;
import android.util.Log;
import com.android.internal.net.VpnProfile;
import com.android.internal.util.HexDump;
+import com.android.net.module.util.IpRange;
import java.net.Inet4Address;
import java.net.Inet6Address;
diff --git a/services/net/Android.bp b/services/net/Android.bp
index afea1a0..312b1dd 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -57,6 +57,8 @@
visibility: [
"//frameworks/opt/net/wifi/service",
"//frameworks/opt/net/wifi/tests/wifitests",
+ "//packages/modules/Wifi/service",
+ "//packages/modules/Wifi/service/tests/wifitests",
],
}
@@ -66,5 +68,5 @@
":framework-annotations",
"java/android/net/util/NetworkConstants.java",
],
- visibility: ["//frameworks/base/packages/Tethering"],
+ visibility: ["//packages/modules/Connectivity/Tethering"],
}
diff --git a/services/tests/servicestests/src/com/android/server/display/color/GlobalSaturationTintControllerTest.java b/services/tests/servicestests/src/com/android/server/display/color/GlobalSaturationTintControllerTest.java
index 7b88a0e..4f0cb32 100644
--- a/services/tests/servicestests/src/com/android/server/display/color/GlobalSaturationTintControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/color/GlobalSaturationTintControllerTest.java
@@ -32,9 +32,11 @@
public void setAndGetMatrix() {
final GlobalSaturationTintController tintController = new GlobalSaturationTintController();
tintController.setMatrix(50);
- assertThat(tintController.getMatrix()).hasValuesWithin(0.00001f)
- .of(new float[]{0.6155f, 0.1155f, 0.1155f, 0.0f, 0.3575f, 0.85749996f, 0.3575f,
- 0.0f, 0.036f, 0.036f, 0.536f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f});
+ assertThat(tintController.getMatrix()).usingTolerance(0.00001f)
+ .containsExactly(
+ 0.6155f, 0.1155f, 0.1155f, 0.0f, 0.3575f, 0.85749996f, 0.3575f,
+ 0.0f, 0.036f, 0.036f, 0.536f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)
+ .inOrder();
}
@Test
@@ -43,6 +45,7 @@
tintController.setMatrix(100);
final float[] matrix = new float[16];
Matrix.setIdentityM(matrix, 0);
- assertThat(tintController.getMatrix()).hasValuesWithin(0.00001f).of(matrix);
+ assertThat(tintController.getMatrix()).usingTolerance(0.00001f)
+ .containsExactly(matrix).inOrder();
}
}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 3365ab7..6f6b041 100755
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -1654,7 +1654,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void enterBackgroundAudioProcessing() {
if (mState != STATE_ACTIVE && mState != STATE_RINGING) {
throw new IllegalStateException("Call must be active or ringing");
@@ -1675,7 +1674,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void exitBackgroundAudioProcessing(boolean shouldRing) {
if (mState != STATE_AUDIO_PROCESSING) {
throw new IllegalStateException("Call must in the audio processing state");
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 8abab90..097a00d 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
@@ -301,7 +300,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @NonNull Builder setShouldScreenCallViaAudioProcessing(
boolean shouldScreenCallViaAudioProcessing) {
mShouldScreenCallViaAudioProcessing = shouldScreenCallViaAudioProcessing;
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index d960552..2b09dee 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -24,7 +24,6 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
@@ -137,7 +136,6 @@
* @hide
*/
@SystemApi
- @TestApi
public final @NonNull String getTelecomCallId() {
return mTelecomCallId;
}
@@ -614,7 +612,6 @@
* @return The primary connection.
* @hide
*/
- @TestApi
@SystemApi
public Connection getPrimaryConnection() {
if (mUnmodifiableChildConnections == null || mUnmodifiableChildConnections.isEmpty()) {
@@ -1018,7 +1015,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(MODIFY_PHONE_STATE)
public void setConferenceState(boolean isConference) {
mIsMultiparty = isConference;
@@ -1073,7 +1069,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(MODIFY_PHONE_STATE)
public final void setAddress(@NonNull Uri address,
@TelecomManager.Presentation int presentation) {
@@ -1161,7 +1156,6 @@
* @hide
*/
@SystemApi
- @TestApi
public final void setCallerDisplayName(@NonNull String callerDisplayName,
@TelecomManager.Presentation int presentation) {
Log.d(this, "setCallerDisplayName %s", callerDisplayName);
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
old mode 100755
new mode 100644
index fa99095..7e824fc
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -25,7 +25,6 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Notification;
import android.bluetooth.BluetoothDevice;
import android.compat.annotation.UnsupportedAppUsage;
@@ -307,7 +306,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 0x00040000;
/**
@@ -345,7 +343,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int CAPABILITY_CONFERENCE_HAS_NO_CHILDREN = 0x00200000;
/**
@@ -415,7 +412,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 1<<0;
/**
@@ -426,7 +422,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROPERTY_GENERIC_CONFERENCE = 1<<1;
/**
@@ -478,7 +473,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROPERTY_IS_DOWNGRADED_CONFERENCE = 1<<6;
/**
@@ -522,7 +516,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int PROPERTY_REMOTELY_HOSTED = 1 << 11;
/**
@@ -701,7 +694,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final String EXTRA_DISABLE_ADD_CALL =
"android.telecom.extra.DISABLE_ADD_CALL";
@@ -2053,7 +2045,6 @@
* @hide
*/
@SystemApi
- @TestApi
public final @Nullable String getTelecomCallId() {
return mTelecomCallId;
}
@@ -2170,7 +2161,6 @@
* @hide
*/
@SystemApi
- @TestApi
public final @IntRange(from = 0) long getConnectTimeMillis() {
return mConnectTimeMillis;
}
@@ -2195,7 +2185,6 @@
* @hide
*/
@SystemApi
- @TestApi
public final @ElapsedRealtimeLong long getConnectionStartElapsedRealtimeMillis() {
return mConnectElapsedTimeMillis;
}
@@ -2278,7 +2267,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void setTelecomCallId(@NonNull String callId) {
mTelecomCallId = callId;
}
@@ -2627,7 +2615,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(MODIFY_PHONE_STATE)
public final void setConnectTimeMillis(@IntRange(from = 0) long connectTimeMillis) {
mConnectTimeMillis = connectTimeMillis;
@@ -2650,7 +2637,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(MODIFY_PHONE_STATE)
public final void setConnectionStartElapsedRealtimeMillis(
@ElapsedRealtimeLong long connectElapsedTimeMillis) {
@@ -2721,7 +2707,6 @@
* @hide
*/
@SystemApi
- @TestApi
public final void resetConnectionTime() {
for (Listener l : mListeners) {
l.onConnectionTimeReset(this);
@@ -3505,7 +3490,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void setPhoneAccountHandle(@NonNull PhoneAccountHandle phoneAccountHandle) {
if (mPhoneAccountHandle != phoneAccountHandle) {
mPhoneAccountHandle = phoneAccountHandle;
@@ -3524,7 +3508,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @Nullable PhoneAccountHandle getPhoneAccountHandle() {
return mPhoneAccountHandle;
}
@@ -3590,7 +3573,6 @@
* @hide
*/
@SystemApi
- @TestApi
public void setCallDirection(@Call.Details.CallDirection int callDirection) {
mCallDirection = callDirection;
}
diff --git a/telecomm/java/android/telecom/ConnectionRequest.java b/telecomm/java/android/telecom/ConnectionRequest.java
index 6d7ceca..b73ef9b 100644
--- a/telecomm/java/android/telecom/ConnectionRequest.java
+++ b/telecomm/java/android/telecom/ConnectionRequest.java
@@ -327,7 +327,6 @@
* @hide
*/
@SystemApi
- @TestApi
public @Nullable String getTelecomCallId() {
return mTelecomCallId;
}
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 768c8ee..1cb8b2e 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -21,7 +21,6 @@
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.net.Uri;
@@ -619,7 +618,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(MODIFY_PHONE_STATE)
public @NonNull Builder setGroupId(@NonNull String groupId) {
if (groupId != null) {
diff --git a/telecomm/java/android/telecom/PhoneAccountSuggestionService.java b/telecomm/java/android/telecom/PhoneAccountSuggestionService.java
index ba3822c..8a91b9e 100644
--- a/telecomm/java/android/telecom/PhoneAccountSuggestionService.java
+++ b/telecomm/java/android/telecom/PhoneAccountSuggestionService.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
@@ -57,7 +56,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class PhoneAccountSuggestionService extends Service {
/**
* The {@link Intent} that must be declared in the {@code intent-filter} element of the
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index f2f1412..76d95f6 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -25,7 +25,6 @@
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
@@ -691,7 +690,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int TTY_MODE_OFF = 0;
@@ -701,7 +699,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int TTY_MODE_FULL = 1;
@@ -712,7 +709,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int TTY_MODE_HCO = 2;
@@ -723,7 +719,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int TTY_MODE_VCO = 3;
@@ -1016,7 +1011,6 @@
* @hide
*/
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- @TestApi
@SystemApi
public void setUserSelectedOutgoingPhoneAccount(@Nullable PhoneAccountHandle accountHandle) {
try {
@@ -1190,7 +1184,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(READ_PRIVILEGED_PHONE_STATE)
public @NonNull List<PhoneAccountHandle> getCallCapablePhoneAccounts(
boolean includeDisabledAccounts) {
@@ -1421,7 +1414,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(READ_PRIVILEGED_PHONE_STATE)
public @Nullable String getDefaultDialerPackage(@NonNull UserHandle userHandle) {
try {
@@ -1802,7 +1794,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(READ_PRIVILEGED_PHONE_STATE)
public @TtyMode int getCurrentTtyMode() {
try {
@@ -2215,7 +2206,6 @@
* @hide
*/
@SystemApi
- @TestApi
@NonNull
public Intent createLaunchEmergencyDialerIntent(@Nullable String number) {
ITelecomService service = getTelecomService();
@@ -2368,7 +2358,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public boolean isInEmergencyCall() {
try {
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index 39a7543..d012971 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -18,7 +18,6 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.hardware.radio.V1_1.GeranBands;
import android.hardware.radio.V1_5.AccessNetwork;
import android.hardware.radio.V1_5.EutranBands;
@@ -49,7 +48,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int TRANSPORT_TYPE_INVALID = -1;
/**
@@ -438,7 +436,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0;
/**
@@ -447,7 +444,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FREQUENCY_RANGE_GROUP_1 = 1;
/**
@@ -456,7 +452,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static final int FREQUENCY_RANGE_GROUP_2 = 2;
/**
@@ -481,7 +476,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static @FrequencyRangeGroup int getFrequencyRangeGroup(@NgranBand int band) {
switch (band) {
case BAND_1:
diff --git a/telephony/java/android/telephony/BarringInfo.java b/telephony/java/android/telephony/BarringInfo.java
index 92423a2..e9698ad 100644
--- a/telephony/java/android/telephony/BarringInfo.java
+++ b/telephony/java/android/telephony/BarringInfo.java
@@ -252,7 +252,6 @@
private SparseArray<BarringServiceInfo> mBarringServiceInfos;
/** @hide */
- @TestApi
@SystemApi
public BarringInfo() {
mBarringServiceInfos = new SparseArray<>();
diff --git a/telephony/java/android/telephony/CallQuality.java b/telephony/java/android/telephony/CallQuality.java
index 1c82e96..ff6a9bb 100644
--- a/telephony/java/android/telephony/CallQuality.java
+++ b/telephony/java/android/telephony/CallQuality.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,7 +40,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class CallQuality implements Parcelable {
// Constants representing the call quality level (see #CallQuality);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
old mode 100755
new mode 100644
index 3d455d5..11af8e0
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -23,7 +23,6 @@
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
@@ -4426,7 +4425,6 @@
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
@SystemApi
- @TestApi
public void overrideConfig(int subscriptionId, @Nullable PersistableBundle overrideValues) {
overrideConfig(subscriptionId, overrideValues, false);
}
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index c667165..0e30225 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -31,7 +30,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class DataSpecificRegistrationInfo implements Parcelable {
/**
* @hide
diff --git a/telephony/java/android/telephony/LteVopsSupportInfo.java b/telephony/java/android/telephony/LteVopsSupportInfo.java
index 7994c1b..83e41bf 100644
--- a/telephony/java/android/telephony/LteVopsSupportInfo.java
+++ b/telephony/java/android/telephony/LteVopsSupportInfo.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -33,7 +32,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class LteVopsSupportInfo implements Parcelable {
/**@hide*/
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 93fbb00..622ef13 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.AccessNetworkConstants.TransportType;
@@ -71,37 +70,37 @@
* Not registered. The device is not currently searching a new operator to register.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0;
/**
* Registered on home network.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int REGISTRATION_STATE_HOME = 1;
/**
* Not registered. The device is currently searching a new operator to register.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2;
/**
* Registration denied.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int REGISTRATION_STATE_DENIED = 3;
/**
* Registration state is unknown.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int REGISTRATION_STATE_UNKNOWN = 4;
/**
* Registered on roaming network.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int REGISTRATION_STATE_ROAMING = 5;
/** @hide */
@@ -383,7 +382,7 @@
*
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @RegistrationState int getRegistrationState() {
return mRegistrationState;
}
@@ -448,7 +447,7 @@
* @return the current network roaming type.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @ServiceState.RoamingType int getRoamingType() {
return mRoamingType;
}
@@ -457,7 +456,7 @@
* @return Whether emergency is enabled.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public boolean isEmergencyEnabled() { return mEmergencyOnly; }
/**
@@ -497,7 +496,7 @@
* 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 A.S0001 6.2.2.44 for CDMA
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public int getRejectCause() {
return mRejectCause;
}
@@ -523,7 +522,7 @@
* @hide
*/
@Nullable
- @SystemApi @TestApi
+ @SystemApi
public DataSpecificRegistrationInfo getDataSpecificInfo() {
return mDataSpecificInfo;
}
@@ -654,7 +653,7 @@
* @hide
*/
@Override
- @SystemApi @TestApi
+ @SystemApi
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mDomain);
dest.writeInt(mTransportType);
@@ -745,7 +744,7 @@
* </code></pre>
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final class Builder {
@Domain
private int mDomain;
@@ -850,7 +849,7 @@
* @return The same instance of the builder.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) {
mEmergencyOnly = emergencyOnly;
return this;
@@ -864,7 +863,7 @@
* @return The same instance of the builder.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @NonNull Builder setAvailableServices(
@NonNull @ServiceType List<Integer> availableServices) {
mAvailableServices = availableServices;
@@ -879,7 +878,7 @@
* @return The same instance of the builder.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) {
mCellIdentity = cellIdentity;
return this;
@@ -902,7 +901,7 @@
* @return the NetworkRegistrationInfo object.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @NonNull NetworkRegistrationInfo build() {
return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState,
mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index ec99408..58e368b 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -2239,7 +2239,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static boolean isVoiceMailNumber(@NonNull Context context, int subId,
@Nullable String number) {
String vmNumber, mdn;
@@ -2728,7 +2727,6 @@
* @return true if number contains @
*/
@SystemApi
- @TestApi
public static boolean isUriNumber(@Nullable String number) {
// Note we allow either "@" or "%40" to indicate a URI, in case
// the passed-in string is URI-escaped. (Neither "@" nor "%40"
@@ -2747,7 +2745,6 @@
* @hide
*/
@SystemApi
- @TestApi
public static @NonNull String getUsernameFromUriNumber(@NonNull String number) {
// The delimiter between username and domain name can be
// either "@" or "%40" (the URI-escaped equivalent.)
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index e9ee06c2..45070f6 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -32,7 +32,6 @@
import android.annotation.SuppressAutoDoc;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.app.PendingIntent;
import android.app.PropertyInvalidatedCache;
import android.compat.annotation.UnsupportedAppUsage;
@@ -280,7 +279,6 @@
*/
@NonNull
@SystemApi
- @TestApi
public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc");
/**
@@ -300,7 +298,6 @@
*/
@NonNull
@SystemApi
- @TestApi
public static final Uri ADVANCED_CALLING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "advanced_calling");
@@ -319,7 +316,6 @@
*/
@NonNull
@SystemApi
- @TestApi
public static final Uri WFC_MODE_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc_mode");
/**
@@ -337,7 +333,6 @@
*/
@NonNull
@SystemApi
- @TestApi
public static final Uri WFC_ROAMING_MODE_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "wfc_roaming_mode");
@@ -357,7 +352,6 @@
*/
@NonNull
@SystemApi
- @TestApi
public static final Uri VT_ENABLED_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "vt_enabled");
@@ -376,7 +370,6 @@
*/
@NonNull
@SystemApi
- @TestApi
public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "wfc_roaming_enabled");
@@ -1963,7 +1956,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setDefaultVoiceSubscriptionId(int subscriptionId) {
if (VDBG) logd("setDefaultVoiceSubId sub id = " + subscriptionId);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 3d51d7c..975fe41 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8508,13 +8508,13 @@
/**
* Values used to return status for hasCarrierPrivileges call.
*/
- /** @hide */ @SystemApi @TestApi
+ /** @hide */ @SystemApi
public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1;
- /** @hide */ @SystemApi @TestApi
+ /** @hide */ @SystemApi
public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0;
- /** @hide */ @SystemApi @TestApi
+ /** @hide */ @SystemApi
public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1;
- /** @hide */ @SystemApi @TestApi
+ /** @hide */ @SystemApi
public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2;
/**
@@ -8716,7 +8716,6 @@
/** @hide */
@SystemApi
- @TestApi
@SuppressLint("Doclava125")
public int checkCarrierPrivilegesForPackage(String pkgName) {
try {
@@ -8749,7 +8748,6 @@
/** @hide */
@SystemApi
- @TestApi
public List<String> getCarrierPackageNamesForIntent(Intent intent) {
return getCarrierPackageNamesForIntentAndPhone(intent, getPhoneId());
}
@@ -10258,7 +10256,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
public @Nullable ComponentName getAndUpdateDefaultRespondViaMessageApplication() {
return SmsApplication.getDefaultRespondViaMessageApplication(mContext, true);
@@ -10271,7 +10268,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
public @Nullable ComponentName getDefaultRespondViaMessageApplication() {
return SmsApplication.getDefaultRespondViaMessageApplication(mContext, false);
@@ -11886,7 +11882,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1;
@@ -11926,7 +11921,6 @@
*/
@RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
@SystemApi
- @TestApi
public void updateOtaEmergencyNumberDbFilePath(
@NonNull ParcelFileDescriptor otaParcelFileDescriptor) {
try {
@@ -11952,7 +11946,6 @@
*/
@RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
@SystemApi
- @TestApi
public void resetOtaEmergencyNumberDbFilePath() {
try {
ITelephony telephony = getITelephony();
@@ -12173,7 +12166,6 @@
*
* @hide
*/
- @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public int getEmergencyNumberDbVersion() {
@@ -12901,7 +12893,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void setSystemSelectionChannels(@NonNull List<RadioAccessSpecifier> specifiers,
@NonNull @CallbackExecutor Executor executor,
@@ -12919,7 +12910,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void setSystemSelectionChannels(@NonNull List<RadioAccessSpecifier> specifiers) {
Objects.requireNonNull(specifiers, "Specifiers must not be null.");
diff --git a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java
index d53a2e6..3f9c8d2 100644
--- a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java
+++ b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java
@@ -19,7 +19,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -33,7 +32,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class ImsCallForwardInfo implements Parcelable {
/**
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index f31fcf4..47a0ab6 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -48,7 +48,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class ImsCallProfile implements Parcelable {
private static final String TAG = "ImsCallProfile";
diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
index 81af99f..b3907ff 100644
--- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java
+++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.RemoteException;
import android.telephony.Annotation;
import android.telephony.CallQuality;
@@ -40,7 +39,6 @@
// TODO: APIs in here do not conform to API guidelines yet. This can be changed if
// ImsCallSessionListenerConverter is also changed.
@SystemApi
-@TestApi
public class ImsCallSessionListener {
private final IImsCallSessionListener mListener;
diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java
index 21bef00..13f1a79 100644
--- a/telephony/java/android/telephony/ims/ImsConferenceState.java
+++ b/telephony/java/android/telephony/ims/ImsConferenceState.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -38,7 +37,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class ImsConferenceState implements Parcelable {
private static final String TAG = "ImsConferenceState";
/**
diff --git a/telephony/java/android/telephony/ims/ImsException.java b/telephony/java/android/telephony/ims/ImsException.java
index 1c3d58d..50fb828 100644
--- a/telephony/java/android/telephony/ims/ImsException.java
+++ b/telephony/java/android/telephony/ims/ImsException.java
@@ -19,7 +19,6 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.pm.PackageManager;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
@@ -83,7 +82,6 @@
* @hide
*/
@SystemApi
- @TestApi
public ImsException(@Nullable String message) {
super(getMessage(message, CODE_ERROR_UNSPECIFIED));
}
@@ -94,7 +92,6 @@
* @hide
*/
@SystemApi
- @TestApi
public ImsException(@Nullable String message, @ImsErrorCode int code) {
super(getMessage(message, code));
mCode = code;
@@ -108,7 +105,6 @@
* @hide
*/
@SystemApi
- @TestApi
public ImsException(@Nullable String message, @ImsErrorCode int code,
@Nullable Throwable cause) {
super(getMessage(message, code), cause);
diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java
index 7d73165..fdf636c 100644
--- a/telephony/java/android/telephony/ims/ImsExternalCallState.java
+++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -35,7 +34,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class ImsExternalCallState implements Parcelable {
private static final String TAG = "ImsExternalCallState";
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index f6c14e6..9300a1c 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -25,7 +25,6 @@
import android.annotation.SuppressAutoDoc;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -96,7 +95,7 @@
*/
// Do not add to this class, add to RegistrationManager.RegistrationCallback instead.
@Deprecated
- @SystemApi @TestApi
+ @SystemApi
public static class RegistrationCallback extends RegistrationManager.RegistrationCallback {
/**
@@ -230,7 +229,6 @@
* @hide
*/
@SystemApi
- @TestApi
@Deprecated
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(anyOf = {
@@ -279,7 +277,7 @@
* @hide
*/
@Deprecated
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull RegistrationCallback c) throws ImsException {
@@ -365,7 +363,7 @@
* @hide
*/
@Deprecated
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c) {
if (c == null) {
@@ -421,7 +419,7 @@
* @hide
*/
@Override
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void getRegistrationState(@NonNull @CallbackExecutor Executor executor,
@NonNull @ImsRegistrationState Consumer<Integer> stateCallback) {
@@ -680,7 +678,7 @@
* @hide
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
- @SystemApi @TestApi
+ @SystemApi
public void setAdvancedCallingSettingEnabled(boolean isEnabled) {
ITelephony iTelephony = getITelephony();
if (iTelephony == null) {
@@ -724,7 +722,7 @@
* @hide
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- @SystemApi @TestApi
+ @SystemApi
public boolean isCapable(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
ITelephony iTelephony = getITelephony();
@@ -757,7 +755,7 @@
* otherwise.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isAvailable(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
@@ -789,7 +787,7 @@
* available.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void isSupported(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
@AccessNetworkConstants.TransportType int transportType,
@@ -878,7 +876,7 @@
* @see #isVtSettingEnabled()
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVtSettingEnabled(boolean isEnabled) {
ITelephony iTelephony = getITelephony();
@@ -953,7 +951,7 @@
* @see #isVoWiFiSettingEnabled()
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVoWiFiSettingEnabled(boolean isEnabled) {
ITelephony iTelephony = getITelephony();
@@ -1031,7 +1029,7 @@
* @see #isVoWiFiRoamingSettingEnabled()
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVoWiFiRoamingSettingEnabled(boolean isEnabled) {
ITelephony iTelephony = getITelephony();
@@ -1068,7 +1066,7 @@
* @see #setVoWiFiSettingEnabled(boolean)
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVoWiFiNonPersistent(boolean isCapable, int mode) {
ITelephony iTelephony = getITelephony();
@@ -1151,7 +1149,7 @@
* @see #getVoWiFiModeSetting()
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVoWiFiModeSetting(@WiFiCallingMode int mode) {
ITelephony iTelephony = getITelephony();
@@ -1187,7 +1185,7 @@
* @see #setVoWiFiRoamingSettingEnabled(boolean)
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public @WiFiCallingMode int getVoWiFiRoamingModeSetting() {
ITelephony iTelephony = getITelephony();
@@ -1223,7 +1221,7 @@
* @see #getVoWiFiRoamingModeSetting()
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVoWiFiRoamingModeSetting(@WiFiCallingMode int mode) {
ITelephony iTelephony = getITelephony();
@@ -1257,7 +1255,7 @@
* @param isEnabled if true RTT should be enabled during calls made on this subscription.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setRttCapabilitySetting(boolean isEnabled) {
ITelephony iTelephony = getITelephony();
@@ -1337,7 +1335,7 @@
* the IMS service is not available.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void getFeatureState(@NonNull @CallbackExecutor Executor executor,
@NonNull @ImsFeature.ImsState Consumer<Integer> callback) throws ImsException {
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java
index 2b3072e..20736ee 100644
--- a/telephony/java/android/telephony/ims/ImsService.java
+++ b/telephony/java/android/telephony/ims/ImsService.java
@@ -17,7 +17,6 @@
package android.telephony.ims;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
@@ -92,7 +91,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class ImsService extends Service {
private static final String LOG_TAG = "ImsService";
@@ -369,4 +367,4 @@
public ImsRegistrationImplBase getRegistration(int slotId) {
return new ImsRegistrationImplBase();
}
-}
\ No newline at end of file
+}
diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java
index 70bf0c5..fb8e5d3 100644
--- a/telephony/java/android/telephony/ims/ImsSsData.java
+++ b/telephony/java/android/telephony/ims/ImsSsData.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -37,7 +36,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class ImsSsData implements Parcelable {
private static final String TAG = ImsSsData.class.getCanonicalName();
diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java
index 9cce95f..27b56b8 100644
--- a/telephony/java/android/telephony/ims/ImsSsInfo.java
+++ b/telephony/java/android/telephony/ims/ImsSsInfo.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -38,7 +37,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class ImsSsInfo implements Parcelable {
/**@hide*/
diff --git a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
index b70fd64..131cb1a 100644
--- a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
+++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,7 +29,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class ImsStreamMediaProfile implements Parcelable {
private static final String TAG = "ImsStreamMediaProfile";
diff --git a/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java
index f67f68e..1630368 100644
--- a/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java
+++ b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,7 +31,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class ImsSuppServiceNotification implements Parcelable {
private static final String TAG = "ImsSuppServiceNotification";
diff --git a/telephony/java/android/telephony/ims/ImsUtListener.java b/telephony/java/android/telephony/ims/ImsUtListener.java
index 460a032..baa0576 100644
--- a/telephony/java/android/telephony/ims/ImsUtListener.java
+++ b/telephony/java/android/telephony/ims/ImsUtListener.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.ims.stub.ImsUtImplBase;
@@ -34,7 +33,6 @@
// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
// will break other implementations of ImsUt maintained by other ImsServices.
@SystemApi
-@TestApi
public class ImsUtListener {
/**
diff --git a/telephony/java/android/telephony/ims/ImsVideoCallProvider.java b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java
index 569c6d5..2fca409 100644
--- a/telephony/java/android/telephony/ims/ImsVideoCallProvider.java
+++ b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java
@@ -17,14 +17,12 @@
package android.telephony.ims;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
-import android.telecom.Connection;
import android.telecom.VideoProfile;
import android.telecom.VideoProfile.CameraCapabilities;
import android.view.Surface;
@@ -37,7 +35,6 @@
* @hide
*/
@SystemApi
-@TestApi
public abstract class ImsVideoCallProvider {
private static final int MSG_SET_CALLBACK = 1;
private static final int MSG_SET_CAMERA = 2;
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 1a606b7..48d14b1 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -23,7 +23,6 @@
import android.annotation.RequiresPermission;
import android.annotation.StringDef;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.annotation.WorkerThread;
import android.os.Binder;
import android.os.RemoteException;
@@ -59,7 +58,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class ProvisioningManager {
/**@hide*/
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index ec11279..94113b4 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -22,7 +22,6 @@
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.Context;
import android.net.Uri;
import android.os.Binder;
@@ -31,7 +30,6 @@
import android.telephony.TelephonyFrameworkInitializer;
import android.telephony.ims.aidl.IImsRcsController;
import android.telephony.ims.aidl.IRcsUceControllerCallback;
-import android.telephony.ims.feature.RcsFeature;
import android.util.Log;
import java.lang.annotation.Retention;
@@ -380,7 +378,6 @@
* @hide
*/
@SystemApi
- @TestApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setUceSettingEnabled(boolean isEnabled) throws ImsException {
IImsRcsController imsRcsController = getIImsRcsController();
diff --git a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
index 1918bcb..87a5094 100644
--- a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
+++ b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -34,7 +33,6 @@
* {@hide}
*/
@SystemApi
-@TestApi
public final class CapabilityChangeRequest implements Parcelable {
/**
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index e5779b3..b0a7b62 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -44,7 +44,6 @@
* @hide
*/
@SystemApi
-@TestApi
public abstract class ImsFeature {
private static final String LOG_TAG = "ImsFeature";
@@ -62,19 +61,19 @@
* CSFB for emergency calling.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int FEATURE_EMERGENCY_MMTEL = 0;
/**
* This feature supports the MMTEL feature.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int FEATURE_MMTEL = 1;
/**
* This feature supports the RCS feature.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int FEATURE_RCS = 2;
/**
* Total number of features defined
@@ -124,7 +123,7 @@
* during this time will result in an {@link IllegalStateException}.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int STATE_UNAVAILABLE = 0;
/**
* This {@link ImsFeature} state is initializing and should not be communicated with. This will
@@ -132,14 +131,14 @@
* during this time will result in an {@link IllegalStateException}.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int STATE_INITIALIZING = 1;
/**
* This {@link ImsFeature} is ready for communication. Do not attempt to call framework methods
* until {@see #onFeatureReady()} is called.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int STATE_READY = 2;
/**
@@ -169,13 +168,13 @@
* The capability was unable to be changed.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int CAPABILITY_ERROR_GENERIC = -1;
/**
* The capability was able to be changed.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int CAPABILITY_SUCCESS = 0;
/**
@@ -349,7 +348,7 @@
* subscription IDs associated with this slot.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public final int getSlotIndex() {
return mSlotId;
}
@@ -359,7 +358,7 @@
* or {@link #STATE_UNAVAILABLE} if it has not been updated yet.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @ImsState int getFeatureState() {
synchronized (mLock) {
return mState;
@@ -373,7 +372,7 @@
* {@link #STATE_INITIALIZING}, or {@link #STATE_READY}.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public final void setFeatureState(@ImsState int state) {
synchronized (mLock) {
if (mState != state) {
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index b3b7b20..d3d194b 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
@@ -60,7 +59,7 @@
/**
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public MmTelFeature() {
}
@@ -228,7 +227,7 @@
* @see #removeCapabilities(int)
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public MmTelCapabilities() {
super();
}
@@ -237,7 +236,7 @@
* @hide
*/
@Deprecated
- @SystemApi @TestApi
+ @SystemApi
public MmTelCapabilities(Capabilities c) {
mCapabilities = c.mCapabilities;
}
@@ -248,7 +247,7 @@
* bitfield.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public MmTelCapabilities(@MmTelCapability int capabilities) {
super(capabilities);
}
@@ -288,7 +287,7 @@
* @hide
*/
@Override
- @SystemApi @TestApi
+ @SystemApi
public final void addCapabilities(@MmTelCapability int capabilities) {
super.addCapabilities(capabilities);
}
@@ -297,7 +296,7 @@
* @hide
*/
@Override
- @SystemApi @TestApi
+ @SystemApi
public final void removeCapabilities(@MmTelCapability int capability) {
super.removeCapabilities(capability);
}
@@ -306,7 +305,7 @@
* @hide
*/
@Override
- @SystemApi @TestApi
+ @SystemApi
public final boolean isCapable(@MmTelCapability int capabilities) {
return super.isCapable(capabilities);
}
@@ -343,7 +342,6 @@
* @hide
*/
@Override
- @SystemApi @TestApi
public void onIncomingCall(IImsCallSession c, Bundle extras) {
}
@@ -355,7 +353,6 @@
* @hide
*/
@Override
- @SystemApi @TestApi
public void onRejectedCall(ImsCallProfile callProfile, ImsReasonInfo reason) {
}
@@ -366,7 +363,6 @@
* @hide
*/
@Override
- @SystemApi @TestApi
public void onVoiceMessageCountUpdate(int count) {
}
@@ -377,14 +373,14 @@
* outgoing call as IMS.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int PROCESS_CALL_IMS = 0;
/**
* To be returned by {@link #shouldProcessCall(String[])} when the telephony framework should
* not process the outgoing call as IMS and should instead use circuit switch.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final int PROCESS_CALL_CSFB = 1;
/** @hide */
@@ -402,7 +398,7 @@
* This is an optional boolean flag.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD";
/**
@@ -415,7 +411,7 @@
* This is an optional boolean flag.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public static final String EXTRA_IS_UNKNOWN_CALL =
"android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
@@ -455,7 +451,7 @@
* @hide
*/
@Override
- @SystemApi @TestApi
+ @SystemApi
public @NonNull final MmTelCapabilities queryCapabilityStatus() {
return new MmTelCapabilities(super.queryCapabilityStatus());
}
@@ -470,7 +466,7 @@
* {@link #changeEnabledCapabilities}) should also show the status as disabled.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public final void notifyCapabilitiesStatusChanged(@NonNull MmTelCapabilities c) {
if (c == null) {
throw new IllegalArgumentException("MmTelCapabilities must be non-null!");
@@ -485,7 +481,7 @@
* {@link #EXTRA_IS_UNKNOWN_CALL} and {@link #EXTRA_IS_USSD} above.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public final void notifyIncomingCall(@NonNull ImsCallSessionImplBase c,
@NonNull Bundle extras) {
if (c == null || extras == null) {
@@ -511,7 +507,7 @@
* @param reason The {@link ImsReasonInfo} call rejection reason.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public final void notifyRejectedCall(@NonNull ImsCallProfile callProfile,
@NonNull ImsReasonInfo reason) {
if (callProfile == null || reason == null) {
@@ -550,7 +546,7 @@
* @link count the new Voice Message count.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public final void notifyVoiceMessageCountUpdate(int count) {
IImsMmTelListener listener = getListener();
if (listener == null) {
@@ -573,7 +569,7 @@
* @hide
*/
@Override
- @SystemApi @TestApi
+ @SystemApi
public boolean queryCapabilityConfiguration(@MmTelCapabilities.MmTelCapability int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
// Base implementation - Override to provide functionality
@@ -594,7 +590,7 @@
* * @hide
*/
@Override
- @SystemApi @TestApi
+ @SystemApi
public void changeEnabledCapabilities(@NonNull CapabilityChangeRequest request,
@NonNull CapabilityCallbackProxy c) {
// Base implementation, no-op
@@ -619,7 +615,7 @@
* @return a {@link ImsCallProfile} object
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @Nullable ImsCallProfile createCallProfile(int callSessionType, int callType) {
// Base Implementation - Should be overridden
return null;
@@ -642,7 +638,7 @@
* @param profile a call profile to make the call
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @Nullable ImsCallSessionImplBase createCallSession(@NonNull ImsCallProfile profile) {
// Base Implementation - Should be overridden
return null;
@@ -661,7 +657,7 @@
* call will be placed over IMS or via CSFB.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @ProcessCallResult int shouldProcessCall(@NonNull String[] numbers) {
return PROCESS_CALL_IMS;
}
@@ -696,7 +692,7 @@
* configuration.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @NonNull ImsUtImplBase getUt() {
// Base Implementation - Should be overridden
return new ImsUtImplBase();
@@ -707,7 +703,7 @@
* calls that support it.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @NonNull ImsEcbmImplBase getEcbm() {
// Base Implementation - Should be overridden
return new ImsEcbmImplBase();
@@ -718,7 +714,7 @@
* package processing for multi-endpoint.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @NonNull ImsMultiEndpointImplBase getMultiEndpoint() {
// Base Implementation - Should be overridden
return new ImsMultiEndpointImplBase();
@@ -746,7 +742,7 @@
* }
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public void setUiTtyMode(int mode, @Nullable Message onCompleteMessage) {
// Base Implementation - Should be overridden
}
@@ -782,7 +778,7 @@
* Provider.
* @hide
*/
- @SystemApi @TestApi
+ @SystemApi
public @NonNull ImsSmsImplBase getSmsImplementation() {
return new ImsSmsImplBase();
}
@@ -796,7 +792,7 @@
* @hide
*/
@Override
- @SystemApi @TestApi
+ @SystemApi
public void onFeatureRemoved() {
// Base Implementation - Should be overridden
}
@@ -806,7 +802,7 @@
* @hide
*/
@Override
- @SystemApi @TestApi
+ @SystemApi
public void onFeatureReady() {
// Base Implementation - Should be overridden
}
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index 98b0bcf..b8ae146 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -20,7 +20,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.net.Uri;
import android.os.RemoteException;
import android.telephony.ims.RcsContactUceCapability;
@@ -50,7 +49,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class RcsFeature extends ImsFeature {
private static final String LOG_TAG = "RcsFeature";
diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
index 73ba0e3..48bc0d6 100644
--- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Message;
import android.os.RemoteException;
import android.telephony.ims.ImsCallProfile;
@@ -39,7 +38,6 @@
* @hide
*/
@SystemApi
-@TestApi
// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
// will break other implementations of ImsCallSession maintained by other ImsServices.
public class ImsCallSessionImplBase implements AutoCloseable {
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index 6a2638b..dc72a22 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -19,7 +19,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.Context;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -51,7 +50,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class ImsConfigImplBase {
private static final String TAG = "ImsConfigImplBase";
diff --git a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java
index 4a3a2ea..06c35ea 100644
--- a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java
@@ -17,7 +17,6 @@
package android.telephony.ims.stub;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.RemoteException;
import android.util.Log;
@@ -34,7 +33,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class ImsEcbmImplBase {
private static final String TAG = "ImsEcbmImplBase";
diff --git a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
index 4e7307e..cd9ebbf 100644
--- a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
+++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.ims.feature.ImsFeature;
@@ -36,7 +35,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class ImsFeatureConfiguration implements Parcelable {
public static final class FeatureSlotPair {
diff --git a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java
index 0ae5bba..d002903 100644
--- a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java
@@ -17,7 +17,6 @@
package android.telephony.ims.stub;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.RemoteException;
import android.telephony.ims.ImsExternalCallState;
import android.util.Log;
@@ -38,7 +37,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class ImsMultiEndpointImplBase {
private static final String TAG = "MultiEndpointImplBase";
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index 7069e0a..aff92b5 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -18,7 +18,6 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.net.Uri;
import android.os.RemoteException;
import android.telephony.ims.ImsReasonInfo;
@@ -39,7 +38,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class ImsRegistrationImplBase {
private static final String LOG_TAG = "ImsRegistrationImplBase";
diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
index ce9a73a..36ece95 100644
--- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
@@ -19,7 +19,6 @@
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.RemoteException;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
@@ -38,7 +37,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class ImsSmsImplBase {
private static final String LOG_TAG = "SmsImplBase";
diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
index 8564f7a..f5219d5 100644
--- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.ims.ImsUtListener;
@@ -40,7 +39,6 @@
// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
// will break other implementations of ImsUt maintained by other ImsServices.
@SystemApi
-@TestApi
public class ImsUtImplBase {
/**
* Bar all incoming calls. (See 3GPP TS 24.611)
diff --git a/telephony/java/android/telephony/mbms/DownloadRequest.java b/telephony/java/android/telephony/mbms/DownloadRequest.java
index ac258cd..eb59f87 100644
--- a/telephony/java/android/telephony/mbms/DownloadRequest.java
+++ b/telephony/java/android/telephony/mbms/DownloadRequest.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.Intent;
import android.net.Uri;
import android.os.Parcel;
@@ -186,7 +185,6 @@
* @hide
*/
@SystemApi
- @TestApi
public Builder setServiceId(String serviceId) {
fileServiceId = serviceId;
return this;
diff --git a/telephony/java/android/telephony/mbms/FileInfo.java b/telephony/java/android/telephony/mbms/FileInfo.java
index ada2872..e52b2ce 100644
--- a/telephony/java/android/telephony/mbms/FileInfo.java
+++ b/telephony/java/android/telephony/mbms/FileInfo.java
@@ -17,7 +17,6 @@
package android.telephony.mbms;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -50,7 +49,6 @@
* @hide
*/
@SystemApi
- @TestApi
public FileInfo(Uri uri, String mimeType) {
this.uri = uri;
this.mimeType = mimeType;
diff --git a/telephony/java/android/telephony/mbms/FileServiceInfo.java b/telephony/java/android/telephony/mbms/FileServiceInfo.java
index 8c79ab6..8777e7f 100644
--- a/telephony/java/android/telephony/mbms/FileServiceInfo.java
+++ b/telephony/java/android/telephony/mbms/FileServiceInfo.java
@@ -17,7 +17,6 @@
package android.telephony.mbms;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -36,7 +35,6 @@
/** @hide */
@SystemApi
- @TestApi
public FileServiceInfo(Map<Locale, String> newNames, String newClassName,
List<Locale> newLocales, String newServiceId, Date start, Date end,
List<FileInfo> newFiles) {
diff --git a/telephony/java/android/telephony/mbms/StreamingServiceInfo.java b/telephony/java/android/telephony/mbms/StreamingServiceInfo.java
index 8ad1d89..316e8656 100644
--- a/telephony/java/android/telephony/mbms/StreamingServiceInfo.java
+++ b/telephony/java/android/telephony/mbms/StreamingServiceInfo.java
@@ -17,7 +17,6 @@
package android.telephony.mbms;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -42,7 +41,6 @@
* @hide
*/
@SystemApi
- @TestApi
public StreamingServiceInfo(Map<Locale, String> names, String className,
List<Locale> locales, String serviceId, Date start, Date end) {
super(names, className, locales, serviceId, start, end);
diff --git a/telephony/java/android/telephony/mbms/UriPathPair.java b/telephony/java/android/telephony/mbms/UriPathPair.java
index f53d7e0..9258919 100644
--- a/telephony/java/android/telephony/mbms/UriPathPair.java
+++ b/telephony/java/android/telephony/mbms/UriPathPair.java
@@ -17,7 +17,6 @@
package android.telephony.mbms;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.ContentResolver;
import android.net.Uri;
import android.os.Parcel;
@@ -30,7 +29,6 @@
* @hide
*/
@SystemApi
-@TestApi
public final class UriPathPair implements Parcelable {
private final Uri mFilePathUri;
private final Uri mContentUri;
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
index 9f22d0a..4e6fc0b 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
@@ -45,7 +44,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub {
private final Map<IBinder, DownloadStatusListener> mDownloadStatusListenerBinderMap =
new HashMap<>();
@@ -553,7 +551,6 @@
// Following two methods exist to workaround b/124210145
/** @hide */
@SystemApi
- @TestApi
@Override
public android.os.IBinder asBinder() {
return super.asBinder();
@@ -561,7 +558,6 @@
/** @hide */
@SystemApi
- @TestApi
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply,
int flags) throws RemoteException {
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java
index 1335b52..e5b18bb 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
@@ -41,7 +40,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class MbmsGroupCallServiceBase extends Service {
private final IBinder mInterface = new Stub() {
@Override
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
index cced447..e169b16 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
@@ -18,7 +18,6 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.Intent;
import android.net.Uri;
import android.os.Binder;
@@ -39,7 +38,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
/**
* Initialize streaming service for this app and subId, registering the listener.
@@ -299,7 +297,6 @@
// Following two methods exist to workaround b/124210145
/** @hide */
@SystemApi
- @TestApi
@Override
public android.os.IBinder asBinder() {
return super.asBinder();
@@ -307,7 +304,6 @@
/** @hide */
@SystemApi
- @TestApi
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply,
int flags) throws RemoteException {
diff --git a/telephony/java/android/telephony/mbms/vendor/VendorUtils.java b/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
index f1cac8c..a43f122 100644
--- a/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
+++ b/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
@@ -17,7 +17,6 @@
package android.telephony.mbms.vendor;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -35,7 +34,6 @@
* @hide
*/
@SystemApi
-@TestApi
public class VendorUtils {
/**
diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt
index 32ca250..79d746a 100644
--- a/test-mock/api/test-current.txt
+++ b/test-mock/api/test-current.txt
@@ -6,21 +6,12 @@
}
@Deprecated public class MockPackageManager extends android.content.pm.PackageManager {
- method public void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener);
- method public boolean arePermissionsIndividuallyControlled();
- method public String getDefaultBrowserPackageNameAsUser(int);
method public int getInstallReason(String, android.os.UserHandle);
method public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int);
- method public java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int);
method public String[] getNamesForUids(int[]);
method public String getPermissionControllerPackageName();
- method public int getPermissionFlags(String, String, android.os.UserHandle);
method @NonNull public String getServicesSystemSharedLibraryPackageName();
method @NonNull public String getSharedSystemSharedLibraryPackageName();
- method public void grantRuntimePermission(String, String, android.os.UserHandle);
- method public void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener);
- method public void revokeRuntimePermission(String, String, android.os.UserHandle);
- method public void updatePermissionFlags(String, String, int, int, android.os.UserHandle);
}
}
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 124b660..464505e 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -42,6 +42,10 @@
android_test {
name: "FrameworksNetTests",
+ // Not built on module branch because these tests depend
+ // on net-tests-utils (frameworks/libs/net), which could
+ // be newer than frameworks/base.
+ enabled: false,
defaults: ["FrameworksNetTests-jni-defaults"],
srcs: [
"java/**/*.java",
diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp
index 46d680f..373aac6 100644
--- a/tests/net/common/Android.bp
+++ b/tests/net/common/Android.bp
@@ -25,6 +25,7 @@
"junit",
"mockito-target-minus-junit4",
"net-tests-utils",
+ "net-utils-framework-common",
"platform-test-annotations",
],
libs: [
diff --git a/tests/net/common/java/android/net/DhcpInfoTest.java b/tests/net/common/java/android/net/DhcpInfoTest.java
index 4d45ad7..ab4726b 100644
--- a/tests/net/common/java/android/net/DhcpInfoTest.java
+++ b/tests/net/common/java/android/net/DhcpInfoTest.java
@@ -17,8 +17,8 @@
package android.net;
import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTL;
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-import static com.android.testutils.ParcelUtilsKt.parcelingRoundTrip;
+import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
+import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/common/java/android/net/IpPrefixTest.java b/tests/net/common/java/android/net/IpPrefixTest.java
index 985e10d..9c0fc7c 100644
--- a/tests/net/common/java/android/net/IpPrefixTest.java
+++ b/tests/net/common/java/android/net/IpPrefixTest.java
@@ -16,10 +16,10 @@
package android.net;
-import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.MiscAsserts.assertEqualBothWays;
+import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
+import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/common/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java
index c74c112..60308e3 100644
--- a/tests/net/common/java/android/net/LinkAddressTest.java
+++ b/tests/net/common/java/android/net/LinkAddressTest.java
@@ -27,10 +27,10 @@
import static android.system.OsConstants.RT_SCOPE_SITE;
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
-import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.MiscAsserts.assertEqualBothWays;
+import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
+import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index 6eba62e..f52ab5b 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -20,9 +20,9 @@
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.RouteInfo.RTN_UNREACHABLE;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
-import static com.android.testutils.ParcelUtilsKt.parcelingRoundTrip;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
+import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -32,7 +32,6 @@
import static org.junit.Assert.fail;
import android.net.LinkProperties.ProvisioningChange;
-import android.net.util.LinkPropertiesUtils.CompareResult;
import android.os.Build;
import android.system.OsConstants;
import android.util.ArraySet;
@@ -41,6 +40,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -447,23 +447,21 @@
assertEquals(3, lp.getRoutes().size());
assertAllRoutesHaveInterface("wlan0", lp);
- // Check comparisons work.
+ // Check routes are updated correctly when calling setInterfaceName.
LinkProperties lp2 = new LinkProperties(lp);
assertAllRoutesHaveInterface("wlan0", lp2);
- // LinkProperties#compareAllRoutes exists both in R and before R, but the return type
- // changed in R, so a test compiled with the R version of LinkProperties cannot run on Q.
- if (isAtLeastR()) {
- assertEquals(0, lp.compareAllRoutes(lp2).added.size());
- assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
- }
+ final CompareResult<RouteInfo> cr1 =
+ new CompareResult<>(lp.getAllRoutes(), lp2.getAllRoutes());
+ assertEquals(0, cr1.added.size());
+ assertEquals(0, cr1.removed.size());
lp2.setInterfaceName("p2p0");
assertAllRoutesHaveInterface("p2p0", lp2);
assertAllRoutesNotHaveInterface("wlan0", lp2);
- if (isAtLeastR()) {
- assertEquals(3, lp.compareAllRoutes(lp2).added.size());
- assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
- }
+ final CompareResult<RouteInfo> cr2 =
+ new CompareResult<>(lp.getAllRoutes(), lp2.getAllRoutes());
+ assertEquals(3, cr2.added.size());
+ assertEquals(3, cr2.removed.size());
// Remove route with incorrect interface, no route removed.
lp.removeRoute(new RouteInfo(prefix2, null, null));
diff --git a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
index ef15b66..a5e44d5 100644
--- a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
+++ b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
@@ -19,13 +19,19 @@
import android.net.wifi.aware.DiscoverySession
import android.net.wifi.aware.PeerHandle
import android.net.wifi.aware.WifiAwareNetworkSpecifier
+import android.os.Build
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import com.android.testutils.assertParcelSane
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import java.lang.IllegalStateException
+import org.junit.Assert.assertFalse
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
@@ -33,18 +39,37 @@
@RunWith(AndroidJUnit4::class)
@SmallTest
class MatchAllNetworkSpecifierTest {
+ @Rule @JvmField
+ val ignoreRule: DevSdkIgnoreRule = DevSdkIgnoreRule()
+
+ private val specifier = MatchAllNetworkSpecifier()
+ private val discoverySession = Mockito.mock(DiscoverySession::class.java)
+ private val peerHandle = Mockito.mock(PeerHandle::class.java)
+ private val wifiAwareNetworkSpecifier = WifiAwareNetworkSpecifier.Builder(discoverySession,
+ peerHandle).build()
+
@Test
fun testParcel() {
assertParcelSane(MatchAllNetworkSpecifier(), 0)
}
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.Q)
+ @IgnoreAfter(Build.VERSION_CODES.R)
+ // Only run this test on Android R.
+ // The method - satisfiedBy() has changed to canBeSatisfiedBy() starting from Android R, so the
+ // method - canBeSatisfiedBy() cannot be found when running this test on Android Q.
+ fun testCanBeSatisfiedBy_OnlyForR() {
+ // MatchAllNetworkSpecifier didn't follow its parent class to change the satisfiedBy() to
+ // canBeSatisfiedBy(), so if a caller calls MatchAllNetworkSpecifier#canBeSatisfiedBy(), the
+ // NetworkSpecifier#canBeSatisfiedBy() will be called actually, and false will be returned.
+ // Although it's not meeting the expectation, the behavior still needs to be verified.
+ assertFalse(specifier.canBeSatisfiedBy(wifiAwareNetworkSpecifier))
+ }
+
@Test(expected = IllegalStateException::class)
- fun testSatisfiedBy() {
- val specifier = MatchAllNetworkSpecifier()
- val discoverySession = Mockito.mock(DiscoverySession::class.java)
- val peerHandle = Mockito.mock(PeerHandle::class.java)
- val wifiAwareNetworkSpecifier = WifiAwareNetworkSpecifier.Builder(discoverySession,
- peerHandle).build()
- specifier.satisfiedBy(wifiAwareNetworkSpecifier)
+ @IgnoreUpTo(Build.VERSION_CODES.R)
+ fun testCanBeSatisfiedBy() {
+ specifier.canBeSatisfiedBy(wifiAwareNetworkSpecifier)
}
}
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 3f8261d..e169312 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -42,8 +42,8 @@
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt
index b7c47c2..dd3f5be 100644
--- a/tests/net/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/net/common/java/android/net/NetworkProviderTest.kt
@@ -19,23 +19,23 @@
import android.app.Instrumentation
import android.content.Context
import android.net.NetworkCapabilities.TRANSPORT_TEST
+import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable
+import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn
+import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequested
import android.os.Build
import android.os.HandlerThread
import android.os.Looper
-import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable
-import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequested
-import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn
import androidx.test.InstrumentationRegistry
-import com.android.testutils.ArrayTrackRecord
+import com.android.net.module.util.ArrayTrackRecord
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
-import java.util.UUID
-import kotlin.test.assertEquals
-import kotlin.test.assertNotEquals
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import java.util.UUID
+import kotlin.test.assertEquals
+import kotlin.test.assertNotEquals
private const val DEFAULT_TIMEOUT_MS = 5000L
private val instrumentation: Instrumentation
diff --git a/tests/net/common/java/android/net/RouteInfoTest.java b/tests/net/common/java/android/net/RouteInfoTest.java
index 60cac0b..71689f9 100644
--- a/tests/net/common/java/android/net/RouteInfoTest.java
+++ b/tests/net/common/java/android/net/RouteInfoTest.java
@@ -18,10 +18,10 @@
import static android.net.RouteInfo.RTN_UNREACHABLE;
-import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.MiscAsserts.assertEqualBothWays;
+import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
+import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
index 8480544..d50406f 100644
--- a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
@@ -16,7 +16,7 @@
package android.net.apf;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/deflake/Android.bp b/tests/net/deflake/Android.bp
index b1b0171..828f59b 100644
--- a/tests/net/deflake/Android.bp
+++ b/tests/net/deflake/Android.bp
@@ -16,6 +16,10 @@
java_test_host {
name: "FrameworksNetDeflakeTest",
+ // Not built on module branch because these tests depend indirectly
+ // on net-tests-utils (frameworks/libs/net), which could be newer
+ // than frameworks/base.
+ enabled: false,
srcs: ["src/**/*.kt"],
libs: [
"junit",
diff --git a/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt b/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt
index fa2b99c..165fd37 100644
--- a/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt
+++ b/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt
@@ -14,6 +14,8 @@
* limitations under the License
*/
+@file:JvmName("ConnectivityServiceTestUtils")
+
package com.android.server
import android.net.ConnectivityManager.TYPE_BLUETOOTH
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index 0ffafd45..9f0b41f 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -24,7 +24,7 @@
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
-import static com.android.server.ConnectivityServiceTestUtilsKt.transportToLegacyType;
+import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType;
import static junit.framework.Assert.assertTrue;
@@ -49,7 +49,7 @@
import android.util.Log;
import com.android.server.connectivity.ConnectivityConstants;
-import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.HandlerUtils;
import com.android.testutils.TestableNetworkCallback;
import java.util.Set;
@@ -265,6 +265,6 @@
}
public void waitForIdle(long timeoutMs) {
- HandlerUtilsKt.waitForIdle(mHandlerThread, timeoutMs);
+ HandlerUtils.waitForIdle(mHandlerThread, timeoutMs);
}
}
diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java
index 91c9a2a..6de31f6 100644
--- a/tests/net/java/android/net/MacAddressTest.java
+++ b/tests/net/java/android/net/MacAddressTest.java
@@ -22,11 +22,11 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import android.net.util.MacAddressUtils;
-
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.net.module.util.MacAddressUtils;
+
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/net/java/com/android/server/NetIdManagerTest.kt b/tests/net/java/com/android/server/NetIdManagerTest.kt
index 045f89f..6f5e740 100644
--- a/tests/net/java/com/android/server/NetIdManagerTest.kt
+++ b/tests/net/java/com/android/server/NetIdManagerTest.kt
@@ -19,8 +19,8 @@
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import com.android.server.NetIdManager.MIN_NET_ID
-import com.android.testutils.ExceptionUtils.ThrowingRunnable
import com.android.testutils.assertThrows
+import com.android.testutils.ExceptionUtils.ThrowingRunnable
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
diff --git a/tests/utils/hostutils/src/com/android/tests/rollback/host/AbandonSessionsRule.java b/tests/utils/hostutils/src/com/android/tests/rollback/host/AbandonSessionsRule.java
new file mode 100644
index 0000000..b086213
--- /dev/null
+++ b/tests/utils/hostutils/src/com/android/tests/rollback/host/AbandonSessionsRule.java
@@ -0,0 +1,62 @@
+/*
+ * 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.tests.rollback.host;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.rules.ExternalResource;
+
+public class AbandonSessionsRule extends ExternalResource {
+ private final BaseHostJUnit4Test mHost;
+
+ public AbandonSessionsRule(BaseHostJUnit4Test host) {
+ mHost = host;
+ }
+
+ @Override
+ protected void before() throws Throwable {
+ abandonSessions(mHost.getDevice());
+ }
+
+ @Override
+ protected void after() {
+ try {
+ abandonSessions(mHost.getDevice());
+ } catch (Exception ignore) {
+ }
+ }
+
+ /**
+ * Abandons all sessions to prevent interference in our tests.
+ */
+ private static void abandonSessions(ITestDevice device) throws Exception {
+ // No point in abandoning applied or failed sessions. We care about ready sessions only.
+ String cmdListReadySessions =
+ "pm list staged-sessions --only-sessionid --only-parent --only-ready";
+ String output = device.executeShellCommand(cmdListReadySessions);
+ if (output.trim().isEmpty()) {
+ // No sessions to abandon
+ return;
+ }
+ // Ensure we have sufficient privilege to abandon sessions from other apps
+ device.enableAdbRoot();
+ device.executeShellCommand("for i in $(" + cmdListReadySessions
+ + "); do pm install-abandon $i; done");
+ device.disableAdbRoot();
+ }
+}
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 3a3fb28..72cb41a 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -1272,7 +1272,8 @@
return false;
}
- ClassDefinition::WriteJavaFile(manifest_class.get(), package_utf8, true, &fout);
+ ClassDefinition::WriteJavaFile(manifest_class.get(), package_utf8, true,
+ false /* strip_api_annotations */, &fout);
fout.Flush();
if (fout.HadError()) {
diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp
index cec59e7..482d91a 100644
--- a/tools/aapt2/java/AnnotationProcessor.cpp
+++ b/tools/aapt2/java/AnnotationProcessor.cpp
@@ -123,7 +123,7 @@
}
}
-void AnnotationProcessor::Print(Printer* printer) const {
+void AnnotationProcessor::Print(Printer* printer, bool strip_api_annotations) const {
if (has_comments_) {
std::string result = comment_.str();
for (const StringPiece& line : util::Tokenize(result, '\n')) {
@@ -137,6 +137,9 @@
printer->Println("@Deprecated");
}
+ if (strip_api_annotations) {
+ return;
+ }
for (const AnnotationRule& rule : sAnnotationRules) {
const auto& it = annotation_parameter_map_.find(rule.bit_mask);
if (it != annotation_parameter_map_.end()) {
diff --git a/tools/aapt2/java/AnnotationProcessor.h b/tools/aapt2/java/AnnotationProcessor.h
index fdb5846..f217afb 100644
--- a/tools/aapt2/java/AnnotationProcessor.h
+++ b/tools/aapt2/java/AnnotationProcessor.h
@@ -65,7 +65,7 @@
void AppendNewLine();
// Writes the comments and annotations to the Printer.
- void Print(text::Printer* printer) const;
+ void Print(text::Printer* printer, bool strip_api_annotations = false) const;
private:
std::stringstream comment_;
diff --git a/tools/aapt2/java/AnnotationProcessor_test.cpp b/tools/aapt2/java/AnnotationProcessor_test.cpp
index 7d0a4e9..6bc8902 100644
--- a/tools/aapt2/java/AnnotationProcessor_test.cpp
+++ b/tools/aapt2/java/AnnotationProcessor_test.cpp
@@ -91,6 +91,21 @@
EXPECT_THAT(annotations, HasSubstr("This is a test API"));
}
+TEST(AnnotationProcessorTest, NotEmitSystemApiAnnotation) {
+ AnnotationProcessor processor;
+ processor.AppendComment("@SystemApi This is a system API");
+
+ std::string annotations;
+ StringOutputStream out(&annotations);
+ Printer printer(&out);
+ processor.Print(&printer, true /* strip_api_annotations */);
+ out.Flush();
+
+ EXPECT_THAT(annotations, Not(HasSubstr("@android.annotation.SystemApi")));
+ EXPECT_THAT(annotations, Not(HasSubstr("@SystemApi")));
+ EXPECT_THAT(annotations, HasSubstr("This is a system API"));
+}
+
TEST(AnnotationProcessor, ExtractsFirstSentence) {
EXPECT_THAT(AnnotationProcessor::ExtractFirstSentence("This is the only sentence"),
Eq("This is the only sentence"));
diff --git a/tools/aapt2/java/ClassDefinition.cpp b/tools/aapt2/java/ClassDefinition.cpp
index f5f5b05..3163497 100644
--- a/tools/aapt2/java/ClassDefinition.cpp
+++ b/tools/aapt2/java/ClassDefinition.cpp
@@ -23,15 +23,15 @@
namespace aapt {
-void ClassMember::Print(bool /*final*/, Printer* printer) const {
- processor_.Print(printer);
+void ClassMember::Print(bool /*final*/, Printer* printer, bool strip_api_annotations) const {
+ processor_.Print(printer, strip_api_annotations);
}
void MethodDefinition::AppendStatement(const StringPiece& statement) {
statements_.push_back(statement.to_string());
}
-void MethodDefinition::Print(bool final, Printer* printer) const {
+void MethodDefinition::Print(bool final, Printer* printer, bool) const {
printer->Print(signature_).Println(" {");
printer->Indent();
for (const auto& statement : statements_) {
@@ -74,12 +74,12 @@
return true;
}
-void ClassDefinition::Print(bool final, Printer* printer) const {
+void ClassDefinition::Print(bool final, Printer* printer, bool strip_api_annotations) const {
if (empty() && !create_if_empty_) {
return;
}
- ClassMember::Print(final, printer);
+ ClassMember::Print(final, printer, strip_api_annotations);
printer->Print("public ");
if (qualifier_ == ClassQualifier::kStatic) {
@@ -93,7 +93,7 @@
// and takes precedence over a previous member with the same name. The overridden member is
// set to nullptr.
if (member != nullptr) {
- member->Print(final, printer);
+ member->Print(final, printer, strip_api_annotations);
printer->Println();
}
}
@@ -111,11 +111,11 @@
" */\n\n";
void ClassDefinition::WriteJavaFile(const ClassDefinition* def, const StringPiece& package,
- bool final, io::OutputStream* out) {
+ bool final, bool strip_api_annotations, io::OutputStream* out) {
Printer printer(out);
printer.Print(sWarningHeader).Print("package ").Print(package).Println(";");
printer.Println();
- def->Print(final, &printer);
+ def->Print(final, &printer, strip_api_annotations);
}
} // namespace aapt
diff --git a/tools/aapt2/java/ClassDefinition.h b/tools/aapt2/java/ClassDefinition.h
index fb11266..1e4b681 100644
--- a/tools/aapt2/java/ClassDefinition.h
+++ b/tools/aapt2/java/ClassDefinition.h
@@ -50,7 +50,7 @@
// Writes the class member to the Printer. Subclasses should derive this method
// to write their own data. Call this base method from the subclass to write out
// this member's comments/annotations.
- virtual void Print(bool final, text::Printer* printer) const;
+ virtual void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) const;
private:
AnnotationProcessor processor_;
@@ -70,10 +70,11 @@
return name_;
}
- void Print(bool final, text::Printer* printer) const override {
+ void Print(bool final, text::Printer* printer, bool strip_api_annotations = false)
+ const override {
using std::to_string;
- ClassMember::Print(final, printer);
+ ClassMember::Print(final, printer, strip_api_annotations);
printer->Print("public static ");
if (final) {
@@ -104,8 +105,9 @@
return name_;
}
- void Print(bool final, text::Printer* printer) const override {
- ClassMember::Print(final, printer);
+ void Print(bool final, text::Printer* printer, bool strip_api_annotations = false)
+ const override {
+ ClassMember::Print(final, printer, strip_api_annotations);
printer->Print("public static ");
if (final) {
@@ -142,8 +144,9 @@
return name_;
}
- void Print(bool final, text::Printer* printer) const override {
- ClassMember::Print(final, printer);
+ void Print(bool final, text::Printer* printer, bool strip_api_annotations = false)
+ const override {
+ ClassMember::Print(final, printer, strip_api_annotations);
printer->Print("public static final int[] ").Print(name_).Print("={");
printer->Indent();
@@ -195,7 +198,7 @@
return false;
}
- void Print(bool final, text::Printer* printer) const override;
+ void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) const override;
private:
DISALLOW_COPY_AND_ASSIGN(MethodDefinition);
@@ -209,7 +212,7 @@
class ClassDefinition : public ClassMember {
public:
static void WriteJavaFile(const ClassDefinition* def, const android::StringPiece& package,
- bool final, io::OutputStream* out);
+ bool final, bool strip_api_annotations, io::OutputStream* out);
ClassDefinition(const android::StringPiece& name, ClassQualifier qualifier, bool createIfEmpty)
: name_(name.to_string()), qualifier_(qualifier), create_if_empty_(createIfEmpty) {}
@@ -227,7 +230,7 @@
return name_;
}
- void Print(bool final, text::Printer* printer) const override;
+ void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) const override;
private:
DISALLOW_COPY_AND_ASSIGN(ClassDefinition);
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index bb541fe..dffad3b 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -604,6 +604,8 @@
rewrite_method->AppendStatement("final int packageIdBits = p << 24;");
}
+ const bool is_public = (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic);
+
for (const auto& package : table_->packages) {
for (const auto& type : package->types) {
if (type->type == ResourceType::kAttrPrivate) {
@@ -612,8 +614,7 @@
}
// Stay consistent with AAPT and generate an empty type class if the R class is public.
- const bool force_creation_if_empty =
- (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic);
+ const bool force_creation_if_empty = is_public;
std::unique_ptr<ClassDefinition> class_def;
if (out != nullptr) {
@@ -637,8 +638,7 @@
}
}
- if (out != nullptr && type->type == ResourceType::kStyleable &&
- options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic) {
+ if (out != nullptr && type->type == ResourceType::kStyleable && is_public) {
// When generating a public R class, we don't want Styleable to be part
// of the API. It is only emitted for documentation purposes.
class_def->GetCommentBuilder()->AppendComment("@doconly");
@@ -657,7 +657,7 @@
if (out != nullptr) {
AppendJavaDocAnnotations(options_.javadoc_annotations, r_class.GetCommentBuilder());
- ClassDefinition::WriteJavaFile(&r_class, out_package_name, options_.use_final, out);
+ ClassDefinition::WriteJavaFile(&r_class, out_package_name, options_.use_final, !is_public, out);
}
return true;
}
diff --git a/tools/aapt2/java/ManifestClassGenerator_test.cpp b/tools/aapt2/java/ManifestClassGenerator_test.cpp
index ab7f9a1..3858fc7 100644
--- a/tools/aapt2/java/ManifestClassGenerator_test.cpp
+++ b/tools/aapt2/java/ManifestClassGenerator_test.cpp
@@ -26,6 +26,7 @@
namespace aapt {
static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, xml::XmlResource* res,
+ bool strip_api_annotations,
std::string* out_str);
TEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) {
@@ -39,7 +40,8 @@
</manifest>)");
std::string actual;
- ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
+ ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(),
+ false /* strip_api_annotations */, &actual));
ASSERT_THAT(actual, HasSubstr("public static final class permission {"));
ASSERT_THAT(actual, HasSubstr("public static final class permission_group {"));
@@ -91,7 +93,8 @@
</manifest>)");
std::string actual;
- ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
+ ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(),
+ false /* strip_api_annotations */, &actual));
const char* expected_access_internet = R"( /**
* Required to access the internet.
@@ -123,6 +126,55 @@
EXPECT_THAT(actual, HasSubstr(expected_test));
}
+TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresentButNoApiAnnotations) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Required to access the internet.
+ Added in API 1. -->
+ <permission android:name="android.permission.ACCESS_INTERNET" />
+ <!-- @deprecated This permission is for playing outside. -->
+ <permission android:name="android.permission.PLAY_OUTSIDE" />
+ <!-- This is a private permission for system only!
+ @hide
+ @SystemApi -->
+ <permission android:name="android.permission.SECRET" />
+ <!-- @TestApi This is a test only permission. -->
+ <permission android:name="android.permission.TEST_ONLY" />
+ </manifest>)");
+
+ std::string actual;
+ ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(),
+ true /* strip_api_annotations */, &actual));
+
+ const char* expected_access_internet = R"( /**
+ * Required to access the internet.
+ * Added in API 1.
+ */
+ public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)";
+ EXPECT_THAT(actual, HasSubstr(expected_access_internet));
+
+ const char* expected_play_outside = R"( /**
+ * @deprecated This permission is for playing outside.
+ */
+ @Deprecated
+ public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)";
+ EXPECT_THAT(actual, HasSubstr(expected_play_outside));
+
+ const char* expected_secret = R"( /**
+ * This is a private permission for system only!
+ * @hide
+ */
+ public static final String SECRET="android.permission.SECRET";)";
+ EXPECT_THAT(actual, HasSubstr(expected_secret));
+
+ const char* expected_test = R"( /**
+ * This is a test only permission.
+ */
+ public static final String TEST_ONLY="android.permission.TEST_ONLY";)";
+ EXPECT_THAT(actual, HasSubstr(expected_test));
+}
+
// This is bad but part of public API behaviour so we need to preserve it.
TEST(ManifestClassGeneratorTest, LastSeenPermissionWithSameLeafNameTakesPrecedence) {
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
@@ -135,7 +187,8 @@
</manifest>)");
std::string actual;
- ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
+ ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(),
+ false /* strip_api_annotations */, &actual));
EXPECT_THAT(actual, HasSubstr("ACCESS_INTERNET=\"com.android.aapt.test.ACCESS_INTERNET\";"));
EXPECT_THAT(actual, Not(HasSubstr("ACCESS_INTERNET=\"android.permission.ACCESS_INTERNET\";")));
EXPECT_THAT(actual, Not(HasSubstr("ACCESS_INTERNET=\"com.android.sample.ACCESS_INTERNET\";")));
@@ -149,11 +202,13 @@
</manifest>)");
std::string actual;
- ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
+ ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(),
+ false /* strip_api_annotations */, &actual));
EXPECT_THAT(actual, HasSubstr("access_internet=\"android.permission.access-internet\";"));
}
static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, xml::XmlResource* res,
+ bool strip_api_annotations,
std::string* out_str) {
std::unique_ptr<ClassDefinition> manifest_class =
GenerateManifestClass(context->GetDiagnostics(), res);
@@ -162,7 +217,7 @@
}
StringOutputStream out(out_str);
- manifest_class->WriteJavaFile(manifest_class.get(), "android", true, &out);
+ manifest_class->WriteJavaFile(manifest_class.get(), "android", true, strip_api_annotations, &out);
out.Flush();
return ::testing::AssertionSuccess();
}
diff --git a/tools/stats_log_api_gen/.clang-format b/tools/stats_log_api_gen/.clang-format
deleted file mode 100644
index cead3a0..0000000
--- a/tools/stats_log_api_gen/.clang-format
+++ /dev/null
@@ -1,17 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: false
-AllowShortLoopsOnASingleLine: true
-BinPackArguments: true
-BinPackParameters: true
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-ContinuationIndentWidth: 8
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-AccessModifierOffset: -4
-IncludeCategories:
- - Regex: '^"Log\.h"'
- Priority: -1
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
deleted file mode 100644
index e3b6db0..0000000
--- a/tools/stats_log_api_gen/Android.bp
+++ /dev/null
@@ -1,131 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// ==========================================================
-// Build the host executable: stats-log-api-gen
-// ==========================================================
-cc_binary_host {
- name: "stats-log-api-gen",
- srcs: [
- "Collation.cpp",
- "java_writer.cpp",
- "java_writer_q.cpp",
- "main.cpp",
- "native_writer.cpp",
- "utils.cpp",
- ],
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- shared_libs: [
- "libstats_proto_host",
- "libprotobuf-cpp-full",
- "libbase",
- ],
-
- proto: {
- type: "full",
- },
-}
-
-// ==========================================================
-// Build the host test executable: stats-log-api-gen
-// ==========================================================
-cc_test_host {
- name: "stats-log-api-gen-test",
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-g",
- "-DUNIT_TEST",
- ],
- srcs: [
- "Collation.cpp",
- "test_collation.cpp",
- "test.proto",
- ],
-
- static_libs: [
- "libgmock_host",
- ],
-
- shared_libs: [
- "libstats_proto_host",
- "libprotobuf-cpp-full",
- ],
-
- proto: {
- type: "full",
- include_dirs: [
- "external/protobuf/src",
- ],
- },
-}
-
-// ==========================================================
-// Native library
-// ==========================================================
-genrule {
- name: "statslog.h",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog.h",
- out: [
- "statslog.h",
- ],
-}
-
-genrule {
- name: "statslog.cpp",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog.cpp",
- out: [
- "statslog.cpp",
- ],
-}
-
-cc_library {
- name: "libstatslog",
- host_supported: true,
- generated_sources: [
- "statslog.cpp",
- ],
- generated_headers: [
- "statslog.h"
- ],
- cflags: [
- "-Wall",
- "-Werror",
- ],
- export_generated_headers: [
- "statslog.h"
- ],
- shared_libs: [
- "liblog",
- "libcutils",
- ],
- target: {
- android: {
- shared_libs: ["libstatssocket"],
- },
- host: {
- static_libs: ["libstatssocket"],
- },
- },
-}
-
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
deleted file mode 100644
index a230de4..0000000
--- a/tools/stats_log_api_gen/Collation.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Collation.h"
-
-#include <stdio.h>
-
-#include <map>
-
-#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using google::protobuf::EnumDescriptor;
-using google::protobuf::FieldDescriptor;
-using google::protobuf::FileDescriptor;
-using google::protobuf::SourceLocation;
-using std::make_shared;
-using std::map;
-
-const bool dbg = false;
-
-//
-// AtomDecl class
-//
-
-AtomDecl::AtomDecl() : code(0), name() {
-}
-
-AtomDecl::AtomDecl(const AtomDecl& that)
- : code(that.code),
- name(that.name),
- message(that.message),
- fields(that.fields),
- fieldNumberToAnnotations(that.fieldNumberToAnnotations),
- primaryFields(that.primaryFields),
- exclusiveField(that.exclusiveField),
- defaultState(that.defaultState),
- triggerStateReset(that.triggerStateReset),
- nested(that.nested),
- uidField(that.uidField) {
-}
-
-AtomDecl::AtomDecl(int c, const string& n, const string& m) : code(c), name(n), message(m) {
-}
-
-AtomDecl::~AtomDecl() {
-}
-
-/**
- * Print an error message for a FieldDescriptor, including the file name and
- * line number.
- */
-static void print_error(const FieldDescriptor* field, const char* format, ...) {
- const Descriptor* message = field->containing_type();
- const FileDescriptor* file = message->file();
-
- SourceLocation loc;
- if (field->GetSourceLocation(&loc)) {
- // TODO: this will work if we can figure out how to pass
- // --include_source_info to protoc
- fprintf(stderr, "%s:%d: ", file->name().c_str(), loc.start_line);
- } else {
- fprintf(stderr, "%s: ", file->name().c_str());
- }
- va_list args;
- va_start(args, format);
- vfprintf(stderr, format, args);
- va_end(args);
-}
-
-/**
- * Convert a protobuf type into a java type.
- */
-static java_type_t java_type(const FieldDescriptor* field) {
- int protoType = field->type();
- switch (protoType) {
- case FieldDescriptor::TYPE_DOUBLE:
- return JAVA_TYPE_DOUBLE;
- case FieldDescriptor::TYPE_FLOAT:
- return JAVA_TYPE_FLOAT;
- case FieldDescriptor::TYPE_INT64:
- return JAVA_TYPE_LONG;
- case FieldDescriptor::TYPE_UINT64:
- return JAVA_TYPE_LONG;
- case FieldDescriptor::TYPE_INT32:
- return JAVA_TYPE_INT;
- case FieldDescriptor::TYPE_FIXED64:
- return JAVA_TYPE_LONG;
- case FieldDescriptor::TYPE_FIXED32:
- return JAVA_TYPE_INT;
- case FieldDescriptor::TYPE_BOOL:
- return JAVA_TYPE_BOOLEAN;
- case FieldDescriptor::TYPE_STRING:
- return JAVA_TYPE_STRING;
- case FieldDescriptor::TYPE_GROUP:
- return JAVA_TYPE_UNKNOWN;
- case FieldDescriptor::TYPE_MESSAGE:
- // TODO: not the final package name
- if (field->message_type()->full_name() == "android.os.statsd.AttributionNode") {
- return JAVA_TYPE_ATTRIBUTION_CHAIN;
- } else if (field->message_type()->full_name() == "android.os.statsd.KeyValuePair") {
- return JAVA_TYPE_KEY_VALUE_PAIR;
- } else if (field->options().GetExtension(os::statsd::log_mode) ==
- os::statsd::LogMode::MODE_BYTES) {
- return JAVA_TYPE_BYTE_ARRAY;
- } else {
- return JAVA_TYPE_OBJECT;
- }
- case FieldDescriptor::TYPE_BYTES:
- return JAVA_TYPE_BYTE_ARRAY;
- case FieldDescriptor::TYPE_UINT32:
- return JAVA_TYPE_INT;
- case FieldDescriptor::TYPE_ENUM:
- return JAVA_TYPE_ENUM;
- case FieldDescriptor::TYPE_SFIXED32:
- return JAVA_TYPE_INT;
- case FieldDescriptor::TYPE_SFIXED64:
- return JAVA_TYPE_LONG;
- case FieldDescriptor::TYPE_SINT32:
- return JAVA_TYPE_INT;
- case FieldDescriptor::TYPE_SINT64:
- return JAVA_TYPE_LONG;
- default:
- return JAVA_TYPE_UNKNOWN;
- }
-}
-
-/**
- * Gather the enums info.
- */
-void collate_enums(const EnumDescriptor& enumDescriptor, AtomField* atomField) {
- for (int i = 0; i < enumDescriptor.value_count(); i++) {
- atomField->enumValues[enumDescriptor.value(i)->number()] =
- enumDescriptor.value(i)->name().c_str();
- }
-}
-
-static void addAnnotationToAtomDecl(AtomDecl* atomDecl, const int fieldNumber,
- const AnnotationId annotationId,
- const AnnotationType annotationType,
- const AnnotationValue annotationValue) {
- if (dbg) {
- printf(" Adding annotation to %s: [%d] = {id: %d, type: %d}\n", atomDecl->name.c_str(),
- fieldNumber, annotationId, annotationType);
- }
- atomDecl->fieldNumberToAnnotations[fieldNumber].insert(
- make_shared<Annotation>(annotationId, atomDecl->code, annotationType, annotationValue));
-}
-
-static int collate_field_annotations(AtomDecl* atomDecl, const FieldDescriptor* field,
- const int fieldNumber, const java_type_t& javaType) {
- int errorCount = 0;
-
- if (field->options().HasExtension(os::statsd::state_field_option)) {
- const os::statsd::StateAtomFieldOption& stateFieldOption =
- field->options().GetExtension(os::statsd::state_field_option);
- const bool primaryField = stateFieldOption.primary_field();
- const bool exclusiveState = stateFieldOption.exclusive_state();
- const bool primaryFieldFirstUid = stateFieldOption.primary_field_first_uid();
-
- // Check the field is only one of primaryField, exclusiveState, or primaryFieldFirstUid.
- if (primaryField + primaryFieldFirstUid + exclusiveState > 1) {
- print_error(field,
- "Field can be max 1 of primary_field, exclusive_state, "
- "or primary_field_first_uid: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- }
-
- if (primaryField) {
- if (javaType == JAVA_TYPE_UNKNOWN || javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
- javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) {
- print_error(field, "Invalid primary state field: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- } else {
- atomDecl->primaryFields.push_back(fieldNumber);
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_PRIMARY_FIELD,
- ANNOTATION_TYPE_BOOL, AnnotationValue(true));
- }
- }
-
- if (primaryFieldFirstUid) {
- if (javaType != JAVA_TYPE_ATTRIBUTION_CHAIN) {
- print_error(field,
- "PRIMARY_FIELD_FIRST_UID annotation is only for AttributionChains: "
- "'%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- } else {
- atomDecl->primaryFields.push_back(FIRST_UID_IN_CHAIN_ID);
- addAnnotationToAtomDecl(atomDecl, fieldNumber,
- ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, ANNOTATION_TYPE_BOOL,
- AnnotationValue(true));
- }
- }
-
- if (exclusiveState) {
- if (javaType == JAVA_TYPE_UNKNOWN || javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
- javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) {
- print_error(field, "Invalid exclusive state field: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- }
-
- if (atomDecl->exclusiveField != 0) {
- print_error(field,
- "Cannot have more than one exclusive state field in an "
- "atom: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- } else {
- atomDecl->exclusiveField = fieldNumber;
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_EXCLUSIVE_STATE,
- ANNOTATION_TYPE_BOOL, AnnotationValue(true));
- }
-
- if (stateFieldOption.has_default_state_value()) {
- const int defaultState = stateFieldOption.default_state_value();
- atomDecl->defaultState = defaultState;
-
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_DEFAULT_STATE,
- ANNOTATION_TYPE_INT, AnnotationValue(defaultState));
- }
-
- if (stateFieldOption.has_trigger_state_reset_value()) {
- const int triggerStateReset = stateFieldOption.trigger_state_reset_value();
-
- atomDecl->triggerStateReset = triggerStateReset;
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_TRIGGER_STATE_RESET,
- ANNOTATION_TYPE_INT, AnnotationValue(triggerStateReset));
- }
-
- if (stateFieldOption.has_nested()) {
- const bool nested = stateFieldOption.nested();
- atomDecl->nested = nested;
-
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_STATE_NESTED,
- ANNOTATION_TYPE_BOOL, AnnotationValue(nested));
- }
- }
- }
-
- if (field->options().GetExtension(os::statsd::is_uid) == true) {
- if (javaType != JAVA_TYPE_INT) {
- print_error(field, "is_uid annotation can only be applied to int32 fields: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- }
-
- if (atomDecl->uidField == 0) {
- atomDecl->uidField = fieldNumber;
-
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_IS_UID,
- ANNOTATION_TYPE_BOOL, AnnotationValue(true));
- } else {
- print_error(field,
- "Cannot have more than one field in an atom with is_uid "
- "annotation: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- }
- }
-
- return errorCount;
-}
-
-/**
- * Gather the info about an atom proto.
- */
-int collate_atom(const Descriptor* atom, AtomDecl* atomDecl, vector<java_type_t>* signature) {
- int errorCount = 0;
-
- // Build a sorted list of the fields. Descriptor has them in source file
- // order.
- map<int, const FieldDescriptor*> fields;
- for (int j = 0; j < atom->field_count(); j++) {
- const FieldDescriptor* field = atom->field(j);
- fields[field->number()] = field;
- }
-
- // Check that the parameters start at 1 and go up sequentially.
- int expectedNumber = 1;
- for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end();
- it++) {
- const int number = it->first;
- const FieldDescriptor* field = it->second;
- if (number != expectedNumber) {
- print_error(field,
- "Fields must be numbered consecutively starting at 1:"
- " '%s' is %d but should be %d\n",
- field->name().c_str(), number, expectedNumber);
- errorCount++;
- expectedNumber = number;
- continue;
- }
- expectedNumber++;
- }
-
- // Check that only allowed types are present. Remove any invalid ones.
- for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end();
- it++) {
- const FieldDescriptor* field = it->second;
- bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) ==
- os::statsd::LogMode::MODE_BYTES;
-
- java_type_t javaType = java_type(field);
-
- if (javaType == JAVA_TYPE_UNKNOWN) {
- print_error(field, "Unknown type for field: %s\n", field->name().c_str());
- errorCount++;
- continue;
- } else if (javaType == JAVA_TYPE_OBJECT && atomDecl->code < PULL_ATOM_START_ID) {
- // Allow attribution chain, but only at position 1.
- print_error(field, "Message type not allowed for field in pushed atoms: %s\n",
- field->name().c_str());
- errorCount++;
- continue;
- } else if (javaType == JAVA_TYPE_BYTE_ARRAY && !isBinaryField) {
- print_error(field, "Raw bytes type not allowed for field: %s\n", field->name().c_str());
- errorCount++;
- continue;
- }
-
- if (isBinaryField && javaType != JAVA_TYPE_BYTE_ARRAY) {
- print_error(field, "Cannot mark field %s as bytes.\n", field->name().c_str());
- errorCount++;
- continue;
- }
-
- // Doubles are not supported yet.
- if (javaType == JAVA_TYPE_DOUBLE) {
- print_error(field,
- "Doubles are not supported in atoms. Please change field %s "
- "to float\n",
- field->name().c_str());
- errorCount++;
- continue;
- }
-
- if (field->is_repeated() &&
- !(javaType == JAVA_TYPE_ATTRIBUTION_CHAIN || javaType == JAVA_TYPE_KEY_VALUE_PAIR)) {
- print_error(field,
- "Repeated fields are not supported in atoms. Please make "
- "field %s not "
- "repeated.\n",
- field->name().c_str());
- errorCount++;
- continue;
- }
- }
-
- // Check that if there's an attribution chain, it's at position 1.
- for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end();
- it++) {
- int number = it->first;
- if (number != 1) {
- const FieldDescriptor* field = it->second;
- java_type_t javaType = java_type(field);
- if (javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- print_error(field,
- "AttributionChain fields must have field id 1, in message: '%s'\n",
- atom->name().c_str());
- errorCount++;
- }
- }
- }
-
- // Build the type signature and the atom data.
- for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end();
- it++) {
- const FieldDescriptor* field = it->second;
- java_type_t javaType = java_type(field);
- bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) ==
- os::statsd::LogMode::MODE_BYTES;
-
- AtomField atField(field->name(), javaType);
-
- if (javaType == JAVA_TYPE_ENUM) {
- // All enums are treated as ints when it comes to function signatures.
- collate_enums(*field->enum_type(), &atField);
- }
-
- // Generate signature for pushed atoms
- if (atomDecl->code < PULL_ATOM_START_ID) {
- if (javaType == JAVA_TYPE_ENUM) {
- // All enums are treated as ints when it comes to function signatures.
- signature->push_back(JAVA_TYPE_INT);
- } else if (javaType == JAVA_TYPE_OBJECT && isBinaryField) {
- signature->push_back(JAVA_TYPE_BYTE_ARRAY);
- } else {
- signature->push_back(javaType);
- }
- }
-
- atomDecl->fields.push_back(atField);
-
- errorCount += collate_field_annotations(atomDecl, field, it->first, javaType);
- }
-
- return errorCount;
-}
-
-// This function flattens the fields of the AttributionNode proto in an Atom
-// proto and generates the corresponding atom decl and signature.
-bool get_non_chained_node(const Descriptor* atom, AtomDecl* atomDecl,
- vector<java_type_t>* signature) {
- // Build a sorted list of the fields. Descriptor has them in source file
- // order.
- map<int, const FieldDescriptor*> fields;
- for (int j = 0; j < atom->field_count(); j++) {
- const FieldDescriptor* field = atom->field(j);
- fields[field->number()] = field;
- }
-
- AtomDecl attributionDecl;
- vector<java_type_t> attributionSignature;
- collate_atom(android::os::statsd::AttributionNode::descriptor(), &attributionDecl,
- &attributionSignature);
-
- // Build the type signature and the atom data.
- bool has_attribution_node = false;
- for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end();
- it++) {
- const FieldDescriptor* field = it->second;
- java_type_t javaType = java_type(field);
- if (javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- atomDecl->fields.insert(atomDecl->fields.end(), attributionDecl.fields.begin(),
- attributionDecl.fields.end());
- signature->insert(signature->end(), attributionSignature.begin(),
- attributionSignature.end());
- has_attribution_node = true;
-
- } else {
- AtomField atField(field->name(), javaType);
- if (javaType == JAVA_TYPE_ENUM) {
- // All enums are treated as ints when it comes to function signatures.
- signature->push_back(JAVA_TYPE_INT);
- collate_enums(*field->enum_type(), &atField);
- } else {
- signature->push_back(javaType);
- }
- atomDecl->fields.push_back(atField);
- }
- }
- return has_attribution_node;
-}
-
-static void populateFieldNumberToAtomDeclSet(const shared_ptr<AtomDecl>& atomDecl,
- FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet) {
- for (FieldNumberToAnnotations::const_iterator it = atomDecl->fieldNumberToAnnotations.begin();
- it != atomDecl->fieldNumberToAnnotations.end(); it++) {
- const int fieldNumber = it->first;
- (*fieldNumberToAtomDeclSet)[fieldNumber].insert(atomDecl);
- }
-}
-
-/**
- * Gather the info about the atoms.
- */
-int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms* atoms) {
- int errorCount = 0;
-
- for (int i = 0; i < descriptor->field_count(); i++) {
- const FieldDescriptor* atomField = descriptor->field(i);
-
- if (moduleName != DEFAULT_MODULE_NAME) {
- const int moduleCount = atomField->options().ExtensionSize(os::statsd::module);
- int j;
- for (j = 0; j < moduleCount; ++j) {
- const string atomModuleName =
- atomField->options().GetExtension(os::statsd::module, j);
- if (atomModuleName == moduleName) {
- break;
- }
- }
-
- // This atom is not in the module we're interested in; skip it.
- if (moduleCount == j) {
- if (dbg) {
- printf(" Skipping %s (%d)\n", atomField->name().c_str(), atomField->number());
- }
- continue;
- }
- }
-
- if (dbg) {
- printf(" %s (%d)\n", atomField->name().c_str(), atomField->number());
- }
-
- // StatsEvent only has one oneof, which contains only messages. Don't allow
- // other types.
- if (atomField->type() != FieldDescriptor::TYPE_MESSAGE) {
- print_error(atomField,
- "Bad type for atom. StatsEvent can only have message type "
- "fields: %s\n",
- atomField->name().c_str());
- errorCount++;
- continue;
- }
-
- const Descriptor* atom = atomField->message_type();
- shared_ptr<AtomDecl> atomDecl =
- make_shared<AtomDecl>(atomField->number(), atomField->name(), atom->name());
-
- if (atomDecl->code < PULL_ATOM_START_ID &&
- atomField->options().GetExtension(os::statsd::truncate_timestamp)) {
- addAnnotationToAtomDecl(atomDecl.get(), ATOM_ID_FIELD_NUMBER,
- ANNOTATION_ID_TRUNCATE_TIMESTAMP, ANNOTATION_TYPE_BOOL,
- AnnotationValue(true));
- if (dbg) {
- printf("%s can have timestamp truncated\n", atomField->name().c_str());
- }
- }
-
- vector<java_type_t> signature;
- errorCount += collate_atom(atom, atomDecl.get(), &signature);
- if (atomDecl->primaryFields.size() != 0 && atomDecl->exclusiveField == 0) {
- print_error(atomField, "Cannot have a primary field without an exclusive field: %s\n",
- atomField->name().c_str());
- errorCount++;
- continue;
- }
-
- FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = atoms->signatureInfoMap[signature];
- populateFieldNumberToAtomDeclSet(atomDecl, &fieldNumberToAtomDeclSet);
-
- atoms->decls.insert(atomDecl);
-
- shared_ptr<AtomDecl> nonChainedAtomDecl =
- make_shared<AtomDecl>(atomField->number(), atomField->name(), atom->name());
- vector<java_type_t> nonChainedSignature;
- if (get_non_chained_node(atom, nonChainedAtomDecl.get(), &nonChainedSignature)) {
- FieldNumberToAtomDeclSet& nonChainedFieldNumberToAtomDeclSet =
- atoms->nonChainedSignatureInfoMap[nonChainedSignature];
- populateFieldNumberToAtomDeclSet(nonChainedAtomDecl,
- &nonChainedFieldNumberToAtomDeclSet);
-
- atoms->non_chained_decls.insert(nonChainedAtomDecl);
- }
- }
-
- if (dbg) {
- printf("signatures = [\n");
- for (SignatureInfoMap::const_iterator it = atoms->signatureInfoMap.begin();
- it != atoms->signatureInfoMap.end(); it++) {
- printf(" ");
- for (vector<java_type_t>::const_iterator jt = it->first.begin(); jt != it->first.end();
- jt++) {
- printf(" %d", (int)*jt);
- }
- printf("\n");
- }
- printf("]\n");
- }
-
- return errorCount;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
deleted file mode 100644
index 10b34ec..0000000
--- a/tools/stats_log_api_gen/Collation.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_STATS_LOG_API_GEN_COLLATION_H
-#define ANDROID_STATS_LOG_API_GEN_COLLATION_H
-
-#include <google/protobuf/descriptor.h>
-#include <stdint.h>
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "frameworks/base/cmds/statsd/src/atom_field_options.pb.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using google::protobuf::Descriptor;
-using google::protobuf::FieldDescriptor;
-using std::map;
-using std::set;
-using std::shared_ptr;
-using std::string;
-using std::vector;
-
-const int PULL_ATOM_START_ID = 10000;
-
-const int FIRST_UID_IN_CHAIN_ID = 0;
-
-enum AnnotationId : uint8_t {
- ANNOTATION_ID_IS_UID = 1,
- ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2,
- ANNOTATION_ID_PRIMARY_FIELD = 3,
- ANNOTATION_ID_EXCLUSIVE_STATE = 4,
- ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5,
- ANNOTATION_ID_DEFAULT_STATE = 6,
- ANNOTATION_ID_TRIGGER_STATE_RESET = 7,
- ANNOTATION_ID_STATE_NESTED = 8,
-};
-
-const int ATOM_ID_FIELD_NUMBER = -1;
-
-const string DEFAULT_MODULE_NAME = "DEFAULT";
-
-/**
- * The types for atom parameters.
- */
-typedef enum {
- JAVA_TYPE_UNKNOWN = 0,
-
- JAVA_TYPE_ATTRIBUTION_CHAIN = 1,
- JAVA_TYPE_BOOLEAN = 2,
- JAVA_TYPE_INT = 3,
- JAVA_TYPE_LONG = 4,
- JAVA_TYPE_FLOAT = 5,
- JAVA_TYPE_DOUBLE = 6,
- JAVA_TYPE_STRING = 7,
- JAVA_TYPE_ENUM = 8,
- JAVA_TYPE_KEY_VALUE_PAIR = 9,
-
- JAVA_TYPE_OBJECT = -1,
- JAVA_TYPE_BYTE_ARRAY = -2,
-} java_type_t;
-
-enum AnnotationType {
- ANNOTATION_TYPE_UNKNOWN = 0,
- ANNOTATION_TYPE_INT = 1,
- ANNOTATION_TYPE_BOOL = 2,
-};
-
-union AnnotationValue {
- int intValue;
- bool boolValue;
-
- AnnotationValue(const int value) : intValue(value) {
- }
- AnnotationValue(const bool value) : boolValue(value) {
- }
-};
-
-struct Annotation {
- const AnnotationId annotationId;
- const int atomId;
- AnnotationType type;
- AnnotationValue value;
-
- inline Annotation(AnnotationId annotationId, int atomId, AnnotationType type,
- AnnotationValue value)
- : annotationId(annotationId), atomId(atomId), type(type), value(value) {
- }
- inline ~Annotation() {
- }
-
- inline bool operator<(const Annotation& that) const {
- return atomId == that.atomId ? annotationId < that.annotationId : atomId < that.atomId;
- }
-};
-
-struct SharedComparator {
- template <typename T>
- inline bool operator()(const shared_ptr<T>& lhs, const shared_ptr<T>& rhs) const {
- return (*lhs) < (*rhs);
- }
-};
-
-using AnnotationSet = set<shared_ptr<Annotation>, SharedComparator>;
-
-using FieldNumberToAnnotations = map<int, AnnotationSet>;
-
-/**
- * The name and type for an atom field.
- */
-struct AtomField {
- string name;
- java_type_t javaType;
-
- // If the field is of type enum, the following map contains the list of enum
- // values.
- map<int /* numeric value */, string /* value name */> enumValues;
-
- inline AtomField() : name(), javaType(JAVA_TYPE_UNKNOWN) {
- }
- inline AtomField(const AtomField& that)
- : name(that.name), javaType(that.javaType), enumValues(that.enumValues) {
- }
-
- inline AtomField(string n, java_type_t jt) : name(n), javaType(jt) {
- }
- inline ~AtomField() {
- }
-};
-
-/**
- * The name and code for an atom.
- */
-struct AtomDecl {
- int code;
- string name;
-
- string message;
- vector<AtomField> fields;
-
- FieldNumberToAnnotations fieldNumberToAnnotations;
-
- vector<int> primaryFields;
- int exclusiveField = 0;
- int defaultState = INT_MAX;
- int triggerStateReset = INT_MAX;
- bool nested = true;
-
- int uidField = 0;
-
- AtomDecl();
- AtomDecl(const AtomDecl& that);
- AtomDecl(int code, const string& name, const string& message);
- ~AtomDecl();
-
- inline bool operator<(const AtomDecl& that) const {
- return (code == that.code) ? (name < that.name) : (code < that.code);
- }
-};
-
-using AtomDeclSet = set<shared_ptr<AtomDecl>, SharedComparator>;
-
-// Maps a field number to a set of atoms that have annotation(s) for their field with that field
-// number.
-using FieldNumberToAtomDeclSet = map<int, AtomDeclSet>;
-
-using SignatureInfoMap = map<vector<java_type_t>, FieldNumberToAtomDeclSet>;
-
-struct Atoms {
- SignatureInfoMap signatureInfoMap;
- AtomDeclSet decls;
- AtomDeclSet non_chained_decls;
- SignatureInfoMap nonChainedSignatureInfoMap;
-};
-
-/**
- * Gather the information about the atoms. Returns the number of errors.
- */
-int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms* atoms);
-int collate_atom(const Descriptor* atom, AtomDecl* atomDecl, vector<java_type_t>* signature);
-
-} // namespace stats_log_api_gen
-} // namespace android
-
-#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H
diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp
deleted file mode 100644
index f4c937c..0000000
--- a/tools/stats_log_api_gen/java_writer.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "java_writer.h"
-
-#include "java_writer_q.h"
-#include "utils.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-static int write_java_q_logger_class(FILE* out, const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl) {
- fprintf(out, "\n");
- fprintf(out, " // Write logging helper methods for statsd in Q and earlier.\n");
- fprintf(out, " private static class QLogger {\n");
-
- write_java_q_logging_constants(out, " ");
-
- // Print Q write methods.
- fprintf(out, "\n");
- fprintf(out, " // Write methods.\n");
- write_java_methods_q_schema(out, signatureInfoMap, attributionDecl, " ");
-
- fprintf(out, " }\n");
- return 0;
-}
-
-static void write_java_annotation_constants(FILE* out) {
- fprintf(out, " // Annotation constants.\n");
-
- for (const auto& [id, name] : ANNOTATION_ID_CONSTANTS) {
- fprintf(out, " public static final byte %s = %hhu;\n", name.c_str(), id);
- }
- fprintf(out, "\n");
-}
-
-static void write_annotations(FILE* out, int argIndex,
- const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet) {
- FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt =
- fieldNumberToAtomDeclSet.find(argIndex);
- if (fieldNumberToAtomDeclSet.end() == fieldNumberToAtomDeclSetIt) {
- return;
- }
- const AtomDeclSet& atomDeclSet = fieldNumberToAtomDeclSetIt->second;
- for (const shared_ptr<AtomDecl>& atomDecl : atomDeclSet) {
- const string atomConstant = make_constant_name(atomDecl->name);
- fprintf(out, " if (%s == code) {\n", atomConstant.c_str());
- const AnnotationSet& annotations = atomDecl->fieldNumberToAnnotations.at(argIndex);
- int resetState = -1;
- int defaultState = -1;
- for (const shared_ptr<Annotation>& annotation : annotations) {
- const string& annotationConstant = ANNOTATION_ID_CONSTANTS.at(annotation->annotationId);
- switch (annotation->type) {
- case ANNOTATION_TYPE_INT:
- if (ANNOTATION_ID_TRIGGER_STATE_RESET == annotation->annotationId) {
- resetState = annotation->value.intValue;
- } else if (ANNOTATION_ID_DEFAULT_STATE == annotation->annotationId) {
- defaultState = annotation->value.intValue;
- } else {
- fprintf(out, " builder.addIntAnnotation(%s, %d);\n",
- annotationConstant.c_str(), annotation->value.intValue);
- }
- break;
- case ANNOTATION_TYPE_BOOL:
- fprintf(out, " builder.addBooleanAnnotation(%s, %s);\n",
- annotationConstant.c_str(),
- annotation->value.boolValue ? "true" : "false");
- break;
- default:
- break;
- }
- }
- if (defaultState != -1 && resetState != -1) {
- const string& annotationConstant =
- ANNOTATION_ID_CONSTANTS.at(ANNOTATION_ID_TRIGGER_STATE_RESET);
- fprintf(out, " if (arg%d == %d) {\n", argIndex, resetState);
- fprintf(out, " builder.addIntAnnotation(%s, %d);\n",
- annotationConstant.c_str(), defaultState);
- fprintf(out, " }\n");
- }
- fprintf(out, " }\n");
- }
-}
-
-static int write_java_methods(FILE* out, const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl, const bool supportQ) {
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- // Print method signature.
- fprintf(out, " public static void write(int code");
- const vector<java_type_t>& signature = signatureInfoMapIt->first;
- const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- fprintf(out, ", %s[] %s", java_type_name(chainField.javaType),
- chainField.name.c_str());
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", android.util.SparseArray<Object> valueMap");
- } else {
- fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ") {\n");
-
- // Print method body.
- string indent("");
- if (supportQ) {
- fprintf(out, " if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {\n");
- indent = " ";
- }
-
- // Start StatsEvent.Builder.
- fprintf(out,
- "%s final StatsEvent.Builder builder = "
- "StatsEvent.newBuilder();\n",
- indent.c_str());
-
- // Write atom code.
- fprintf(out, "%s builder.setAtomId(code);\n", indent.c_str());
- write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet);
-
- // Write the args.
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- switch (*arg) {
- case JAVA_TYPE_BOOLEAN:
- fprintf(out, "%s builder.writeBoolean(arg%d);\n", indent.c_str(),
- argIndex);
- break;
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- fprintf(out, "%s builder.writeInt(arg%d);\n", indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_FLOAT:
- fprintf(out, "%s builder.writeFloat(arg%d);\n", indent.c_str(),
- argIndex);
- break;
- case JAVA_TYPE_LONG:
- fprintf(out, "%s builder.writeLong(arg%d);\n", indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_STRING:
- fprintf(out, "%s builder.writeString(arg%d);\n", indent.c_str(),
- argIndex);
- break;
- case JAVA_TYPE_BYTE_ARRAY:
- fprintf(out,
- "%s builder.writeByteArray(null == arg%d ? new byte[0] : "
- "arg%d);\n",
- indent.c_str(), argIndex, argIndex);
- break;
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
-
- fprintf(out, "%s builder.writeAttributionChain(\n", indent.c_str());
- fprintf(out, "%s null == %s ? new int[0] : %s,\n",
- indent.c_str(), uidName, uidName);
- fprintf(out, "%s null == %s ? new String[0] : %s);\n",
- indent.c_str(), tagName, tagName);
- break;
- }
- case JAVA_TYPE_KEY_VALUE_PAIR:
- fprintf(out, "\n");
- fprintf(out, "%s // Write KeyValuePairs.\n", indent.c_str());
- fprintf(out, "%s final int count = valueMap.size();\n", indent.c_str());
- fprintf(out, "%s android.util.SparseIntArray intMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseLongArray longMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseArray<String> stringMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseArray<Float> floatMap = null;\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < count; i++) {\n", indent.c_str());
- fprintf(out, "%s final int key = valueMap.keyAt(i);\n",
- indent.c_str());
- fprintf(out, "%s final Object value = valueMap.valueAt(i);\n",
- indent.c_str());
- fprintf(out, "%s if (value instanceof Integer) {\n", indent.c_str());
- fprintf(out, "%s if (null == intMap) {\n", indent.c_str());
- fprintf(out,
- "%s intMap = new "
- "android.util.SparseIntArray();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s intMap.put(key, (Integer) value);\n",
- indent.c_str());
- fprintf(out, "%s } else if (value instanceof Long) {\n",
- indent.c_str());
- fprintf(out, "%s if (null == longMap) {\n", indent.c_str());
- fprintf(out,
- "%s longMap = new "
- "android.util.SparseLongArray();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s longMap.put(key, (Long) value);\n",
- indent.c_str());
- fprintf(out, "%s } else if (value instanceof String) {\n",
- indent.c_str());
- fprintf(out, "%s if (null == stringMap) {\n", indent.c_str());
- fprintf(out,
- "%s stringMap = new "
- "android.util.SparseArray<>();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s stringMap.put(key, (String) value);\n",
- indent.c_str());
- fprintf(out, "%s } else if (value instanceof Float) {\n",
- indent.c_str());
- fprintf(out, "%s if (null == floatMap) {\n", indent.c_str());
- fprintf(out,
- "%s floatMap = new "
- "android.util.SparseArray<>();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s floatMap.put(key, (Float) value);\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out,
- "%s builder.writeKeyValuePairs("
- "intMap, longMap, stringMap, floatMap);\n",
- indent.c_str());
- break;
- default:
- // Unsupported types: OBJECT, DOUBLE.
- fprintf(stderr, "Encountered unsupported type.");
- return 1;
- }
- write_annotations(out, argIndex, fieldNumberToAtomDeclSet);
- argIndex++;
- }
-
- fprintf(out, "\n");
- fprintf(out, "%s builder.usePooledBuffer();\n", indent.c_str());
- fprintf(out, "%s StatsLog.write(builder.build());\n", indent.c_str());
-
- // Add support for writing using Q schema if this is not the default module.
- if (supportQ) {
- fprintf(out, " } else {\n");
- fprintf(out, " QLogger.write(code");
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- fprintf(out, ", %s, %s", uidName, tagName);
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- // Module logging does not yet support key value pair.
- fprintf(stderr, "Module logging does not yet support key value pair.\n");
- return 1;
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- argIndex++;
- }
- fprintf(out, ");\n");
- fprintf(out, " }\n"); // if
- }
-
- fprintf(out, " }\n"); // method
- fprintf(out, "\n");
- }
- return 0;
-}
-
-int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& javaClass, const string& javaPackage, const bool supportQ,
- const bool supportWorkSource) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "package %s;\n", javaPackage.c_str());
- fprintf(out, "\n");
- fprintf(out, "\n");
- if (supportQ) {
- fprintf(out, "import android.os.Build;\n");
- fprintf(out, "import android.os.SystemClock;\n");
- }
-
- fprintf(out, "import android.util.StatsEvent;\n");
- fprintf(out, "import android.util.StatsLog;\n");
-
- fprintf(out, "\n");
- fprintf(out, "\n");
- fprintf(out, "/**\n");
- fprintf(out, " * Utility class for logging statistics events.\n");
- fprintf(out, " */\n");
- fprintf(out, "public class %s {\n", javaClass.c_str());
-
- write_java_atom_codes(out, atoms);
- write_java_enum_values(out, atoms);
- write_java_annotation_constants(out);
-
- int errors = 0;
-
- // Print write methods.
- fprintf(out, " // Write methods\n");
- errors += write_java_methods(out, atoms.signatureInfoMap, attributionDecl, supportQ);
- errors += write_java_non_chained_methods(out, atoms.nonChainedSignatureInfoMap);
- if (supportWorkSource) {
- errors += write_java_work_source_methods(out, atoms.signatureInfoMap);
- }
-
- if (supportQ) {
- errors += write_java_q_logger_class(out, atoms.signatureInfoMap, attributionDecl);
- }
-
- fprintf(out, "}\n");
-
- return errors;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/java_writer.h b/tools/stats_log_api_gen/java_writer.h
deleted file mode 100644
index 8b3b505..0000000
--- a/tools/stats_log_api_gen/java_writer.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "Collation.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using namespace std;
-
-int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& javaClass, const string& javaPackage, const bool supportQ,
- const bool supportWorkSource);
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/java_writer_q.cpp b/tools/stats_log_api_gen/java_writer_q.cpp
deleted file mode 100644
index d21e270..0000000
--- a/tools/stats_log_api_gen/java_writer_q.cpp
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "java_writer_q.h"
-
-#include "utils.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-void write_java_q_logging_constants(FILE* out, const string& indent) {
- fprintf(out, "%s// Payload limits.\n", indent.c_str());
- fprintf(out, "%sprivate static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;\n", indent.c_str());
- fprintf(out,
- "%sprivate static final int MAX_EVENT_PAYLOAD = "
- "LOGGER_ENTRY_MAX_PAYLOAD - 4;\n",
- indent.c_str());
-
- // Value types. Must match with EventLog.java and log.h.
- fprintf(out, "\n");
- fprintf(out, "%s// Value types.\n", indent.c_str());
- fprintf(out, "%sprivate static final byte INT_TYPE = 0;\n", indent.c_str());
- fprintf(out, "%sprivate static final byte LONG_TYPE = 1;\n", indent.c_str());
- fprintf(out, "%sprivate static final byte STRING_TYPE = 2;\n", indent.c_str());
- fprintf(out, "%sprivate static final byte LIST_TYPE = 3;\n", indent.c_str());
- fprintf(out, "%sprivate static final byte FLOAT_TYPE = 4;\n", indent.c_str());
-
- // Size of each value type.
- // Booleans, ints, floats, and enums take 5 bytes, 1 for the type and 4 for
- // the value.
- fprintf(out, "\n");
- fprintf(out, "%s// Size of each value type.\n", indent.c_str());
- fprintf(out, "%sprivate static final int INT_TYPE_SIZE = 5;\n", indent.c_str());
- fprintf(out, "%sprivate static final int FLOAT_TYPE_SIZE = 5;\n", indent.c_str());
- // Longs take 9 bytes, 1 for the type and 8 for the value.
- fprintf(out, "%sprivate static final int LONG_TYPE_SIZE = 9;\n", indent.c_str());
- // Strings take 5 metadata bytes: 1 byte is for the type, 4 are for the
- // length.
- fprintf(out, "%sprivate static final int STRING_TYPE_OVERHEAD = 5;\n", indent.c_str());
- fprintf(out, "%sprivate static final int LIST_TYPE_OVERHEAD = 2;\n", indent.c_str());
-}
-
-int write_java_methods_q_schema(FILE* out, const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl, const string& indent) {
- int requiredHelpers = 0;
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- // Print method signature.
- vector<java_type_t> signature = signatureInfoMapIt->first;
- fprintf(out, "%spublic static void write(int code", indent.c_str());
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- fprintf(out, ", %s[] %s", java_type_name(chainField.javaType),
- chainField.name.c_str());
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", android.util.SparseArray<Object> valueMap");
- } else {
- fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ") {\n");
-
- // Calculate the size of the buffer.
- fprintf(out, "%s // Initial overhead of the list, timestamp, and atom tag.\n",
- indent.c_str());
- fprintf(out,
- "%s int needed = LIST_TYPE_OVERHEAD + LONG_TYPE_SIZE + "
- "INT_TYPE_SIZE;\n",
- indent.c_str());
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- switch (*arg) {
- case JAVA_TYPE_BOOLEAN:
- case JAVA_TYPE_INT:
- case JAVA_TYPE_FLOAT:
- case JAVA_TYPE_ENUM:
- fprintf(out, "%s needed += INT_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_LONG:
- // Longs take 9 bytes, 1 for the type and 8 for the value.
- fprintf(out, "%s needed += LONG_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_STRING:
- // Strings take 5 metadata bytes + length of byte encoded string.
- fprintf(out, "%s if (arg%d == null) {\n", indent.c_str(), argIndex);
- fprintf(out, "%s arg%d = \"\";\n", indent.c_str(), argIndex);
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out,
- "%s byte[] arg%dBytes = "
- "arg%d.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n",
- indent.c_str(), argIndex, argIndex);
- fprintf(out, "%s needed += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n",
- indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_BYTE_ARRAY:
- // Byte arrays take 5 metadata bytes + length of byte array.
- fprintf(out, "%s if (arg%d == null) {\n", indent.c_str(), argIndex);
- fprintf(out, "%s arg%d = new byte[0];\n", indent.c_str(), argIndex);
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s needed += STRING_TYPE_OVERHEAD + arg%d.length;\n",
- indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- // Null checks on the params.
- fprintf(out, "%s if (%s == null) {\n", indent.c_str(), uidName);
- fprintf(out, "%s %s = new %s[0];\n", indent.c_str(), uidName,
- java_type_name(attributionDecl.fields.front().javaType));
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s if (%s == null) {\n", indent.c_str(), tagName);
- fprintf(out, "%s %s = new %s[0];\n", indent.c_str(), tagName,
- java_type_name(attributionDecl.fields.back().javaType));
- fprintf(out, "%s }\n", indent.c_str());
-
- // First check that the lengths of the uid and tag arrays are the
- // same.
- fprintf(out, "%s if (%s.length != %s.length) {\n", indent.c_str(), uidName,
- tagName);
- fprintf(out, "%s return;\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s int attrSize = LIST_TYPE_OVERHEAD;\n", indent.c_str());
- fprintf(out, "%s for (int i = 0; i < %s.length; i++) {\n", indent.c_str(),
- tagName);
- fprintf(out, "%s String str%d = (%s[i] == null) ? \"\" : %s[i];\n",
- indent.c_str(), argIndex, tagName, tagName);
- fprintf(out,
- "%s int str%dlen = "
- "str%d.getBytes(java.nio.charset.StandardCharsets.UTF_8)."
- "length;\n",
- indent.c_str(), argIndex, argIndex);
- fprintf(out,
- "%s attrSize += "
- "LIST_TYPE_OVERHEAD + INT_TYPE_SIZE + STRING_TYPE_OVERHEAD + "
- "str%dlen;\n",
- indent.c_str(), argIndex);
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s needed += attrSize;\n", indent.c_str());
- break;
- }
- case JAVA_TYPE_KEY_VALUE_PAIR: {
- fprintf(out, "%s // Calculate bytes needed by Key Value Pairs.\n",
- indent.c_str());
- fprintf(out, "%s final int count = valueMap.size();\n", indent.c_str());
- fprintf(out, "%s android.util.SparseIntArray intMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseLongArray longMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseArray<String> stringMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseArray<Float> floatMap = null;\n",
- indent.c_str());
- fprintf(out, "%s int keyValuePairSize = LIST_TYPE_OVERHEAD;\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < count; i++) {\n", indent.c_str());
- fprintf(out, "%s final int key = valueMap.keyAt(i);\n", indent.c_str());
- fprintf(out, "%s final Object value = valueMap.valueAt(i);\n",
- indent.c_str());
- fprintf(out, "%s if (value instanceof Integer) {\n", indent.c_str());
- fprintf(out, "%s keyValuePairSize += LIST_TYPE_OVERHEAD\n",
- indent.c_str());
- fprintf(out, "%s + INT_TYPE_SIZE + INT_TYPE_SIZE;\n",
- indent.c_str());
- fprintf(out, "%s if (null == intMap) {\n", indent.c_str());
- fprintf(out, "%s intMap = new android.util.SparseIntArray();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s intMap.put(key, (Integer) value);\n",
- indent.c_str());
- fprintf(out, "%s } else if (value instanceof Long) {\n", indent.c_str());
- fprintf(out, "%s keyValuePairSize += LIST_TYPE_OVERHEAD\n",
- indent.c_str());
- fprintf(out, "%s + INT_TYPE_SIZE + LONG_TYPE_SIZE;\n",
- indent.c_str());
- fprintf(out, "%s if (null == longMap) {\n", indent.c_str());
- fprintf(out,
- "%s longMap = new "
- "android.util.SparseLongArray();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s longMap.put(key, (Long) value);\n", indent.c_str());
- fprintf(out, "%s } else if (value instanceof String) {\n",
- indent.c_str());
- fprintf(out,
- "%s final String str = (value == null) ? \"\" : "
- "(String) value;\n",
- indent.c_str());
- fprintf(out,
- "%s final int len = "
- "str.getBytes(java.nio.charset.StandardCharsets.UTF_8).length;\n",
- indent.c_str());
- fprintf(out,
- "%s keyValuePairSize += LIST_TYPE_OVERHEAD + "
- "INT_TYPE_SIZE\n",
- indent.c_str());
- fprintf(out, "%s + STRING_TYPE_OVERHEAD + len;\n",
- indent.c_str());
- fprintf(out, "%s if (null == stringMap) {\n", indent.c_str());
- fprintf(out,
- "%s stringMap = new "
- "android.util.SparseArray<>();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s stringMap.put(key, str);\n", indent.c_str());
- fprintf(out, "%s } else if (value instanceof Float) {\n",
- indent.c_str());
- fprintf(out, "%s keyValuePairSize += LIST_TYPE_OVERHEAD\n",
- indent.c_str());
- fprintf(out, "%s + INT_TYPE_SIZE + FLOAT_TYPE_SIZE;\n",
- indent.c_str());
- fprintf(out, "%s if (null == floatMap) {\n", indent.c_str());
- fprintf(out,
- "%s floatMap = new "
- "android.util.SparseArray<>();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s floatMap.put(key, (Float) value);\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s needed += keyValuePairSize;\n", indent.c_str());
- break;
- }
- default:
- // Unsupported types: OBJECT, DOUBLE.
- fprintf(stderr, "Module logging does not yet support Object and Double.\n");
- return 1;
- }
- argIndex++;
- }
-
- // Now we have the size that is needed. Check for overflow and return if
- // needed.
- fprintf(out, "%s if (needed > MAX_EVENT_PAYLOAD) {\n", indent.c_str());
- fprintf(out, "%s return;\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
-
- // Create new buffer, and associated data types.
- fprintf(out, "%s byte[] buff = new byte[needed];\n", indent.c_str());
- fprintf(out, "%s int pos = 0;\n", indent.c_str());
-
- // Initialize the buffer with list data type.
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = %zu;\n", indent.c_str(), signature.size() + 2);
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
-
- // Write timestamp.
- fprintf(out, "%s long elapsedRealtime = SystemClock.elapsedRealtimeNanos();\n",
- indent.c_str());
- fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyLong(buff, pos + 1, elapsedRealtime);\n", indent.c_str());
- fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str());
-
- // Write atom code.
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, code);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
-
- // Write the args.
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- switch (*arg) {
- case JAVA_TYPE_BOOLEAN:
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, arg%d? 1 : 0);\n", indent.c_str(),
- argIndex);
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, arg%d);\n", indent.c_str(),
- argIndex);
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_FLOAT:
- requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT;
- fprintf(out, "%s buff[pos] = FLOAT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyFloat(buff, pos + 1, arg%d);\n", indent.c_str(),
- argIndex);
- fprintf(out, "%s pos += FLOAT_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_LONG:
- fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyLong(buff, pos + 1, arg%d);\n", indent.c_str(),
- argIndex);
- fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_STRING:
- fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, arg%dBytes.length);\n",
- indent.c_str(), argIndex);
- fprintf(out,
- "%s System.arraycopy("
- "arg%dBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, "
- "arg%dBytes.length);\n",
- indent.c_str(), argIndex, argIndex);
- fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n",
- indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_BYTE_ARRAY:
- fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, arg%d.length);\n", indent.c_str(),
- argIndex);
- fprintf(out,
- "%s System.arraycopy("
- "arg%d, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%d.length);\n",
- indent.c_str(), argIndex, argIndex);
- fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + arg%d.length;\n",
- indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- requiredHelpers |= JAVA_MODULE_REQUIRES_ATTRIBUTION;
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
-
- fprintf(out, "%s writeAttributionChain(buff, pos, %s, %s);\n",
- indent.c_str(), uidName, tagName);
- fprintf(out, "%s pos += attrSize;\n", indent.c_str());
- break;
- }
- case JAVA_TYPE_KEY_VALUE_PAIR:
- requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT;
- requiredHelpers |= JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS;
- fprintf(out,
- "%s writeKeyValuePairs(buff, pos, (byte) count, intMap, "
- "longMap, "
- "stringMap, floatMap);\n",
- indent.c_str());
- fprintf(out, "%s pos += keyValuePairSize;\n", indent.c_str());
- break;
- default:
- // Unsupported types: OBJECT, DOUBLE.
- fprintf(stderr, "Object and Double are not supported in module logging");
- return 1;
- }
- argIndex++;
- }
-
- fprintf(out, "%s StatsLog.writeRaw(buff, pos);\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
- }
-
- write_java_helpers_for_q_schema_methods(out, attributionDecl, requiredHelpers, indent);
-
- return 0;
-}
-
-void write_java_helpers_for_q_schema_methods(FILE* out, const AtomDecl& attributionDecl,
- const int requiredHelpers, const string& indent) {
- fprintf(out, "\n");
- fprintf(out, "%s// Helper methods for copying primitives\n", indent.c_str());
- fprintf(out, "%sprivate static void copyInt(byte[] buff, int pos, int val) {\n",
- indent.c_str());
- fprintf(out, "%s buff[pos] = (byte) (val);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) (val >> 8);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 2] = (byte) (val >> 16);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 3] = (byte) (val >> 24);\n", indent.c_str());
- fprintf(out, "%s return;\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
-
- fprintf(out, "%sprivate static void copyLong(byte[] buff, int pos, long val) {\n",
- indent.c_str());
- fprintf(out, "%s buff[pos] = (byte) (val);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) (val >> 8);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 2] = (byte) (val >> 16);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 3] = (byte) (val >> 24);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 4] = (byte) (val >> 32);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 5] = (byte) (val >> 40);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 6] = (byte) (val >> 48);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 7] = (byte) (val >> 56);\n", indent.c_str());
- fprintf(out, "%s return;\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
-
- if (requiredHelpers & JAVA_MODULE_REQUIRES_FLOAT) {
- fprintf(out, "%sprivate static void copyFloat(byte[] buff, int pos, float val) {\n",
- indent.c_str());
- fprintf(out, "%s copyInt(buff, pos, Float.floatToIntBits(val));\n", indent.c_str());
- fprintf(out, "%s return;\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
- }
-
- if (requiredHelpers & JAVA_MODULE_REQUIRES_ATTRIBUTION) {
- fprintf(out, "%sprivate static void writeAttributionChain(byte[] buff, int pos",
- indent.c_str());
- for (auto chainField : attributionDecl.fields) {
- fprintf(out, ", %s[] %s", java_type_name(chainField.javaType), chainField.name.c_str());
- }
- fprintf(out, ") {\n");
-
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
-
- // Write the first list begin.
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) (%s.length);\n", indent.c_str(), tagName);
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
-
- // Iterate through the attribution chain and write the nodes.
- fprintf(out, "%s for (int i = 0; i < %s.length; i++) {\n", indent.c_str(), tagName);
- // Write the list begin.
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = %lu;\n", indent.c_str(),
- attributionDecl.fields.size());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
-
- // Write the uid.
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, %s[i]);\n", indent.c_str(), uidName);
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
-
- // Write the tag.
- fprintf(out, "%s String %sStr = (%s[i] == null) ? \"\" : %s[i];\n", indent.c_str(),
- tagName, tagName, tagName);
- fprintf(out,
- "%s byte[] %sByte = "
- "%sStr.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n",
- indent.c_str(), tagName, tagName);
- fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, %sByte.length);\n", indent.c_str(), tagName);
- fprintf(out,
- "%s System.arraycopy("
- "%sByte, 0, buff, pos + STRING_TYPE_OVERHEAD, %sByte.length);\n",
- indent.c_str(), tagName, tagName);
- fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + %sByte.length;\n", indent.c_str(),
- tagName);
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
- }
-
- if (requiredHelpers & JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS) {
- fprintf(out,
- "%sprivate static void writeKeyValuePairs(byte[] buff, int pos, "
- "byte numPairs,\n",
- indent.c_str());
- fprintf(out, "%s final android.util.SparseIntArray intMap,\n", indent.c_str());
- fprintf(out, "%s final android.util.SparseLongArray longMap,\n", indent.c_str());
- fprintf(out, "%s final android.util.SparseArray<String> stringMap,\n",
- indent.c_str());
- fprintf(out, "%s final android.util.SparseArray<Float> floatMap) {\n",
- indent.c_str());
-
- // Start list of lists.
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) numPairs;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
-
- // Write integers.
- fprintf(out, "%s final int intMapSize = null == intMap ? 0 : intMap.size();\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < intMapSize; i++) {\n", indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
- fprintf(out, "%s final int key = intMap.keyAt(i);\n", indent.c_str());
- fprintf(out, "%s final int value = intMap.valueAt(i);\n", indent.c_str());
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, value);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
-
- // Write longs.
- fprintf(out, "%s final int longMapSize = null == longMap ? 0 : longMap.size();\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < longMapSize; i++) {\n", indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
- fprintf(out, "%s final int key = longMap.keyAt(i);\n", indent.c_str());
- fprintf(out, "%s final long value = longMap.valueAt(i);\n", indent.c_str());
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyLong(buff, pos + 1, value);\n", indent.c_str());
- fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
-
- // Write Strings.
- fprintf(out,
- "%s final int stringMapSize = null == stringMap ? 0 : "
- "stringMap.size();\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < stringMapSize; i++) {\n", indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
- fprintf(out, "%s final int key = stringMap.keyAt(i);\n", indent.c_str());
- fprintf(out, "%s final String value = stringMap.valueAt(i);\n", indent.c_str());
- fprintf(out,
- "%s final byte[] valueBytes = "
- "value.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n",
- indent.c_str());
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, valueBytes.length);\n", indent.c_str());
- fprintf(out,
- "%s System.arraycopy("
- "valueBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, "
- "valueBytes.length);\n",
- indent.c_str());
- fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + valueBytes.length;\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
-
- // Write floats.
- fprintf(out,
- "%s final int floatMapSize = null == floatMap ? 0 : "
- "floatMap.size();\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < floatMapSize; i++) {\n", indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
- fprintf(out, "%s final int key = floatMap.keyAt(i);\n", indent.c_str());
- fprintf(out, "%s final float value = floatMap.valueAt(i);\n", indent.c_str());
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s buff[pos] = FLOAT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyFloat(buff, pos + 1, value);\n", indent.c_str());
- fprintf(out, "%s pos += FLOAT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
- }
-}
-
-// This method is called in main.cpp to generate StatsLog for modules that's
-// compatible with Q at compile-time.
-int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl, const string& javaClass,
- const string& javaPackage, const bool supportWorkSource) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "package %s;\n", javaPackage.c_str());
- fprintf(out, "\n");
- fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n");
- fprintf(out, "\n");
- fprintf(out, "import android.util.StatsLog;\n");
- fprintf(out, "import android.os.SystemClock;\n");
- fprintf(out, "\n");
- fprintf(out, "\n");
- fprintf(out, "/**\n");
- fprintf(out, " * Utility class for logging statistics events.\n");
- fprintf(out, " */\n");
- fprintf(out, "public class %s {\n", javaClass.c_str());
-
- write_java_q_logging_constants(out, " ");
-
- write_java_atom_codes(out, atoms);
-
- write_java_enum_values(out, atoms);
-
- int errors = 0;
- // Print write methods
- fprintf(out, " // Write methods\n");
- errors += write_java_methods_q_schema(out, atoms.signatureInfoMap, attributionDecl, " ");
- errors += write_java_non_chained_methods(out, atoms.nonChainedSignatureInfoMap);
- if (supportWorkSource) {
- errors += write_java_work_source_methods(out, atoms.signatureInfoMap);
- }
-
- fprintf(out, "}\n");
-
- return errors;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/java_writer_q.h b/tools/stats_log_api_gen/java_writer_q.h
deleted file mode 100644
index c511a84..0000000
--- a/tools/stats_log_api_gen/java_writer_q.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "Collation.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using namespace std;
-
-void write_java_q_logging_constants(FILE* out, const string& indent);
-
-int write_java_methods_q_schema(FILE* out, const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl, const string& indent);
-
-void write_java_helpers_for_q_schema_methods(FILE* out, const AtomDecl& attributionDecl,
- const int requiredHelpers, const string& indent);
-
-int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl, const string& javaClass,
- const string& javaPackage, const bool supportWorkSource);
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
deleted file mode 100644
index b888ce9..0000000
--- a/tools/stats_log_api_gen/main.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "Collation.h"
-#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
-#include "java_writer.h"
-#include "java_writer_q.h"
-#include "native_writer.h"
-#include "utils.h"
-
-using namespace google::protobuf;
-using namespace std;
-
-namespace android {
-namespace stats_log_api_gen {
-
-using android::os::statsd::Atom;
-
-static void print_usage() {
- fprintf(stderr, "usage: stats-log-api-gen OPTIONS\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "OPTIONS\n");
- fprintf(stderr, " --cpp FILENAME the header file to output for write helpers\n");
- fprintf(stderr, " --header FILENAME the cpp file to output for write helpers\n");
- fprintf(stderr, " --help this message\n");
- fprintf(stderr, " --java FILENAME the java file to output\n");
- fprintf(stderr, " --module NAME optional, module name to generate outputs for\n");
- fprintf(stderr,
- " --namespace COMMA,SEP,NAMESPACE required for cpp/header with "
- "module\n");
- fprintf(stderr,
- " comma separated namespace of "
- "the files\n");
- fprintf(stderr,
- " --importHeader NAME required for cpp/jni to say which header to "
- "import "
- "for write helpers\n");
- fprintf(stderr, " --javaPackage PACKAGE the package for the java file.\n");
- fprintf(stderr, " required for java with module\n");
- fprintf(stderr, " --javaClass CLASS the class name of the java class.\n");
- fprintf(stderr, " Optional for Java with module.\n");
- fprintf(stderr, " Default is \"StatsLogInternal\"\n");
- fprintf(stderr, " --supportQ Include runtime support for Android Q.\n");
- fprintf(stderr,
- " --worksource Include support for logging WorkSource "
- "objects.\n");
- fprintf(stderr,
- " --compileQ Include compile-time support for Android Q "
- "(Java only).\n");
-}
-
-/**
- * Do the argument parsing and execute the tasks.
- */
-static int run(int argc, char const* const* argv) {
- string cppFilename;
- string headerFilename;
- string javaFilename;
- string javaPackage;
- string javaClass;
-
- string moduleName = DEFAULT_MODULE_NAME;
- string cppNamespace = DEFAULT_CPP_NAMESPACE;
- string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT;
- bool supportQ = false;
- bool supportWorkSource = false;
- bool compileQ = false;
-
- int index = 1;
- while (index < argc) {
- if (0 == strcmp("--help", argv[index])) {
- print_usage();
- return 0;
- } else if (0 == strcmp("--cpp", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- cppFilename = argv[index];
- } else if (0 == strcmp("--header", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- headerFilename = argv[index];
- } else if (0 == strcmp("--java", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- javaFilename = argv[index];
- } else if (0 == strcmp("--module", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- moduleName = argv[index];
- } else if (0 == strcmp("--namespace", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- cppNamespace = argv[index];
- } else if (0 == strcmp("--importHeader", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- cppHeaderImport = argv[index];
- } else if (0 == strcmp("--javaPackage", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- javaPackage = argv[index];
- } else if (0 == strcmp("--javaClass", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- javaClass = argv[index];
- } else if (0 == strcmp("--supportQ", argv[index])) {
- supportQ = true;
- } else if (0 == strcmp("--worksource", argv[index])) {
- supportWorkSource = true;
- } else if (0 == strcmp("--compileQ", argv[index])) {
- compileQ = true;
- }
-
- index++;
- }
-
- if (cppFilename.size() == 0 && headerFilename.size() == 0 && javaFilename.size() == 0) {
- print_usage();
- return 1;
- }
-
- if (DEFAULT_MODULE_NAME == moduleName && (supportQ || compileQ)) {
- // Support for Q schema is not needed for default module.
- fprintf(stderr, "%s cannot support Q schema\n", moduleName.c_str());
- return 1;
- }
-
- if (supportQ && compileQ) {
- // Runtime Q support is redundant if compile-time Q support is required.
- fprintf(stderr, "Cannot specify compileQ and supportQ simultaneously.\n");
- return 1;
- }
-
- // Collate the parameters
- Atoms atoms;
- int errorCount = collate_atoms(Atom::descriptor(), moduleName, &atoms);
- if (errorCount != 0) {
- return 1;
- }
-
- AtomDecl attributionDecl;
- vector<java_type_t> attributionSignature;
- collate_atom(android::os::statsd::AttributionNode::descriptor(), &attributionDecl,
- &attributionSignature);
-
- // Write the .cpp file
- if (cppFilename.size() != 0) {
- FILE* out = fopen(cppFilename.c_str(), "w");
- if (out == NULL) {
- fprintf(stderr, "Unable to open file for write: %s\n", cppFilename.c_str());
- return 1;
- }
- // If this is for a specific module, the namespace must also be provided.
- if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) {
- fprintf(stderr, "Must supply --namespace if supplying a specific module\n");
- return 1;
- }
- // If this is for a specific module, the header file to import must also be
- // provided.
- if (moduleName != DEFAULT_MODULE_NAME && cppHeaderImport == DEFAULT_CPP_HEADER_IMPORT) {
- fprintf(stderr, "Must supply --headerImport if supplying a specific module\n");
- return 1;
- }
- errorCount = android::stats_log_api_gen::write_stats_log_cpp(
- out, atoms, attributionDecl, cppNamespace, cppHeaderImport, supportQ);
- fclose(out);
- }
-
- // Write the .h file
- if (headerFilename.size() != 0) {
- FILE* out = fopen(headerFilename.c_str(), "w");
- if (out == NULL) {
- fprintf(stderr, "Unable to open file for write: %s\n", headerFilename.c_str());
- return 1;
- }
- // If this is for a specific module, the namespace must also be provided.
- if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) {
- fprintf(stderr, "Must supply --namespace if supplying a specific module\n");
- }
- errorCount = android::stats_log_api_gen::write_stats_log_header(out, atoms, attributionDecl,
- cppNamespace);
- fclose(out);
- }
-
- // Write the .java file
- if (javaFilename.size() != 0) {
- if (javaClass.size() == 0) {
- fprintf(stderr, "Must supply --javaClass if supplying a Java filename");
- return 1;
- }
-
- if (javaPackage.size() == 0) {
- fprintf(stderr, "Must supply --javaPackage if supplying a Java filename");
- return 1;
- }
-
- if (moduleName.size() == 0) {
- fprintf(stderr, "Must supply --module if supplying a Java filename");
- return 1;
- }
-
- FILE* out = fopen(javaFilename.c_str(), "w");
- if (out == NULL) {
- fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str());
- return 1;
- }
-
- if (compileQ) {
- errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module(
- out, atoms, attributionDecl, javaClass, javaPackage, supportWorkSource);
- } else {
- errorCount = android::stats_log_api_gen::write_stats_log_java(
- out, atoms, attributionDecl, javaClass, javaPackage, supportQ,
- supportWorkSource);
- }
-
- fclose(out);
- }
-
- return errorCount;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
-
-/**
- * Main.
- */
-int main(int argc, char const* const* argv) {
- GOOGLE_PROTOBUF_VERIFY_VERSION;
-
- return android::stats_log_api_gen::run(argc, argv);
-}
diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp
deleted file mode 100644
index 0c6c009..0000000
--- a/tools/stats_log_api_gen/native_writer.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "native_writer.h"
-
-#include "utils.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-static void write_native_annotation_constants(FILE* out) {
- fprintf(out, "// Annotation constants.\n");
-
- for (const auto& [id, name] : ANNOTATION_ID_CONSTANTS) {
- fprintf(out, "const uint8_t %s = %hhu;\n", name.c_str(), id);
- }
- fprintf(out, "\n");
-}
-
-static void write_annotations(FILE* out, int argIndex,
- const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet,
- const string& methodPrefix, const string& methodSuffix) {
- FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt =
- fieldNumberToAtomDeclSet.find(argIndex);
- if (fieldNumberToAtomDeclSet.end() == fieldNumberToAtomDeclSetIt) {
- return;
- }
- const AtomDeclSet& atomDeclSet = fieldNumberToAtomDeclSetIt->second;
- for (const shared_ptr<AtomDecl>& atomDecl : atomDeclSet) {
- const string atomConstant = make_constant_name(atomDecl->name);
- fprintf(out, " if (%s == code) {\n", atomConstant.c_str());
- const AnnotationSet& annotations = atomDecl->fieldNumberToAnnotations.at(argIndex);
- int resetState = -1;
- int defaultState = -1;
- for (const shared_ptr<Annotation>& annotation : annotations) {
- const string& annotationConstant = ANNOTATION_ID_CONSTANTS.at(annotation->annotationId);
- switch (annotation->type) {
- case ANNOTATION_TYPE_INT:
- if (ANNOTATION_ID_TRIGGER_STATE_RESET == annotation->annotationId) {
- resetState = annotation->value.intValue;
- } else if (ANNOTATION_ID_DEFAULT_STATE == annotation->annotationId) {
- defaultState = annotation->value.intValue;
- } else {
- fprintf(out, " %saddInt32Annotation(%s%s, %d);\n",
- methodPrefix.c_str(), methodSuffix.c_str(),
- annotationConstant.c_str(), annotation->value.intValue);
- }
- break;
- case ANNOTATION_TYPE_BOOL:
- // TODO(b/151786433): Write annotation constant name instead of
- // annotation id literal.
- fprintf(out, " %saddBoolAnnotation(%s%s, %s);\n", methodPrefix.c_str(),
- methodSuffix.c_str(), annotationConstant.c_str(),
- annotation->value.boolValue ? "true" : "false");
- break;
- default:
- break;
- }
- }
- if (defaultState != -1 && resetState != -1) {
- const string& annotationConstant =
- ANNOTATION_ID_CONSTANTS.at(ANNOTATION_ID_TRIGGER_STATE_RESET);
- fprintf(out, " if (arg%d == %d) {\n", argIndex, resetState);
- fprintf(out, " %saddInt32Annotation(%s%s, %d);\n", methodPrefix.c_str(),
- methodSuffix.c_str(), annotationConstant.c_str(), defaultState);
- fprintf(out, " }\n");
- }
- fprintf(out, " }\n");
- }
-}
-
-static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl, const bool supportQ) {
- fprintf(out, "\n");
- for (auto signatureInfoMapIt = atoms.signatureInfoMap.begin();
- signatureInfoMapIt != atoms.signatureInfoMap.end(); signatureInfoMapIt++) {
- vector<java_type_t> signature = signatureInfoMapIt->first;
- const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
- // Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
- continue;
- }
- write_native_method_signature(out, "int stats_write", signature, attributionDecl, " {");
-
- int argIndex = 1;
- if (supportQ) {
- fprintf(out, " StatsEventCompat event;\n");
- fprintf(out, " event.setAtomId(code);\n");
- write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "event.", "");
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- switch (*arg) {
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- fprintf(out, " event.writeAttributionChain(%s, %s_length, %s);\n",
- uidName, uidName, tagName);
- break;
- }
- case JAVA_TYPE_BYTE_ARRAY:
- fprintf(out, " event.writeByteArray(arg%d.arg, arg%d.arg_length);\n",
- argIndex, argIndex);
- break;
- case JAVA_TYPE_BOOLEAN:
- fprintf(out, " event.writeBool(arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_INT: // Fall through.
- case JAVA_TYPE_ENUM:
- fprintf(out, " event.writeInt32(arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_FLOAT:
- fprintf(out, " event.writeFloat(arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_LONG:
- fprintf(out, " event.writeInt64(arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_STRING:
- fprintf(out, " event.writeString(arg%d);\n", argIndex);
- break;
- default:
- // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS.
- fprintf(stderr, "Encountered unsupported type.");
- return 1;
- }
- write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "event.", "");
- argIndex++;
- }
- fprintf(out, " return event.writeToSocket();\n");
- } else {
- fprintf(out, " AStatsEvent* event = AStatsEvent_obtain();\n");
- fprintf(out, " AStatsEvent_setAtomId(event, code);\n");
- write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "AStatsEvent_",
- "event, ");
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- switch (*arg) {
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- fprintf(out,
- " AStatsEvent_writeAttributionChain(event, "
- "reinterpret_cast<const uint32_t*>(%s), %s.data(), "
- "static_cast<uint8_t>(%s_length));\n",
- uidName, tagName, uidName);
- break;
- }
- case JAVA_TYPE_BYTE_ARRAY:
- fprintf(out,
- " AStatsEvent_writeByteArray(event, "
- "reinterpret_cast<const uint8_t*>(arg%d.arg), "
- "arg%d.arg_length);\n",
- argIndex, argIndex);
- break;
- case JAVA_TYPE_BOOLEAN:
- fprintf(out, " AStatsEvent_writeBool(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_INT: // Fall through.
- case JAVA_TYPE_ENUM:
- fprintf(out, " AStatsEvent_writeInt32(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_FLOAT:
- fprintf(out, " AStatsEvent_writeFloat(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_LONG:
- fprintf(out, " AStatsEvent_writeInt64(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_STRING:
- fprintf(out, " AStatsEvent_writeString(event, arg%d);\n", argIndex);
- break;
- default:
- // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS
- fprintf(stderr, "Encountered unsupported type.");
- return 1;
- }
- write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "AStatsEvent_",
- "event, ");
- argIndex++;
- }
- fprintf(out, " const int ret = AStatsEvent_write(event);\n");
- fprintf(out, " AStatsEvent_release(event);\n");
- fprintf(out, " return ret;\n");
- }
- fprintf(out, "}\n\n");
- }
- return 0;
-}
-
-static void write_native_stats_write_non_chained_methods(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl) {
- fprintf(out, "\n");
- for (auto signature_it = atoms.nonChainedSignatureInfoMap.begin();
- signature_it != atoms.nonChainedSignatureInfoMap.end(); signature_it++) {
- vector<java_type_t> signature = signature_it->first;
- // Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
- continue;
- }
-
- write_native_method_signature(out, "int stats_write_non_chained", signature,
- attributionDecl, " {");
-
- vector<java_type_t> newSignature;
-
- // First two args form the attribution node so size goes down by 1.
- newSignature.reserve(signature.size() - 1);
-
- // First arg is Attribution Chain.
- newSignature.push_back(JAVA_TYPE_ATTRIBUTION_CHAIN);
-
- // Followed by the originial signature except the first 2 args.
- newSignature.insert(newSignature.end(), signature.begin() + 2, signature.end());
-
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- fprintf(out, " const int32_t* %s = &arg1;\n", uidName);
- fprintf(out, " const size_t %s_length = 1;\n", uidName);
- fprintf(out, " const std::vector<char const*> %s(1, arg2);\n", tagName);
- fprintf(out, " return ");
- write_native_method_call(out, "stats_write", newSignature, attributionDecl, 2);
-
- fprintf(out, "}\n\n");
- }
-}
-
-static void write_native_method_header(FILE* out, const string& methodName,
- const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl) {
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- vector<java_type_t> signature = signatureInfoMapIt->first;
-
- // Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
- continue;
- }
- write_native_method_signature(out, methodName, signature, attributionDecl, ";");
- }
-}
-
-int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& cppNamespace, const string& importHeader,
- const bool supportQ) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
-
- fprintf(out, "#include <%s>\n", importHeader.c_str());
- if (supportQ) {
- fprintf(out, "#include <StatsEventCompat.h>\n");
- } else {
- fprintf(out, "#include <stats_event.h>\n");
- }
-
- fprintf(out, "\n");
- write_namespace(out, cppNamespace);
-
- write_native_stats_write_methods(out, atoms, attributionDecl, supportQ);
- write_native_stats_write_non_chained_methods(out, atoms, attributionDecl);
-
- // Print footer
- fprintf(out, "\n");
- write_closing_namespace(out, cppNamespace);
-
- return 0;
-}
-
-int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& cppNamespace) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "#pragma once\n");
- fprintf(out, "\n");
- fprintf(out, "#include <stdint.h>\n");
- fprintf(out, "#include <vector>\n");
- fprintf(out, "#include <map>\n");
- fprintf(out, "#include <set>\n");
- fprintf(out, "\n");
-
- write_namespace(out, cppNamespace);
- fprintf(out, "\n");
- fprintf(out, "/*\n");
- fprintf(out, " * API For logging statistics events.\n");
- fprintf(out, " */\n");
- fprintf(out, "\n");
-
- write_native_atom_constants(out, atoms, attributionDecl);
-
- // Print constants for the enum values.
- fprintf(out, "//\n");
- fprintf(out, "// Constants for enum values\n");
- fprintf(out, "//\n\n");
- for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
- atomIt++) {
- for (vector<AtomField>::const_iterator field = (*atomIt)->fields.begin();
- field != (*atomIt)->fields.end(); field++) {
- if (field->javaType == JAVA_TYPE_ENUM) {
- fprintf(out, "// Values for %s.%s\n", (*atomIt)->message.c_str(),
- field->name.c_str());
- for (map<int, string>::const_iterator value = field->enumValues.begin();
- value != field->enumValues.end(); value++) {
- fprintf(out, "const int32_t %s__%s__%s = %d;\n",
- make_constant_name((*atomIt)->message).c_str(),
- make_constant_name(field->name).c_str(),
- make_constant_name(value->second).c_str(), value->first);
- }
- fprintf(out, "\n");
- }
- }
- }
-
- write_native_annotation_constants(out);
-
- fprintf(out, "struct BytesField {\n");
- fprintf(out,
- " BytesField(char const* array, size_t len) : arg(array), "
- "arg_length(len) {}\n");
- fprintf(out, " char const* arg;\n");
- fprintf(out, " size_t arg_length;\n");
- fprintf(out, "};\n");
- fprintf(out, "\n");
-
- // Print write methods
- fprintf(out, "//\n");
- fprintf(out, "// Write methods\n");
- fprintf(out, "//\n");
- write_native_method_header(out, "int stats_write", atoms.signatureInfoMap, attributionDecl);
-
- fprintf(out, "//\n");
- fprintf(out, "// Write flattened methods\n");
- fprintf(out, "//\n");
- write_native_method_header(out, "int stats_write_non_chained", atoms.nonChainedSignatureInfoMap,
- attributionDecl);
-
- fprintf(out, "\n");
- write_closing_namespace(out, cppNamespace);
-
- return 0;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/native_writer.h b/tools/stats_log_api_gen/native_writer.h
deleted file mode 100644
index 264d4db..0000000
--- a/tools/stats_log_api_gen/native_writer.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-
-#include "Collation.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using namespace std;
-
-int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& cppNamespace, const string& importHeader,
- const bool supportQ);
-
-int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& cppNamespace);
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
deleted file mode 100644
index aaa488e..0000000
--- a/tools/stats_log_api_gen/test.proto
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-import "frameworks/base/cmds/statsd/src/atoms.proto";
-import "frameworks/base/cmds/statsd/src/atom_field_options.proto";
-
-package android.stats_log_api_gen;
-
-message IntAtom {
- optional int32 field1 = 1;
-}
-
-message AnotherIntAtom {
- optional int32 field1 = 1;
-}
-
-message OutOfOrderAtom {
- optional int32 field2 = 2;
- optional int32 field1 = 1;
-}
-
-enum AnEnum {
- VALUE0 = 0;
- VALUE1 = 1;
-}
-
-message AllTypesAtom {
- repeated android.os.statsd.AttributionNode attribution_chain = 1;
- optional float float_field = 2;
- optional int64 int64_field = 3;
- optional uint64 uint64_field = 4;
- optional int32 int32_field = 5;
- optional fixed64 fixed64_field = 6;
- optional fixed32 fixed32_field = 7;
- optional bool bool_field = 8;
- optional string string_field = 9;
- optional uint32 uint32_field = 10;
- optional AnEnum enum_field = 11;
- optional sfixed32 sfixed32_field = 12;
- optional sfixed64 sfixed64_field = 13;
- optional sint32 sint32_field = 14;
- optional sint64 sint64_field = 15;
-}
-
-message Event {
- oneof event {
- OutOfOrderAtom out_of_order_atom = 2;
- IntAtom int_atom = 1;
- AnotherIntAtom another_int_atom = 3;
- AllTypesAtom all_types_atom = 4;
- }
-}
-
-message BadTypesAtom {
- optional IntAtom bad_int_atom = 1;
- optional bytes bad_bytes = 2;
- repeated int32 repeated_field = 3;
- optional double double_field = 4;
-}
-
-message BadTypesEvent {
- oneof event {
- BadTypesAtom bad_types_atom = 1;
- }
-}
-
-message BadSkippedFieldSingleAtom {
- optional int32 field2 = 2;
-}
-
-message BadSkippedFieldSingle {
- oneof event {
- BadSkippedFieldSingleAtom bad = 1;
- }
-}
-
-message BadSkippedFieldMultipleAtom {
- optional int32 field1 = 1;
- optional int32 field3 = 3;
- optional int32 field5 = 5;
-}
-
-message BadSkippedFieldMultiple {
- oneof event {
- BadSkippedFieldMultipleAtom bad = 1;
- }
-}
-
-message BadAttributionNodePositionAtom {
- optional int32 field1 = 1;
- repeated android.os.statsd.AttributionNode attribution = 2;
-}
-
-message BadAttributionNodePosition {
- oneof event { BadAttributionNodePositionAtom bad = 1; }
-}
-
-message GoodEventWithBinaryFieldAtom {
- oneof event { GoodBinaryFieldAtom field1 = 1; }
-}
-
-message ComplexField {
- optional string str = 1;
-}
-
-message GoodBinaryFieldAtom {
- optional int32 field1 = 1;
- optional ComplexField bf = 2 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-message BadEventWithBinaryFieldAtom {
- oneof event { BadBinaryFieldAtom field1 = 1; }
-}
-
-message BadBinaryFieldAtom {
- optional int32 field1 = 1;
- optional ComplexField bf = 2;
-}
-
-message BadStateAtoms {
- oneof event {
- BadStateAtom1 bad1 = 1;
- BadStateAtom2 bad2 = 2;
- BadStateAtom3 bad3 = 3;
- }
-}
-
-message GoodStateAtoms {
- oneof event {
- GoodStateAtom1 good1 = 1;
- GoodStateAtom2 good2 = 2;
- }
-}
-
-// The atom has only primary field but no exclusive state field.
-message BadStateAtom1 {
- optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
-}
-
-// Only primative types can be annotated.
-message BadStateAtom2 {
- repeated android.os.statsd.AttributionNode attribution = 1
- [(android.os.statsd.state_field_option).primary_field = true];
- optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-// Having 2 exclusive state field in the atom means the atom is badly designed.
-// E.g., putting bluetooth state and wifi state in the same atom.
-message BadStateAtom3 {
- optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
- optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
- optional int32 state2 = 3 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-message GoodStateAtom1 {
- optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
- optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-// Atoms can have exclusive state field, but no primary field. That means
-// the state is globally exclusive (e.g., DisplayState).
-message GoodStateAtom2 {
- optional int32 uid = 1;
- optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-// We can have more than one primary fields. That means their combination is a
-// primary key.
-message GoodStateAtom3 {
- optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
- optional int32 tid = 2 [(android.os.statsd.state_field_option).primary_field = true];
- optional int32 state = 3 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-message ModuleOneAtom {
- optional int32 field = 1 [(android.os.statsd.is_uid) = true];
-}
-
-message ModuleTwoAtom {
- optional int32 field = 1;
-}
-
-message ModuleOneAndTwoAtom {
- optional int32 field = 1 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-message NoModuleAtom {
- optional string field = 1;
-}
-
-message ModuleAtoms {
- oneof event {
- ModuleOneAtom module_one_atom = 1 [(android.os.statsd.module) = "module1"];
- ModuleTwoAtom module_two_atom = 2 [(android.os.statsd.module) = "module2"];
- ModuleOneAndTwoAtom module_one_and_two_atom = 3 [
- (android.os.statsd.module) = "module1", (android.os.statsd.module) = "module2"
- ];
- NoModuleAtom no_module_atom = 4;
- }
-}
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
deleted file mode 100644
index dbae588..0000000
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Copyright (C) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include "Collation.h"
-#include "frameworks/base/tools/stats_log_api_gen/test.pb.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using std::map;
-using std::set;
-using std::vector;
-
-/**
- * Return whether the map contains a vector of the elements provided.
- */
-static bool map_contains_vector(const SignatureInfoMap& s, int count, ...) {
- va_list args;
- vector<java_type_t> v;
-
- va_start(args, count);
- for (int i = 0; i < count; i++) {
- v.push_back((java_type_t)va_arg(args, int));
- }
- va_end(args);
-
- return s.find(v) != s.end();
-}
-
-/**
- * Expect that the provided map contains the elements provided.
- */
-#define EXPECT_MAP_CONTAINS_SIGNATURE(s, ...) \
- do { \
- int count = sizeof((int[]){__VA_ARGS__}) / sizeof(int); \
- EXPECT_TRUE(map_contains_vector(s, count, __VA_ARGS__)); \
- } while (0)
-
-/** Expects that the provided atom has no enum values for any field. */
-#define EXPECT_NO_ENUM_FIELD(atom) \
- do { \
- for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
- field != atom->fields.end(); field++) { \
- EXPECT_TRUE(field->enumValues.empty()); \
- } \
- } while (0)
-
-/** Expects that exactly one specific field has expected enum values. */
-#define EXPECT_HAS_ENUM_FIELD(atom, field_name, values) \
- do { \
- for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
- field != atom->fields.end(); field++) { \
- if (field->name == field_name) { \
- EXPECT_EQ(field->enumValues, values); \
- } else { \
- EXPECT_TRUE(field->enumValues.empty()); \
- } \
- } \
- } while (0)
-
-/**
- * Test a correct collation, with all the types.
- */
-TEST(CollationTest, CollateStats) {
- Atoms atoms;
- int errorCount = collate_atoms(Event::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(0, errorCount);
- EXPECT_EQ(3ul, atoms.signatureInfoMap.size());
-
- // IntAtom, AnotherIntAtom
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
-
- // OutOfOrderAtom
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_INT);
-
- // AllTypesAtom
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap,
- JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain
- JAVA_TYPE_FLOAT, // float
- JAVA_TYPE_LONG, // int64
- JAVA_TYPE_LONG, // uint64
- JAVA_TYPE_INT, // int32
- JAVA_TYPE_LONG, // fixed64
- JAVA_TYPE_INT, // fixed32
- JAVA_TYPE_BOOLEAN, // bool
- JAVA_TYPE_STRING, // string
- JAVA_TYPE_INT, // uint32
- JAVA_TYPE_INT, // AnEnum
- JAVA_TYPE_INT, // sfixed32
- JAVA_TYPE_LONG, // sfixed64
- JAVA_TYPE_INT, // sint32
- JAVA_TYPE_LONG // sint64
- );
-
- EXPECT_EQ(4ul, atoms.decls.size());
-
- AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
- EXPECT_EQ(1, (*atomIt)->code);
- EXPECT_EQ("int_atom", (*atomIt)->name);
- EXPECT_EQ("IntAtom", (*atomIt)->message);
- EXPECT_NO_ENUM_FIELD((*atomIt));
- atomIt++;
-
- EXPECT_EQ(2, (*atomIt)->code);
- EXPECT_EQ("out_of_order_atom", (*atomIt)->name);
- EXPECT_EQ("OutOfOrderAtom", (*atomIt)->message);
- EXPECT_NO_ENUM_FIELD((*atomIt));
- atomIt++;
-
- EXPECT_EQ(3, (*atomIt)->code);
- EXPECT_EQ("another_int_atom", (*atomIt)->name);
- EXPECT_EQ("AnotherIntAtom", (*atomIt)->message);
- EXPECT_NO_ENUM_FIELD((*atomIt));
- atomIt++;
-
- EXPECT_EQ(4, (*atomIt)->code);
- EXPECT_EQ("all_types_atom", (*atomIt)->name);
- EXPECT_EQ("AllTypesAtom", (*atomIt)->message);
- map<int, string> enumValues;
- enumValues[0] = "VALUE0";
- enumValues[1] = "VALUE1";
- EXPECT_HAS_ENUM_FIELD((*atomIt), "enum_field", enumValues);
- atomIt++;
-
- EXPECT_EQ(atoms.decls.end(), atomIt);
-}
-
-/**
- * Test that event class that contains stuff other than the atoms is rejected.
- */
-TEST(CollationTest, NonMessageTypeFails) {
- Atoms atoms;
- int errorCount = collate_atoms(IntAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(1, errorCount);
-}
-
-/**
- * Test that atoms that have non-primitive types or repeated fields are
- * rejected.
- */
-TEST(CollationTest, FailOnBadTypes) {
- Atoms atoms;
- int errorCount = collate_atoms(BadTypesEvent::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(4, errorCount);
-}
-
-/**
- * Test that atoms that skip field numbers (in the first position) are rejected.
- */
-TEST(CollationTest, FailOnSkippedFieldsSingle) {
- Atoms atoms;
- int errorCount =
- collate_atoms(BadSkippedFieldSingle::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(1, errorCount);
-}
-
-/**
- * Test that atoms that skip field numbers (not in the first position, and
- * multiple times) are rejected.
- */
-TEST(CollationTest, FailOnSkippedFieldsMultiple) {
- Atoms atoms;
- int errorCount =
- collate_atoms(BadSkippedFieldMultiple::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(2, errorCount);
-}
-
-/**
- * Test that atoms that have an attribution chain not in the first position are
- * rejected.
- */
-TEST(CollationTest, FailBadAttributionNodePosition) {
- Atoms atoms;
- int errorCount =
- collate_atoms(BadAttributionNodePosition::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(1, errorCount);
-}
-
-TEST(CollationTest, FailOnBadStateAtomOptions) {
- Atoms atoms;
- int errorCount = collate_atoms(BadStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(3, errorCount);
-}
-
-TEST(CollationTest, PassOnGoodStateAtomOptions) {
- Atoms atoms;
- int errorCount = collate_atoms(GoodStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_EQ(0, errorCount);
-}
-
-TEST(CollationTest, PassOnGoodBinaryFieldAtom) {
- Atoms atoms;
- int errorCount =
- collate_atoms(GoodEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_EQ(0, errorCount);
-}
-
-TEST(CollationTest, FailOnBadBinaryFieldAtom) {
- Atoms atoms;
- int errorCount =
- collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_TRUE(errorCount > 0);
-}
-
-TEST(CollationTest, PassOnLogFromModuleAtom) {
- Atoms atoms;
- int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_EQ(errorCount, 0);
- EXPECT_EQ(atoms.decls.size(), 4ul);
-}
-
-TEST(CollationTest, RecognizeModuleAtom) {
- Atoms atoms;
- int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_EQ(errorCount, 0);
- EXPECT_EQ(atoms.decls.size(), 4ul);
- EXPECT_EQ(atoms.signatureInfoMap.size(), 2u);
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_STRING);
-
- SignatureInfoMap::const_iterator signatureInfoMapIt;
- const vector<java_type_t>* signature;
- const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet;
- FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt;
- const AtomDeclSet* atomDeclSet;
- AtomDeclSet::const_iterator atomDeclSetIt;
- AtomDecl* atomDecl;
- FieldNumberToAnnotations* fieldNumberToAnnotations;
- FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt;
- const AnnotationSet* annotationSet;
- AnnotationSet::const_iterator annotationSetIt;
- Annotation* annotation;
-
- signatureInfoMapIt = atoms.signatureInfoMap.begin();
- signature = &(signatureInfoMapIt->first);
- fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
- EXPECT_EQ(1ul, signature->size());
- EXPECT_EQ(JAVA_TYPE_INT, signature->at(0));
- EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size());
- fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin();
- EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first);
- atomDeclSet = &fieldNumberToAtomDeclSetIt->second;
- EXPECT_EQ(2ul, atomDeclSet->size());
- atomDeclSetIt = atomDeclSet->begin();
- atomDecl = atomDeclSetIt->get();
- EXPECT_EQ(1, atomDecl->code);
- fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
- fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
- EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
- annotationSet = &fieldNumberToAnnotationsIt->second;
- EXPECT_EQ(1ul, annotationSet->size());
- annotationSetIt = annotationSet->begin();
- annotation = annotationSetIt->get();
- EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
- EXPECT_EQ(1, annotation->atomId);
- EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
- EXPECT_TRUE(annotation->value.boolValue);
-
- atomDeclSetIt++;
- atomDecl = atomDeclSetIt->get();
- EXPECT_EQ(3, atomDecl->code);
- fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
- fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
- EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
- annotationSet = &fieldNumberToAnnotationsIt->second;
- EXPECT_EQ(1ul, annotationSet->size());
- annotationSetIt = annotationSet->begin();
- annotation = annotationSetIt->get();
- EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId);
- EXPECT_EQ(3, annotation->atomId);
- EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
- EXPECT_TRUE(annotation->value.boolValue);
-
- signatureInfoMapIt++;
- signature = &signatureInfoMapIt->first;
- fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
- EXPECT_EQ(1ul, signature->size());
- EXPECT_EQ(JAVA_TYPE_STRING, signature->at(0));
- EXPECT_EQ(0ul, fieldNumberToAtomDeclSet->size());
-}
-
-TEST(CollationTest, RecognizeModule1Atom) {
- Atoms atoms;
- const string moduleName = "module1";
- int errorCount = collate_atoms(ModuleAtoms::descriptor(), moduleName, &atoms);
- EXPECT_EQ(errorCount, 0);
- EXPECT_EQ(atoms.decls.size(), 2ul);
- EXPECT_EQ(atoms.signatureInfoMap.size(), 1u);
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
-
- SignatureInfoMap::const_iterator signatureInfoMapIt;
- const vector<java_type_t>* signature;
- const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet;
- FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt;
- const AtomDeclSet* atomDeclSet;
- AtomDeclSet::const_iterator atomDeclSetIt;
- AtomDecl* atomDecl;
- FieldNumberToAnnotations* fieldNumberToAnnotations;
- FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt;
- const AnnotationSet* annotationSet;
- AnnotationSet::const_iterator annotationSetIt;
- Annotation* annotation;
-
- signatureInfoMapIt = atoms.signatureInfoMap.begin();
- signature = &(signatureInfoMapIt->first);
- fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
- EXPECT_EQ(1ul, signature->size());
- EXPECT_EQ(JAVA_TYPE_INT, signature->at(0));
- EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size());
- fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin();
- EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first);
- atomDeclSet = &fieldNumberToAtomDeclSetIt->second;
- EXPECT_EQ(2ul, atomDeclSet->size());
- atomDeclSetIt = atomDeclSet->begin();
- atomDecl = atomDeclSetIt->get();
- EXPECT_EQ(1, atomDecl->code);
- fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
- fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
- EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
- annotationSet = &fieldNumberToAnnotationsIt->second;
- EXPECT_EQ(1ul, annotationSet->size());
- annotationSetIt = annotationSet->begin();
- annotation = annotationSetIt->get();
- EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
- EXPECT_EQ(1, annotation->atomId);
- EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
- EXPECT_TRUE(annotation->value.boolValue);
-
- atomDeclSetIt++;
- atomDecl = atomDeclSetIt->get();
- EXPECT_EQ(3, atomDecl->code);
- fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
- fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
- EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
- annotationSet = &fieldNumberToAnnotationsIt->second;
- EXPECT_EQ(1ul, annotationSet->size());
- annotationSetIt = annotationSet->begin();
- annotation = annotationSetIt->get();
- EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId);
- EXPECT_EQ(3, annotation->atomId);
- EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
- EXPECT_TRUE(annotation->value.boolValue);
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp
deleted file mode 100644
index abb8913..0000000
--- a/tools/stats_log_api_gen/utils.cpp
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "utils.h"
-
-#include "android-base/strings.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-static void build_non_chained_decl_map(const Atoms& atoms,
- std::map<int, AtomDeclSet::const_iterator>* decl_map) {
- for (AtomDeclSet::const_iterator atomIt = atoms.non_chained_decls.begin();
- atomIt != atoms.non_chained_decls.end(); atomIt++) {
- decl_map->insert(std::make_pair((*atomIt)->code, atomIt));
- }
-}
-
-/**
- * Turn lower and camel case into upper case with underscores.
- */
-string make_constant_name(const string& str) {
- string result;
- const int N = str.size();
- bool underscore_next = false;
- for (int i = 0; i < N; i++) {
- char c = str[i];
- if (c >= 'A' && c <= 'Z') {
- if (underscore_next) {
- result += '_';
- underscore_next = false;
- }
- } else if (c >= 'a' && c <= 'z') {
- c = 'A' + c - 'a';
- underscore_next = true;
- } else if (c == '_') {
- underscore_next = false;
- }
- result += c;
- }
- return result;
-}
-
-const char* cpp_type_name(java_type_t type) {
- switch (type) {
- case JAVA_TYPE_BOOLEAN:
- return "bool";
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- return "int32_t";
- case JAVA_TYPE_LONG:
- return "int64_t";
- case JAVA_TYPE_FLOAT:
- return "float";
- case JAVA_TYPE_DOUBLE:
- return "double";
- case JAVA_TYPE_STRING:
- return "char const*";
- case JAVA_TYPE_BYTE_ARRAY:
- return "const BytesField&";
- default:
- return "UNKNOWN";
- }
-}
-
-const char* java_type_name(java_type_t type) {
- switch (type) {
- case JAVA_TYPE_BOOLEAN:
- return "boolean";
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- return "int";
- case JAVA_TYPE_LONG:
- return "long";
- case JAVA_TYPE_FLOAT:
- return "float";
- case JAVA_TYPE_DOUBLE:
- return "double";
- case JAVA_TYPE_STRING:
- return "java.lang.String";
- case JAVA_TYPE_BYTE_ARRAY:
- return "byte[]";
- default:
- return "UNKNOWN";
- }
-}
-
-// Native
-// Writes namespaces for the cpp and header files, returning the number of
-// namespaces written.
-void write_namespace(FILE* out, const string& cppNamespaces) {
- vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ",");
- for (string cppNamespace : cppNamespaceVec) {
- fprintf(out, "namespace %s {\n", cppNamespace.c_str());
- }
-}
-
-// Writes namespace closing brackets for cpp and header files.
-void write_closing_namespace(FILE* out, const string& cppNamespaces) {
- vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ",");
- for (auto it = cppNamespaceVec.rbegin(); it != cppNamespaceVec.rend(); ++it) {
- fprintf(out, "} // namespace %s\n", it->c_str());
- }
-}
-
-static void write_cpp_usage(FILE* out, const string& method_name, const string& atom_code_name,
- const shared_ptr<AtomDecl> atom, const AtomDecl& attributionDecl) {
- fprintf(out, " * Usage: %s(StatsLog.%s", method_name.c_str(), atom_code_name.c_str());
-
- for (vector<AtomField>::const_iterator field = atom->fields.begin();
- field != atom->fields.end(); field++) {
- if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", const std::vector<%s>& %s", cpp_type_name(chainField.javaType),
- chainField.name.c_str());
- } else {
- fprintf(out, ", const %s* %s, size_t %s_length",
- cpp_type_name(chainField.javaType), chainField.name.c_str(),
- chainField.name.c_str());
- }
- }
- } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out,
- ", const std::map<int, int32_t>& %s_int"
- ", const std::map<int, int64_t>& %s_long"
- ", const std::map<int, char const*>& %s_str"
- ", const std::map<int, float>& %s_float",
- field->name.c_str(), field->name.c_str(), field->name.c_str(),
- field->name.c_str());
- } else {
- fprintf(out, ", %s %s", cpp_type_name(field->javaType), field->name.c_str());
- }
- }
- fprintf(out, ");\n");
-}
-
-void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl) {
- fprintf(out, "/**\n");
- fprintf(out, " * Constants for atom codes.\n");
- fprintf(out, " */\n");
- fprintf(out, "enum {\n");
-
- std::map<int, AtomDeclSet::const_iterator> atom_code_to_non_chained_decl_map;
- build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map);
-
- size_t i = 0;
- // Print atom constants
- for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
- atomIt++) {
- string constant = make_constant_name((*atomIt)->name);
- fprintf(out, "\n");
- fprintf(out, " /**\n");
- fprintf(out, " * %s %s\n", (*atomIt)->message.c_str(), (*atomIt)->name.c_str());
- write_cpp_usage(out, "stats_write", constant, *atomIt, attributionDecl);
-
- auto non_chained_decl = atom_code_to_non_chained_decl_map.find((*atomIt)->code);
- if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) {
- write_cpp_usage(out, "stats_write_non_chained", constant, *non_chained_decl->second,
- attributionDecl);
- }
- fprintf(out, " */\n");
- char const* const comma = (i == atoms.decls.size() - 1) ? "" : ",";
- fprintf(out, " %s = %d%s\n", constant.c_str(), (*atomIt)->code, comma);
- i++;
- }
- fprintf(out, "\n");
- fprintf(out, "};\n");
- fprintf(out, "\n");
-}
-
-void write_native_method_signature(FILE* out, const string& methodName,
- const vector<java_type_t>& signature,
- const AtomDecl& attributionDecl, const string& closer) {
- fprintf(out, "%s(int32_t code", methodName.c_str());
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", const std::vector<%s>& %s", cpp_type_name(chainField.javaType),
- chainField.name.c_str());
- } else {
- fprintf(out, ", const %s* %s, size_t %s_length",
- cpp_type_name(chainField.javaType), chainField.name.c_str(),
- chainField.name.c_str());
- }
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out,
- ", const std::map<int, int32_t>& arg%d_1, "
- "const std::map<int, int64_t>& arg%d_2, "
- "const std::map<int, char const*>& arg%d_3, "
- "const std::map<int, float>& arg%d_4",
- argIndex, argIndex, argIndex, argIndex);
- } else {
- fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ")%s\n", closer.c_str());
-}
-
-void write_native_method_call(FILE* out, const string& methodName,
- const vector<java_type_t>& signature, const AtomDecl& attributionDecl,
- int argIndex) {
- fprintf(out, "%s(code", methodName.c_str());
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", %s", chainField.name.c_str());
- } else {
- fprintf(out, ", %s, %s_length", chainField.name.c_str(),
- chainField.name.c_str());
- }
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", arg%d_1, arg%d_2, arg%d_3, arg%d_4", argIndex, argIndex, argIndex,
- argIndex);
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- argIndex++;
- }
- fprintf(out, ");\n");
-}
-
-// Java
-void write_java_atom_codes(FILE* out, const Atoms& atoms) {
- fprintf(out, " // Constants for atom codes.\n");
-
- std::map<int, AtomDeclSet::const_iterator> atom_code_to_non_chained_decl_map;
- build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map);
-
- // Print constants for the atom codes.
- for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
- atomIt++) {
- string constant = make_constant_name((*atomIt)->name);
- fprintf(out, "\n");
- fprintf(out, " /**\n");
- fprintf(out, " * %s %s<br>\n", (*atomIt)->message.c_str(), (*atomIt)->name.c_str());
- write_java_usage(out, "write", constant, **atomIt);
- auto non_chained_decl = atom_code_to_non_chained_decl_map.find((*atomIt)->code);
- if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) {
- write_java_usage(out, "write_non_chained", constant, **(non_chained_decl->second));
- }
- fprintf(out, " */\n");
- fprintf(out, " public static final int %s = %d;\n", constant.c_str(), (*atomIt)->code);
- }
- fprintf(out, "\n");
-}
-
-void write_java_enum_values(FILE* out, const Atoms& atoms) {
- fprintf(out, " // Constants for enum values.\n\n");
- for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
- atomIt++) {
- for (vector<AtomField>::const_iterator field = (*atomIt)->fields.begin();
- field != (*atomIt)->fields.end(); field++) {
- if (field->javaType == JAVA_TYPE_ENUM) {
- fprintf(out, " // Values for %s.%s\n", (*atomIt)->message.c_str(),
- field->name.c_str());
- for (map<int, string>::const_iterator value = field->enumValues.begin();
- value != field->enumValues.end(); value++) {
- fprintf(out, " public static final int %s__%s__%s = %d;\n",
- make_constant_name((*atomIt)->message).c_str(),
- make_constant_name(field->name).c_str(),
- make_constant_name(value->second).c_str(), value->first);
- }
- fprintf(out, "\n");
- }
- }
- }
-}
-
-void write_java_usage(FILE* out, const string& method_name, const string& atom_code_name,
- const AtomDecl& atom) {
- fprintf(out, " * Usage: StatsLog.%s(StatsLog.%s", method_name.c_str(),
- atom_code_name.c_str());
- for (vector<AtomField>::const_iterator field = atom.fields.begin(); field != atom.fields.end();
- field++) {
- if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- fprintf(out, ", android.os.WorkSource workSource");
- } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", android.util.SparseArray<Object> value_map");
- } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) {
- fprintf(out, ", byte[] %s", field->name.c_str());
- } else {
- fprintf(out, ", %s %s", java_type_name(field->javaType), field->name.c_str());
- }
- }
- fprintf(out, ");<br>\n");
-}
-
-int write_java_non_chained_methods(FILE* out, const SignatureInfoMap& signatureInfoMap) {
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- // Print method signature.
- fprintf(out, " public static void write_non_chained(int code");
- vector<java_type_t> signature = signatureInfoMapIt->first;
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- fprintf(stderr, "Non chained signatures should not have attribution chains.\n");
- return 1;
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(stderr, "Module logging does not yet support key value pair.\n");
- return 1;
- } else {
- fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ") {\n");
-
- fprintf(out, " write(code");
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- // First two args are uid and tag of attribution chain.
- if (argIndex == 1) {
- fprintf(out, ", new int[] {arg%d}", argIndex);
- } else if (argIndex == 2) {
- fprintf(out, ", new java.lang.String[] {arg%d}", argIndex);
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- argIndex++;
- }
- fprintf(out, ");\n");
- fprintf(out, " }\n");
- fprintf(out, "\n");
- }
- return 0;
-}
-
-int write_java_work_source_methods(FILE* out, const SignatureInfoMap& signatureInfoMap) {
- fprintf(out, " // WorkSource methods.\n");
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- vector<java_type_t> signature = signatureInfoMapIt->first;
- // Determine if there is Attribution in this signature.
- int attributionArg = -1;
- int argIndexMax = 0;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- argIndexMax++;
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- if (attributionArg > -1) {
- fprintf(stderr, "An atom contains multiple AttributionNode fields.\n");
- fprintf(stderr, "This is not supported. Aborting WorkSource method writing.\n");
- fprintf(out,
- "\n// Invalid for WorkSource: more than one attribution "
- "chain.\n");
- return 1;
- }
- attributionArg = argIndexMax;
- }
- }
- if (attributionArg < 0) {
- continue;
- }
-
- fprintf(out, "\n");
- // Method header (signature)
- fprintf(out, " public static void write(int code");
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- fprintf(out, ", android.os.WorkSource ws");
- } else {
- fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ") {\n");
-
- // write_non_chained() component. TODO: Remove when flat uids are no longer
- // needed.
- fprintf(out, " for (int i = 0; i < ws.size(); ++i) {\n");
- fprintf(out, " write_non_chained(code");
- for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) {
- if (argIndex == attributionArg) {
- fprintf(out, ", ws.getUid(i), ws.getPackageName(i)");
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- }
- fprintf(out, ");\n");
- fprintf(out, " }\n"); // close for-loop
-
- // write() component.
- fprintf(out,
- " java.util.List<android.os.WorkSource.WorkChain> workChains = "
- "ws.getWorkChains();\n");
- fprintf(out, " if (workChains != null) {\n");
- fprintf(out,
- " for (android.os.WorkSource.WorkChain wc : workChains) "
- "{\n");
- fprintf(out, " write(code");
- for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) {
- if (argIndex == attributionArg) {
- fprintf(out, ", wc.getUids(), wc.getTags()");
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- }
- fprintf(out, ");\n");
- fprintf(out, " }\n"); // close for-loop
- fprintf(out, " }\n"); // close if
- fprintf(out, " }\n"); // close method
- }
- return 0;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h
deleted file mode 100644
index 73e0cb8..0000000
--- a/tools/stats_log_api_gen/utils.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "Collation.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using namespace std;
-
-const string DEFAULT_CPP_NAMESPACE = "android,util";
-const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
-
-const int JAVA_MODULE_REQUIRES_FLOAT = 0x01;
-const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02;
-const int JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS = 0x04;
-
-const map<AnnotationId, string> ANNOTATION_ID_CONSTANTS = {
- {ANNOTATION_ID_IS_UID, "ANNOTATION_ID_IS_UID"},
- {ANNOTATION_ID_TRUNCATE_TIMESTAMP, "ANNOTATION_ID_TRUNCATE_TIMESTAMP"},
- {ANNOTATION_ID_PRIMARY_FIELD, "ANNOTATION_ID_PRIMARY_FIELD"},
- {ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, "ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID"},
- {ANNOTATION_ID_EXCLUSIVE_STATE, "ANNOTATION_ID_EXCLUSIVE_STATE"},
- {ANNOTATION_ID_TRIGGER_STATE_RESET, "ANNOTATION_ID_TRIGGER_STATE_RESET"},
- {ANNOTATION_ID_STATE_NESTED, "ANNOTATION_ID_STATE_NESTED"}};
-
-string make_constant_name(const string& str);
-
-const char* cpp_type_name(java_type_t type);
-
-const char* java_type_name(java_type_t type);
-
-// Common Native helpers
-void write_namespace(FILE* out, const string& cppNamespaces);
-
-void write_closing_namespace(FILE* out, const string& cppNamespaces);
-
-void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl);
-
-void write_native_method_signature(FILE* out, const string& methodName,
- const vector<java_type_t>& signature,
- const AtomDecl& attributionDecl, const string& closer);
-
-void write_native_method_call(FILE* out, const string& methodName,
- const vector<java_type_t>& signature, const AtomDecl& attributionDecl,
- int argIndex = 1);
-
-// Common Java helpers.
-void write_java_atom_codes(FILE* out, const Atoms& atoms);
-
-void write_java_enum_values(FILE* out, const Atoms& atoms);
-
-void write_java_usage(FILE* out, const string& method_name, const string& atom_code_name,
- const AtomDecl& atom);
-
-int write_java_non_chained_methods(FILE* out, const SignatureInfoMap& signatureInfoMap);
-
-int write_java_work_source_methods(FILE* out, const SignatureInfoMap& signatureInfoMap);
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/wifi/Android.bp b/wifi/Android.bp
deleted file mode 100644
index 941ff61..0000000
--- a/wifi/Android.bp
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_defaults {
- name: "wifi-module-sdk-version-defaults",
- min_sdk_version: "30",
- target_sdk_version: "30",
-}
-
-filegroup {
- name: "framework-wifi-updatable-exported-aidl-sources",
- srcs: ["aidl-export/**/*.aidl"],
- path: "aidl-export",
- visibility: ["//visibility:private"],
-}
-
-filegroup {
- name: "framework-wifi-updatable-java-sources",
- srcs: [
- "java/**/*.java",
- "java/**/*.aidl",
- ],
- exclude_srcs: [
- ":framework-wifi-non-updatable-sources"
- ],
- path: "java",
- visibility: ["//visibility:private"],
-}
-
-filegroup {
- name: "framework-wifi-updatable-sources",
- srcs: [
- ":framework-wifi-updatable-java-sources",
- ":framework-wifi-updatable-exported-aidl-sources",
- ],
-}
-
-filegroup {
- name: "framework-wifi-non-updatable-sources",
- srcs: [
- // TODO(b/146011398) package android.net.wifi is now split amongst 2 jars: framework.jar and
- // framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache
- // to a separate package.
- "java/android/net/wifi/SoftApConfToXmlMigrationUtil.java",
- "java/android/net/wifi/WifiNetworkScoreCache.java",
- "java/android/net/wifi/WifiMigration.java",
- "java/android/net/wifi/nl80211/*.java",
- ":libwificond_ipc_aidl",
- ],
-}
-
-filegroup {
- name: "framework-wifi-annotations",
- srcs: ["java/android/net/wifi/WifiAnnotations.java"],
-}
-
-// list of tests that are allowed to access @hide APIs from framework-wifi
-test_access_hidden_api_whitelist = [
- "//frameworks/base/wifi/tests",
- "//frameworks/opt/net/wifi/tests/wifitests:__subpackages__",
-
- "//external/robolectric-shadows:__subpackages__",
- "//frameworks/base/packages/SettingsLib/tests/integ",
- "//external/sl4a:__subpackages__",
-]
-
-// wifi-service needs pre-jarjared version of framework-wifi so it can reference copied utility
-// classes before they are renamed.
-java_library {
- name: "framework-wifi-pre-jarjar",
- defaults: ["wifi-module-sdk-version-defaults"],
- sdk_version: "module_current",
- static_libs: [
- "framework-wifi-util-lib",
- "android.hardware.wifi-V1.0-java-constants",
- ],
- libs: [
- "framework-annotations-lib",
- "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
- ],
- srcs: [
- ":framework-wifi-updatable-sources",
- ":framework-wifi-util-lib-aidls",
- ],
- // java_api_finder must accompany `srcs`
- plugins: ["java_api_finder"],
- installable: false,
- visibility: [
- "//frameworks/opt/net/wifi/service",
- "//frameworks/opt/net/wifi/tests/wifitests",
- ],
-}
-
-// post-jarjar version of framework-wifi
-java_sdk_library {
- name: "framework-wifi",
- defaults: [
- "framework-module-defaults",
- "wifi-module-sdk-version-defaults",
- ],
- static_libs: [
- "framework-wifi-util-lib",
- "android.hardware.wifi-V1.0-java-constants",
- ],
- libs: [
- "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
- ],
- srcs: [
- ":framework-wifi-updatable-sources",
- ":framework-wifi-util-lib-aidls",
- ],
-
- jarjar_rules: ":wifi-jarjar-rules",
-
- installable: true,
- optimize: {
- enabled: false
- },
- hostdex: true, // for hiddenapi check
-
- // Allow access to the stubs from anywhere.
- visibility: ["//visibility:public"],
-
- // Restrict access to implementation library.
- impl_library_visibility: [
- "//visibility:override", // Ignore the visibility property.
- "//frameworks/opt/net/wifi/service:__subpackages__",
- ] + test_access_hidden_api_whitelist,
-
- apex_available: [
- "com.android.wifi",
- "test_com.android.wifi",
- ],
- permitted_packages: [
- "android.hardware.wifi",
- "android.net.wifi",
- // Created by jarjar rules.
- "com.android.wifi.x",
- ],
-}
-
-// defaults for tests that need to build against framework-wifi's @hide APIs
-java_defaults {
- name: "framework-wifi-test-defaults",
- sdk_version: "core_platform", // tests can use @CorePlatformApi's
- libs: [
- // order matters: classes in framework-wifi are resolved before framework, meaning
- // @hide APIs in framework-wifi are resolved before @SystemApi stubs in framework
- "framework-wifi.impl",
- "framework",
-
- // if sdk_version="" this gets automatically included, but here we need to add manually.
- "framework-res",
- ],
- visibility: test_access_hidden_api_whitelist,
-}
-
-filegroup {
- name: "wifi-jarjar-rules",
- srcs: ["jarjar-rules.txt"],
-}
diff --git a/wifi/MOVED.txt b/wifi/MOVED.txt
new file mode 100644
index 0000000..6ffb23c
--- /dev/null
+++ b/wifi/MOVED.txt
@@ -0,0 +1,8 @@
+Source code and tests for Wifi module APIs have moved to
+packages/modules/Wifi/framework.
+
+- frameworks/base/wifi/java -> packages/modules/Wifi/framework/java
+- frameworks/base/wifi/tests -> packages/modules/Wifi/framework/tests
+
+What remains in frameworks/base/wifi are Wifi APIs that
+are not part of the Wifi module.
diff --git a/wifi/aidl-export/android/net/wifi/ScanResult.aidl b/wifi/aidl-export/android/net/wifi/ScanResult.aidl
deleted file mode 100644
index b30689c..0000000
--- a/wifi/aidl-export/android/net/wifi/ScanResult.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-@JavaOnlyStableParcelable parcelable ScanResult;
diff --git a/wifi/aidl-export/android/net/wifi/SoftApCapability.aidl b/wifi/aidl-export/android/net/wifi/SoftApCapability.aidl
deleted file mode 100644
index bf30709..0000000
--- a/wifi/aidl-export/android/net/wifi/SoftApCapability.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi;
-
-parcelable SoftApCapability;
diff --git a/wifi/aidl-export/android/net/wifi/SoftApConfiguration.aidl b/wifi/aidl-export/android/net/wifi/SoftApConfiguration.aidl
deleted file mode 100644
index 1d06f45..0000000
--- a/wifi/aidl-export/android/net/wifi/SoftApConfiguration.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi;
-
-parcelable SoftApConfiguration;
\ No newline at end of file
diff --git a/wifi/aidl-export/android/net/wifi/SoftApInfo.aidl b/wifi/aidl-export/android/net/wifi/SoftApInfo.aidl
deleted file mode 100644
index d4551cf..0000000
--- a/wifi/aidl-export/android/net/wifi/SoftApInfo.aidl
+++ /dev/null
@@ -1,20 +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.net.wifi;
-
-parcelable SoftApInfo;
-
diff --git a/wifi/aidl-export/android/net/wifi/WifiClient.aidl b/wifi/aidl-export/android/net/wifi/WifiClient.aidl
deleted file mode 100644
index accdadd..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiClient.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi;
-
-@JavaOnlyStableParcelable parcelable WifiClient;
\ No newline at end of file
diff --git a/wifi/aidl-export/android/net/wifi/WifiConfiguration.aidl b/wifi/aidl-export/android/net/wifi/WifiConfiguration.aidl
deleted file mode 100644
index 237a74d..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiConfiguration.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-parcelable WifiConfiguration;
diff --git a/wifi/aidl-export/android/net/wifi/WifiEnterpriseConfig.aidl b/wifi/aidl-export/android/net/wifi/WifiEnterpriseConfig.aidl
deleted file mode 100644
index b0f5f84..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiEnterpriseConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2013, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-parcelable WifiEnterpriseConfig;
diff --git a/wifi/aidl-export/android/net/wifi/WifiInfo.aidl b/wifi/aidl-export/android/net/wifi/WifiInfo.aidl
deleted file mode 100644
index db47f0b..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-parcelable WifiInfo;
diff --git a/wifi/aidl-export/android/net/wifi/WifiNetworkConnectionStatistics.aidl b/wifi/aidl-export/android/net/wifi/WifiNetworkConnectionStatistics.aidl
deleted file mode 100644
index 5f497e2..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiNetworkConnectionStatistics.aidl
+++ /dev/null
@@ -1,19 +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.
- */
-
-package android.net.wifi;
-
-parcelable WifiNetworkConnectionStatistics;
diff --git a/wifi/aidl-export/android/net/wifi/WifiNetworkSuggestion.aidl b/wifi/aidl-export/android/net/wifi/WifiNetworkSuggestion.aidl
deleted file mode 100644
index eb6995f..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiNetworkSuggestion.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2018, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable WifiNetworkSuggestion;
diff --git a/wifi/aidl-export/android/net/wifi/WifiUsabilityStatsEntry.aidl b/wifi/aidl-export/android/net/wifi/WifiUsabilityStatsEntry.aidl
deleted file mode 100644
index 839af54..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiUsabilityStatsEntry.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi;
-
-parcelable WifiUsabilityStatsEntry;
diff --git a/wifi/aidl-export/android/net/wifi/WpsInfo.aidl b/wifi/aidl-export/android/net/wifi/WpsInfo.aidl
deleted file mode 100644
index f5e4ebe..0000000
--- a/wifi/aidl-export/android/net/wifi/WpsInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-parcelable WpsInfo;
diff --git a/wifi/aidl-export/android/net/wifi/aware/Characteristics.aidl b/wifi/aidl-export/android/net/wifi/aware/Characteristics.aidl
deleted file mode 100644
index 77305e9..0000000
--- a/wifi/aidl-export/android/net/wifi/aware/Characteristics.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.aware;
-
-parcelable Characteristics;
diff --git a/wifi/aidl-export/android/net/wifi/aware/PublishConfig.aidl b/wifi/aidl-export/android/net/wifi/aware/PublishConfig.aidl
deleted file mode 100644
index 2e6dd00..0000000
--- a/wifi/aidl-export/android/net/wifi/aware/PublishConfig.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.aware;
-
-parcelable PublishConfig;
diff --git a/wifi/aidl-export/android/net/wifi/aware/SubscribeConfig.aidl b/wifi/aidl-export/android/net/wifi/aware/SubscribeConfig.aidl
deleted file mode 100644
index bd73d5e..0000000
--- a/wifi/aidl-export/android/net/wifi/aware/SubscribeConfig.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.aware;
-
-parcelable SubscribeConfig;
diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/OsuProvider.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/OsuProvider.aidl
deleted file mode 100644
index 23d0f22..0000000
--- a/wifi/aidl-export/android/net/wifi/hotspot2/OsuProvider.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.hotspot2;
-
-parcelable OsuProvider;
diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/PasspointConfiguration.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/PasspointConfiguration.aidl
deleted file mode 100644
index 6b1cea8..0000000
--- a/wifi/aidl-export/android/net/wifi/hotspot2/PasspointConfiguration.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.hotspot2;
-
-parcelable PasspointConfiguration;
diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/pps/Credential.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/pps/Credential.aidl
deleted file mode 100644
index 3d8e833..0000000
--- a/wifi/aidl-export/android/net/wifi/hotspot2/pps/Credential.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.hotspot2.pps;
-
-parcelable Credential;
diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/pps/HomeSp.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/pps/HomeSp.aidl
deleted file mode 100644
index 6d343bd..0000000
--- a/wifi/aidl-export/android/net/wifi/hotspot2/pps/HomeSp.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.hotspot2.pps;
-
-parcelable HomeSp;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pConfig.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pConfig.aidl
deleted file mode 100644
index ea3b280..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-parcelable WifiP2pConfig;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDevice.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDevice.aidl
deleted file mode 100644
index 8790c6f..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDevice.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-parcelable WifiP2pDevice;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDeviceList.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDeviceList.aidl
deleted file mode 100644
index 6c79009..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDeviceList.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-parcelable WifiP2pDeviceList;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pGroup.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pGroup.aidl
deleted file mode 100644
index 403f2b1..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pGroup.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-parcelable WifiP2pGroup;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pInfo.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pInfo.aidl
deleted file mode 100644
index a347148..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-parcelable WifiP2pInfo;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl
deleted file mode 100644
index cf2cb4a..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.servicediscovery;
-
-parcelable WifiP2pServiceInfo;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl
deleted file mode 100644
index d5a1e8f..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.servicediscovery;
-
-parcelable WifiP2pServiceRequest;
diff --git a/wifi/aidl-export/android/net/wifi/rtt/RangingRequest.aidl b/wifi/aidl-export/android/net/wifi/rtt/RangingRequest.aidl
deleted file mode 100644
index 8053c94..0000000
--- a/wifi/aidl-export/android/net/wifi/rtt/RangingRequest.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.rtt;
-
-parcelable RangingRequest;
diff --git a/wifi/aidl-export/android/net/wifi/rtt/RangingResult.aidl b/wifi/aidl-export/android/net/wifi/rtt/RangingResult.aidl
deleted file mode 100644
index ae295a6..0000000
--- a/wifi/aidl-export/android/net/wifi/rtt/RangingResult.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.rtt;
-
-parcelable RangingResult;
diff --git a/wifi/aidl-export/android/net/wifi/rtt/ResponderConfig.aidl b/wifi/aidl-export/android/net/wifi/rtt/ResponderConfig.aidl
deleted file mode 100644
index fd3988a..0000000
--- a/wifi/aidl-export/android/net/wifi/rtt/ResponderConfig.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.rtt;
-
-parcelable ResponderConfig;
diff --git a/wifi/api/current.txt b/wifi/api/current.txt
deleted file mode 100644
index 53c3b33..0000000
--- a/wifi/api/current.txt
+++ /dev/null
@@ -1,1199 +0,0 @@
-// Signature format: 2.0
-package android.net.wifi {
-
- public abstract class EasyConnectStatusCallback {
- field public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2; // 0xfffffffe
- field public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5; // 0xfffffffb
- field public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10; // 0xfffffff6
- field public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4; // 0xfffffffc
- field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11; // 0xfffffff5
- field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12; // 0xfffffff4
- field public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7; // 0xfffffff9
- field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9; // 0xfffffff7
- field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1; // 0xffffffff
- field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE = -3; // 0xfffffffd
- field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8; // 0xfffffff8
- field public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6; // 0xfffffffa
- }
-
- public final class ScanResult implements android.os.Parcelable {
- ctor public ScanResult(@NonNull android.net.wifi.ScanResult);
- ctor public ScanResult();
- method public int describeContents();
- method @NonNull public java.util.List<android.net.wifi.ScanResult.InformationElement> getInformationElements();
- method public int getWifiStandard();
- method public boolean is80211mcResponder();
- method public boolean isPasspointNetwork();
- method public void writeToParcel(android.os.Parcel, int);
- field public String BSSID;
- field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
- field public static final int CHANNEL_WIDTH_20MHZ = 0; // 0x0
- field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
- field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
- field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.ScanResult> CREATOR;
- field public String SSID;
- field public static final int WIFI_STANDARD_11AC = 5; // 0x5
- field public static final int WIFI_STANDARD_11AX = 6; // 0x6
- field public static final int WIFI_STANDARD_11N = 4; // 0x4
- field public static final int WIFI_STANDARD_LEGACY = 1; // 0x1
- field public static final int WIFI_STANDARD_UNKNOWN = 0; // 0x0
- field public String capabilities;
- field public int centerFreq0;
- field public int centerFreq1;
- field public int channelWidth;
- field public int frequency;
- field public int level;
- field public CharSequence operatorFriendlyName;
- field public long timestamp;
- field public CharSequence venueName;
- }
-
- public static class ScanResult.InformationElement {
- ctor public ScanResult.InformationElement(@NonNull android.net.wifi.ScanResult.InformationElement);
- method @NonNull public java.nio.ByteBuffer getBytes();
- method public int getId();
- method public int getIdExt();
- }
-
- public final class SoftApConfiguration implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public android.net.MacAddress getBssid();
- method @Nullable public String getPassphrase();
- method public int getSecurityType();
- method @Nullable public String getSsid();
- method public boolean isHiddenSsid();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApConfiguration> CREATOR;
- field public static final int SECURITY_TYPE_OPEN = 0; // 0x0
- field public static final int SECURITY_TYPE_WPA2_PSK = 1; // 0x1
- field public static final int SECURITY_TYPE_WPA3_SAE = 3; // 0x3
- field public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; // 0x2
- }
-
- public enum SupplicantState implements android.os.Parcelable {
- method public int describeContents();
- method public static boolean isValidState(android.net.wifi.SupplicantState);
- method public void writeToParcel(android.os.Parcel, int);
- enum_constant public static final android.net.wifi.SupplicantState ASSOCIATED;
- enum_constant public static final android.net.wifi.SupplicantState ASSOCIATING;
- enum_constant public static final android.net.wifi.SupplicantState AUTHENTICATING;
- enum_constant public static final android.net.wifi.SupplicantState COMPLETED;
- enum_constant public static final android.net.wifi.SupplicantState DISCONNECTED;
- enum_constant public static final android.net.wifi.SupplicantState DORMANT;
- enum_constant public static final android.net.wifi.SupplicantState FOUR_WAY_HANDSHAKE;
- enum_constant public static final android.net.wifi.SupplicantState GROUP_HANDSHAKE;
- enum_constant public static final android.net.wifi.SupplicantState INACTIVE;
- enum_constant public static final android.net.wifi.SupplicantState INTERFACE_DISABLED;
- enum_constant public static final android.net.wifi.SupplicantState INVALID;
- enum_constant public static final android.net.wifi.SupplicantState SCANNING;
- enum_constant public static final android.net.wifi.SupplicantState UNINITIALIZED;
- }
-
- @Deprecated public class WifiConfiguration implements android.os.Parcelable {
- ctor @Deprecated public WifiConfiguration();
- ctor @Deprecated public WifiConfiguration(@NonNull android.net.wifi.WifiConfiguration);
- method public int describeContents();
- method @Deprecated public android.net.ProxyInfo getHttpProxy();
- method @Deprecated @NonNull public String getKey();
- method @Deprecated @NonNull public android.net.MacAddress getRandomizedMacAddress();
- method @Deprecated public boolean isPasspoint();
- method @Deprecated public void setHttpProxy(android.net.ProxyInfo);
- method @Deprecated public void setSecurityParams(int);
- method public void writeToParcel(android.os.Parcel, int);
- field @Deprecated public String BSSID;
- field @Deprecated public String FQDN;
- field @Deprecated public static final int SECURITY_TYPE_EAP = 3; // 0x3
- field @Deprecated public static final int SECURITY_TYPE_EAP_SUITE_B = 5; // 0x5
- field @Deprecated public static final int SECURITY_TYPE_OPEN = 0; // 0x0
- field @Deprecated public static final int SECURITY_TYPE_OWE = 6; // 0x6
- field @Deprecated public static final int SECURITY_TYPE_PSK = 2; // 0x2
- field @Deprecated public static final int SECURITY_TYPE_SAE = 4; // 0x4
- field @Deprecated public static final int SECURITY_TYPE_WAPI_CERT = 8; // 0x8
- field @Deprecated public static final int SECURITY_TYPE_WAPI_PSK = 7; // 0x7
- field @Deprecated public static final int SECURITY_TYPE_WEP = 1; // 0x1
- field @Deprecated public String SSID;
- field @Deprecated @NonNull public java.util.BitSet allowedAuthAlgorithms;
- field @Deprecated @NonNull public java.util.BitSet allowedGroupCiphers;
- field @Deprecated @NonNull public java.util.BitSet allowedGroupManagementCiphers;
- field @Deprecated @NonNull public java.util.BitSet allowedKeyManagement;
- field @Deprecated @NonNull public java.util.BitSet allowedPairwiseCiphers;
- field @Deprecated @NonNull public java.util.BitSet allowedProtocols;
- field @Deprecated @NonNull public java.util.BitSet allowedSuiteBCiphers;
- field @Deprecated public android.net.wifi.WifiEnterpriseConfig enterpriseConfig;
- field @Deprecated public boolean hiddenSSID;
- field @Deprecated public boolean isHomeProviderNetwork;
- field @Deprecated public int networkId;
- field @Deprecated public String preSharedKey;
- field @Deprecated public int priority;
- field @Deprecated public String providerFriendlyName;
- field @Deprecated public long[] roamingConsortiumIds;
- field @Deprecated public int status;
- field @Deprecated public String[] wepKeys;
- field @Deprecated public int wepTxKeyIndex;
- }
-
- @Deprecated public static class WifiConfiguration.AuthAlgorithm {
- field @Deprecated public static final int LEAP = 2; // 0x2
- field @Deprecated public static final int OPEN = 0; // 0x0
- field @Deprecated public static final int SAE = 3; // 0x3
- field @Deprecated public static final int SHARED = 1; // 0x1
- field @Deprecated public static final String[] strings;
- field @Deprecated public static final String varName = "auth_alg";
- }
-
- @Deprecated public static class WifiConfiguration.GroupCipher {
- field @Deprecated public static final int CCMP = 3; // 0x3
- field @Deprecated public static final int GCMP_256 = 5; // 0x5
- field @Deprecated public static final int SMS4 = 6; // 0x6
- field @Deprecated public static final int TKIP = 2; // 0x2
- field @Deprecated public static final int WEP104 = 1; // 0x1
- field @Deprecated public static final int WEP40 = 0; // 0x0
- field @Deprecated public static final String[] strings;
- field @Deprecated public static final String varName = "group";
- }
-
- @Deprecated public static class WifiConfiguration.GroupMgmtCipher {
- field @Deprecated public static final int BIP_CMAC_256 = 0; // 0x0
- field @Deprecated public static final int BIP_GMAC_128 = 1; // 0x1
- field @Deprecated public static final int BIP_GMAC_256 = 2; // 0x2
- }
-
- @Deprecated public static class WifiConfiguration.KeyMgmt {
- field @Deprecated public static final int IEEE8021X = 3; // 0x3
- field @Deprecated public static final int NONE = 0; // 0x0
- field @Deprecated public static final int OWE = 9; // 0x9
- field @Deprecated public static final int SAE = 8; // 0x8
- field @Deprecated public static final int SUITE_B_192 = 10; // 0xa
- field @Deprecated public static final int WPA_EAP = 2; // 0x2
- field @Deprecated public static final int WPA_PSK = 1; // 0x1
- field @Deprecated public static final String[] strings;
- field @Deprecated public static final String varName = "key_mgmt";
- }
-
- @Deprecated public static class WifiConfiguration.PairwiseCipher {
- field @Deprecated public static final int CCMP = 2; // 0x2
- field @Deprecated public static final int GCMP_256 = 3; // 0x3
- field @Deprecated public static final int NONE = 0; // 0x0
- field @Deprecated public static final int SMS4 = 4; // 0x4
- field @Deprecated public static final int TKIP = 1; // 0x1
- field @Deprecated public static final String[] strings;
- field @Deprecated public static final String varName = "pairwise";
- }
-
- @Deprecated public static class WifiConfiguration.Protocol {
- field @Deprecated public static final int RSN = 1; // 0x1
- field @Deprecated public static final int WAPI = 3; // 0x3
- field @Deprecated public static final int WPA = 0; // 0x0
- field @Deprecated public static final String[] strings;
- field @Deprecated public static final String varName = "proto";
- }
-
- @Deprecated public static class WifiConfiguration.Status {
- field @Deprecated public static final int CURRENT = 0; // 0x0
- field @Deprecated public static final int DISABLED = 1; // 0x1
- field @Deprecated public static final int ENABLED = 2; // 0x2
- field @Deprecated public static final String[] strings;
- }
-
- public class WifiEnterpriseConfig implements android.os.Parcelable {
- ctor public WifiEnterpriseConfig();
- ctor public WifiEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig);
- method public int describeContents();
- method public String getAltSubjectMatch();
- method public String getAnonymousIdentity();
- method @Nullable public java.security.cert.X509Certificate getCaCertificate();
- method @Nullable public java.security.cert.X509Certificate[] getCaCertificates();
- method public java.security.cert.X509Certificate getClientCertificate();
- method @Nullable public java.security.cert.X509Certificate[] getClientCertificateChain();
- method @Nullable public java.security.PrivateKey getClientPrivateKey();
- method public String getDomainSuffixMatch();
- method public int getEapMethod();
- method public String getIdentity();
- method public String getPassword();
- method public int getPhase2Method();
- method public String getPlmn();
- method public String getRealm();
- method @Deprecated public String getSubjectMatch();
- method public boolean isAuthenticationSimBased();
- method public void setAltSubjectMatch(String);
- method public void setAnonymousIdentity(String);
- method public void setCaCertificate(@Nullable java.security.cert.X509Certificate);
- method public void setCaCertificates(@Nullable java.security.cert.X509Certificate[]);
- method public void setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate);
- method public void setClientKeyEntryWithCertificateChain(java.security.PrivateKey, java.security.cert.X509Certificate[]);
- method public void setDomainSuffixMatch(String);
- method public void setEapMethod(int);
- method public void setIdentity(String);
- method public void setPassword(String);
- method public void setPhase2Method(int);
- method public void setPlmn(String);
- method public void setRealm(String);
- method @Deprecated public void setSubjectMatch(String);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiEnterpriseConfig> CREATOR;
- field public static final String EXTRA_WAPI_AS_CERTIFICATE_DATA = "android.net.wifi.extra.WAPI_AS_CERTIFICATE_DATA";
- field public static final String EXTRA_WAPI_AS_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_AS_CERTIFICATE_NAME";
- field public static final String EXTRA_WAPI_USER_CERTIFICATE_DATA = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_DATA";
- field public static final String EXTRA_WAPI_USER_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_NAME";
- field public static final String WAPI_AS_CERTIFICATE = "WAPIAS_";
- field public static final String WAPI_USER_CERTIFICATE = "WAPIUSR_";
- }
-
- public static final class WifiEnterpriseConfig.Eap {
- field public static final int AKA = 5; // 0x5
- field public static final int AKA_PRIME = 6; // 0x6
- field public static final int NONE = -1; // 0xffffffff
- field public static final int PEAP = 0; // 0x0
- field public static final int PWD = 3; // 0x3
- field public static final int SIM = 4; // 0x4
- field public static final int TLS = 1; // 0x1
- field public static final int TTLS = 2; // 0x2
- field public static final int UNAUTH_TLS = 7; // 0x7
- field public static final int WAPI_CERT = 8; // 0x8
- }
-
- public static final class WifiEnterpriseConfig.Phase2 {
- field public static final int AKA = 6; // 0x6
- field public static final int AKA_PRIME = 7; // 0x7
- field public static final int GTC = 4; // 0x4
- field public static final int MSCHAP = 2; // 0x2
- field public static final int MSCHAPV2 = 3; // 0x3
- field public static final int NONE = 0; // 0x0
- field public static final int PAP = 1; // 0x1
- field public static final int SIM = 5; // 0x5
- }
-
- public class WifiInfo implements android.os.Parcelable {
- method public int describeContents();
- method public String getBSSID();
- method public static android.net.NetworkInfo.DetailedState getDetailedStateOf(android.net.wifi.SupplicantState);
- method public int getFrequency();
- method public boolean getHiddenSSID();
- method public int getIpAddress();
- method public int getLinkSpeed();
- method public String getMacAddress();
- method public int getMaxSupportedRxLinkSpeedMbps();
- method public int getMaxSupportedTxLinkSpeedMbps();
- method public int getNetworkId();
- method @Nullable public String getPasspointFqdn();
- method @Nullable public String getPasspointProviderFriendlyName();
- method public int getRssi();
- method @IntRange(from=0xffffffff) public int getRxLinkSpeedMbps();
- method public String getSSID();
- method public android.net.wifi.SupplicantState getSupplicantState();
- method @IntRange(from=0xffffffff) public int getTxLinkSpeedMbps();
- method public int getWifiStandard();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final String FREQUENCY_UNITS = "MHz";
- field public static final String LINK_SPEED_UNITS = "Mbps";
- field public static final int LINK_SPEED_UNKNOWN = -1; // 0xffffffff
- }
-
- public static final class WifiInfo.Builder {
- ctor public WifiInfo.Builder();
- method @NonNull public android.net.wifi.WifiInfo build();
- method @NonNull public android.net.wifi.WifiInfo.Builder setBssid(@NonNull String);
- method @NonNull public android.net.wifi.WifiInfo.Builder setNetworkId(int);
- method @NonNull public android.net.wifi.WifiInfo.Builder setRssi(int);
- method @NonNull public android.net.wifi.WifiInfo.Builder setSsid(@NonNull byte[]);
- }
-
- public class WifiManager {
- method @Deprecated public int addNetwork(android.net.wifi.WifiConfiguration);
- method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int addNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
- method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
- method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public void addSuggestionConnectionStatusListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
- method @Deprecated public static int calculateSignalLevel(int, int);
- method @IntRange(from=0) public int calculateSignalLevel(int);
- method @Deprecated public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
- method public static int compareSignalLevel(int, int);
- method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(String);
- method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, String);
- method @Deprecated public android.net.wifi.WifiManager.WifiLock createWifiLock(String);
- method @Deprecated public boolean disableNetwork(int);
- method @Deprecated public boolean disconnect();
- method @Deprecated public boolean enableNetwork(int, boolean);
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
- method public android.net.wifi.WifiInfo getConnectionInfo();
- method public android.net.DhcpInfo getDhcpInfo();
- method public int getMaxNumberOfNetworkSuggestionsPerApp();
- method @IntRange(from=0) public int getMaxSignalLevel();
- method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public java.util.List<android.net.wifi.WifiNetworkSuggestion> getNetworkSuggestions();
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
- method public java.util.List<android.net.wifi.ScanResult> getScanResults();
- method public int getWifiState();
- method public boolean is5GHzBandSupported();
- method public boolean is6GHzBandSupported();
- method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isAutoWakeupEnabled();
- method @Deprecated public boolean isDeviceToApRttSupported();
- method public boolean isEasyConnectSupported();
- method public boolean isEnhancedOpenSupported();
- method public boolean isEnhancedPowerReportingSupported();
- method public boolean isP2pSupported();
- method public boolean isPreferredNetworkOffloadSupported();
- method @Deprecated public boolean isScanAlwaysAvailable();
- method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isScanThrottleEnabled();
- method public boolean isStaApConcurrencySupported();
- method public boolean isTdlsSupported();
- method public boolean isWapiSupported();
- method public boolean isWifiEnabled();
- method public boolean isWifiStandardSupported(int);
- method public boolean isWpa3SaeSupported();
- method public boolean isWpa3SuiteBSupported();
- method @Deprecated public boolean pingSupplicant();
- method @Deprecated public boolean reassociate();
- method @Deprecated public boolean reconnect();
- method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void registerScanResultsCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.ScanResultsCallback);
- method @Deprecated public boolean removeNetwork(int);
- method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int removeNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}) public void removePasspointConfiguration(String);
- method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionConnectionStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
- method @Deprecated public boolean saveConfiguration();
- method public void setTdlsEnabled(java.net.InetAddress, boolean);
- method public void setTdlsEnabledWithMacAddress(String, boolean);
- method @Deprecated public boolean setWifiEnabled(boolean);
- method @RequiresPermission(allOf={android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, @Nullable android.os.Handler);
- method @Deprecated public boolean startScan();
- method @Deprecated public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void unregisterScanResultsCallback(@NonNull android.net.wifi.WifiManager.ScanResultsCallback);
- method @Deprecated public int updateNetwork(android.net.wifi.WifiConfiguration);
- field public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
- field public static final String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
- field public static final String ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION = "android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION";
- field public static final String ACTION_WIFI_SCAN_AVAILABILITY_CHANGED = "android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED";
- field @Deprecated public static final int ERROR_AUTHENTICATING = 1; // 0x1
- field @Deprecated public static final String EXTRA_BSSID = "bssid";
- field public static final String EXTRA_NETWORK_INFO = "networkInfo";
- field public static final String EXTRA_NETWORK_SUGGESTION = "android.net.wifi.extra.NETWORK_SUGGESTION";
- field public static final String EXTRA_NEW_RSSI = "newRssi";
- field @Deprecated public static final String EXTRA_NEW_STATE = "newState";
- field public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
- field public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated";
- field public static final String EXTRA_SCAN_AVAILABLE = "android.net.wifi.extra.SCAN_AVAILABLE";
- field @Deprecated public static final String EXTRA_SUPPLICANT_CONNECTED = "connected";
- field @Deprecated public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";
- field @Deprecated public static final String EXTRA_WIFI_INFO = "wifiInfo";
- field public static final String EXTRA_WIFI_STATE = "wifi_state";
- field public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
- field public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
- field public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
- field public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
- field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3; // 0x3
- field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4; // 0x4
- field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID = 7; // 0x7
- field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6; // 0x6
- field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED = 2; // 0x2
- field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1; // 0x1
- field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; // 0x5
- field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
- field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1; // 0x1
- field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2; // 0x2
- field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3; // 0x3
- field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0; // 0x0
- field @Deprecated public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE";
- field @Deprecated public static final String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE";
- field public static final String UNKNOWN_SSID = "<unknown ssid>";
- field @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1
- field public static final int WIFI_MODE_FULL_HIGH_PERF = 3; // 0x3
- field public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; // 0x4
- field @Deprecated public static final int WIFI_MODE_SCAN_ONLY = 2; // 0x2
- field public static final String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED";
- field public static final int WIFI_STATE_DISABLED = 1; // 0x1
- field public static final int WIFI_STATE_DISABLING = 0; // 0x0
- field public static final int WIFI_STATE_ENABLED = 3; // 0x3
- field public static final int WIFI_STATE_ENABLING = 2; // 0x2
- field public static final int WIFI_STATE_UNKNOWN = 4; // 0x4
- field @Deprecated public static final int WPS_AUTH_FAILURE = 6; // 0x6
- field @Deprecated public static final int WPS_OVERLAP_ERROR = 3; // 0x3
- field @Deprecated public static final int WPS_TIMED_OUT = 7; // 0x7
- field @Deprecated public static final int WPS_TKIP_ONLY_PROHIBITED = 5; // 0x5
- field @Deprecated public static final int WPS_WEP_PROHIBITED = 4; // 0x4
- }
-
- public static class WifiManager.LocalOnlyHotspotCallback {
- ctor public WifiManager.LocalOnlyHotspotCallback();
- method public void onFailed(int);
- method public void onStarted(android.net.wifi.WifiManager.LocalOnlyHotspotReservation);
- method public void onStopped();
- field public static final int ERROR_GENERIC = 2; // 0x2
- field public static final int ERROR_INCOMPATIBLE_MODE = 3; // 0x3
- field public static final int ERROR_NO_CHANNEL = 1; // 0x1
- field public static final int ERROR_TETHERING_DISALLOWED = 4; // 0x4
- }
-
- public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
- method public void close();
- method @NonNull public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
- method @Deprecated @Nullable public android.net.wifi.WifiConfiguration getWifiConfiguration();
- }
-
- public class WifiManager.MulticastLock {
- method public void acquire();
- method public boolean isHeld();
- method public void release();
- method public void setReferenceCounted(boolean);
- }
-
- public abstract static class WifiManager.ScanResultsCallback {
- ctor public WifiManager.ScanResultsCallback();
- method public abstract void onScanResultsAvailable();
- }
-
- public static interface WifiManager.SuggestionConnectionStatusListener {
- method public void onConnectionStatus(@NonNull android.net.wifi.WifiNetworkSuggestion, int);
- }
-
- public class WifiManager.WifiLock {
- method public void acquire();
- method public boolean isHeld();
- method public void release();
- method public void setReferenceCounted(boolean);
- method public void setWorkSource(android.os.WorkSource);
- }
-
- @Deprecated public abstract static class WifiManager.WpsCallback {
- ctor @Deprecated public WifiManager.WpsCallback();
- method @Deprecated public abstract void onFailed(int);
- method @Deprecated public abstract void onStarted(String);
- method @Deprecated public abstract void onSucceeded();
- }
-
- public final class WifiNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSpecifier> CREATOR;
- }
-
- public static final class WifiNetworkSpecifier.Builder {
- ctor public WifiNetworkSpecifier.Builder();
- method @NonNull public android.net.wifi.WifiNetworkSpecifier build();
- method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssid(@NonNull android.net.MacAddress);
- method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssidPattern(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
- method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsEnhancedOpen(boolean);
- method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsHiddenSsid(boolean);
- method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setSsid(@NonNull String);
- method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setSsidPattern(@NonNull android.os.PatternMatcher);
- method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
- method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2Passphrase(@NonNull String);
- method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
- method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa3Passphrase(@NonNull String);
- }
-
- public final class WifiNetworkSuggestion implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public android.net.MacAddress getBssid();
- method @Nullable public android.net.wifi.WifiEnterpriseConfig getEnterpriseConfig();
- method @Nullable public String getPassphrase();
- method @Nullable public android.net.wifi.hotspot2.PasspointConfiguration getPasspointConfig();
- method @IntRange(from=0) public int getPriority();
- method @Nullable public String getSsid();
- method public boolean isAppInteractionRequired();
- method public boolean isCredentialSharedWithUser();
- method public boolean isEnhancedOpen();
- method public boolean isHiddenSsid();
- method public boolean isInitialAutojoinEnabled();
- method public boolean isMetered();
- method public boolean isUntrusted();
- method public boolean isUserInteractionRequired();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSuggestion> CREATOR;
- }
-
- public static final class WifiNetworkSuggestion.Builder {
- ctor public WifiNetworkSuggestion.Builder();
- method @NonNull public android.net.wifi.WifiNetworkSuggestion build();
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setBssid(@NonNull android.net.MacAddress);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setCredentialSharedWithUser(boolean);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsAppInteractionRequired(boolean);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsEnhancedOpen(boolean);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsHiddenSsid(boolean);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsInitialAutojoinEnabled(boolean);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsMetered(boolean);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsUserInteractionRequired(boolean);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPasspointConfig(@NonNull android.net.wifi.hotspot2.PasspointConfiguration);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriority(@IntRange(from=0) int);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setSsid(@NonNull String);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setUntrusted(boolean);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiEnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiPassphrase(@NonNull String);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2Passphrase(@NonNull String);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
- method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa3Passphrase(@NonNull String);
- }
-
- public class WpsInfo implements android.os.Parcelable {
- ctor public WpsInfo();
- ctor public WpsInfo(android.net.wifi.WpsInfo);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public String BSSID;
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WpsInfo> CREATOR;
- field public static final int DISPLAY = 1; // 0x1
- field public static final int INVALID = 4; // 0x4
- field public static final int KEYPAD = 2; // 0x2
- field public static final int LABEL = 3; // 0x3
- field public static final int PBC = 0; // 0x0
- field public String pin;
- field public int setup;
- }
-
-}
-
-package android.net.wifi.aware {
-
- public class AttachCallback {
- ctor public AttachCallback();
- method public void onAttachFailed();
- method public void onAttached(android.net.wifi.aware.WifiAwareSession);
- }
-
- public final class Characteristics implements android.os.Parcelable {
- method public int describeContents();
- method public int getMaxMatchFilterLength();
- method public int getMaxServiceNameLength();
- method public int getMaxServiceSpecificInfoLength();
- method public int getSupportedCipherSuites();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.Characteristics> CREATOR;
- field public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_128 = 1; // 0x1
- field public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_256 = 2; // 0x2
- }
-
- public class DiscoverySession implements java.lang.AutoCloseable {
- method public void close();
- method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierOpen(@NonNull android.net.wifi.aware.PeerHandle);
- method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(@NonNull android.net.wifi.aware.PeerHandle, @NonNull String);
- method public void sendMessage(@NonNull android.net.wifi.aware.PeerHandle, int, @Nullable byte[]);
- }
-
- public class DiscoverySessionCallback {
- ctor public DiscoverySessionCallback();
- method public void onMessageReceived(android.net.wifi.aware.PeerHandle, byte[]);
- method public void onMessageSendFailed(int);
- method public void onMessageSendSucceeded(int);
- method public void onPublishStarted(@NonNull android.net.wifi.aware.PublishDiscoverySession);
- method public void onServiceDiscovered(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>);
- method public void onServiceDiscoveredWithinRange(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>, int);
- method public void onSessionConfigFailed();
- method public void onSessionConfigUpdated();
- method public void onSessionTerminated();
- method public void onSubscribeStarted(@NonNull android.net.wifi.aware.SubscribeDiscoverySession);
- }
-
- public class IdentityChangedListener {
- ctor public IdentityChangedListener();
- method public void onIdentityChanged(byte[]);
- }
-
- public final class ParcelablePeerHandle extends android.net.wifi.aware.PeerHandle implements android.os.Parcelable {
- ctor public ParcelablePeerHandle(@NonNull android.net.wifi.aware.PeerHandle);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.ParcelablePeerHandle> CREATOR;
- }
-
- public class PeerHandle {
- }
-
- public final class PublishConfig implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.PublishConfig> CREATOR;
- field public static final int PUBLISH_TYPE_SOLICITED = 1; // 0x1
- field public static final int PUBLISH_TYPE_UNSOLICITED = 0; // 0x0
- }
-
- public static final class PublishConfig.Builder {
- ctor public PublishConfig.Builder();
- method public android.net.wifi.aware.PublishConfig build();
- method public android.net.wifi.aware.PublishConfig.Builder setMatchFilter(@Nullable java.util.List<byte[]>);
- method public android.net.wifi.aware.PublishConfig.Builder setPublishType(int);
- method public android.net.wifi.aware.PublishConfig.Builder setRangingEnabled(boolean);
- method public android.net.wifi.aware.PublishConfig.Builder setServiceName(@NonNull String);
- method public android.net.wifi.aware.PublishConfig.Builder setServiceSpecificInfo(@Nullable byte[]);
- method public android.net.wifi.aware.PublishConfig.Builder setTerminateNotificationEnabled(boolean);
- method public android.net.wifi.aware.PublishConfig.Builder setTtlSec(int);
- }
-
- public class PublishDiscoverySession extends android.net.wifi.aware.DiscoverySession {
- method public void updatePublish(@NonNull android.net.wifi.aware.PublishConfig);
- }
-
- public final class SubscribeConfig implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.SubscribeConfig> CREATOR;
- field public static final int SUBSCRIBE_TYPE_ACTIVE = 1; // 0x1
- field public static final int SUBSCRIBE_TYPE_PASSIVE = 0; // 0x0
- }
-
- public static final class SubscribeConfig.Builder {
- ctor public SubscribeConfig.Builder();
- method public android.net.wifi.aware.SubscribeConfig build();
- method public android.net.wifi.aware.SubscribeConfig.Builder setMatchFilter(@Nullable java.util.List<byte[]>);
- method public android.net.wifi.aware.SubscribeConfig.Builder setMaxDistanceMm(int);
- method public android.net.wifi.aware.SubscribeConfig.Builder setMinDistanceMm(int);
- method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(@NonNull String);
- method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(@Nullable byte[]);
- method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int);
- method public android.net.wifi.aware.SubscribeConfig.Builder setTerminateNotificationEnabled(boolean);
- method public android.net.wifi.aware.SubscribeConfig.Builder setTtlSec(int);
- }
-
- public class SubscribeDiscoverySession extends android.net.wifi.aware.DiscoverySession {
- method public void updateSubscribe(@NonNull android.net.wifi.aware.SubscribeConfig);
- }
-
- public class WifiAwareManager {
- method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @Nullable android.os.Handler);
- method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler);
- method public android.net.wifi.aware.Characteristics getCharacteristics();
- method public boolean isAvailable();
- field public static final String ACTION_WIFI_AWARE_STATE_CHANGED = "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED";
- field public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0; // 0x0
- field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
- }
-
- public final class WifiAwareNetworkInfo implements android.os.Parcelable android.net.TransportInfo {
- method public int describeContents();
- method @Nullable public java.net.Inet6Address getPeerIpv6Addr();
- method public int getPort();
- method public int getTransportProtocol();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkInfo> CREATOR;
- }
-
- public final class WifiAwareNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkSpecifier> CREATOR;
- }
-
- public static final class WifiAwareNetworkSpecifier.Builder {
- ctor public WifiAwareNetworkSpecifier.Builder(@NonNull android.net.wifi.aware.DiscoverySession, @NonNull android.net.wifi.aware.PeerHandle);
- method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier build();
- method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPmk(@NonNull byte[]);
- method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPort(@IntRange(from=0, to=65535) int);
- method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPskPassphrase(@NonNull String);
- method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setTransportProtocol(@IntRange(from=0, to=255) int);
- }
-
- public class WifiAwareSession implements java.lang.AutoCloseable {
- method public void close();
- method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, @NonNull byte[]);
- method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(int, @NonNull byte[], @NonNull String);
- method public void publish(@NonNull android.net.wifi.aware.PublishConfig, @NonNull android.net.wifi.aware.DiscoverySessionCallback, @Nullable android.os.Handler);
- method public void subscribe(@NonNull android.net.wifi.aware.SubscribeConfig, @NonNull android.net.wifi.aware.DiscoverySessionCallback, @Nullable android.os.Handler);
- }
-
-}
-
-package android.net.wifi.hotspot2 {
-
- public final class ConfigParser {
- method public static android.net.wifi.hotspot2.PasspointConfiguration parsePasspointConfig(String, byte[]);
- }
-
- public final class PasspointConfiguration implements android.os.Parcelable {
- ctor public PasspointConfiguration();
- ctor public PasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
- method public int describeContents();
- method public android.net.wifi.hotspot2.pps.Credential getCredential();
- method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
- method public long getSubscriptionExpirationTimeMillis();
- method @NonNull public String getUniqueId();
- method public boolean isOsuProvisioned();
- method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
- method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
- }
-
-}
-
-package android.net.wifi.hotspot2.omadm {
-
- public final class PpsMoParser {
- method public static android.net.wifi.hotspot2.PasspointConfiguration parseMoText(String);
- }
-
-}
-
-package android.net.wifi.hotspot2.pps {
-
- public final class Credential implements android.os.Parcelable {
- ctor public Credential();
- ctor public Credential(android.net.wifi.hotspot2.pps.Credential);
- method public int describeContents();
- method public java.security.cert.X509Certificate getCaCertificate();
- method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
- method public java.security.cert.X509Certificate[] getClientCertificateChain();
- method public java.security.PrivateKey getClientPrivateKey();
- method public String getRealm();
- method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
- method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
- method public void setCaCertificate(java.security.cert.X509Certificate);
- method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
- method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
- method public void setClientPrivateKey(java.security.PrivateKey);
- method public void setRealm(String);
- method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
- method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
- }
-
- public static final class Credential.CertificateCredential implements android.os.Parcelable {
- ctor public Credential.CertificateCredential();
- ctor public Credential.CertificateCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
- method public int describeContents();
- method public byte[] getCertSha256Fingerprint();
- method public String getCertType();
- method public void setCertSha256Fingerprint(byte[]);
- method public void setCertType(String);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
- }
-
- public static final class Credential.SimCredential implements android.os.Parcelable {
- ctor public Credential.SimCredential();
- ctor public Credential.SimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
- method public int describeContents();
- method public int getEapType();
- method public String getImsi();
- method public void setEapType(int);
- method public void setImsi(String);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
- }
-
- public static final class Credential.UserCredential implements android.os.Parcelable {
- ctor public Credential.UserCredential();
- ctor public Credential.UserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
- method public int describeContents();
- method public int getEapType();
- method public String getNonEapInnerMethod();
- method public String getPassword();
- method public String getUsername();
- method public void setEapType(int);
- method public void setNonEapInnerMethod(String);
- method public void setPassword(String);
- method public void setUsername(String);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
- }
-
- public final class HomeSp implements android.os.Parcelable {
- ctor public HomeSp();
- ctor public HomeSp(android.net.wifi.hotspot2.pps.HomeSp);
- method public int describeContents();
- method public String getFqdn();
- method public String getFriendlyName();
- method public long[] getRoamingConsortiumOis();
- method public void setFqdn(String);
- method public void setFriendlyName(String);
- method public void setRoamingConsortiumOis(long[]);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
- }
-
-}
-
-package android.net.wifi.p2p {
-
- public class WifiP2pConfig implements android.os.Parcelable {
- ctor public WifiP2pConfig();
- ctor public WifiP2pConfig(android.net.wifi.p2p.WifiP2pConfig);
- method public int describeContents();
- method public int getGroupOwnerBand();
- method public int getNetworkId();
- method @Nullable public String getNetworkName();
- method @Nullable public String getPassphrase();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pConfig> CREATOR;
- field public static final int GROUP_OWNER_BAND_2GHZ = 1; // 0x1
- field public static final int GROUP_OWNER_BAND_5GHZ = 2; // 0x2
- field public static final int GROUP_OWNER_BAND_AUTO = 0; // 0x0
- field public static final int GROUP_OWNER_INTENT_AUTO = -1; // 0xffffffff
- field public static final int GROUP_OWNER_INTENT_MAX = 15; // 0xf
- field public static final int GROUP_OWNER_INTENT_MIN = 0; // 0x0
- field public String deviceAddress;
- field @IntRange(from=0, to=15) public int groupOwnerIntent;
- field public android.net.wifi.WpsInfo wps;
- }
-
- public static final class WifiP2pConfig.Builder {
- ctor public WifiP2pConfig.Builder();
- method @NonNull public android.net.wifi.p2p.WifiP2pConfig build();
- method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder enablePersistentMode(boolean);
- method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setDeviceAddress(@Nullable android.net.MacAddress);
- method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupOperatingBand(int);
- method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupOperatingFrequency(int);
- method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setNetworkName(@NonNull String);
- method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setPassphrase(@NonNull String);
- }
-
- public class WifiP2pDevice implements android.os.Parcelable {
- ctor public WifiP2pDevice();
- ctor public WifiP2pDevice(android.net.wifi.p2p.WifiP2pDevice);
- method public int describeContents();
- method @Nullable public android.net.wifi.p2p.WifiP2pWfdInfo getWfdInfo();
- method public boolean isGroupOwner();
- method public boolean isServiceDiscoveryCapable();
- method public void update(@NonNull android.net.wifi.p2p.WifiP2pDevice);
- method public boolean wpsDisplaySupported();
- method public boolean wpsKeypadSupported();
- method public boolean wpsPbcSupported();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int AVAILABLE = 3; // 0x3
- field public static final int CONNECTED = 0; // 0x0
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pDevice> CREATOR;
- field public static final int FAILED = 2; // 0x2
- field public static final int INVITED = 1; // 0x1
- field public static final int UNAVAILABLE = 4; // 0x4
- field public String deviceAddress;
- field public String deviceName;
- field public String primaryDeviceType;
- field public String secondaryDeviceType;
- field public int status;
- }
-
- public class WifiP2pDeviceList implements android.os.Parcelable {
- ctor public WifiP2pDeviceList();
- ctor public WifiP2pDeviceList(android.net.wifi.p2p.WifiP2pDeviceList);
- method public int describeContents();
- method public android.net.wifi.p2p.WifiP2pDevice get(String);
- method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getDeviceList();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pDeviceList> CREATOR;
- }
-
- public class WifiP2pGroup implements android.os.Parcelable {
- ctor public WifiP2pGroup();
- ctor public WifiP2pGroup(android.net.wifi.p2p.WifiP2pGroup);
- method public int describeContents();
- method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getClientList();
- method public int getFrequency();
- method public String getInterface();
- method public int getNetworkId();
- method public String getNetworkName();
- method public android.net.wifi.p2p.WifiP2pDevice getOwner();
- method public String getPassphrase();
- method public boolean isGroupOwner();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroup> CREATOR;
- field public static final int NETWORK_ID_PERSISTENT = -2; // 0xfffffffe
- field public static final int NETWORK_ID_TEMPORARY = -1; // 0xffffffff
- }
-
- public class WifiP2pInfo implements android.os.Parcelable {
- ctor public WifiP2pInfo();
- ctor public WifiP2pInfo(android.net.wifi.p2p.WifiP2pInfo);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pInfo> CREATOR;
- field public boolean groupFormed;
- field public java.net.InetAddress groupOwnerAddress;
- field public boolean isGroupOwner;
- }
-
- public class WifiP2pManager {
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void addLocalService(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method public void addServiceRequest(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceRequest, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method public void cancelConnect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method public void clearLocalServices(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method public void clearServiceRequests(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void connect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void createGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void createGroup(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pConfig, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void discoverPeers(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void discoverServices(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method public android.net.wifi.p2p.WifiP2pManager.Channel initialize(android.content.Context, android.os.Looper, android.net.wifi.p2p.WifiP2pManager.ChannelListener);
- method public void removeGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method public void removeLocalService(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method public void removeServiceRequest(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceRequest, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method public void requestConnectionInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestDeviceInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.DeviceInfoListener);
- method public void requestDiscoveryState(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.DiscoveryStateListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestGroupInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.GroupInfoListener);
- method public void requestNetworkInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.NetworkInfoListener);
- method public void requestP2pState(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.P2pStateListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestPeers(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.PeerListListener);
- method public void setDnsSdResponseListeners(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.DnsSdServiceResponseListener, android.net.wifi.p2p.WifiP2pManager.DnsSdTxtRecordListener);
- method public void setServiceResponseListener(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ServiceResponseListener);
- method public void setUpnpServiceResponseListener(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.UpnpServiceResponseListener);
- method public void stopPeerDiscovery(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
- field public static final int BUSY = 2; // 0x2
- field public static final int ERROR = 0; // 0x0
- field public static final String EXTRA_DISCOVERY_STATE = "discoveryState";
- field public static final String EXTRA_NETWORK_INFO = "networkInfo";
- field public static final String EXTRA_P2P_DEVICE_LIST = "wifiP2pDeviceList";
- field public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice";
- field public static final String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo";
- field public static final String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo";
- field public static final String EXTRA_WIFI_STATE = "wifi_p2p_state";
- field public static final int NO_SERVICE_REQUESTS = 3; // 0x3
- field public static final int P2P_UNSUPPORTED = 1; // 0x1
- field public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION = "android.net.wifi.p2p.CONNECTION_STATE_CHANGE";
- field public static final String WIFI_P2P_DISCOVERY_CHANGED_ACTION = "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE";
- field public static final int WIFI_P2P_DISCOVERY_STARTED = 2; // 0x2
- field public static final int WIFI_P2P_DISCOVERY_STOPPED = 1; // 0x1
- field public static final String WIFI_P2P_PEERS_CHANGED_ACTION = "android.net.wifi.p2p.PEERS_CHANGED";
- field public static final String WIFI_P2P_STATE_CHANGED_ACTION = "android.net.wifi.p2p.STATE_CHANGED";
- field public static final int WIFI_P2P_STATE_DISABLED = 1; // 0x1
- field public static final int WIFI_P2P_STATE_ENABLED = 2; // 0x2
- field public static final String WIFI_P2P_THIS_DEVICE_CHANGED_ACTION = "android.net.wifi.p2p.THIS_DEVICE_CHANGED";
- }
-
- public static interface WifiP2pManager.ActionListener {
- method public void onFailure(int);
- method public void onSuccess();
- }
-
- public static class WifiP2pManager.Channel implements java.lang.AutoCloseable {
- method public void close();
- }
-
- public static interface WifiP2pManager.ChannelListener {
- method public void onChannelDisconnected();
- }
-
- public static interface WifiP2pManager.ConnectionInfoListener {
- method public void onConnectionInfoAvailable(android.net.wifi.p2p.WifiP2pInfo);
- }
-
- public static interface WifiP2pManager.DeviceInfoListener {
- method public void onDeviceInfoAvailable(@Nullable android.net.wifi.p2p.WifiP2pDevice);
- }
-
- public static interface WifiP2pManager.DiscoveryStateListener {
- method public void onDiscoveryStateAvailable(int);
- }
-
- public static interface WifiP2pManager.DnsSdServiceResponseListener {
- method public void onDnsSdServiceAvailable(String, String, android.net.wifi.p2p.WifiP2pDevice);
- }
-
- public static interface WifiP2pManager.DnsSdTxtRecordListener {
- method public void onDnsSdTxtRecordAvailable(String, java.util.Map<java.lang.String,java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
- }
-
- public static interface WifiP2pManager.GroupInfoListener {
- method public void onGroupInfoAvailable(android.net.wifi.p2p.WifiP2pGroup);
- }
-
- public static interface WifiP2pManager.NetworkInfoListener {
- method public void onNetworkInfoAvailable(@NonNull android.net.NetworkInfo);
- }
-
- public static interface WifiP2pManager.P2pStateListener {
- method public void onP2pStateAvailable(int);
- }
-
- public static interface WifiP2pManager.PeerListListener {
- method public void onPeersAvailable(android.net.wifi.p2p.WifiP2pDeviceList);
- }
-
- public static interface WifiP2pManager.ServiceResponseListener {
- method public void onServiceAvailable(int, byte[], android.net.wifi.p2p.WifiP2pDevice);
- }
-
- public static interface WifiP2pManager.UpnpServiceResponseListener {
- method public void onUpnpServiceAvailable(java.util.List<java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
- }
-
- public final class WifiP2pWfdInfo implements android.os.Parcelable {
- ctor public WifiP2pWfdInfo();
- ctor public WifiP2pWfdInfo(@Nullable android.net.wifi.p2p.WifiP2pWfdInfo);
- method public int describeContents();
- method public int getControlPort();
- method public int getDeviceType();
- method public int getMaxThroughput();
- method public boolean isContentProtectionSupported();
- method public boolean isEnabled();
- method public boolean isSessionAvailable();
- method public void setContentProtectionSupported(boolean);
- method public void setControlPort(@IntRange(from=0) int);
- method public boolean setDeviceType(int);
- method public void setEnabled(boolean);
- method public void setMaxThroughput(@IntRange(from=0) int);
- method public void setSessionAvailable(boolean);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pWfdInfo> CREATOR;
- field public static final int DEVICE_TYPE_PRIMARY_SINK = 1; // 0x1
- field public static final int DEVICE_TYPE_SECONDARY_SINK = 2; // 0x2
- field public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3; // 0x3
- field public static final int DEVICE_TYPE_WFD_SOURCE = 0; // 0x0
- }
-
-}
-
-package android.net.wifi.p2p.nsd {
-
- public class WifiP2pDnsSdServiceInfo extends android.net.wifi.p2p.nsd.WifiP2pServiceInfo {
- method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo newInstance(String, String, java.util.Map<java.lang.String,java.lang.String>);
- }
-
- public class WifiP2pDnsSdServiceRequest extends android.net.wifi.p2p.nsd.WifiP2pServiceRequest {
- method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance();
- method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance(String);
- method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance(String, String);
- }
-
- public class WifiP2pServiceInfo implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int SERVICE_TYPE_ALL = 0; // 0x0
- field public static final int SERVICE_TYPE_BONJOUR = 1; // 0x1
- field public static final int SERVICE_TYPE_UPNP = 2; // 0x2
- field public static final int SERVICE_TYPE_VENDOR_SPECIFIC = 255; // 0xff
- }
-
- public class WifiP2pServiceRequest implements android.os.Parcelable {
- method public int describeContents();
- method public static android.net.wifi.p2p.nsd.WifiP2pServiceRequest newInstance(int, String);
- method public static android.net.wifi.p2p.nsd.WifiP2pServiceRequest newInstance(int);
- method public void writeToParcel(android.os.Parcel, int);
- }
-
- public class WifiP2pUpnpServiceInfo extends android.net.wifi.p2p.nsd.WifiP2pServiceInfo {
- method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo newInstance(String, String, java.util.List<java.lang.String>);
- }
-
- public class WifiP2pUpnpServiceRequest extends android.net.wifi.p2p.nsd.WifiP2pServiceRequest {
- method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest newInstance();
- method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest newInstance(String);
- }
-
-}
-
-package android.net.wifi.rtt {
-
- public class CivicLocationKeys {
- field public static final int ADDITIONAL_CODE = 32; // 0x20
- field public static final int APT = 26; // 0x1a
- field public static final int BOROUGH = 4; // 0x4
- field public static final int BRANCH_ROAD_NAME = 36; // 0x24
- field public static final int BUILDING = 25; // 0x19
- field public static final int CITY = 3; // 0x3
- field public static final int COUNTY = 2; // 0x2
- field public static final int DESK = 33; // 0x21
- field public static final int FLOOR = 27; // 0x1b
- field public static final int GROUP_OF_STREETS = 6; // 0x6
- field public static final int HNO = 19; // 0x13
- field public static final int HNS = 20; // 0x14
- field public static final int LANGUAGE = 0; // 0x0
- field public static final int LMK = 21; // 0x15
- field public static final int LOC = 22; // 0x16
- field public static final int NAM = 23; // 0x17
- field public static final int NEIGHBORHOOD = 5; // 0x5
- field public static final int PCN = 30; // 0x1e
- field public static final int POD = 17; // 0x11
- field public static final int POSTAL_CODE = 24; // 0x18
- field public static final int PO_BOX = 31; // 0x1f
- field public static final int PRD = 16; // 0x10
- field public static final int PRIMARY_ROAD_NAME = 34; // 0x22
- field public static final int ROAD_SECTION = 35; // 0x23
- field public static final int ROOM = 28; // 0x1c
- field public static final int SCRIPT = 128; // 0x80
- field public static final int STATE = 1; // 0x1
- field public static final int STREET_NAME_POST_MODIFIER = 39; // 0x27
- field public static final int STREET_NAME_PRE_MODIFIER = 38; // 0x26
- field public static final int STS = 18; // 0x12
- field public static final int SUBBRANCH_ROAD_NAME = 37; // 0x25
- field public static final int TYPE_OF_PLACE = 29; // 0x1d
- }
-
- public final class RangingRequest implements android.os.Parcelable {
- method public int describeContents();
- method public static int getMaxPeers();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.RangingRequest> CREATOR;
- }
-
- public static final class RangingRequest.Builder {
- ctor public RangingRequest.Builder();
- method public android.net.wifi.rtt.RangingRequest.Builder addAccessPoint(@NonNull android.net.wifi.ScanResult);
- method public android.net.wifi.rtt.RangingRequest.Builder addAccessPoints(@NonNull java.util.List<android.net.wifi.ScanResult>);
- method public android.net.wifi.rtt.RangingRequest.Builder addWifiAwarePeer(@NonNull android.net.MacAddress);
- method public android.net.wifi.rtt.RangingRequest.Builder addWifiAwarePeer(@NonNull android.net.wifi.aware.PeerHandle);
- method public android.net.wifi.rtt.RangingRequest build();
- }
-
- public final class RangingResult implements android.os.Parcelable {
- method public int describeContents();
- method public int getDistanceMm();
- method public int getDistanceStdDevMm();
- method @Nullable public android.net.MacAddress getMacAddress();
- method public int getNumAttemptedMeasurements();
- method public int getNumSuccessfulMeasurements();
- method @Nullable public android.net.wifi.aware.PeerHandle getPeerHandle();
- method public long getRangingTimestampMillis();
- method public int getRssi();
- method public int getStatus();
- method @Nullable public android.net.wifi.rtt.ResponderLocation getUnverifiedResponderLocation();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.RangingResult> CREATOR;
- field public static final int STATUS_FAIL = 1; // 0x1
- field public static final int STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC = 2; // 0x2
- field public static final int STATUS_SUCCESS = 0; // 0x0
- }
-
- public abstract class RangingResultCallback {
- ctor public RangingResultCallback();
- method public abstract void onRangingFailure(int);
- method public abstract void onRangingResults(@NonNull java.util.List<android.net.wifi.rtt.RangingResult>);
- field public static final int STATUS_CODE_FAIL = 1; // 0x1
- field public static final int STATUS_CODE_FAIL_RTT_NOT_AVAILABLE = 2; // 0x2
- }
-
- public final class ResponderLocation implements android.os.Parcelable {
- method public int describeContents();
- method public double getAltitude();
- method public int getAltitudeType();
- method public double getAltitudeUncertainty();
- method public java.util.List<android.net.MacAddress> getColocatedBssids();
- method public int getDatum();
- method public int getExpectedToMove();
- method public double getFloorNumber();
- method public double getHeightAboveFloorMeters();
- method public double getHeightAboveFloorUncertaintyMeters();
- method public double getLatitude();
- method public double getLatitudeUncertainty();
- method public int getLciVersion();
- method public double getLongitude();
- method public double getLongitudeUncertainty();
- method @Nullable public String getMapImageMimeType();
- method @Nullable public android.net.Uri getMapImageUri();
- method public boolean getRegisteredLocationAgreementIndication();
- method public boolean isLciSubelementValid();
- method public boolean isZaxisSubelementValid();
- method @Nullable public android.location.Address toCivicLocationAddress();
- method @Nullable public android.util.SparseArray<java.lang.String> toCivicLocationSparseArray();
- method @NonNull public android.location.Location toLocation();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int ALTITUDE_FLOORS = 2; // 0x2
- field public static final int ALTITUDE_METERS = 1; // 0x1
- field public static final int ALTITUDE_UNDEFINED = 0; // 0x0
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderLocation> CREATOR;
- field public static final int DATUM_NAD83_MLLW = 3; // 0x3
- field public static final int DATUM_NAD83_NAV88 = 2; // 0x2
- field public static final int DATUM_UNDEFINED = 0; // 0x0
- field public static final int DATUM_WGS84 = 1; // 0x1
- field public static final int LCI_VERSION_1 = 1; // 0x1
- field public static final int LOCATION_FIXED = 0; // 0x0
- field public static final int LOCATION_MOVEMENT_UNKNOWN = 2; // 0x2
- field public static final int LOCATION_RESERVED = 3; // 0x3
- field public static final int LOCATION_VARIABLE = 1; // 0x1
- }
-
- public class WifiRttManager {
- method public boolean isAvailable();
- method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_WIFI_STATE}) public void startRanging(@NonNull android.net.wifi.rtt.RangingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.rtt.RangingResultCallback);
- field public static final String ACTION_WIFI_RTT_STATE_CHANGED = "android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED";
- }
-
-}
-
diff --git a/wifi/api/lint-baseline.txt b/wifi/api/lint-baseline.txt
deleted file mode 100644
index 892411f..0000000
--- a/wifi/api/lint-baseline.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-// Baseline format: 1.0
-GenericException: android.net.wifi.WifiManager.LocalOnlyHotspotReservation#finalize():
- Methods must not throw generic exceptions (`java.lang.Throwable`)
-GenericException: android.net.wifi.WifiManager.MulticastLock#finalize():
- Methods must not throw generic exceptions (`java.lang.Throwable`)
-GenericException: android.net.wifi.WifiManager.WifiLock#finalize():
- Methods must not throw generic exceptions (`java.lang.Throwable`)
-
-
-VisiblySynchronized: PsiThisExpression:WifiManager.this:
- Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.net.wifi.WifiManager.WifiLock.finalize()
-VisiblySynchronized: android.net.wifi.WifiManager.WifiLock#finalize():
- Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.net.wifi.WifiManager.WifiLock.finalize()
diff --git a/wifi/api/module-lib-current.txt b/wifi/api/module-lib-current.txt
deleted file mode 100644
index d802177..0000000
--- a/wifi/api/module-lib-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/wifi/api/module-lib-removed.txt b/wifi/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/wifi/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/wifi/api/removed.txt b/wifi/api/removed.txt
deleted file mode 100644
index d802177..0000000
--- a/wifi/api/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt
deleted file mode 100644
index 07793c1..0000000
--- a/wifi/api/system-current.txt
+++ /dev/null
@@ -1,939 +0,0 @@
-// Signature format: 2.0
-package android.net.wifi {
-
- public abstract class EasyConnectStatusCallback {
- ctor public EasyConnectStatusCallback();
- method public abstract void onConfiguratorSuccess(int);
- method public abstract void onEnrolleeSuccess(int);
- method public void onFailure(int);
- method public void onFailure(int, @Nullable String, @NonNull android.util.SparseArray<int[]>, @NonNull int[]);
- method public abstract void onProgress(int);
- field public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; // 0x0
- field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3; // 0x3
- field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2; // 0x2
- field public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; // 0x1
- field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1; // 0x1
- field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; // 0x0
- }
-
- @Deprecated public class RttManager {
- method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void disableResponder(android.net.wifi.RttManager.ResponderCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void enableResponder(android.net.wifi.RttManager.ResponderCallback);
- method @Deprecated public android.net.wifi.RttManager.Capabilities getCapabilities();
- method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.net.wifi.RttManager.RttCapabilities getRttCapabilities();
- method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startRanging(android.net.wifi.RttManager.RttParams[], android.net.wifi.RttManager.RttListener);
- method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopRanging(android.net.wifi.RttManager.RttListener);
- field @Deprecated public static final int BASE = 160256; // 0x27200
- field @Deprecated public static final int CMD_OP_ABORTED = 160260; // 0x27204
- field @Deprecated public static final int CMD_OP_DISABLE_RESPONDER = 160262; // 0x27206
- field @Deprecated public static final int CMD_OP_ENABLE_RESPONDER = 160261; // 0x27205
- field @Deprecated public static final int CMD_OP_ENALBE_RESPONDER_FAILED = 160264; // 0x27208
- field @Deprecated public static final int CMD_OP_ENALBE_RESPONDER_SUCCEEDED = 160263; // 0x27207
- field @Deprecated public static final int CMD_OP_FAILED = 160258; // 0x27202
- field @Deprecated public static final int CMD_OP_START_RANGING = 160256; // 0x27200
- field @Deprecated public static final int CMD_OP_STOP_RANGING = 160257; // 0x27201
- field @Deprecated public static final int CMD_OP_SUCCEEDED = 160259; // 0x27203
- field @Deprecated public static final String DESCRIPTION_KEY = "android.net.wifi.RttManager.Description";
- field @Deprecated public static final int PREAMBLE_HT = 2; // 0x2
- field @Deprecated public static final int PREAMBLE_LEGACY = 1; // 0x1
- field @Deprecated public static final int PREAMBLE_VHT = 4; // 0x4
- field @Deprecated public static final int REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON = -6; // 0xfffffffa
- field @Deprecated public static final int REASON_INVALID_LISTENER = -3; // 0xfffffffd
- field @Deprecated public static final int REASON_INVALID_REQUEST = -4; // 0xfffffffc
- field @Deprecated public static final int REASON_NOT_AVAILABLE = -2; // 0xfffffffe
- field @Deprecated public static final int REASON_PERMISSION_DENIED = -5; // 0xfffffffb
- field @Deprecated public static final int REASON_UNSPECIFIED = -1; // 0xffffffff
- field @Deprecated public static final int RTT_BW_10_SUPPORT = 2; // 0x2
- field @Deprecated public static final int RTT_BW_160_SUPPORT = 32; // 0x20
- field @Deprecated public static final int RTT_BW_20_SUPPORT = 4; // 0x4
- field @Deprecated public static final int RTT_BW_40_SUPPORT = 8; // 0x8
- field @Deprecated public static final int RTT_BW_5_SUPPORT = 1; // 0x1
- field @Deprecated public static final int RTT_BW_80_SUPPORT = 16; // 0x10
- field @Deprecated public static final int RTT_CHANNEL_WIDTH_10 = 6; // 0x6
- field @Deprecated public static final int RTT_CHANNEL_WIDTH_160 = 3; // 0x3
- field @Deprecated public static final int RTT_CHANNEL_WIDTH_20 = 0; // 0x0
- field @Deprecated public static final int RTT_CHANNEL_WIDTH_40 = 1; // 0x1
- field @Deprecated public static final int RTT_CHANNEL_WIDTH_5 = 5; // 0x5
- field @Deprecated public static final int RTT_CHANNEL_WIDTH_80 = 2; // 0x2
- field @Deprecated public static final int RTT_CHANNEL_WIDTH_80P80 = 4; // 0x4
- field @Deprecated public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1; // 0xffffffff
- field @Deprecated public static final int RTT_PEER_NAN = 5; // 0x5
- field @Deprecated public static final int RTT_PEER_P2P_CLIENT = 4; // 0x4
- field @Deprecated public static final int RTT_PEER_P2P_GO = 3; // 0x3
- field @Deprecated public static final int RTT_PEER_TYPE_AP = 1; // 0x1
- field @Deprecated public static final int RTT_PEER_TYPE_STA = 2; // 0x2
- field @Deprecated public static final int RTT_PEER_TYPE_UNSPECIFIED = 0; // 0x0
- field @Deprecated public static final int RTT_STATUS_ABORTED = 8; // 0x8
- field @Deprecated public static final int RTT_STATUS_FAILURE = 1; // 0x1
- field @Deprecated public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6; // 0x6
- field @Deprecated public static final int RTT_STATUS_FAIL_BUSY_TRY_LATER = 12; // 0xc
- field @Deprecated public static final int RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15; // 0xf
- field @Deprecated public static final int RTT_STATUS_FAIL_INVALID_TS = 9; // 0x9
- field @Deprecated public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4; // 0x4
- field @Deprecated public static final int RTT_STATUS_FAIL_NO_CAPABILITY = 7; // 0x7
- field @Deprecated public static final int RTT_STATUS_FAIL_NO_RSP = 2; // 0x2
- field @Deprecated public static final int RTT_STATUS_FAIL_PROTOCOL = 10; // 0xa
- field @Deprecated public static final int RTT_STATUS_FAIL_REJECTED = 3; // 0x3
- field @Deprecated public static final int RTT_STATUS_FAIL_SCHEDULE = 11; // 0xb
- field @Deprecated public static final int RTT_STATUS_FAIL_TM_TIMEOUT = 5; // 0x5
- field @Deprecated public static final int RTT_STATUS_INVALID_REQ = 13; // 0xd
- field @Deprecated public static final int RTT_STATUS_NO_WIFI = 14; // 0xe
- field @Deprecated public static final int RTT_STATUS_SUCCESS = 0; // 0x0
- field @Deprecated public static final int RTT_TYPE_11_MC = 4; // 0x4
- field @Deprecated public static final int RTT_TYPE_11_V = 2; // 0x2
- field @Deprecated public static final int RTT_TYPE_ONE_SIDED = 1; // 0x1
- field @Deprecated public static final int RTT_TYPE_TWO_SIDED = 2; // 0x2
- field @Deprecated public static final int RTT_TYPE_UNSPECIFIED = 0; // 0x0
- }
-
- @Deprecated public class RttManager.Capabilities {
- ctor @Deprecated public RttManager.Capabilities();
- field @Deprecated public int supportedPeerType;
- field @Deprecated public int supportedType;
- }
-
- @Deprecated public static class RttManager.ParcelableRttParams implements android.os.Parcelable {
- field @Deprecated @NonNull public android.net.wifi.RttManager.RttParams[] mParams;
- }
-
- @Deprecated public static class RttManager.ParcelableRttResults implements android.os.Parcelable {
- ctor @Deprecated public RttManager.ParcelableRttResults(android.net.wifi.RttManager.RttResult[]);
- field @Deprecated public android.net.wifi.RttManager.RttResult[] mResults;
- }
-
- @Deprecated public abstract static class RttManager.ResponderCallback {
- ctor @Deprecated public RttManager.ResponderCallback();
- method @Deprecated public abstract void onResponderEnableFailure(int);
- method @Deprecated public abstract void onResponderEnabled(android.net.wifi.RttManager.ResponderConfig);
- }
-
- @Deprecated public static class RttManager.ResponderConfig implements android.os.Parcelable {
- ctor @Deprecated public RttManager.ResponderConfig();
- method @Deprecated public int describeContents();
- method @Deprecated public void writeToParcel(android.os.Parcel, int);
- field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.RttManager.ResponderConfig> CREATOR;
- field @Deprecated public int centerFreq0;
- field @Deprecated public int centerFreq1;
- field @Deprecated public int channelWidth;
- field @Deprecated public int frequency;
- field @Deprecated public String macAddress;
- field @Deprecated public int preamble;
- }
-
- @Deprecated public static class RttManager.RttCapabilities implements android.os.Parcelable {
- ctor @Deprecated public RttManager.RttCapabilities();
- field @Deprecated public int bwSupported;
- field @Deprecated public boolean lciSupported;
- field @Deprecated public boolean lcrSupported;
- field @Deprecated public int mcVersion;
- field @Deprecated public boolean oneSidedRttSupported;
- field @Deprecated public int preambleSupported;
- field @Deprecated public boolean responderSupported;
- field @Deprecated public boolean secureRttSupported;
- field @Deprecated public boolean supportedPeerType;
- field @Deprecated public boolean supportedType;
- field @Deprecated public boolean twoSided11McRttSupported;
- }
-
- @Deprecated public static interface RttManager.RttListener {
- method @Deprecated public void onAborted();
- method @Deprecated public void onFailure(int, String);
- method @Deprecated public void onSuccess(android.net.wifi.RttManager.RttResult[]);
- }
-
- @Deprecated public static class RttManager.RttParams {
- ctor @Deprecated public RttManager.RttParams();
- field @Deprecated public boolean LCIRequest;
- field @Deprecated public boolean LCRRequest;
- field @Deprecated public int bandwidth;
- field @Deprecated public String bssid;
- field @Deprecated public int burstTimeout;
- field @Deprecated public int centerFreq0;
- field @Deprecated public int centerFreq1;
- field @Deprecated public int channelWidth;
- field @Deprecated public int deviceType;
- field @Deprecated public int frequency;
- field @Deprecated public int interval;
- field @Deprecated public int numRetriesPerFTMR;
- field @Deprecated public int numRetriesPerMeasurementFrame;
- field @Deprecated public int numSamplesPerBurst;
- field @Deprecated public int num_retries;
- field @Deprecated public int num_samples;
- field @Deprecated public int numberBurst;
- field @Deprecated public int preamble;
- field @Deprecated public int requestType;
- field @Deprecated public boolean secure;
- }
-
- @Deprecated public static class RttManager.RttResult {
- ctor @Deprecated public RttManager.RttResult();
- field @Deprecated public android.net.wifi.RttManager.WifiInformationElement LCI;
- field @Deprecated public android.net.wifi.RttManager.WifiInformationElement LCR;
- field @Deprecated public String bssid;
- field @Deprecated public int burstDuration;
- field @Deprecated public int burstNumber;
- field @Deprecated public int distance;
- field @Deprecated public int distanceSpread;
- field @Deprecated public int distanceStandardDeviation;
- field @Deprecated public int distance_cm;
- field @Deprecated public int distance_sd_cm;
- field @Deprecated public int distance_spread_cm;
- field @Deprecated public int frameNumberPerBurstPeer;
- field @Deprecated public int measurementFrameNumber;
- field @Deprecated public int measurementType;
- field @Deprecated public int negotiatedBurstNum;
- field @Deprecated public int requestType;
- field @Deprecated public int retryAfterDuration;
- field @Deprecated public int rssi;
- field @Deprecated public int rssiSpread;
- field @Deprecated public int rssi_spread;
- field @Deprecated public long rtt;
- field @Deprecated public long rttSpread;
- field @Deprecated public long rttStandardDeviation;
- field @Deprecated public long rtt_ns;
- field @Deprecated public long rtt_sd_ns;
- field @Deprecated public long rtt_spread_ns;
- field @Deprecated public int rxRate;
- field @Deprecated public boolean secure;
- field @Deprecated public int status;
- field @Deprecated public int successMeasurementFrameNumber;
- field @Deprecated public long ts;
- field @Deprecated public int txRate;
- field @Deprecated public int tx_rate;
- }
-
- @Deprecated public static class RttManager.WifiInformationElement {
- ctor @Deprecated public RttManager.WifiInformationElement();
- field @Deprecated public byte[] data;
- field @Deprecated public byte id;
- }
-
- public final class ScanResult implements android.os.Parcelable {
- field public static final int CIPHER_CCMP = 3; // 0x3
- field public static final int CIPHER_GCMP_256 = 4; // 0x4
- field public static final int CIPHER_NONE = 0; // 0x0
- field public static final int CIPHER_NO_GROUP_ADDRESSED = 1; // 0x1
- field public static final int CIPHER_SMS4 = 5; // 0x5
- field public static final int CIPHER_TKIP = 2; // 0x2
- field public static final int KEY_MGMT_EAP = 2; // 0x2
- field public static final int KEY_MGMT_EAP_SHA256 = 6; // 0x6
- field public static final int KEY_MGMT_EAP_SUITE_B_192 = 10; // 0xa
- field public static final int KEY_MGMT_FT_EAP = 4; // 0x4
- field public static final int KEY_MGMT_FT_PSK = 3; // 0x3
- field public static final int KEY_MGMT_FT_SAE = 11; // 0xb
- field public static final int KEY_MGMT_NONE = 0; // 0x0
- field public static final int KEY_MGMT_OSEN = 7; // 0x7
- field public static final int KEY_MGMT_OWE = 9; // 0x9
- field public static final int KEY_MGMT_OWE_TRANSITION = 12; // 0xc
- field public static final int KEY_MGMT_PSK = 1; // 0x1
- field public static final int KEY_MGMT_PSK_SHA256 = 5; // 0x5
- field public static final int KEY_MGMT_SAE = 8; // 0x8
- field public static final int KEY_MGMT_WAPI_CERT = 14; // 0xe
- field public static final int KEY_MGMT_WAPI_PSK = 13; // 0xd
- field public static final int PROTOCOL_NONE = 0; // 0x0
- field public static final int PROTOCOL_OSEN = 3; // 0x3
- field public static final int PROTOCOL_RSN = 2; // 0x2
- field public static final int PROTOCOL_WAPI = 4; // 0x4
- field public static final int PROTOCOL_WPA = 1; // 0x1
- }
-
- public final class SoftApCapability implements android.os.Parcelable {
- method public boolean areFeaturesSupported(long);
- method public int describeContents();
- method public int getMaxSupportedClients();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApCapability> CREATOR;
- field public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1L; // 0x1L
- field public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 2L; // 0x2L
- field public static final long SOFTAP_FEATURE_WPA3_SAE = 4L; // 0x4L
- }
-
- public final class SoftApConfiguration implements android.os.Parcelable {
- method @NonNull public java.util.List<android.net.MacAddress> getAllowedClientList();
- method public int getBand();
- method @NonNull public java.util.List<android.net.MacAddress> getBlockedClientList();
- method public int getChannel();
- method public int getMaxNumberOfClients();
- method public long getShutdownTimeoutMillis();
- method public boolean isAutoShutdownEnabled();
- method public boolean isClientControlByUserEnabled();
- method @Nullable public android.net.wifi.WifiConfiguration toWifiConfiguration();
- field public static final int BAND_2GHZ = 1; // 0x1
- field public static final int BAND_5GHZ = 2; // 0x2
- field public static final int BAND_6GHZ = 4; // 0x4
- field public static final int BAND_ANY = 7; // 0x7
- }
-
- public static final class SoftApConfiguration.Builder {
- ctor public SoftApConfiguration.Builder();
- ctor public SoftApConfiguration.Builder(@NonNull android.net.wifi.SoftApConfiguration);
- method @NonNull public android.net.wifi.SoftApConfiguration build();
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAllowedClientList(@NonNull java.util.List<android.net.MacAddress>);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAutoShutdownEnabled(boolean);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBand(int);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBlockedClientList(@NonNull java.util.List<android.net.MacAddress>);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBssid(@Nullable android.net.MacAddress);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setChannel(int, int);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setClientControlByUserEnabled(boolean);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setHiddenSsid(boolean);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setMaxNumberOfClients(@IntRange(from=0) int);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setPassphrase(@Nullable String, int);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setShutdownTimeoutMillis(@IntRange(from=0) long);
- method @NonNull public android.net.wifi.SoftApConfiguration.Builder setSsid(@Nullable String);
- }
-
- public final class SoftApInfo implements android.os.Parcelable {
- method public int describeContents();
- method public int getBandwidth();
- method public int getFrequency();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field public static final int CHANNEL_WIDTH_160MHZ = 6; // 0x6
- field public static final int CHANNEL_WIDTH_20MHZ = 2; // 0x2
- field public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1; // 0x1
- field public static final int CHANNEL_WIDTH_40MHZ = 3; // 0x3
- field public static final int CHANNEL_WIDTH_80MHZ = 4; // 0x4
- field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5; // 0x5
- field public static final int CHANNEL_WIDTH_INVALID = 0; // 0x0
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApInfo> CREATOR;
- }
-
- public final class WifiClient implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.net.MacAddress getMacAddress();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiClient> CREATOR;
- }
-
- @Deprecated public class WifiConfiguration implements android.os.Parcelable {
- method @Deprecated public int getAuthType();
- method @Deprecated @NonNull public android.net.IpConfiguration getIpConfiguration();
- method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus getNetworkSelectionStatus();
- method @Deprecated @NonNull public String getPrintableSsid();
- method @Deprecated public int getRecentFailureReason();
- method @Deprecated public boolean hasNoInternetAccess();
- method @Deprecated public boolean isEphemeral();
- method @Deprecated public static boolean isMetered(@Nullable android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiInfo);
- method @Deprecated public boolean isNoInternetAccessExpected();
- method @Deprecated public void setIpConfiguration(@Nullable android.net.IpConfiguration);
- method @Deprecated public void setNetworkSelectionStatus(@NonNull android.net.wifi.WifiConfiguration.NetworkSelectionStatus);
- field @Deprecated public static final int INVALID_NETWORK_ID = -1; // 0xffffffff
- field @Deprecated public static final int METERED_OVERRIDE_METERED = 1; // 0x1
- field @Deprecated public static final int METERED_OVERRIDE_NONE = 0; // 0x0
- field @Deprecated public static final int METERED_OVERRIDE_NOT_METERED = 2; // 0x2
- field @Deprecated public static final int RANDOMIZATION_NONE = 0; // 0x0
- field @Deprecated public static final int RANDOMIZATION_PERSISTENT = 1; // 0x1
- field @Deprecated public static final int RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA = 17; // 0x11
- field @Deprecated public static final int RECENT_FAILURE_NONE = 0; // 0x0
- field @Deprecated public boolean allowAutojoin;
- field @Deprecated public int carrierId;
- field @Deprecated public String creatorName;
- field @Deprecated public int creatorUid;
- field @Deprecated public boolean fromWifiNetworkSpecifier;
- field @Deprecated public boolean fromWifiNetworkSuggestion;
- field @Deprecated public String lastUpdateName;
- field @Deprecated public int lastUpdateUid;
- field @Deprecated public int macRandomizationSetting;
- field @Deprecated public boolean meteredHint;
- field @Deprecated public int meteredOverride;
- field @Deprecated public int numAssociation;
- field @Deprecated public int numScorerOverride;
- field @Deprecated public int numScorerOverrideAndSwitchedNetwork;
- field @Deprecated public boolean requirePmf;
- field @Deprecated public boolean shared;
- field @Deprecated public boolean useExternalScores;
- }
-
- @Deprecated public static class WifiConfiguration.KeyMgmt {
- field @Deprecated public static final int WAPI_CERT = 14; // 0xe
- field @Deprecated public static final int WAPI_PSK = 13; // 0xd
- field @Deprecated public static final int WPA2_PSK = 4; // 0x4
- }
-
- @Deprecated public static class WifiConfiguration.NetworkSelectionStatus {
- method @Deprecated public int getDisableReasonCounter(int);
- method @Deprecated public long getDisableTime();
- method @Deprecated public static int getMaxNetworkSelectionDisableReason();
- method @Deprecated public int getNetworkSelectionDisableReason();
- method @Deprecated @Nullable public static String getNetworkSelectionDisableReasonString(int);
- method @Deprecated public int getNetworkSelectionStatus();
- method @Deprecated @NonNull public String getNetworkStatusString();
- method @Deprecated public boolean hasEverConnected();
- field @Deprecated public static final int DISABLED_ASSOCIATION_REJECTION = 1; // 0x1
- field @Deprecated public static final int DISABLED_AUTHENTICATION_FAILURE = 2; // 0x2
- field @Deprecated public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 5; // 0x5
- field @Deprecated public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 9; // 0x9
- field @Deprecated public static final int DISABLED_BY_WIFI_MANAGER = 7; // 0x7
- field @Deprecated public static final int DISABLED_BY_WRONG_PASSWORD = 8; // 0x8
- field @Deprecated public static final int DISABLED_DHCP_FAILURE = 3; // 0x3
- field @Deprecated public static final int DISABLED_NONE = 0; // 0x0
- field @Deprecated public static final int DISABLED_NO_INTERNET_PERMANENT = 6; // 0x6
- field @Deprecated public static final int DISABLED_NO_INTERNET_TEMPORARY = 4; // 0x4
- field @Deprecated public static final int NETWORK_SELECTION_ENABLED = 0; // 0x0
- field @Deprecated public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2; // 0x2
- field @Deprecated public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1; // 0x1
- }
-
- @Deprecated public static final class WifiConfiguration.NetworkSelectionStatus.Builder {
- ctor @Deprecated public WifiConfiguration.NetworkSelectionStatus.Builder();
- method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus build();
- method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus.Builder setNetworkSelectionDisableReason(int);
- method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus.Builder setNetworkSelectionStatus(int);
- }
-
- public class WifiEnterpriseConfig implements android.os.Parcelable {
- method @Nullable public String[] getCaCertificateAliases();
- method @NonNull public String getCaPath();
- method @NonNull public String getClientCertificateAlias();
- method public int getOcsp();
- method @NonNull public String getWapiCertSuite();
- method public void setCaCertificateAliases(@Nullable String[]);
- method public void setCaPath(@NonNull String);
- method public void setClientCertificateAlias(@NonNull String);
- method public void setOcsp(int);
- method public void setWapiCertSuite(@NonNull String);
- field public static final int OCSP_NONE = 0; // 0x0
- field public static final int OCSP_REQUEST_CERT_STATUS = 1; // 0x1
- field public static final int OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS = 3; // 0x3
- field public static final int OCSP_REQUIRE_CERT_STATUS = 2; // 0x2
- }
-
- public class WifiFrameworkInitializer {
- method public static void registerServiceWrappers();
- }
-
- public class WifiInfo implements android.os.Parcelable {
- method public double getLostTxPacketsPerSecond();
- method @Nullable public String getRequestingPackageName();
- method public double getRetriedTxPacketsPerSecond();
- method public int getScore();
- method public double getSuccessfulRxPacketsPerSecond();
- method public double getSuccessfulTxPacketsPerSecond();
- method public boolean isEphemeral();
- method public boolean isOsuAp();
- method public boolean isPasspointAp();
- method @Nullable public static String sanitizeSsid(@Nullable String);
- field public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
- field public static final int INVALID_RSSI = -127; // 0xffffff81
- }
-
- public class WifiManager {
- method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinGlobal(boolean);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinPasspoint(@NonNull String, boolean);
- method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void clearWifiConnectedNetworkScorer();
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK}) public void disableEphemeralNetwork(@NonNull String);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset();
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener);
- method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>);
- method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCountryCode();
- method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public android.net.Network getCurrentNetwork();
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses();
- method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>);
- method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,android.net.wifi.hotspot2.PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set<android.net.wifi.hotspot2.OsuProvider>);
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.Map<android.net.wifi.WifiNetworkSuggestion,java.util.List<android.net.wifi.ScanResult>> getMatchingScanResults(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>, @Nullable java.util.List<android.net.wifi.ScanResult>);
- method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
- method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void getWifiActivityEnergyInfoAsync(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener);
- method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
- method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
- method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(@NonNull java.util.List<android.net.wifi.ScanResult>);
- method public boolean isApMacRandomizationSupported();
- method public boolean isConnectedMacRandomizationSupported();
- method @Deprecated public boolean isDeviceToDeviceRttSupported();
- method public boolean isPortableHotspotSupported();
- method public boolean isVerboseLoggingEnabled();
- method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
- method public boolean isWifiScannerSupported();
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerNetworkRequestMatchCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerTrafficStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.TrafficStateCallback);
- method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void removeOnWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreBackupData(@NonNull byte[]);
- method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public android.net.wifi.SoftApConfiguration restoreSoftApBackupData(@NonNull byte[]);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreSupplicantBackupData(@NonNull byte[], @NonNull byte[]);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveBackupData();
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveSoftApBackupData();
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setAutoWakeupEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(int);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setMacRandomizationSettingPasspointEnabled(@NonNull String, boolean);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setPasspointMeteredOverride(@NonNull String, int);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanAlwaysAvailable(boolean);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanThrottleEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean setSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setVerboseLoggingEnabled(boolean);
- method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
- method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public boolean setWifiConnectedNetworkScorer(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiConnectedNetworkScorer);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback);
- method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public boolean startScan(android.os.WorkSource);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(@NonNull android.net.wifi.hotspot2.OsuProvider, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.hotspot2.ProvisioningCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startTetheredHotspot(@Nullable android.net.wifi.SoftApConfiguration);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession();
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean stopSoftAp();
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterNetworkRequestMatchCallback(@NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterSoftApCallback(@NonNull android.net.wifi.WifiManager.SoftApCallback);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterTrafficStateCallback(@NonNull android.net.wifi.WifiManager.TrafficStateCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateInterfaceIpState(@Nullable String, int);
- method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void updateWifiUsabilityScore(int, int, int);
- field public static final String ACTION_LINK_CONFIGURATION_CHANGED = "android.net.wifi.LINK_CONFIGURATION_CHANGED";
- field @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public static final String ACTION_NETWORK_SETTINGS_RESET = "android.net.wifi.action.NETWORK_SETTINGS_RESET";
- field public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW = "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW";
- field public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE";
- field public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE";
- field public static final int CHANGE_REASON_ADDED = 0; // 0x0
- field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
- field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
- field public static final String CONFIGURED_NETWORKS_CHANGED_ACTION = "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
- field public static final int DEVICE_MOBILITY_STATE_HIGH_MVMT = 1; // 0x1
- field public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2; // 0x2
- field public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3; // 0x3
- field public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0; // 0x0
- field public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1; // 0x1
- field public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0; // 0x0
- field public static final String EXTRA_CHANGE_REASON = "changeReason";
- field public static final String EXTRA_LINK_PROPERTIES = "android.net.wifi.extra.LINK_PROPERTIES";
- field public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
- field public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK";
- field public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
- field public static final String EXTRA_URL = "android.net.wifi.extra.URL";
- field public static final String EXTRA_WIFI_AP_FAILURE_REASON = "android.net.wifi.extra.WIFI_AP_FAILURE_REASON";
- field public static final String EXTRA_WIFI_AP_INTERFACE_NAME = "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME";
- field public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE";
- field public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
- field public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
- field public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
- field public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid";
- field public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0; // 0x0
- field public static final int IFACE_IP_MODE_LOCAL_ONLY = 2; // 0x2
- field public static final int IFACE_IP_MODE_TETHERED = 1; // 0x1
- field public static final int IFACE_IP_MODE_UNSPECIFIED = -1; // 0xffffffff
- field public static final int PASSPOINT_HOME_NETWORK = 0; // 0x0
- field public static final int PASSPOINT_ROAMING_NETWORK = 1; // 0x1
- field public static final int SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER = 0; // 0x0
- field public static final int SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS = 1; // 0x1
- field public static final int SAP_START_FAILURE_GENERAL = 0; // 0x0
- field public static final int SAP_START_FAILURE_NO_CHANNEL = 1; // 0x1
- field public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2; // 0x2
- field public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED";
- field public static final int WIFI_AP_STATE_DISABLED = 11; // 0xb
- field public static final int WIFI_AP_STATE_DISABLING = 10; // 0xa
- field public static final int WIFI_AP_STATE_ENABLED = 13; // 0xd
- field public static final int WIFI_AP_STATE_ENABLING = 12; // 0xc
- field public static final int WIFI_AP_STATE_FAILED = 14; // 0xe
- field public static final String WIFI_CREDENTIAL_CHANGED_ACTION = "android.net.wifi.WIFI_CREDENTIAL_CHANGED";
- field public static final int WIFI_CREDENTIAL_FORGOT = 1; // 0x1
- field public static final int WIFI_CREDENTIAL_SAVED = 0; // 0x0
- }
-
- public static interface WifiManager.ActionListener {
- method public void onFailure(int);
- method public void onSuccess();
- }
-
- public static interface WifiManager.NetworkRequestMatchCallback {
- method public default void onAbort();
- method public default void onMatch(@NonNull java.util.List<android.net.wifi.ScanResult>);
- method public default void onUserSelectionCallbackRegistration(@NonNull android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback);
- method public default void onUserSelectionConnectFailure(@NonNull android.net.wifi.WifiConfiguration);
- method public default void onUserSelectionConnectSuccess(@NonNull android.net.wifi.WifiConfiguration);
- }
-
- public static interface WifiManager.NetworkRequestUserSelectionCallback {
- method public default void reject();
- method public default void select(@NonNull android.net.wifi.WifiConfiguration);
- }
-
- public static interface WifiManager.OnWifiActivityEnergyInfoListener {
- method public void onWifiActivityEnergyInfo(@Nullable android.os.connectivity.WifiActivityEnergyInfo);
- }
-
- public static interface WifiManager.OnWifiUsabilityStatsListener {
- method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry);
- }
-
- public static interface WifiManager.ScoreUpdateObserver {
- method public void notifyScoreUpdate(int, int);
- method public void triggerUpdateOfWifiUsabilityStats(int);
- }
-
- public static interface WifiManager.SoftApCallback {
- method public default void onBlockedClientConnecting(@NonNull android.net.wifi.WifiClient, int);
- method public default void onCapabilityChanged(@NonNull android.net.wifi.SoftApCapability);
- method public default void onConnectedClientsChanged(@NonNull java.util.List<android.net.wifi.WifiClient>);
- method public default void onInfoChanged(@NonNull android.net.wifi.SoftApInfo);
- method public default void onStateChanged(int, int);
- }
-
- public static interface WifiManager.TrafficStateCallback {
- method public void onStateChanged(int);
- field public static final int DATA_ACTIVITY_IN = 1; // 0x1
- field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3
- field public static final int DATA_ACTIVITY_NONE = 0; // 0x0
- field public static final int DATA_ACTIVITY_OUT = 2; // 0x2
- }
-
- public static interface WifiManager.WifiConnectedNetworkScorer {
- method public void onSetScoreUpdateObserver(@NonNull android.net.wifi.WifiManager.ScoreUpdateObserver);
- method public void onStart(int);
- method public void onStop(int);
- }
-
- public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
- ctor public WifiNetworkConnectionStatistics(int, int);
- ctor public WifiNetworkConnectionStatistics();
- ctor public WifiNetworkConnectionStatistics(android.net.wifi.WifiNetworkConnectionStatistics);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkConnectionStatistics> CREATOR;
- field public int numConnection;
- field public int numUsage;
- }
-
- public final class WifiNetworkSuggestion implements android.os.Parcelable {
- method @NonNull public android.net.wifi.WifiConfiguration getWifiConfiguration();
- }
-
- public static final class WifiNetworkSuggestion.Builder {
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public android.net.wifi.WifiNetworkSuggestion.Builder setCarrierId(int);
- }
-
- public class WifiScanner {
- method @Deprecated public void configureWifiChange(int, int, int, int, int, android.net.wifi.WifiScanner.BssidInfo[]);
- method @Deprecated public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings);
- method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<java.lang.Integer> getAvailableChannels(int);
- method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults();
- method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<android.net.wifi.ScanResult> getSingleScanResults();
- method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void registerScanListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiScanner.ScanListener);
- method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setScanningEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
- method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
- method @Deprecated public void startTrackingBssids(android.net.wifi.WifiScanner.BssidInfo[], int, android.net.wifi.WifiScanner.BssidListener);
- method @Deprecated public void startTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
- method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopBackgroundScan(android.net.wifi.WifiScanner.ScanListener);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopScan(android.net.wifi.WifiScanner.ScanListener);
- method @Deprecated public void stopTrackingBssids(android.net.wifi.WifiScanner.BssidListener);
- method @Deprecated public void stopTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
- method public void unregisterScanListener(@NonNull android.net.wifi.WifiScanner.ScanListener);
- field public static final int MAX_SCAN_PERIOD_MS = 1024000; // 0xfa000
- field public static final int MIN_SCAN_PERIOD_MS = 1000; // 0x3e8
- field public static final int REASON_DUPLICATE_REQEUST = -5; // 0xfffffffb
- field public static final int REASON_INVALID_LISTENER = -2; // 0xfffffffe
- field public static final int REASON_INVALID_REQUEST = -3; // 0xfffffffd
- field public static final int REASON_NOT_AUTHORIZED = -4; // 0xfffffffc
- field public static final int REASON_SUCCEEDED = 0; // 0x0
- field public static final int REASON_UNSPECIFIED = -1; // 0xffffffff
- field @Deprecated public static final int REPORT_EVENT_AFTER_BUFFER_FULL = 0; // 0x0
- field public static final int REPORT_EVENT_AFTER_EACH_SCAN = 1; // 0x1
- field public static final int REPORT_EVENT_FULL_SCAN_RESULT = 2; // 0x2
- field public static final int REPORT_EVENT_NO_BATCH = 4; // 0x4
- field public static final int SCAN_TYPE_HIGH_ACCURACY = 2; // 0x2
- field public static final int SCAN_TYPE_LOW_LATENCY = 0; // 0x0
- field public static final int SCAN_TYPE_LOW_POWER = 1; // 0x1
- field public static final int WIFI_BAND_24_5_6_GHZ = 11; // 0xb
- field public static final int WIFI_BAND_24_5_WITH_DFS_6_GHZ = 15; // 0xf
- field public static final int WIFI_BAND_24_GHZ = 1; // 0x1
- field public static final int WIFI_BAND_5_GHZ = 2; // 0x2
- field public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; // 0x4
- field public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; // 0x6
- field public static final int WIFI_BAND_6_GHZ = 8; // 0x8
- field public static final int WIFI_BAND_BOTH = 3; // 0x3
- field public static final int WIFI_BAND_BOTH_WITH_DFS = 7; // 0x7
- field public static final int WIFI_BAND_UNSPECIFIED = 0; // 0x0
- }
-
- public static interface WifiScanner.ActionListener {
- method public void onFailure(int, String);
- method public void onSuccess();
- }
-
- @Deprecated public static class WifiScanner.BssidInfo {
- ctor @Deprecated public WifiScanner.BssidInfo();
- field @Deprecated public String bssid;
- field @Deprecated public int frequencyHint;
- field @Deprecated public int high;
- field @Deprecated public int low;
- }
-
- @Deprecated public static interface WifiScanner.BssidListener extends android.net.wifi.WifiScanner.ActionListener {
- method @Deprecated public void onFound(android.net.wifi.ScanResult[]);
- method @Deprecated public void onLost(android.net.wifi.ScanResult[]);
- }
-
- public static class WifiScanner.ChannelSpec {
- ctor public WifiScanner.ChannelSpec(int);
- field public int frequency;
- }
-
- @Deprecated public static class WifiScanner.HotlistSettings implements android.os.Parcelable {
- ctor @Deprecated public WifiScanner.HotlistSettings();
- field @Deprecated public int apLostThreshold;
- field @Deprecated public android.net.wifi.WifiScanner.BssidInfo[] bssidInfos;
- }
-
- public static class WifiScanner.ParcelableScanData implements android.os.Parcelable {
- ctor public WifiScanner.ParcelableScanData(android.net.wifi.WifiScanner.ScanData[]);
- method public android.net.wifi.WifiScanner.ScanData[] getResults();
- field public android.net.wifi.WifiScanner.ScanData[] mResults;
- }
-
- public static class WifiScanner.ParcelableScanResults implements android.os.Parcelable {
- ctor public WifiScanner.ParcelableScanResults(android.net.wifi.ScanResult[]);
- method public android.net.wifi.ScanResult[] getResults();
- field public android.net.wifi.ScanResult[] mResults;
- }
-
- public static class WifiScanner.ScanData implements android.os.Parcelable {
- ctor public WifiScanner.ScanData(int, int, android.net.wifi.ScanResult[]);
- ctor public WifiScanner.ScanData(android.net.wifi.WifiScanner.ScanData);
- method public int getFlags();
- method public int getId();
- method public android.net.wifi.ScanResult[] getResults();
- }
-
- public static interface WifiScanner.ScanListener extends android.net.wifi.WifiScanner.ActionListener {
- method public void onFullResult(android.net.wifi.ScanResult);
- method @Deprecated public void onPeriodChanged(int);
- method public void onResults(android.net.wifi.WifiScanner.ScanData[]);
- }
-
- public static class WifiScanner.ScanSettings implements android.os.Parcelable {
- ctor public WifiScanner.ScanSettings();
- field public int band;
- field public android.net.wifi.WifiScanner.ChannelSpec[] channels;
- field @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public final java.util.List<android.net.wifi.WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworks;
- field public boolean hideFromAppOps;
- field public boolean ignoreLocationSettings;
- field @Deprecated public int maxPeriodInMs;
- field @Deprecated public int maxScansToCache;
- field @Deprecated public int numBssidsPerScan;
- field @Deprecated public int periodInMs;
- field @Deprecated public int reportEvents;
- field @Deprecated public int stepCount;
- field @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public int type;
- }
-
- public static class WifiScanner.ScanSettings.HiddenNetwork {
- ctor public WifiScanner.ScanSettings.HiddenNetwork(@NonNull String);
- field @NonNull public final String ssid;
- }
-
- @Deprecated public static interface WifiScanner.WifiChangeListener extends android.net.wifi.WifiScanner.ActionListener {
- method @Deprecated public void onChanging(android.net.wifi.ScanResult[]);
- method @Deprecated public void onQuiescence(android.net.wifi.ScanResult[]);
- }
-
- @Deprecated public static class WifiScanner.WifiChangeSettings implements android.os.Parcelable {
- ctor @Deprecated public WifiScanner.WifiChangeSettings();
- field @Deprecated public android.net.wifi.WifiScanner.BssidInfo[] bssidInfos;
- field @Deprecated public int lostApSampleSize;
- field @Deprecated public int minApsBreachingThreshold;
- field @Deprecated public int periodInMs;
- field @Deprecated public int rssiSampleSize;
- field @Deprecated public int unchangedSampleSize;
- }
-
- public final class WifiUsabilityStatsEntry implements android.os.Parcelable {
- method public int describeContents();
- method public int getCellularDataNetworkType();
- method public int getCellularSignalStrengthDb();
- method public int getCellularSignalStrengthDbm();
- method public int getLinkSpeedMbps();
- method public int getProbeElapsedTimeSinceLastUpdateMillis();
- method public int getProbeMcsRateSinceLastUpdate();
- method public int getProbeStatusSinceLastUpdate();
- method public int getRssi();
- method public int getRxLinkSpeedMbps();
- method public long getTimeStampMillis();
- method public long getTotalBackgroundScanTimeMillis();
- method public long getTotalBeaconRx();
- method public long getTotalCcaBusyFreqTimeMillis();
- method public long getTotalHotspot2ScanTimeMillis();
- method public long getTotalNanScanTimeMillis();
- method public long getTotalPnoScanTimeMillis();
- method public long getTotalRadioOnFreqTimeMillis();
- method public long getTotalRadioOnTimeMillis();
- method public long getTotalRadioRxTimeMillis();
- method public long getTotalRadioTxTimeMillis();
- method public long getTotalRoamScanTimeMillis();
- method public long getTotalRxSuccess();
- method public long getTotalScanTimeMillis();
- method public long getTotalTxBad();
- method public long getTotalTxRetries();
- method public long getTotalTxSuccess();
- method public boolean isSameRegisteredCell();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiUsabilityStatsEntry> CREATOR;
- field public static final int PROBE_STATUS_FAILURE = 3; // 0x3
- field public static final int PROBE_STATUS_NO_PROBE = 1; // 0x1
- field public static final int PROBE_STATUS_SUCCESS = 2; // 0x2
- field public static final int PROBE_STATUS_UNKNOWN = 0; // 0x0
- }
-
-}
-
-package android.net.wifi.aware {
-
- public class DiscoverySession implements java.lang.AutoCloseable {
- method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPmk(@NonNull android.net.wifi.aware.PeerHandle, @NonNull byte[]);
- }
-
- public class WifiAwareSession implements java.lang.AutoCloseable {
- method public android.net.NetworkSpecifier createNetworkSpecifierPmk(int, @NonNull byte[], @NonNull byte[]);
- }
-
-}
-
-package android.net.wifi.hotspot2 {
-
- public final class OsuProvider implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public String getFriendlyName();
- method @Nullable public android.net.Uri getServerUri();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.OsuProvider> CREATOR;
- }
-
- public final class PasspointConfiguration implements android.os.Parcelable {
- method public int getMeteredOverride();
- method public boolean isAutojoinEnabled();
- method public boolean isMacRandomizationEnabled();
- }
-
- public abstract class ProvisioningCallback {
- ctor public ProvisioningCallback();
- method public abstract void onProvisioningComplete();
- method public abstract void onProvisioningFailure(int);
- method public abstract void onProvisioningStatus(int);
- field public static final int OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION = 22; // 0x16
- field public static final int OSU_FAILURE_AP_CONNECTION = 1; // 0x1
- field public static final int OSU_FAILURE_INVALID_URL_FORMAT_FOR_OSU = 8; // 0x8
- field public static final int OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE = 17; // 0x11
- field public static final int OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE = 21; // 0x15
- field public static final int OSU_FAILURE_NO_OSU_ACTIVITY_FOUND = 14; // 0xe
- field public static final int OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE = 19; // 0x13
- field public static final int OSU_FAILURE_NO_PPS_MO = 16; // 0x10
- field public static final int OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE = 18; // 0x12
- field public static final int OSU_FAILURE_OSU_PROVIDER_NOT_FOUND = 23; // 0x17
- field public static final int OSU_FAILURE_PROVISIONING_ABORTED = 6; // 0x6
- field public static final int OSU_FAILURE_PROVISIONING_NOT_AVAILABLE = 7; // 0x7
- field public static final int OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES = 20; // 0x14
- field public static final int OSU_FAILURE_SERVER_CONNECTION = 3; // 0x3
- field public static final int OSU_FAILURE_SERVER_URL_INVALID = 2; // 0x2
- field public static final int OSU_FAILURE_SERVER_VALIDATION = 4; // 0x4
- field public static final int OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION = 5; // 0x5
- field public static final int OSU_FAILURE_SOAP_MESSAGE_EXCHANGE = 11; // 0xb
- field public static final int OSU_FAILURE_START_REDIRECT_LISTENER = 12; // 0xc
- field public static final int OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER = 13; // 0xd
- field public static final int OSU_FAILURE_UNEXPECTED_COMMAND_TYPE = 9; // 0x9
- field public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS = 15; // 0xf
- field public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE = 10; // 0xa
- field public static final int OSU_STATUS_AP_CONNECTED = 2; // 0x2
- field public static final int OSU_STATUS_AP_CONNECTING = 1; // 0x1
- field public static final int OSU_STATUS_INIT_SOAP_EXCHANGE = 6; // 0x6
- field public static final int OSU_STATUS_REDIRECT_RESPONSE_RECEIVED = 8; // 0x8
- field public static final int OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS = 11; // 0xb
- field public static final int OSU_STATUS_SECOND_SOAP_EXCHANGE = 9; // 0x9
- field public static final int OSU_STATUS_SERVER_CONNECTED = 5; // 0x5
- field public static final int OSU_STATUS_SERVER_CONNECTING = 3; // 0x3
- field public static final int OSU_STATUS_SERVER_VALIDATED = 4; // 0x4
- field public static final int OSU_STATUS_THIRD_SOAP_EXCHANGE = 10; // 0xa
- field public static final int OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE = 7; // 0x7
- }
-
-}
-
-package android.net.wifi.p2p {
-
- public final class WifiP2pGroupList implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public java.util.List<android.net.wifi.p2p.WifiP2pGroup> getGroupList();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroupList> CREATOR;
- }
-
- public class WifiP2pManager {
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void deletePersistentGroup(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public void requestPersistentGroupInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setDeviceName(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull String, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setMiracastMode(int);
- method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setWfdInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pWfdInfo, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setWifiP2pChannels(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void startListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void stopListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
- field public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED";
- field public static final int MIRACAST_DISABLED = 0; // 0x0
- field public static final int MIRACAST_SINK = 2; // 0x2
- field public static final int MIRACAST_SOURCE = 1; // 0x1
- }
-
- public static interface WifiP2pManager.PersistentGroupInfoListener {
- method public void onPersistentGroupInfoAvailable(@NonNull android.net.wifi.p2p.WifiP2pGroupList);
- }
-
-}
-
-package android.net.wifi.rtt {
-
- public static final class RangingRequest.Builder {
- method public android.net.wifi.rtt.RangingRequest.Builder addResponder(@NonNull android.net.wifi.rtt.ResponderConfig);
- }
-
- public final class RangingResult implements android.os.Parcelable {
- method @NonNull public byte[] getLci();
- method @NonNull public byte[] getLcr();
- }
-
- public final class ResponderConfig implements android.os.Parcelable {
- ctor public ResponderConfig(@NonNull android.net.MacAddress, int, boolean, int, int, int, int, int);
- ctor public ResponderConfig(@NonNull android.net.wifi.aware.PeerHandle, int, boolean, int, int, int, int, int);
- method public int describeContents();
- method public static android.net.wifi.rtt.ResponderConfig fromScanResult(android.net.wifi.ScanResult);
- method public static android.net.wifi.rtt.ResponderConfig fromWifiAwarePeerHandleWithDefaults(android.net.wifi.aware.PeerHandle);
- method public static android.net.wifi.rtt.ResponderConfig fromWifiAwarePeerMacAddressWithDefaults(android.net.MacAddress);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
- field public static final int CHANNEL_WIDTH_20MHZ = 0; // 0x0
- field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
- field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
- field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderConfig> CREATOR;
- field public static final int PREAMBLE_HE = 3; // 0x3
- field public static final int PREAMBLE_HT = 1; // 0x1
- field public static final int PREAMBLE_LEGACY = 0; // 0x0
- field public static final int PREAMBLE_VHT = 2; // 0x2
- field public static final int RESPONDER_AP = 0; // 0x0
- field public static final int RESPONDER_AWARE = 4; // 0x4
- field public static final int RESPONDER_P2P_CLIENT = 3; // 0x3
- field public static final int RESPONDER_P2P_GO = 2; // 0x2
- field public static final int RESPONDER_STA = 1; // 0x1
- field public final int centerFreq0;
- field public final int centerFreq1;
- field public final int channelWidth;
- field public final int frequency;
- field public final android.net.MacAddress macAddress;
- field public final android.net.wifi.aware.PeerHandle peerHandle;
- field public final int preamble;
- field public final int responderType;
- field public final boolean supports80211mc;
- }
-
- public final class ResponderLocation implements android.os.Parcelable {
- method public boolean getExtraInfoOnAssociationIndication();
- }
-
- public class WifiRttManager {
- method @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE}) public void cancelRanging(@Nullable android.os.WorkSource);
- method @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_WIFI_STATE}) public void startRanging(@Nullable android.os.WorkSource, @NonNull android.net.wifi.rtt.RangingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.rtt.RangingResultCallback);
- }
-
-}
-
diff --git a/wifi/api/system-lint-baseline.txt b/wifi/api/system-lint-baseline.txt
deleted file mode 100644
index 6547ee8..0000000
--- a/wifi/api/system-lint-baseline.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-// Baseline format: 1.0
-MissingGetterMatchingBuilder: android.net.wifi.rtt.RangingRequest.Builder#addResponder(android.net.wifi.rtt.ResponderConfig):
- android.net.wifi.rtt.RangingRequest does not declare a `getResponders()` method matching method android.net.wifi.rtt.RangingRequest.Builder.addResponder(android.net.wifi.rtt.ResponderConfig)
-
-MissingNullability: android.net.wifi.rtt.RangingRequest.Builder#addResponder(android.net.wifi.rtt.ResponderConfig):
-
diff --git a/wifi/api/system-removed.txt b/wifi/api/system-removed.txt
deleted file mode 100644
index a2d0dff..0000000
--- a/wifi/api/system-removed.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-// Signature format: 2.0
-package android.net.wifi {
-
- @Deprecated public class BatchedScanResult implements android.os.Parcelable {
- ctor public BatchedScanResult();
- ctor public BatchedScanResult(android.net.wifi.BatchedScanResult);
- field public final java.util.List<android.net.wifi.ScanResult> scanResults;
- field public boolean truncated;
- }
-
- public final class ScanResult implements android.os.Parcelable {
- field public boolean untrusted;
- }
-
-}
-
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
deleted file mode 100644
index e253ae2..0000000
--- a/wifi/jarjar-rules.txt
+++ /dev/null
@@ -1,126 +0,0 @@
-## used by service-wifi ##
-
-# Network Stack AIDL interface.
-rule android.net.DataStallReportParcelable* com.android.wifi.x.@0
-rule android.net.DhcpResultsParcelable* com.android.wifi.x.@0
-rule android.net.IIpMemoryStore* com.android.wifi.x.@0
-rule android.net.IIpMemoryStoreCallbacks* com.android.wifi.x.@0
-rule android.net.INetd* com.android.wifi.x.@0
-rule android.net.INetdUnsolicitedEventListener* com.android.wifi.x.@0
-rule android.net.INetworkStackConnector* com.android.wifi.x.@0
-rule android.net.InformationElementParcelable* com.android.wifi.x.@0
-rule android.net.InitialConfigurationParcelable* com.android.wifi.x.@0
-rule android.net.InterfaceConfigurationParcel* com.android.wifi.x.@0
-rule android.net.Layer2InformationParcelable* com.android.wifi.x.@0
-rule android.net.Layer2PacketParcelable* com.android.wifi.x.@0
-rule android.net.MarkMaskParcel* com.android.wifi.x.@0
-rule android.net.NattKeepalivePacketDataParcelable* com.android.wifi.x.@0
-rule android.net.NetworkTestResultParcelable* com.android.wifi.x.@0
-rule android.net.PrivateDnsConfigParcel* com.android.wifi.x.@0
-rule android.net.ProvisioningConfigurationParcelable* com.android.wifi.x.@0
-rule android.net.ResolverParamsParcel* com.android.wifi.x.@0
-rule android.net.RouteInfoParcel* com.android.wifi.x.@0
-rule android.net.ScanResultInfoParcelable* com.android.wifi.x.@0
-rule android.net.TetherConfigParcel* com.android.wifi.x.@0
-rule android.net.TetherOffloadRuleParcel* com.android.wifi.x.@0
-rule android.net.TetherStatsParcel* com.android.wifi.x.@0
-rule android.net.UidRangeParcel* com.android.wifi.x.@0
-rule android.net.dhcp.DhcpLeaseParcelable* com.android.wifi.x.@0
-rule android.net.dhcp.DhcpServingParamsParcel* com.android.wifi.x.@0
-rule android.net.ip.IIpClient* com.android.wifi.x.@0
-rule android.net.ip.IIpClientCallbacks* com.android.wifi.x.@0
-rule android.net.ipmemorystore.Blob* com.android.wifi.x.@0
-rule android.net.ipmemorystore.IOnBlobRetrievedListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.IOnStatusAndCountListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.IOnStatusListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.NetworkAttributesParcelable* com.android.wifi.x.@0
-rule android.net.ipmemorystore.SameL3NetworkResponseParcelable* com.android.wifi.x.@0
-rule android.net.ipmemorystore.StatusParcelable* com.android.wifi.x.@0
-
-# Net utils (includes Network Stack helper classes).
-rule android.net.DhcpResults* com.android.wifi.x.@0
-rule android.net.InterfaceConfiguration* com.android.wifi.x.@0
-rule android.net.IpMemoryStore* com.android.wifi.x.@0
-rule android.net.NetworkMonitorManager* com.android.wifi.x.@0
-rule android.net.TcpKeepalivePacketData* com.android.wifi.x.@0
-rule android.net.NetworkFactory* com.android.wifi.x.@0
-rule android.net.ip.IpClientCallbacks* com.android.wifi.x.@0
-rule android.net.ip.IpClientManager* com.android.wifi.x.@0
-rule android.net.ip.IpClientUtil* com.android.wifi.x.@0
-rule android.net.ipmemorystore.NetworkAttributes* com.android.wifi.x.@0
-rule android.net.ipmemorystore.OnBlobRetrievedListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.OnDeleteStatusListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.OnStatusListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.Status* com.android.wifi.x.@0
-rule android.net.networkstack.ModuleNetworkStackClient* com.android.wifi.x.@0
-rule android.net.networkstack.NetworkStackClientBase* com.android.wifi.x.@0
-rule android.net.shared.InetAddressUtils* com.android.wifi.x.@0
-rule android.net.shared.InitialConfiguration* com.android.wifi.x.@0
-rule android.net.shared.IpConfigurationParcelableUtil* com.android.wifi.x.@0
-rule android.net.shared.Layer2Information* com.android.wifi.x.@0
-rule android.net.shared.LinkPropertiesParcelableUtil* com.android.wifi.x.@0
-rule android.net.shared.NetdUtils* com.android.wifi.x.@0
-rule android.net.shared.NetworkMonitorUtils* com.android.wifi.x.@0
-rule android.net.shared.ParcelableUtil* com.android.wifi.x.@0
-rule android.net.shared.PrivateDnsConfig* com.android.wifi.x.@0
-rule android.net.shared.ProvisioningConfiguration* com.android.wifi.x.@0
-rule android.net.shared.RouteUtils* com.android.wifi.x.@0
-rule android.net.util.KeepalivePacketDataUtil* com.android.wifi.x.@0
-rule android.net.util.NetworkConstants* com.android.wifi.x.@0
-rule android.net.util.InterfaceParams* com.android.wifi.x.@0
-rule android.net.util.SharedLog* com.android.wifi.x.@0
-rule android.net.util.NetUtils* com.android.wifi.x.@0
-rule android.net.util.IpUtils* com.android.wifi.x.@0
-
-rule androidx.annotation.** com.android.wifi.x.@0
-
-# We don't jar-jar the entire package because, we still use some classes (like
-# AsyncChannel in com.android.internal.util) from these packages which are not
-# inside our jar (currently in framework.jar, but will be in wifisdk.jar in the future).
-rule com.android.internal.util.FastXmlSerializer* com.android.wifi.x.@0
-rule com.android.internal.util.HexDump* com.android.wifi.x.@0
-rule com.android.internal.util.IState* com.android.wifi.x.@0
-rule com.android.internal.util.MessageUtils* com.android.wifi.x.@0
-rule com.android.internal.util.State* com.android.wifi.x.@0
-rule com.android.internal.util.StateMachine* com.android.wifi.x.@0
-rule com.android.internal.util.WakeupMessage* com.android.wifi.x.@0
-
-rule android.util.BackupUtils* com.android.wifi.x.@0
-rule android.util.LocalLog* com.android.wifi.x.@0
-rule android.util.Rational* com.android.wifi.x.@0
-
-rule android.os.BasicShellCommandHandler* com.android.wifi.x.@0
-
-# Use our statically linked bouncy castle library
-rule org.bouncycastle.** com.android.wifi.x.@0
-# Use our statically linked protobuf library
-rule com.google.protobuf.** com.android.wifi.x.@0
-# use statically linked SystemMessageProto
-rule com.android.internal.messages.SystemMessageProto* com.android.wifi.x.@0
-# Use our statically linked PlatformProperties library
-rule android.sysprop.** com.android.wifi.x.@0
-# Use our statically linked HIDL stubs
-# Note: android.hardware.wifi.** is used by various wifi feature flags. This unfortunately is also the namespace
-# used by vendor HAL stubs. So, this rule is intentionally weird to try and filter the vendor HAL stubs only.
-rule android.hardware.wifi.V** com.android.wifi.x.@0
-rule android.hardware.wifi.supplicant.** com.android.wifi.x.@0
-rule android.hardware.wifi.hostapd.** com.android.wifi.x.@0
-rule android.hidl.** com.android.wifi.x.@0
-# Use our statically linked ksoap2
-rule org.ksoap2.** com.android.wifi.x.@0
-# Use our statically linked nanohttpd
-rule fi.iki.elonen.** com.android.wifi.x.@0
-
-## used by both framework-wifi and service-wifi ##
-rule android.content.pm.BaseParceledListSlice* com.android.wifi.x.@0
-rule android.content.pm.ParceledListSlice* com.android.wifi.x.@0
-rule android.net.util.MacAddressUtils* com.android.wifi.x.@0
-rule android.net.util.nsd.DnsSdTxtRecord* com.android.wifi.x.@0
-rule android.os.HandlerExecutor* com.android.wifi.x.@0
-rule android.telephony.Annotation* com.android.wifi.x.@0
-rule com.android.internal.util.AsyncChannel* com.android.wifi.x.@0
-rule com.android.internal.util.AsyncService* com.android.wifi.x.@0
-rule com.android.internal.util.Preconditions* com.android.wifi.x.@0
-rule com.android.internal.util.Protocol* com.android.wifi.x.@0
-
-rule com.android.net.module.util.** com.android.wifi.x.@0
diff --git a/wifi/java/Android.bp b/wifi/java/Android.bp
new file mode 100644
index 0000000..b35b4be
--- /dev/null
+++ b/wifi/java/Android.bp
@@ -0,0 +1,35 @@
+// 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.
+
+// This directory contains framework Wifi APIs that are not part of the Wifi module (i.e. not
+// updatable), and are generally only called by the Wifi module.
+
+// necessary since we only want the `path` property to only refer to these files
+filegroup {
+ name: "framework-wifi-non-updatable-sources-internal",
+ srcs: ["src/**/*.java"],
+ path: "src",
+ visibility: ["//visibility:private"],
+}
+
+filegroup {
+ name: "framework-wifi-non-updatable-sources",
+ srcs: [
+ // TODO(b/146011398) package android.net.wifi is now split amongst 2 jars: framework.jar and
+ // framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache
+ // to a separate package.
+ ":framework-wifi-non-updatable-sources-internal",
+ ":libwificond_ipc_aidl",
+ ],
+}
diff --git a/wifi/java/android/net/wifi/AnqpInformationElement.java b/wifi/java/android/net/wifi/AnqpInformationElement.java
deleted file mode 100644
index 47b7129..0000000
--- a/wifi/java/android/net/wifi/AnqpInformationElement.java
+++ /dev/null
@@ -1,80 +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.net.wifi;
-
-/**
- * This object contains the payload of an ANQP element.
- * Vendor id is the vendor ID for the element, or 0 if it is an 802.11(u) element.
- * Hotspot 2.0 uses the WFA Vendor ID which is 0x506f9a
- * The payload contains the bytes of the payload, starting after the length octet(s).
- * @hide
- */
-public class AnqpInformationElement {
- public static final int HOTSPOT20_VENDOR_ID = 0x506f9a;
-
- public static final int ANQP_QUERY_LIST = 256;
- public static final int ANQP_CAPABILITY_LIST = 257;
- public static final int ANQP_VENUE_NAME = 258;
- public static final int ANQP_EMERGENCY_NUMBER = 259;
- public static final int ANQP_NWK_AUTH_TYPE = 260;
- public static final int ANQP_ROAMING_CONSORTIUM = 261;
- public static final int ANQP_IP_ADDR_AVAILABILITY = 262;
- public static final int ANQP_NAI_REALM = 263;
- public static final int ANQP_3GPP_NETWORK = 264;
- public static final int ANQP_GEO_LOC = 265;
- public static final int ANQP_CIVIC_LOC = 266;
- public static final int ANQP_LOC_URI = 267;
- public static final int ANQP_DOM_NAME = 268;
- public static final int ANQP_EMERGENCY_ALERT = 269;
- public static final int ANQP_TDLS_CAP = 270;
- public static final int ANQP_EMERGENCY_NAI = 271;
- public static final int ANQP_NEIGHBOR_REPORT = 272;
- public static final int ANQP_VENDOR_SPEC = 56797;
-
- public static final int HS_QUERY_LIST = 1;
- public static final int HS_CAPABILITY_LIST = 2;
- public static final int HS_FRIENDLY_NAME = 3;
- public static final int HS_WAN_METRICS = 4;
- public static final int HS_CONN_CAPABILITY = 5;
- public static final int HS_NAI_HOME_REALM_QUERY = 6;
- public static final int HS_OPERATING_CLASS = 7;
- public static final int HS_OSU_PROVIDERS = 8;
- public static final int HS_ICON_REQUEST = 10;
- public static final int HS_ICON_FILE = 11;
-
- private final int mVendorId;
- private final int mElementId;
- private final byte[] mPayload;
-
- public AnqpInformationElement(int vendorId, int elementId, byte[] payload) {
- mVendorId = vendorId;
- mElementId = elementId;
- mPayload = payload;
- }
-
- public int getVendorId() {
- return mVendorId;
- }
-
- public int getElementId() {
- return mElementId;
- }
-
- public byte[] getPayload() {
- return mPayload;
- }
-}
diff --git a/wifi/java/android/net/wifi/BatchedScanResult.java b/wifi/java/android/net/wifi/BatchedScanResult.java
deleted file mode 100644
index ed8845dd..0000000
--- a/wifi/java/android/net/wifi/BatchedScanResult.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.os.Parcelable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Describes the Results of a batched set of wifi scans where the firmware performs many
- * scans and stores the timestamped results without waking the main processor each time.
- * @hide
- * @removed
- */
-@Deprecated
-@SystemApi
-public class BatchedScanResult implements Parcelable {
- private static final String TAG = "BatchedScanResult";
-
- /** Inidcates this scan was interrupted and may only have partial results. */
- public boolean truncated;
-
- /** The result of this particular scan. */
- public final List<ScanResult> scanResults = new ArrayList<ScanResult>();
-
-
- public BatchedScanResult() {
- }
-
- public BatchedScanResult(BatchedScanResult source) {
- truncated = source.truncated;
- for (ScanResult s : source.scanResults) scanResults.add(new ScanResult(s));
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
-
- sb.append("BatchedScanResult: ").
- append("truncated: ").append(String.valueOf(truncated)).
- append("scanResults: [");
- for (ScanResult s : scanResults) {
- sb.append(" <").append(s.toString()).append("> ");
- }
- sb.append(" ]");
- return sb.toString();
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(truncated ? 1 : 0);
- dest.writeInt(scanResults.size());
- for (ScanResult s : scanResults) {
- s.writeToParcel(dest, flags);
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<BatchedScanResult> CREATOR =
- new Creator<BatchedScanResult>() {
- public BatchedScanResult createFromParcel(Parcel in) {
- BatchedScanResult result = new BatchedScanResult();
- result.truncated = (in.readInt() == 1);
- int count = in.readInt();
- while (count-- > 0) {
- result.scanResults.add(ScanResult.CREATOR.createFromParcel(in));
- }
- return result;
- }
-
- public BatchedScanResult[] newArray(int size) {
- return new BatchedScanResult[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/EAPConstants.java b/wifi/java/android/net/wifi/EAPConstants.java
deleted file mode 100644
index b5f7c94..0000000
--- a/wifi/java/android/net/wifi/EAPConstants.java
+++ /dev/null
@@ -1,57 +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.net.wifi;
-
-/**
- * Utility class containing EAP (Extensible Authentication Protocol) Related constants.
- *
- * @hide
- */
-public final class EAPConstants {
- // Constant definition for EAP types. Refer to
- // http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml for more info.
- public static final int EAP_MD5 = 4;
- public static final int EAP_OTP = 5;
- public static final int EAP_RSA = 9;
- public static final int EAP_KEA = 11;
- public static final int EAP_KEA_VALIDATE = 12;
- public static final int EAP_TLS = 13;
- public static final int EAP_LEAP = 17;
- public static final int EAP_SIM = 18;
- public static final int EAP_TTLS = 21;
- public static final int EAP_AKA = 23;
- public static final int EAP_3Com = 24;
- public static final int EAP_MSCHAPv2 = 26;
- public static final int EAP_PEAP = 29;
- public static final int EAP_POTP = 32;
- public static final int EAP_ActiontecWireless = 35;
- public static final int EAP_HTTPDigest = 38;
- public static final int EAP_SPEKE = 41;
- public static final int EAP_MOBAC = 42;
- public static final int EAP_FAST = 43;
- public static final int EAP_ZLXEAP = 44;
- public static final int EAP_Link = 45;
- public static final int EAP_PAX = 46;
- public static final int EAP_PSK = 47;
- public static final int EAP_SAKE = 48;
- public static final int EAP_IKEv2 = 49;
- public static final int EAP_AKA_PRIME = 50;
- public static final int EAP_GPSK = 51;
- public static final int EAP_PWD = 52;
- public static final int EAP_EKE = 53;
- public static final int EAP_TEAP = 55;
-}
diff --git a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java
deleted file mode 100644
index 6c2e6dd..0000000
--- a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java
+++ /dev/null
@@ -1,267 +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.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.util.SparseArray;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.concurrent.Executor;
-
-/**
- * Easy Connect (DPP) Status Callback. Use this callback to get status updates (success, failure,
- * progress) from the Easy Connect operations.
- */
-public abstract class EasyConnectStatusCallback {
- /**
- * Easy Connect R1 Success event: Configuration sent (Configurator mode). This is the last
- * and final Easy Connect event when either the local device or remote device implement R1.
- * If both devices implement R2, this event will never be received, and the
- * {@link #EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED} will be received.
- * @hide
- */
- @SystemApi
- public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0;
-
- /**
- * Easy Connect R2 Success event: Configuration applied by Enrollee (Configurator mode).
- * This is the last and final Easy Connect event when both the local device and remote device
- * implement R2. If either the local device or remote device implement R1, this event will never
- * be received, and the {@link #EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT} will be received.
- * @hide
- */
- @SystemApi
- public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1;
-
- /** @hide */
- @IntDef(prefix = {"EASY_CONNECT_EVENT_SUCCESS_"}, value = {
- EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT,
- EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface EasyConnectSuccessStatusCode {
- }
-
- /**
- * Easy Connect Progress event: Initial authentication with peer succeeded.
- * @hide
- */
- @SystemApi
- public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0;
-
- /**
- * Easy Connect Progress event: Peer requires more time to process bootstrapping.
- * @hide
- */
- @SystemApi
- public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1;
-
- /**
- * Easy Connect R2 Progress event: Configuration sent to Enrollee, waiting for response
- * @hide
- */
- @SystemApi
- public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2;
-
- /**
- * Easy Connect R2 Progress event: Configuration accepted by Enrollee, waiting for response
- * @hide
- */
- @SystemApi
- public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3;
-
- /** @hide */
- @IntDef(prefix = {"EASY_CONNECT_EVENT_PROGRESS_"}, value = {
- EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS,
- EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING,
- EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE,
- EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface EasyConnectProgressStatusCode {
- }
-
- /**
- * Easy Connect Failure event: Scanned QR code is either not a Easy Connect URI, or the Easy
- * Connect URI has errors.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1;
-
- /**
- * Easy Connect Failure event: Bootstrapping/Authentication initialization process failure.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2;
-
- /**
- * Easy Connect Failure event: Both devices are implementing the same role and are incompatible.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE = -3;
-
- /**
- * Easy Connect Failure event: Configuration process has failed due to malformed message.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4;
-
- /**
- * Easy Connect Failure event: Easy Connect request while in another Easy Connect exchange.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5;
-
- /**
- * Easy Connect Failure event: No response from the peer.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6;
-
- /**
- * Easy Connect Failure event: General protocol failure.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7;
-
- /**
- * Easy Connect Failure event: Feature or option is not supported.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8;
-
- /**
- * Easy Connect Failure event: Invalid network provided to Easy Connect configurator.
- * Network must either be WPA3-Personal (SAE) or WPA2-Personal (PSK).
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9;
-
- /**
- * Easy Connect R2 Failure event: Enrollee cannot find the network.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10;
-
- /**
- * Easy Connect R2 Failure event: Enrollee failed to authenticate with the network.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11;
-
- /**
- * Easy Connect R2 Failure event: Enrollee rejected the configuration.
- */
- public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12;
-
- /** @hide */
- @IntDef(prefix = {"EASY_CONNECT_EVENT_FAILURE_"}, value = {
- EASY_CONNECT_EVENT_FAILURE_INVALID_URI,
- EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION,
- EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE,
- EASY_CONNECT_EVENT_FAILURE_CONFIGURATION,
- EASY_CONNECT_EVENT_FAILURE_BUSY,
- EASY_CONNECT_EVENT_FAILURE_TIMEOUT,
- EASY_CONNECT_EVENT_FAILURE_GENERIC,
- EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED,
- EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK,
- EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK,
- EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION,
- EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface EasyConnectFailureStatusCode {
- }
-
- /** @hide */
- @SystemApi
- public EasyConnectStatusCallback() {
- // Fully-static utility classes must not have constructor
- }
-
- /**
- * Called when local Easy Connect Enrollee successfully receives a new Wi-Fi configuration from
- * the
- * peer Easy Connect configurator. This callback marks the successful end of the Easy Connect
- * current Easy Connect
- * session, and no further callbacks will be called. This callback is the successful outcome
- * of a Easy Connect flow starting with
- * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, Executor,
- * EasyConnectStatusCallback)} .
- *
- * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator
- * @hide
- */
- @SystemApi
- public abstract void onEnrolleeSuccess(int newNetworkId);
-
- /**
- * Called when a Easy Connect success event takes place, except for when configuration is
- * received from an external Configurator. The callback onSuccessConfigReceived will be used in
- * this case. This callback marks the successful end of the current Easy Connect session, and no
- * further callbacks will be called. This callback is the successful outcome of a Easy Connect
- * flow starting with {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int,
- * int, Executor,EasyConnectStatusCallback)}.
- *
- * @param code Easy Connect success status code.
- * @hide
- */
- @SystemApi
- public abstract void onConfiguratorSuccess(@EasyConnectSuccessStatusCode int code);
-
- /**
- * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful
- * end of the current Easy Connect session, and no further callbacks will be called.
- *
- * @param code Easy Connect failure status code.
- * @hide
- */
- @SystemApi
- public void onFailure(@EasyConnectFailureStatusCode int code) {}
-
- /**
- * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful
- * end of the current Easy Connect session, and no further callbacks will be called.
- *
- * Note: Easy Connect (DPP) R2, provides additional details for the Configurator when the
- * remote Enrollee is unable to connect to a network. The ssid, channelList and bandList
- * inputs are initialized only for the EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK failure
- * code, and the ssid and bandList are initialized for the
- * EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION failure code.
- *
- * @param code Easy Connect failure status code.
- * @param ssid SSID of the network the Enrollee tried to connect to.
- * @param channelListArray List of Global Operating classes and channel sets the Enrollee used
- * to scan to find the network, see the "DPP Connection Status Object"
- * section in the specification for the format, and Table E-4 in
- * IEEE Std 802.11-2016 - Global operating classes for more details.
- * The sparse array key is the Global Operating class, and the value
- * is an integer array of Wi-Fi channels.
- * @param operatingClassArray Array of bands the Enrollee supports as expressed as the Global
- * Operating Class, see Table E-4 in IEEE Std 802.11-2016 - Global
- * operating classes.
- * @hide
- */
- @SystemApi
- public void onFailure(@EasyConnectFailureStatusCode int code, @Nullable String ssid,
- @NonNull SparseArray<int[]> channelListArray, @NonNull int[] operatingClassArray) {
- onFailure(code);
- }
-
- /**
- * Called when Easy Connect events that indicate progress take place. Can be used by UI elements
- * to show progress.
- *
- * @param code Easy Connect progress status code.
- * @hide
- */
- @SystemApi
- public abstract void onProgress(@EasyConnectProgressStatusCode int code);
-}
diff --git a/wifi/java/android/net/wifi/IActionListener.aidl b/wifi/java/android/net/wifi/IActionListener.aidl
deleted file mode 100644
index faa0901..0000000
--- a/wifi/java/android/net/wifi/IActionListener.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for generic wifi callbacks.
- * @hide
- */
-oneway interface IActionListener
-{
- void onSuccess();
- void onFailure(int reason);
-}
diff --git a/wifi/java/android/net/wifi/IDppCallback.aidl b/wifi/java/android/net/wifi/IDppCallback.aidl
deleted file mode 100644
index d7a958a..0000000
--- a/wifi/java/android/net/wifi/IDppCallback.aidl
+++ /dev/null
@@ -1,48 +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.net.wifi;
-
-/**
- * Interface for DPP callback.
- *
- * @hide
- */
-oneway interface IDppCallback
-{
- /**
- * Called when local DPP Enrollee successfully receives a new Wi-Fi configuratrion from the
- * peer DPP configurator.
- */
- void onSuccessConfigReceived(int newNetworkId);
-
- /**
- * Called when DPP success events take place, except for when configuration is received from
- * an external Configurator. The callback onSuccessConfigReceived will be used in this case.
- */
- void onSuccess(int status);
-
- /**
- * Called when DPP Failure events take place.
- */
- void onFailure(int status, String ssid, String channelList, in int[] bandArray);
-
- /**
- * Called when DPP events that indicate progress take place. Can be used by UI elements
- * to show progress.
- */
- void onProgress(int status);
-}
diff --git a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
deleted file mode 100644
index b567f29..0000000
--- a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.SoftApConfiguration;
-
-/**
- * Communicates LOHS status back to the application process.
- *
- * @hide
- */
-oneway interface ILocalOnlyHotspotCallback {
- void onHotspotStarted(in SoftApConfiguration config);
- void onHotspotStopped();
- void onHotspotFailed(int reason);
-}
diff --git a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
deleted file mode 100644
index d14ec57..0000000
--- a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.INetworkRequestUserSelectionCallback;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-
-/**
- * Interface for network request match callback.
- *
- * @hide
- */
-oneway interface INetworkRequestMatchCallback
-{
- void onUserSelectionCallbackRegistration(in INetworkRequestUserSelectionCallback userSelectionCallback);
-
- void onAbort();
-
- void onMatch(in List<ScanResult> scanResults);
-
- void onUserSelectionConnectSuccess(in WifiConfiguration wificonfiguration);
-
- void onUserSelectionConnectFailure(in WifiConfiguration wificonfiguration);
-}
diff --git a/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl
deleted file mode 100644
index 524cefb..0000000
--- a/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl
+++ /dev/null
@@ -1,31 +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.net.wifi;
-
-import android.net.wifi.WifiConfiguration;
-
-/**
- * Interface for providing user selection in response to
- * network request match callback.
- * @hide
- */
-oneway interface INetworkRequestUserSelectionCallback
-{
- void select(in WifiConfiguration wificonfiguration);
-
- void reject();
-}
diff --git a/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl b/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl
deleted file mode 100644
index 7e25fd8a..0000000
--- a/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl
+++ /dev/null
@@ -1,33 +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.net.wifi;
-
-import android.os.connectivity.WifiActivityEnergyInfo;
-
-/**
- * Interface for Wi-Fi activity energy info listener.
- *
- * @hide
- */
-oneway interface IOnWifiActivityEnergyInfoListener
-{
- /**
- * Service to manager callback providing current Wi-Fi activity energy info.
- * @param info the Wi-Fi activity energy info
- */
- void onWifiActivityEnergyInfo(in WifiActivityEnergyInfo info);
-}
diff --git a/wifi/java/android/net/wifi/IOnWifiUsabilityStatsListener.aidl b/wifi/java/android/net/wifi/IOnWifiUsabilityStatsListener.aidl
deleted file mode 100644
index 4687f30..0000000
--- a/wifi/java/android/net/wifi/IOnWifiUsabilityStatsListener.aidl
+++ /dev/null
@@ -1,41 +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.net.wifi;
-
-import android.net.wifi.WifiUsabilityStatsEntry;
-
-/**
- * Interface for Wi-Fi usability stats listener.
- *
- * @hide
- */
-oneway interface IOnWifiUsabilityStatsListener
-{
- /**
- * Service to manager callback providing current Wi-Fi usability stats.
- *
- * @param seqNum The sequence number of stats, used to derive the timing of updated Wi-Fi
- * usability statistics, set by framework and shall be incremented by one
- * after each update.
- * @param isSameBssidAndFreq The flag to indicate whether the BSSID and the frequency of
- * network stays the same or not relative to the last update of
- * Wi-Fi usability stats.
- * @param stats The updated Wi-Fi usability statistics.
- */
- void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
- in WifiUsabilityStatsEntry stats);
-}
diff --git a/wifi/java/android/net/wifi/IScanResultsCallback.aidl b/wifi/java/android/net/wifi/IScanResultsCallback.aidl
deleted file mode 100644
index 56f6025..0000000
--- a/wifi/java/android/net/wifi/IScanResultsCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for Wi-Fi scan result available callback.
- *
- * @hide
- */
-oneway interface IScanResultsCallback
-{
- void onScanResultsAvailable();
-}
diff --git a/wifi/java/android/net/wifi/IScanResultsListener.aidl b/wifi/java/android/net/wifi/IScanResultsListener.aidl
deleted file mode 100644
index e7eaddd..0000000
--- a/wifi/java/android/net/wifi/IScanResultsListener.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/** @hide */
-
-oneway interface IScanResultsListener
-{
- void onScanResultsAvailable();
-}
diff --git a/wifi/java/android/net/wifi/IScoreUpdateObserver.aidl b/wifi/java/android/net/wifi/IScoreUpdateObserver.aidl
deleted file mode 100644
index 775fed7..0000000
--- a/wifi/java/android/net/wifi/IScoreUpdateObserver.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for Wi-Fi score callback.
- *
- * @hide
- */
-oneway interface IScoreUpdateObserver
-{
- void notifyScoreUpdate(int sessionId, int score);
-
- void triggerUpdateOfWifiUsabilityStats(int sessionId);
-}
diff --git a/wifi/java/android/net/wifi/ISoftApCallback.aidl b/wifi/java/android/net/wifi/ISoftApCallback.aidl
deleted file mode 100644
index f81bcb9..0000000
--- a/wifi/java/android/net/wifi/ISoftApCallback.aidl
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-import android.net.wifi.SoftApCapability;
-import android.net.wifi.SoftApInfo;
-
-import android.net.wifi.WifiClient;
-
-/**
- * Interface for Soft AP callback.
- *
- * @hide
- */
-oneway interface ISoftApCallback
-{
- /**
- * Service to manager callback providing current soft AP state. The possible
- * parameter values listed are defined in WifiManager.java
- *
- * @param state new AP state. One of WIFI_AP_STATE_DISABLED,
- * WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED,
- * WIFI_AP_STATE_ENABLING, WIFI_AP_STATE_FAILED
- * @param failureReason reason when in failed state. One of
- * SAP_START_FAILURE_GENERAL, SAP_START_FAILURE_NO_CHANNEL
- */
- void onStateChanged(int state, int failureReason);
-
- /**
- * Service to manager callback providing connected client's information.
- *
- * @param clients the currently connected clients
- */
- void onConnectedClientsChanged(in List<WifiClient> clients);
-
- /**
- * Service to manager callback providing information of softap.
- *
- * @param softApInfo is the softap information. {@link SoftApInfo}
- */
- void onInfoChanged(in SoftApInfo softApInfo);
-
-
- /**
- * Service to manager callback providing capability of softap.
- *
- * @param capability is the softap capability. {@link SoftApCapability}
- */
- void onCapabilityChanged(in SoftApCapability capability);
-
- /**
- * Service to manager callback providing blocked client of softap with specific reason code.
- *
- * @param client the currently blocked client.
- * @param blockedReason one of blocked reason from {@link WifiManager.SapClientBlockedReason}
- */
- void onBlockedClientConnecting(in WifiClient client, int blockedReason);
-}
diff --git a/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl b/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl
deleted file mode 100644
index b49e49b..0000000
--- a/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl
+++ /dev/null
@@ -1,29 +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.net.wifi;
-
-import android.net.wifi.WifiNetworkSuggestion;
-
-/**
- * Interface for suggestion network connection listener.
- *
- * @hide
- */
-oneway interface ISuggestionConnectionStatusListener
-{
- void onConnectionStatus(in WifiNetworkSuggestion wifiNetworkSuggestion, int failureReason);
-}
diff --git a/wifi/java/android/net/wifi/ITrafficStateCallback.aidl b/wifi/java/android/net/wifi/ITrafficStateCallback.aidl
deleted file mode 100644
index 0c8e777..0000000
--- a/wifi/java/android/net/wifi/ITrafficStateCallback.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for Traffic state callback.
- *
- * @hide
- */
-oneway interface ITrafficStateCallback
-{
- /**
- * Callback invoked to inform clients about the current traffic state.
- *
- * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN},
- * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}.
- * @hide
- */
- void onStateChanged(int state);
-}
diff --git a/wifi/java/android/net/wifi/ITxPacketCountListener.aidl b/wifi/java/android/net/wifi/ITxPacketCountListener.aidl
deleted file mode 100644
index 9105bd0..0000000
--- a/wifi/java/android/net/wifi/ITxPacketCountListener.aidl
+++ /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 android.net.wifi;
-
-/**
- * Interface for tx packet counter callback.
- * @deprecated no longer used, remove once removed from BaseWifiService
- * @hide
- */
-oneway interface ITxPacketCountListener
-{
- void onSuccess(int count);
- void onFailure(int reason);
-}
diff --git a/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl b/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
deleted file mode 100644
index f96d037..0000000
--- a/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.IScoreUpdateObserver;
-
-/**
- * Interface for Wi-Fi connected network scorer.
- *
- * @hide
- */
-oneway interface IWifiConnectedNetworkScorer
-{
- void onStart(int sessionId);
-
- void onStop(int sessionId);
-
- void onSetScoreUpdateObserver(IScoreUpdateObserver observerImpl);
-}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
deleted file mode 100644
index 5063ad6..0000000
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ /dev/null
@@ -1,278 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.content.pm.ParceledListSlice;
-
-import android.net.wifi.hotspot2.OsuProvider;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.IProvisioningCallback;
-
-import android.net.DhcpInfo;
-import android.net.Network;
-import android.net.wifi.IActionListener;
-import android.net.wifi.IDppCallback;
-import android.net.wifi.ILocalOnlyHotspotCallback;
-import android.net.wifi.INetworkRequestMatchCallback;
-import android.net.wifi.IOnWifiActivityEnergyInfoListener;
-import android.net.wifi.IOnWifiUsabilityStatsListener;
-import android.net.wifi.IScanResultsCallback;
-import android.net.wifi.ISoftApCallback;
-import android.net.wifi.ISuggestionConnectionStatusListener;
-import android.net.wifi.ITrafficStateCallback;
-import android.net.wifi.IWifiConnectedNetworkScorer;
-import android.net.wifi.ScanResult;
-import android.net.wifi.SoftApConfiguration;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiNetworkSuggestion;
-
-import android.os.Messenger;
-import android.os.ResultReceiver;
-import android.os.WorkSource;
-
-/**
- * Interface that allows controlling and querying Wi-Fi connectivity.
- *
- * {@hide}
- */
-interface IWifiManager
-{
- long getSupportedFeatures();
-
- oneway void getWifiActivityEnergyInfoAsync(in IOnWifiActivityEnergyInfoListener listener);
-
- ParceledListSlice getConfiguredNetworks(String packageName, String featureId);
-
- ParceledListSlice getPrivilegedConfiguredNetworks(String packageName, String featureId);
-
- Map getAllMatchingFqdnsForScanResults(in List<ScanResult> scanResult);
-
- Map getMatchingOsuProviders(in List<ScanResult> scanResult);
-
- Map getMatchingPasspointConfigsForOsuProviders(in List<OsuProvider> osuProviders);
-
- int addOrUpdateNetwork(in WifiConfiguration config, String packageName);
-
- boolean addOrUpdatePasspointConfiguration(in PasspointConfiguration config, String packageName);
-
- boolean removePasspointConfiguration(in String fqdn, String packageName);
-
- List<PasspointConfiguration> getPasspointConfigurations(in String packageName);
-
- List<WifiConfiguration> getWifiConfigsForPasspointProfiles(in List<String> fqdnList);
-
- void queryPasspointIcon(long bssid, String fileName);
-
- int matchProviderWithCurrentNetwork(String fqdn);
-
- void deauthenticateNetwork(long holdoff, boolean ess);
-
- boolean removeNetwork(int netId, String packageName);
-
- boolean enableNetwork(int netId, boolean disableOthers, String packageName);
-
- boolean disableNetwork(int netId, String packageName);
-
- void allowAutojoinGlobal(boolean choice);
-
- void allowAutojoin(int netId, boolean choice);
-
- void allowAutojoinPasspoint(String fqdn, boolean enableAutoJoin);
-
- void setMacRandomizationSettingPasspointEnabled(String fqdn, boolean enable);
-
- void setPasspointMeteredOverride(String fqdn, int meteredOverride);
-
- boolean startScan(String packageName, String featureId);
-
- List<ScanResult> getScanResults(String callingPackage, String callingFeatureId);
-
- boolean disconnect(String packageName);
-
- boolean reconnect(String packageName);
-
- boolean reassociate(String packageName);
-
- WifiInfo getConnectionInfo(String callingPackage, String callingFeatureId);
-
- boolean setWifiEnabled(String packageName, boolean enable);
-
- int getWifiEnabledState();
-
- String getCountryCode();
-
- boolean is5GHzBandSupported();
-
- boolean is6GHzBandSupported();
-
- boolean isWifiStandardSupported(int standard);
-
- DhcpInfo getDhcpInfo();
-
- void setScanAlwaysAvailable(boolean isAvailable);
-
- boolean isScanAlwaysAvailable();
-
- boolean acquireWifiLock(IBinder lock, int lockType, String tag, in WorkSource ws);
-
- void updateWifiLockWorkSource(IBinder lock, in WorkSource ws);
-
- boolean releaseWifiLock(IBinder lock);
-
- void initializeMulticastFiltering();
-
- boolean isMulticastEnabled();
-
- void acquireMulticastLock(IBinder binder, String tag);
-
- void releaseMulticastLock(String tag);
-
- void updateInterfaceIpState(String ifaceName, int mode);
-
- boolean startSoftAp(in WifiConfiguration wifiConfig);
-
- boolean startTetheredHotspot(in SoftApConfiguration softApConfig);
-
- boolean stopSoftAp();
-
- int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName,
- String featureId, in SoftApConfiguration customConfig);
-
- void stopLocalOnlyHotspot();
-
- void startWatchLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback);
-
- void stopWatchLocalOnlyHotspot();
-
- @UnsupportedAppUsage
- int getWifiApEnabledState();
-
- @UnsupportedAppUsage
- WifiConfiguration getWifiApConfiguration();
-
- SoftApConfiguration getSoftApConfiguration();
-
- boolean setWifiApConfiguration(in WifiConfiguration wifiConfig, String packageName);
-
- boolean setSoftApConfiguration(in SoftApConfiguration softApConfig, String packageName);
-
- void notifyUserOfApBandConversion(String packageName);
-
- void enableTdls(String remoteIPAddress, boolean enable);
-
- void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable);
-
- String getCurrentNetworkWpsNfcConfigurationToken();
-
- void enableVerboseLogging(int verbose);
-
- int getVerboseLoggingLevel();
-
- void disableEphemeralNetwork(String SSID, String packageName);
-
- void factoryReset(String packageName);
-
- @UnsupportedAppUsage
- Network getCurrentNetwork();
-
- byte[] retrieveBackupData();
-
- void restoreBackupData(in byte[] data);
-
- byte[] retrieveSoftApBackupData();
-
- SoftApConfiguration restoreSoftApBackupData(in byte[] data);
-
- void restoreSupplicantBackupData(in byte[] supplicantData, in byte[] ipConfigData);
-
- void startSubscriptionProvisioning(in OsuProvider provider, in IProvisioningCallback callback);
-
- void registerSoftApCallback(in IBinder binder, in ISoftApCallback callback, int callbackIdentifier);
-
- void unregisterSoftApCallback(int callbackIdentifier);
-
- void addOnWifiUsabilityStatsListener(in IBinder binder, in IOnWifiUsabilityStatsListener listener, int listenerIdentifier);
-
- void removeOnWifiUsabilityStatsListener(int listenerIdentifier);
-
- void registerTrafficStateCallback(in IBinder binder, in ITrafficStateCallback callback, int callbackIdentifier);
-
- void unregisterTrafficStateCallback(int callbackIdentifier);
-
- void registerNetworkRequestMatchCallback(in IBinder binder, in INetworkRequestMatchCallback callback, int callbackIdentifier);
-
- void unregisterNetworkRequestMatchCallback(int callbackIdentifier);
-
- int addNetworkSuggestions(in List<WifiNetworkSuggestion> networkSuggestions, in String packageName,
- in String featureId);
-
- int removeNetworkSuggestions(in List<WifiNetworkSuggestion> networkSuggestions, in String packageName);
-
- List<WifiNetworkSuggestion> getNetworkSuggestions(in String packageName);
-
- String[] getFactoryMacAddresses();
-
- void setDeviceMobilityState(int state);
-
- void startDppAsConfiguratorInitiator(in IBinder binder, in String enrolleeUri,
- int selectedNetworkId, int netRole, in IDppCallback callback);
-
- void startDppAsEnrolleeInitiator(in IBinder binder, in String configuratorUri,
- in IDppCallback callback);
-
- void stopDppSession();
-
- void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec);
-
- oneway void connect(in WifiConfiguration config, int netId, in IBinder binder, in IActionListener listener, int callbackIdentifier);
-
- oneway void save(in WifiConfiguration config, in IBinder binder, in IActionListener listener, int callbackIdentifier);
-
- oneway void forget(int netId, in IBinder binder, in IActionListener listener, int callbackIdentifier);
-
- void registerScanResultsCallback(in IScanResultsCallback callback);
-
- void unregisterScanResultsCallback(in IScanResultsCallback callback);
-
- void registerSuggestionConnectionStatusListener(in IBinder binder, in ISuggestionConnectionStatusListener listener, int listenerIdentifier, String packageName, String featureId);
-
- void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, String packageName);
-
- int calculateSignalLevel(int rssi);
-
- List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List<ScanResult> scanResults);
-
- boolean setWifiConnectedNetworkScorer(in IBinder binder, in IWifiConnectedNetworkScorer scorer);
-
- void clearWifiConnectedNetworkScorer();
-
- /**
- * Return the Map of {@link WifiNetworkSuggestion} and the list of <ScanResult>
- */
- Map getMatchingScanResults(in List<WifiNetworkSuggestion> networkSuggestions, in List<ScanResult> scanResults, String callingPackage, String callingFeatureId);
-
- void setScanThrottleEnabled(boolean enable);
-
- boolean isScanThrottleEnabled();
-
- Map getAllMatchingPasspointProfilesForScanResults(in List<ScanResult> scanResult);
-
- void setAutoWakeupEnabled(boolean enable);
-
- boolean isAutoWakeupEnabled();
-}
diff --git a/wifi/java/android/net/wifi/IWifiScanner.aidl b/wifi/java/android/net/wifi/IWifiScanner.aidl
deleted file mode 100644
index 485f5ce..0000000
--- a/wifi/java/android/net/wifi/IWifiScanner.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.os.Messenger;
-import android.os.Bundle;
-
-/**
- * {@hide}
- */
-interface IWifiScanner
-{
- Messenger getMessenger();
-
- Bundle getAvailableChannels(int band, String packageName, String featureId);
-}
diff --git a/wifi/java/android/net/wifi/ParcelUtil.java b/wifi/java/android/net/wifi/ParcelUtil.java
deleted file mode 100644
index a26877d..0000000
--- a/wifi/java/android/net/wifi/ParcelUtil.java
+++ /dev/null
@@ -1,165 +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.net.wifi;
-
-import android.os.Parcel;
-
-import java.io.ByteArrayInputStream;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-
-/**
- * Provides utilities for writing/reading a non-Parcelable objects to/from
- * a Parcel object.
- *
- * @hide
- */
-public class ParcelUtil {
- /**
- * Write a PrivateKey object |key| to the specified Parcel |dest|.
- *
- * Below is the data format:
- * |algorithm| -> String of algorithm name
- * |endcodedKey| -> byte[] of key data
- *
- * For a null PrivateKey object, a null string will be written to |algorithm| and
- * |encodedKey| will be skipped. Since a PrivateKey can only be constructed with
- * a valid algorithm String.
- *
- * @param dest Parcel object to write to
- * @param key PrivateKey object to read from.
- */
- public static void writePrivateKey(Parcel dest, PrivateKey key) {
- if (key == null) {
- dest.writeString(null);
- return;
- }
-
- dest.writeString(key.getAlgorithm());
- dest.writeByteArray(key.getEncoded());
- }
-
- /**
- * Read/create a PrivateKey object from a specified Parcel object |in|.
- *
- * Refer to the function above for the expected data format.
- *
- * @param in Parcel object to read from
- * @return a PrivateKey object or null
- */
- public static PrivateKey readPrivateKey(Parcel in) {
- String algorithm = in.readString();
- if (algorithm == null) {
- return null;
- }
-
- byte[] userKeyBytes = in.createByteArray();
- try {
- KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
- return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(userKeyBytes));
- } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
- return null;
- }
- }
-
- /**
- * Write a X509Certificate object |cert| to a Parcel object |dest|.
- * The data being written to the Parcel is just a byte[] of the encoded certificate data.
- *
- * @param dest Parcel object to write to
- * @param cert X509Certificate object to read from
- */
- public static void writeCertificate(Parcel dest, X509Certificate cert) {
- byte[] certBytes = null;
- if (cert != null) {
- try {
- certBytes = cert.getEncoded();
- } catch (CertificateEncodingException e) {
- /* empty, write null. */
- }
- }
- dest.writeByteArray(certBytes);
- }
-
- /**
- * Read/create a X509Certificate object from a specified Parcel object |in|.
- *
- * @param in Parcel object to read from
- * @return a X509Certficate object or null
- */
- public static X509Certificate readCertificate(Parcel in) {
- byte[] certBytes = in.createByteArray();
- if (certBytes == null) {
- return null;
- }
-
- try {
- CertificateFactory cFactory = CertificateFactory.getInstance("X.509");
- return (X509Certificate) cFactory
- .generateCertificate(new ByteArrayInputStream(certBytes));
- } catch (CertificateException e) {
- return null;
- }
- }
-
- /**
- * Write an array of X509Certificate objects |certs| to a Parcel object |dest|.
- * The data being written to the Parcel are consist of an integer indicating
- * the size of the array and the certificates data. Certificates data will be
- * skipped for a null array or size of 0 array.
- *
- * @param dest Parcel object to write to
- * @param certs array of X509Certificate objects to read from
- */
- public static void writeCertificates(Parcel dest, X509Certificate[] certs) {
- if (certs == null || certs.length == 0) {
- dest.writeInt(0);
- return;
- }
-
- dest.writeInt(certs.length);
- for (int i = 0; i < certs.length; i++) {
- writeCertificate(dest, certs[i]);
- }
- }
-
- /**
- * Read/create an array of X509Certificate objects from a specified Parcel object |in|.
- *
- * @param in Parcel object to read from
- * @return X509Certficate[] or null
- */
- public static X509Certificate[] readCertificates(Parcel in) {
- int length = in.readInt();
- if (length == 0) {
- return null;
- }
-
- X509Certificate[] certs = new X509Certificate[length];
- for (int i = 0; i < length; i++) {
- certs[i] = readCertificate(in);
- }
- return certs;
- }
-}
diff --git a/wifi/java/android/net/wifi/RttManager.aidl b/wifi/java/android/net/wifi/RttManager.aidl
deleted file mode 100644
index 9479cf0..0000000
--- a/wifi/java/android/net/wifi/RttManager.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Copyright (c) 2015, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-parcelable RttManager.RttCapabilities;
-parcelable RttManager.ParcelableRttResults;
-parcelable RttManager.ParcelableRttParams;
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
deleted file mode 100644
index 73c52ab..0000000
--- a/wifi/java/android/net/wifi/RttManager.java
+++ /dev/null
@@ -1,1233 +0,0 @@
-package android.net.wifi;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.net.wifi.rtt.RangingRequest;
-import android.net.wifi.rtt.RangingResult;
-import android.net.wifi.rtt.RangingResultCallback;
-import android.net.wifi.rtt.WifiRttManager;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Protocol;
-
-import java.util.List;
-
-/** @hide */
-@SystemApi
-@Deprecated
-@SystemService(Context.WIFI_RTT_SERVICE)
-public class RttManager {
-
- private static final boolean DBG = false;
- private static final String TAG = "RttManager";
-
- /** @deprecated It is Not supported anymore. */
- @Deprecated
- public static final int RTT_TYPE_UNSPECIFIED = 0;
-
- public static final int RTT_TYPE_ONE_SIDED = 1;
- public static final int RTT_TYPE_TWO_SIDED = 2;
-
- /** @deprecated It is not supported anymore. */
- @Deprecated
- public static final int RTT_TYPE_11_V = 2;
-
- /** @deprecated It is not supported anymore. */
- @Deprecated
- public static final int RTT_TYPE_11_MC = 4;
-
- /** @deprecated It is not supported anymore. */
- @Deprecated
- public static final int RTT_PEER_TYPE_UNSPECIFIED = 0;
-
- public static final int RTT_PEER_TYPE_AP = 1;
- public static final int RTT_PEER_TYPE_STA = 2; /* requires NAN */
- public static final int RTT_PEER_P2P_GO = 3;
- public static final int RTT_PEER_P2P_CLIENT = 4;
- public static final int RTT_PEER_NAN = 5;
-
- /**
- * @deprecated It is not supported anymore.
- * Use {@link android.net.wifi.RttManager#RTT_BW_20_SUPPORT} API.
- */
- @Deprecated
- public static final int RTT_CHANNEL_WIDTH_20 = 0;
-
- /**
- * @deprecated It is not supported anymore.
- * Use {@link android.net.wifi.RttManager#RTT_BW_40_SUPPORT} API.
- */
- @Deprecated
- public static final int RTT_CHANNEL_WIDTH_40 = 1;
-
- /**
- * @deprecated It is not supported anymore.
- * Use {@link android.net.wifi.RttManager#RTT_BW_80_SUPPORT} API.
- */
- @Deprecated
- public static final int RTT_CHANNEL_WIDTH_80 = 2;
-
- /**@deprecated It is not supported anymore.
- * Use {@link android.net.wifi.RttManager#RTT_BW_160_SUPPORT} API.
- */
- @Deprecated
- public static final int RTT_CHANNEL_WIDTH_160 = 3;
-
- /**@deprecated not supported anymore*/
- @Deprecated
- public static final int RTT_CHANNEL_WIDTH_80P80 = 4;
-
- /**@deprecated It is not supported anymore.
- * Use {@link android.net.wifi.RttManager#RTT_BW_5_SUPPORT} API.
- */
- @Deprecated
- public static final int RTT_CHANNEL_WIDTH_5 = 5;
-
- /**@deprecated It is not supported anymore.
- * Use {@link android.net.wifi.RttManager#RTT_BW_10_SUPPORT} API.
- */
- @Deprecated
- public static final int RTT_CHANNEL_WIDTH_10 = 6;
-
- /** @deprecated channel info must be specified. */
- @Deprecated
- public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1;
-
- public static final int RTT_STATUS_SUCCESS = 0;
- /** General failure*/
- public static final int RTT_STATUS_FAILURE = 1;
- /** Destination does not respond to RTT request*/
- public static final int RTT_STATUS_FAIL_NO_RSP = 2;
- /** RTT request is rejected by the destination. Double side RTT only*/
- public static final int RTT_STATUS_FAIL_REJECTED = 3;
- /** */
- public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4;
- /** Timing measurement timeout*/
- public static final int RTT_STATUS_FAIL_TM_TIMEOUT = 5;
- /** Destination is on a different channel from the RTT Request*/
- public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6;
- /** This type of Ranging is not support by Hardware*/
- public static final int RTT_STATUS_FAIL_NO_CAPABILITY = 7;
- /** Request abort fro uncertain reason*/
- public static final int RTT_STATUS_ABORTED = 8;
- /** The T1-T4 or TOD/TOA Timestamp is illegal*/
- public static final int RTT_STATUS_FAIL_INVALID_TS = 9;
- /** 11mc protocol level failed, eg, unrecognized FTMR/FTM frame*/
- public static final int RTT_STATUS_FAIL_PROTOCOL = 10;
- /** Request can not be scheduled by hardware*/
- public static final int RTT_STATUS_FAIL_SCHEDULE = 11;
- /** destination is busy now, you can try after a specified time from destination*/
- public static final int RTT_STATUS_FAIL_BUSY_TRY_LATER = 12;
- /** Bad Request argument*/
- public static final int RTT_STATUS_INVALID_REQ = 13;
- /** Wifi is not enabled*/
- public static final int RTT_STATUS_NO_WIFI = 14;
- /** Responder overrides param info, cannot range with new params 2-side RTT only*/
- public static final int RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15;
-
- public static final int REASON_UNSPECIFIED = -1;
- public static final int REASON_NOT_AVAILABLE = -2;
- public static final int REASON_INVALID_LISTENER = -3;
- public static final int REASON_INVALID_REQUEST = -4;
- /** Do not have required permission */
- public static final int REASON_PERMISSION_DENIED = -5;
- /** Ranging failed because responder role is enabled in STA mode.*/
- public static final int
- REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON = -6;
-
- public static final String DESCRIPTION_KEY = "android.net.wifi.RttManager.Description";
-
- /**
- * RTT BW supported bit mask, used as RTT param bandWidth too
- */
- public static final int RTT_BW_5_SUPPORT = 0x01;
- public static final int RTT_BW_10_SUPPORT = 0x02;
- public static final int RTT_BW_20_SUPPORT = 0x04;
- public static final int RTT_BW_40_SUPPORT = 0x08;
- public static final int RTT_BW_80_SUPPORT = 0x10;
- public static final int RTT_BW_160_SUPPORT = 0x20;
-
- /**
- * RTT Preamble Support bit mask
- */
- public static final int PREAMBLE_LEGACY = 0x01;
- public static final int PREAMBLE_HT = 0x02;
- public static final int PREAMBLE_VHT = 0x04;
-
- /** @deprecated Use the new {@link android.net.wifi.RttManager.RttCapabilities} API */
- @Deprecated
- public class Capabilities {
- public int supportedType;
- public int supportedPeerType;
- }
-
- /** @deprecated Use the new {@link android.net.wifi.RttManager#getRttCapabilities()} API.*/
- @Deprecated
- @SuppressLint("Doclava125")
- public Capabilities getCapabilities() {
- throw new UnsupportedOperationException(
- "getCapabilities is not supported in the adaptation layer");
- }
-
- /**
- * This class describe the RTT capability of the Hardware
- */
- @Deprecated
- public static class RttCapabilities implements Parcelable {
- /** @deprecated It is not supported*/
- @Deprecated
- public boolean supportedType;
- /** @deprecated It is not supported*/
- @Deprecated
- public boolean supportedPeerType;
- //1-sided rtt measurement is supported
- public boolean oneSidedRttSupported;
- //11mc 2-sided rtt measurement is supported
- public boolean twoSided11McRttSupported;
- //location configuration information supported
- public boolean lciSupported;
- //location civic records supported
- public boolean lcrSupported;
- //preamble supported, see bit mask definition above
- public int preambleSupported;
- //RTT bandwidth supported
- public int bwSupported;
- // Whether STA responder role is supported.
- public boolean responderSupported;
-
- /** Whether the secure RTT protocol is supported. */
- public boolean secureRttSupported;
-
- /** Draft 11mc version supported, including major and minor version. e.g, draft 4.3 is 43 */
- public int mcVersion;
-
- @NonNull
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("oneSidedRtt ").
- append(oneSidedRttSupported ? "is Supported. " : "is not supported. ").
- append("twoSided11McRtt ").
- append(twoSided11McRttSupported ? "is Supported. " : "is not supported. ").
- append("lci ").
- append(lciSupported ? "is Supported. " : "is not supported. ").
- append("lcr ").
- append(lcrSupported ? "is Supported. " : "is not supported. ");
-
- if ((preambleSupported & PREAMBLE_LEGACY) != 0) {
- sb.append("Legacy ");
- }
-
- if ((preambleSupported & PREAMBLE_HT) != 0) {
- sb.append("HT ");
- }
-
- if ((preambleSupported & PREAMBLE_VHT) != 0) {
- sb.append("VHT ");
- }
-
- sb.append("is supported. ");
-
- if ((bwSupported & RTT_BW_5_SUPPORT) != 0) {
- sb.append("5 MHz ");
- }
-
- if ((bwSupported & RTT_BW_10_SUPPORT) != 0) {
- sb.append("10 MHz ");
- }
-
- if ((bwSupported & RTT_BW_20_SUPPORT) != 0) {
- sb.append("20 MHz ");
- }
-
- if ((bwSupported & RTT_BW_40_SUPPORT) != 0) {
- sb.append("40 MHz ");
- }
-
- if ((bwSupported & RTT_BW_80_SUPPORT) != 0) {
- sb.append("80 MHz ");
- }
-
- if ((bwSupported & RTT_BW_160_SUPPORT) != 0) {
- sb.append("160 MHz ");
- }
-
- sb.append("is supported.");
-
- sb.append(" STA responder role is ")
- .append(responderSupported ? "supported" : "not supported");
- sb.append(" Secure RTT protocol is ")
- .append(secureRttSupported ? "supported" : "not supported");
- sb.append(" 11mc version is " + mcVersion);
-
- return sb.toString();
- }
- /** Implement the Parcelable interface {@hide} */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(oneSidedRttSupported ? 1 : 0);
- dest.writeInt(twoSided11McRttSupported ? 1 : 0);
- dest.writeInt(lciSupported ? 1 : 0);
- dest.writeInt(lcrSupported ? 1 : 0);
- dest.writeInt(preambleSupported);
- dest.writeInt(bwSupported);
- dest.writeInt(responderSupported ? 1 : 0);
- dest.writeInt(secureRttSupported ? 1 : 0);
- dest.writeInt(mcVersion);
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<RttCapabilities> CREATOR =
- new Creator<RttCapabilities>() {
- @Override
- public RttCapabilities createFromParcel(Parcel in) {
- RttCapabilities capabilities = new RttCapabilities();
- capabilities.oneSidedRttSupported = (in.readInt() == 1);
- capabilities.twoSided11McRttSupported = (in.readInt() == 1);
- capabilities.lciSupported = (in.readInt() == 1);
- capabilities.lcrSupported = (in.readInt() == 1);
- capabilities.preambleSupported = in.readInt();
- capabilities.bwSupported = in.readInt();
- capabilities.responderSupported = (in.readInt() == 1);
- capabilities.secureRttSupported = (in.readInt() == 1);
- capabilities.mcVersion = in.readInt();
- return capabilities;
- }
- /** Implement the Parcelable interface {@hide} */
- @Override
- public RttCapabilities[] newArray(int size) {
- return new RttCapabilities[size];
- }
- };
- }
-
- /**
- * This method is deprecated. Please use the {@link WifiRttManager} API.
- */
- @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
- public RttCapabilities getRttCapabilities() {
- return mRttCapabilities;
- }
-
- /** specifies parameters for RTT request */
- @Deprecated
- public static class RttParams {
- /**
- * type of destination device being ranged
- * currently only support RTT_PEER_TYPE_AP
- * Range:RTT_PEER_TYPE_xxxx Default value:RTT_PEER_TYPE_AP
- */
- public int deviceType;
-
- /**
- * type of RTT measurement method. Need check scan result and RttCapabilities first
- * Range: RTT_TYPE_ONE_SIDED or RTT_TYPE_TWO_SIDED
- * Default value: RTT_TYPE_ONE_SIDED
- */
- public int requestType;
-
- /**
- * Whether the secure RTT protocol needs to be used for ranging this peer device.
- */
- public boolean secure;
-
- /**
- * mac address of the device being ranged
- * Default value: null
- */
- public String bssid;
-
- /**
- * The primary control channel over which the client is
- * communicating with the AP.Same as ScanResult.frequency
- * Default value: 0
- */
- public int frequency;
-
- /**
- * channel width of the destination AP. Same as ScanResult.channelWidth
- * Default value: 0
- */
- public int channelWidth;
-
- /**
- * Not used if the AP bandwidth is 20 MHz
- * If the AP use 40, 80 or 160 MHz, this is the center frequency
- * if the AP use 80 + 80 MHz, this is the center frequency of the first segment
- * same as ScanResult.centerFreq0
- * Default value: 0
- */
- public int centerFreq0;
-
- /**
- * Only used if the AP bandwidth is 80 + 80 MHz
- * if the AP use 80 + 80 MHz, this is the center frequency of the second segment
- * same as ScanResult.centerFreq1
- * Default value: 0
- */
- public int centerFreq1;
-
- /**
- * number of samples to be taken
- * @deprecated Use the new {@link android.net.wifi.RttManager.RttParams#numSamplesPerBurst}
- */
- @Deprecated
- public int num_samples;
-
- /**
- * number of retries if a sample fails
- * @deprecated
- * Use {@link android.net.wifi.RttManager.RttParams#numRetriesPerMeasurementFrame} API.
- */
- @Deprecated
- public int num_retries;
-
- /** Number of burst in exp , 2^x. 0 means single shot measurement, range 0-15
- * Currently only single shot is supported
- * Default value: 0
- */
- public int numberBurst;
-
- /**
- * valid only if numberBurst > 1, interval between burst(100ms).
- * Range : 0-31, 0--means no specific
- * Default value: 0
- */
- public int interval;
-
- /**
- * number of samples to be taken in one burst
- * Range: 1-31
- * Default value: 8
- */
- public int numSamplesPerBurst;
-
- /** number of retries for each measurement frame if a sample fails
- * Only used by single side RTT,
- * Range 0 - 3 Default value: 0
- */
- public int numRetriesPerMeasurementFrame;
-
- /**
- * number of retries for FTMR frame (control frame) if it fails.
- * Only used by 80211MC double side RTT
- * Range: 0-3 Default Value : 0
- */
- public int numRetriesPerFTMR;
-
- /**
- * Request LCI information, only available when choose double side RTT measurement
- * need check RttCapabilties first.
- * Default value: false
- * */
- public boolean LCIRequest;
-
- /**
- * Request LCR information, only available when choose double side RTT measurement
- * need check RttCapabilties first.
- * Default value: false
- * */
- public boolean LCRRequest;
-
- /**
- * Timeout for each burst, (250 * 2^x) us,
- * Range 1-11 and 15. 15 means no control Default value: 15
- * */
- public int burstTimeout;
-
- /** preamble used for RTT measurement
- * Range: PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT
- * Default value: PREAMBLE_HT
- */
- public int preamble;
-
- /** bandWidth used for RTT measurement.User need verify the highest BW the destination
- * support (from scan result etc) before set this value. Wider channels result usually give
- * better accuracy. However, the frame loss can increase too.
- * should be one of RTT_BW_5_SUPPORT to RTT_BW_160_SUPPORT. However, need check
- * RttCapabilities firstto verify HW support this bandwidth.
- * Default value:RTT_BW_20_SUPPORT
- */
- public int bandwidth;
-
- public RttParams() {
- //provide initial value for RttParams
- deviceType = RTT_PEER_TYPE_AP;
- requestType = RTT_TYPE_ONE_SIDED;
- numberBurst = 0;
- numSamplesPerBurst = 8;
- numRetriesPerMeasurementFrame = 0;
- numRetriesPerFTMR = 0;
- burstTimeout = 15;
- preamble = PREAMBLE_HT;
- bandwidth = RTT_BW_20_SUPPORT;
- }
-
- /**
- * {@hide}
- */
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("deviceType=" + deviceType);
- sb.append(", requestType=" + requestType);
- sb.append(", secure=" + secure);
- sb.append(", bssid=" + bssid);
- sb.append(", frequency=" + frequency);
- sb.append(", channelWidth=" + channelWidth);
- sb.append(", centerFreq0=" + centerFreq0);
- sb.append(", centerFreq1=" + centerFreq1);
- sb.append(", num_samples=" + num_samples);
- sb.append(", num_retries=" + num_retries);
- sb.append(", numberBurst=" + numberBurst);
- sb.append(", interval=" + interval);
- sb.append(", numSamplesPerBurst=" + numSamplesPerBurst);
- sb.append(", numRetriesPerMeasurementFrame=" + numRetriesPerMeasurementFrame);
- sb.append(", numRetriesPerFTMR=" + numRetriesPerFTMR);
- sb.append(", LCIRequest=" + LCIRequest);
- sb.append(", LCRRequest=" + LCRRequest);
- sb.append(", burstTimeout=" + burstTimeout);
- sb.append(", preamble=" + preamble);
- sb.append(", bandwidth=" + bandwidth);
- return sb.toString();
- }
- }
-
- /** pseudo-private class used to parcel arguments */
- @Deprecated
- public static class ParcelableRttParams implements Parcelable {
-
- @NonNull
- public RttParams mParams[];
-
- /**
- * @hide
- */
- @VisibleForTesting
- public ParcelableRttParams(RttParams[] params) {
- mParams = (params == null ? new RttParams[0] : params);
- }
-
- /** Implement the Parcelable interface {@hide} */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mParams.length);
-
- for (RttParams params : mParams) {
- dest.writeInt(params.deviceType);
- dest.writeInt(params.requestType);
- dest.writeByte(params.secure ? (byte) 1 : 0);
- dest.writeString(params.bssid);
- dest.writeInt(params.channelWidth);
- dest.writeInt(params.frequency);
- dest.writeInt(params.centerFreq0);
- dest.writeInt(params.centerFreq1);
- dest.writeInt(params.numberBurst);
- dest.writeInt(params.interval);
- dest.writeInt(params.numSamplesPerBurst);
- dest.writeInt(params.numRetriesPerMeasurementFrame);
- dest.writeInt(params.numRetriesPerFTMR);
- dest.writeInt(params.LCIRequest ? 1 : 0);
- dest.writeInt(params.LCRRequest ? 1 : 0);
- dest.writeInt(params.burstTimeout);
- dest.writeInt(params.preamble);
- dest.writeInt(params.bandwidth);
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<ParcelableRttParams> CREATOR =
- new Creator<ParcelableRttParams>() {
- @Override
- public ParcelableRttParams createFromParcel(Parcel in) {
-
- int num = in.readInt();
- RttParams params[] = new RttParams[num];
- for (int i = 0; i < num; i++) {
- params[i] = new RttParams();
- params[i].deviceType = in.readInt();
- params[i].requestType = in.readInt();
- params[i].secure = (in.readByte() != 0);
- params[i].bssid = in.readString();
- params[i].channelWidth = in.readInt();
- params[i].frequency = in.readInt();
- params[i].centerFreq0 = in.readInt();
- params[i].centerFreq1 = in.readInt();
- params[i].numberBurst = in.readInt();
- params[i].interval = in.readInt();
- params[i].numSamplesPerBurst = in.readInt();
- params[i].numRetriesPerMeasurementFrame = in.readInt();
- params[i].numRetriesPerFTMR = in.readInt();
- params[i].LCIRequest = (in.readInt() == 1);
- params[i].LCRRequest = (in.readInt() == 1);
- params[i].burstTimeout = in.readInt();
- params[i].preamble = in.readInt();
- params[i].bandwidth = in.readInt();
- }
-
- ParcelableRttParams parcelableParams = new ParcelableRttParams(params);
- return parcelableParams;
- }
-
- @Override
- public ParcelableRttParams[] newArray(int size) {
- return new ParcelableRttParams[size];
- }
- };
- }
-
- @Deprecated
- public static class WifiInformationElement {
- /** Information Element ID 0xFF means element is invalid. */
- public byte id;
- public byte[] data;
- }
- /** specifies RTT results */
- @Deprecated
- public static class RttResult {
- /** mac address of the device being ranged. */
- public String bssid;
-
- /** # of burst for this measurement. */
- public int burstNumber;
-
- /** total number of measurement frames attempted in this measurement. */
- public int measurementFrameNumber;
-
- /** total successful number of measurement frames in this measurement. */
- public int successMeasurementFrameNumber;
-
- /**
- * Maximum number of frames per burst supported by peer. Two side RTT only
- * Valid only if less than request
- */
- public int frameNumberPerBurstPeer;
-
- /** status of the request */
- public int status;
-
- /**
- * type of the request used
- * @deprecated Use {@link android.net.wifi.RttManager.RttResult#measurementType}
- */
- @Deprecated
- public int requestType;
-
- /** RTT measurement method type used, should be one of RTT_TYPE_ONE_SIDED or
- * RTT_TYPE_TWO_SIDED.
- */
- public int measurementType;
-
- /**
- * only valid when status == RTT_STATUS_FAIL_BUSY_TRY_LATER
- * please retry RTT measurement after this duration since peer indicate busy at ths moment
- * Unit S Range:1-31
- */
- public int retryAfterDuration;
-
- /** timestamp of completion, in microsecond since boot. */
- public long ts;
-
- /** average RSSI observed, unit of 0.5 dB. */
- public int rssi;
-
- /**
- * RSSI spread (i.e. max - min)
- * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rssiSpread} API.
- */
- @Deprecated
- public int rssi_spread;
-
- /**RSSI spread (i.e. max - min), unit of 0.5 dB. */
- public int rssiSpread;
-
- /**
- * average transmit rate
- * @deprecated Use {@link android.net.wifi.RttManager.RttResult#txRate} API.
- */
- @Deprecated
- public int tx_rate;
-
- /** average transmit rate. Unit (kbps). */
- public int txRate;
-
- /** average receiving rate Unit (kbps). */
- public int rxRate;
-
- /**
- * average round trip time in nano second
- * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rtt} API.
- */
- @Deprecated
- public long rtt_ns;
-
- /** average round trip time in picoseconds. */
- public long rtt;
-
- /**
- * standard deviation observed in round trip time
- * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rttStandardDeviation} API.
- */
- @Deprecated
- public long rtt_sd_ns;
-
- /** standard deviation of RTT in picoseconds. */
- public long rttStandardDeviation;
-
- /**
- * spread (i.e. max - min) round trip time
- * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rttSpread} API.
- */
- @Deprecated
- public long rtt_spread_ns;
-
- /** spread (i.e. max - min) RTT in picoseconds. */
- public long rttSpread;
-
- /**
- * average distance in centimeter, computed based on rtt_ns
- * @deprecated use {@link android.net.wifi.RttManager.RttResult#distance} API.
- */
- @Deprecated
- public int distance_cm;
-
- /** average distance in cm, computed based on rtt. */
- public int distance;
-
- /**
- * standard deviation observed in distance
- * @deprecated
- * Use {@link .android.net.wifi.RttManager.RttResult#distanceStandardDeviation} API.
- */
- @Deprecated
- public int distance_sd_cm;
-
- /** standard deviation observed in distance in cm. */
- public int distanceStandardDeviation;
-
- /**
- * spread (i.e. max - min) distance
- * @deprecated Use {@link android.net.wifi.RttManager.RttResult#distanceSpread} API.
- */
- @Deprecated
- public int distance_spread_cm;
-
- /** spread (i.e. max - min) distance in cm. */
- public int distanceSpread;
-
- /** the duration of this measurement burst, unit ms. */
- public int burstDuration;
-
- /** Burst number supported by peer after negotiation, 2side RTT only*/
- public int negotiatedBurstNum;
-
- /** LCI information Element, only available for double side RTT. */
- public WifiInformationElement LCI;
-
- /** LCR information Element, only available to double side RTT. */
- public WifiInformationElement LCR;
-
- /**
- * Whether the secure RTT protocol was used for ranging.
- */
- public boolean secure;
- }
-
-
- /** pseudo-private class used to parcel results. */
- @Deprecated
- public static class ParcelableRttResults implements Parcelable {
-
- public RttResult mResults[];
-
- public ParcelableRttResults(RttResult[] results) {
- mResults = results;
- }
-
- /**
- * {@hide}
- */
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < mResults.length; ++i) {
- sb.append("[" + i + "]: ");
- sb.append("bssid=" + mResults[i].bssid);
- sb.append(", burstNumber=" + mResults[i].burstNumber);
- sb.append(", measurementFrameNumber=" + mResults[i].measurementFrameNumber);
- sb.append(", successMeasurementFrameNumber="
- + mResults[i].successMeasurementFrameNumber);
- sb.append(", frameNumberPerBurstPeer=" + mResults[i].frameNumberPerBurstPeer);
- sb.append(", status=" + mResults[i].status);
- sb.append(", requestType=" + mResults[i].requestType);
- sb.append(", measurementType=" + mResults[i].measurementType);
- sb.append(", retryAfterDuration=" + mResults[i].retryAfterDuration);
- sb.append(", ts=" + mResults[i].ts);
- sb.append(", rssi=" + mResults[i].rssi);
- sb.append(", rssi_spread=" + mResults[i].rssi_spread);
- sb.append(", rssiSpread=" + mResults[i].rssiSpread);
- sb.append(", tx_rate=" + mResults[i].tx_rate);
- sb.append(", txRate=" + mResults[i].txRate);
- sb.append(", rxRate=" + mResults[i].rxRate);
- sb.append(", rtt_ns=" + mResults[i].rtt_ns);
- sb.append(", rtt=" + mResults[i].rtt);
- sb.append(", rtt_sd_ns=" + mResults[i].rtt_sd_ns);
- sb.append(", rttStandardDeviation=" + mResults[i].rttStandardDeviation);
- sb.append(", rtt_spread_ns=" + mResults[i].rtt_spread_ns);
- sb.append(", rttSpread=" + mResults[i].rttSpread);
- sb.append(", distance_cm=" + mResults[i].distance_cm);
- sb.append(", distance=" + mResults[i].distance);
- sb.append(", distance_sd_cm=" + mResults[i].distance_sd_cm);
- sb.append(", distanceStandardDeviation=" + mResults[i].distanceStandardDeviation);
- sb.append(", distance_spread_cm=" + mResults[i].distance_spread_cm);
- sb.append(", distanceSpread=" + mResults[i].distanceSpread);
- sb.append(", burstDuration=" + mResults[i].burstDuration);
- sb.append(", negotiatedBurstNum=" + mResults[i].negotiatedBurstNum);
- sb.append(", LCI=" + mResults[i].LCI);
- sb.append(", LCR=" + mResults[i].LCR);
- sb.append(", secure=" + mResults[i].secure);
- }
- return sb.toString();
- }
-
- /** Implement the Parcelable interface {@hide} */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- if (mResults != null) {
- dest.writeInt(mResults.length);
- for (RttResult result : mResults) {
- dest.writeString(result.bssid);
- dest.writeInt(result.burstNumber);
- dest.writeInt(result.measurementFrameNumber);
- dest.writeInt(result.successMeasurementFrameNumber);
- dest.writeInt(result.frameNumberPerBurstPeer);
- dest.writeInt(result.status);
- dest.writeInt(result.measurementType);
- dest.writeInt(result.retryAfterDuration);
- dest.writeLong(result.ts);
- dest.writeInt(result.rssi);
- dest.writeInt(result.rssiSpread);
- dest.writeInt(result.txRate);
- dest.writeLong(result.rtt);
- dest.writeLong(result.rttStandardDeviation);
- dest.writeLong(result.rttSpread);
- dest.writeInt(result.distance);
- dest.writeInt(result.distanceStandardDeviation);
- dest.writeInt(result.distanceSpread);
- dest.writeInt(result.burstDuration);
- dest.writeInt(result.negotiatedBurstNum);
- dest.writeByte(result.LCI.id);
- if (result.LCI.id != (byte) 0xFF) {
- dest.writeByte((byte)result.LCI.data.length);
- dest.writeByteArray(result.LCI.data);
- }
- dest.writeByte(result.LCR.id);
- if (result.LCR.id != (byte) 0xFF) {
- dest.writeByte((byte) result.LCR.data.length);
- dest.writeByteArray(result.LCR.data);
- }
- dest.writeByte(result.secure ? (byte) 1 : 0);
- }
- } else {
- dest.writeInt(0);
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<ParcelableRttResults> CREATOR =
- new Creator<ParcelableRttResults>() {
- @Override
- public ParcelableRttResults createFromParcel(Parcel in) {
-
- int num = in.readInt();
-
- if (num == 0) {
- return new ParcelableRttResults(null);
- }
-
- RttResult results[] = new RttResult[num];
- for (int i = 0; i < num; i++) {
- results[i] = new RttResult();
- results[i].bssid = in.readString();
- results[i].burstNumber = in.readInt();
- results[i].measurementFrameNumber = in.readInt();
- results[i].successMeasurementFrameNumber = in.readInt();
- results[i].frameNumberPerBurstPeer = in.readInt();
- results[i].status = in.readInt();
- results[i].measurementType = in.readInt();
- results[i].retryAfterDuration = in.readInt();
- results[i].ts = in.readLong();
- results[i].rssi = in.readInt();
- results[i].rssiSpread = in.readInt();
- results[i].txRate = in.readInt();
- results[i].rtt = in.readLong();
- results[i].rttStandardDeviation = in.readLong();
- results[i].rttSpread = in.readLong();
- results[i].distance = in.readInt();
- results[i].distanceStandardDeviation = in.readInt();
- results[i].distanceSpread = in.readInt();
- results[i].burstDuration = in.readInt();
- results[i].negotiatedBurstNum = in.readInt();
- results[i].LCI = new WifiInformationElement();
- results[i].LCI.id = in.readByte();
- if (results[i].LCI.id != (byte) 0xFF) {
- byte length = in.readByte();
- results[i].LCI.data = new byte[length];
- in.readByteArray(results[i].LCI.data);
- }
- results[i].LCR = new WifiInformationElement();
- results[i].LCR.id = in.readByte();
- if (results[i].LCR.id != (byte) 0xFF) {
- byte length = in.readByte();
- results[i].LCR.data = new byte[length];
- in.readByteArray(results[i].LCR.data);
- }
- results[i].secure = (in.readByte() != 0);
- }
-
- ParcelableRttResults parcelableResults = new ParcelableRttResults(results);
- return parcelableResults;
- }
-
- @Override
- public ParcelableRttResults[] newArray(int size) {
- return new ParcelableRttResults[size];
- }
- };
- }
-
- @Deprecated
- public static interface RttListener {
- public void onSuccess(RttResult[] results);
- public void onFailure(int reason, String description);
- public void onAborted();
- }
-
- /**
- * Request to start an RTT ranging
- * <p>
- * This method is deprecated. Please use the
- * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}
- * API.
- *
- * @param params -- RTT request Parameters
- * @param listener -- Call back to inform RTT result
- * @exception throw IllegalArgumentException when params are illegal
- * throw IllegalStateException when RttCapabilities do not exist
- */
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void startRanging(RttParams[] params, RttListener listener) {
- Log.i(TAG, "Send RTT request to RTT Service");
-
- if (!mNewService.isAvailable()) {
- listener.onFailure(REASON_NOT_AVAILABLE, "");
- return;
- }
-
- RangingRequest.Builder builder = new RangingRequest.Builder();
- for (RttParams rttParams : params) {
- if (rttParams.deviceType != RTT_PEER_TYPE_AP) {
- listener.onFailure(REASON_INVALID_REQUEST, "Only AP peers are supported");
- return;
- }
-
- ScanResult reconstructed = new ScanResult();
- reconstructed.BSSID = rttParams.bssid;
- if (rttParams.requestType == RTT_TYPE_TWO_SIDED) {
- reconstructed.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
- }
- reconstructed.channelWidth = rttParams.channelWidth;
- reconstructed.frequency = rttParams.frequency;
- reconstructed.centerFreq0 = rttParams.centerFreq0;
- reconstructed.centerFreq1 = rttParams.centerFreq1;
- builder.addResponder(
- android.net.wifi.rtt.ResponderConfig.fromScanResult(reconstructed));
- }
- try {
- mNewService.startRanging(builder.build(),
- mContext.getMainExecutor(),
- new RangingResultCallback() {
- @Override
- public void onRangingFailure(int code) {
- int localCode = REASON_UNSPECIFIED;
- if (code == STATUS_CODE_FAIL_RTT_NOT_AVAILABLE) {
- localCode = REASON_NOT_AVAILABLE;
- }
- listener.onFailure(localCode, "");
- }
-
- @Override
- public void onRangingResults(List<RangingResult> results) {
- RttResult[] legacyResults = new RttResult[results.size()];
- int i = 0;
- for (RangingResult result : results) {
- legacyResults[i] = new RttResult();
- legacyResults[i].status = result.getStatus();
- legacyResults[i].bssid = result.getMacAddress().toString();
- if (result.getStatus() == RangingResult.STATUS_SUCCESS) {
- legacyResults[i].distance = result.getDistanceMm() / 10;
- legacyResults[i].distanceStandardDeviation =
- result.getDistanceStdDevMm() / 10;
- legacyResults[i].rssi = result.getRssi() * -2;
- legacyResults[i].ts = result.getRangingTimestampMillis() * 1000;
- legacyResults[i].measurementFrameNumber =
- result.getNumAttemptedMeasurements();
- legacyResults[i].successMeasurementFrameNumber =
- result.getNumSuccessfulMeasurements();
- } else {
- // just in case legacy API needed some relatively real timestamp
- legacyResults[i].ts = SystemClock.elapsedRealtime() * 1000;
- }
- i++;
- }
- listener.onSuccess(legacyResults);
- }
- });
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "startRanging: invalid arguments - " + e);
- listener.onFailure(REASON_INVALID_REQUEST, e.getMessage());
- } catch (SecurityException e) {
- Log.e(TAG, "startRanging: security exception - " + e);
- listener.onFailure(REASON_PERMISSION_DENIED, e.getMessage());
- }
- }
-
- /**
- * This method is deprecated and performs no function. Please use the {@link WifiRttManager}
- * API.
- */
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void stopRanging(RttListener listener) {
- Log.e(TAG, "stopRanging: unsupported operation - nop");
- }
-
- /**
- * Callbacks for responder operations.
- * <p>
- * A {@link ResponderCallback} is the handle to the calling client. {@link RttManager} will keep
- * a reference to the callback for the entire period when responder is enabled. The same
- * callback as used in enabling responder needs to be passed for disabling responder.
- * The client can freely destroy or reuse the callback after {@link RttManager#disableResponder}
- * is called.
- */
- @Deprecated
- public abstract static class ResponderCallback {
- /** Callback when responder is enabled. */
- public abstract void onResponderEnabled(ResponderConfig config);
- /** Callback when enabling responder failed. */
- public abstract void onResponderEnableFailure(int reason);
- // TODO: consider adding onResponderAborted once it's supported.
- }
-
- /**
- * Enable Wi-Fi RTT responder mode on the device. The enabling result will be delivered via
- * {@code callback}.
- * <p>
- * Note calling this method with the same callback when the responder is already enabled won't
- * change the responder state, a cached {@link ResponderConfig} from the last enabling will be
- * returned through the callback.
- * <p>
- * This method is deprecated and will throw an {@link UnsupportedOperationException}
- * exception. Please use the {@link WifiRttManager} API to perform a Wi-Fi Aware peer-to-peer
- * ranging.
- *
- * @param callback Callback for responder enabling/disabling result.
- * @throws IllegalArgumentException If {@code callback} is null.
- */
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void enableResponder(ResponderCallback callback) {
- throw new UnsupportedOperationException(
- "enableResponder is not supported in the adaptation layer");
- }
-
- /**
- * Disable Wi-Fi RTT responder mode on the device. The {@code callback} needs to be the
- * same one used in {@link #enableResponder(ResponderCallback)}.
- * <p>
- * Calling this method when responder isn't enabled won't have any effect. The callback can be
- * reused for enabling responder after this method is called.
- * <p>
- * This method is deprecated and will throw an {@link UnsupportedOperationException}
- * exception. Please use the {@link WifiRttManager} API to perform a Wi-Fi Aware peer-to-peer
- * ranging.
- *
- * @param callback The same callback used for enabling responder.
- * @throws IllegalArgumentException If {@code callback} is null.
- */
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void disableResponder(ResponderCallback callback) {
- throw new UnsupportedOperationException(
- "disableResponder is not supported in the adaptation layer");
- }
-
- /**
- * Configuration used for RTT responder mode. The configuration information can be used by a
- * peer device to range the responder.
- *
- * @see ScanResult
- */
- @Deprecated
- public static class ResponderConfig implements Parcelable {
-
- // TODO: make all fields final once we can get mac address from responder HAL APIs.
- /**
- * Wi-Fi mac address used for responder mode.
- */
- public String macAddress = "";
-
- /**
- * The primary 20 MHz frequency (in MHz) of the channel where responder is enabled.
- * @see ScanResult#frequency
- */
- public int frequency;
-
- /**
- * Center frequency of the channel where responder is enabled on. Only in use when channel
- * width is at least 40MHz.
- * @see ScanResult#centerFreq0
- */
- public int centerFreq0;
-
- /**
- * Center frequency of the second segment when channel width is 80 + 80 MHz.
- * @see ScanResult#centerFreq1
- */
- public int centerFreq1;
-
- /**
- * Width of the channel where responder is enabled on.
- * @see ScanResult#channelWidth
- */
- public int channelWidth;
-
- /**
- * Preamble supported by responder.
- */
- public int preamble;
-
- @NonNull
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("macAddress = ").append(macAddress)
- .append(" frequency = ").append(frequency)
- .append(" centerFreq0 = ").append(centerFreq0)
- .append(" centerFreq1 = ").append(centerFreq1)
- .append(" channelWidth = ").append(channelWidth)
- .append(" preamble = ").append(preamble);
- return builder.toString();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(macAddress);
- dest.writeInt(frequency);
- dest.writeInt(centerFreq0);
- dest.writeInt(centerFreq1);
- dest.writeInt(channelWidth);
- dest.writeInt(preamble);
- }
-
- /** Implement {@link Parcelable} interface */
- public static final @android.annotation.NonNull Parcelable.Creator<ResponderConfig> CREATOR =
- new Parcelable.Creator<ResponderConfig>() {
- @Override
- public ResponderConfig createFromParcel(Parcel in) {
- ResponderConfig config = new ResponderConfig();
- config.macAddress = in.readString();
- config.frequency = in.readInt();
- config.centerFreq0 = in.readInt();
- config.centerFreq1 = in.readInt();
- config.channelWidth = in.readInt();
- config.preamble = in.readInt();
- return config;
- }
-
- @Override
- public ResponderConfig[] newArray(int size) {
- return new ResponderConfig[size];
- }
- };
-
- }
-
- /* private methods */
- public static final int BASE = Protocol.BASE_WIFI_RTT_MANAGER;
-
- public static final int CMD_OP_START_RANGING = BASE + 0;
- public static final int CMD_OP_STOP_RANGING = BASE + 1;
- public static final int CMD_OP_FAILED = BASE + 2;
- public static final int CMD_OP_SUCCEEDED = BASE + 3;
- public static final int CMD_OP_ABORTED = BASE + 4;
- public static final int CMD_OP_ENABLE_RESPONDER = BASE + 5;
- public static final int CMD_OP_DISABLE_RESPONDER = BASE + 6;
- public static final int
- CMD_OP_ENALBE_RESPONDER_SUCCEEDED = BASE + 7;
- public static final int
- CMD_OP_ENALBE_RESPONDER_FAILED = BASE + 8;
- /** @hide */
- public static final int CMD_OP_REG_BINDER = BASE + 9;
-
- private final WifiRttManager mNewService;
- private final Context mContext;
- private RttCapabilities mRttCapabilities;
-
- /**
- * Create a new WifiScanner instance.
- * Applications will almost always want to use
- * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
- * the standard {@link android.content.Context#WIFI_RTT_SERVICE Context.WIFI_RTT_SERVICE}.
- * @param service the new WifiRttManager service
- *
- * @hide
- */
- public RttManager(@NonNull Context context, @NonNull WifiRttManager service) {
- mNewService = service;
- mContext = context;
-
- boolean rttSupported = context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_RTT);
-
- mRttCapabilities = new RttCapabilities();
- mRttCapabilities.oneSidedRttSupported = rttSupported;
- mRttCapabilities.twoSided11McRttSupported = rttSupported;
- mRttCapabilities.lciSupported = false;
- mRttCapabilities.lcrSupported = false;
- mRttCapabilities.preambleSupported = PREAMBLE_HT | PREAMBLE_VHT;
- mRttCapabilities.bwSupported = RTT_BW_40_SUPPORT | RTT_BW_80_SUPPORT;
- mRttCapabilities.responderSupported = false;
- mRttCapabilities.secureRttSupported = false;
- }
-}
-
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
deleted file mode 100644
index aa3a139..0000000
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ /dev/null
@@ -1,1144 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.wifi.WifiAnnotations.ChannelWidth;
-import android.net.wifi.WifiAnnotations.WifiStandard;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Describes information about a detected access point. In addition
- * to the attributes described here, the supplicant keeps track of
- * {@code quality}, {@code noise}, and {@code maxbitrate} attributes,
- * but does not currently report them to external clients.
- */
-public final class ScanResult implements Parcelable {
- /**
- * The network name.
- */
- public String SSID;
-
- /**
- * Ascii encoded SSID. This will replace SSID when we deprecate it. @hide
- */
- @UnsupportedAppUsage
- public WifiSsid wifiSsid;
-
- /**
- * The address of the access point.
- */
- public String BSSID;
-
- /**
- * The HESSID from the beacon.
- * @hide
- */
- @UnsupportedAppUsage
- public long hessid;
-
- /**
- * The ANQP Domain ID from the Hotspot 2.0 Indication element, if present.
- * @hide
- */
- @UnsupportedAppUsage
- public int anqpDomainId;
-
- /*
- * This field is equivalent to the |flags|, rather than the |capabilities| field
- * of the per-BSS scan results returned by WPA supplicant. See the definition of
- * |struct wpa_bss| in wpa_supplicant/bss.h for more details.
- */
- /**
- * Describes the authentication, key management, and encryption schemes
- * supported by the access point.
- */
- public String capabilities;
-
- /**
- * @hide
- * No security protocol.
- */
- @SystemApi
- public static final int PROTOCOL_NONE = 0;
- /**
- * @hide
- * Security protocol type: WPA version 1.
- */
- @SystemApi
- public static final int PROTOCOL_WPA = 1;
- /**
- * @hide
- * Security protocol type: RSN, for WPA version 2, and version 3.
- */
- @SystemApi
- public static final int PROTOCOL_RSN = 2;
- /**
- * @hide
- * Security protocol type:
- * OSU Server-only authenticated layer 2 Encryption Network.
- * Used for Hotspot 2.0.
- */
- @SystemApi
- public static final int PROTOCOL_OSEN = 3;
-
- /**
- * @hide
- * Security protocol type: WAPI.
- */
- @SystemApi
- public static final int PROTOCOL_WAPI = 4;
-
- /**
- * @hide
- * No security key management scheme.
- */
- @SystemApi
- public static final int KEY_MGMT_NONE = 0;
- /**
- * @hide
- * Security key management scheme: PSK.
- */
- @SystemApi
- public static final int KEY_MGMT_PSK = 1;
- /**
- * @hide
- * Security key management scheme: EAP.
- */
- @SystemApi
- public static final int KEY_MGMT_EAP = 2;
- /**
- * @hide
- * Security key management scheme: FT_PSK.
- */
- @SystemApi
- public static final int KEY_MGMT_FT_PSK = 3;
- /**
- * @hide
- * Security key management scheme: FT_EAP.
- */
- @SystemApi
- public static final int KEY_MGMT_FT_EAP = 4;
- /**
- * @hide
- * Security key management scheme: PSK_SHA256
- */
- @SystemApi
- public static final int KEY_MGMT_PSK_SHA256 = 5;
- /**
- * @hide
- * Security key management scheme: EAP_SHA256.
- */
- @SystemApi
- public static final int KEY_MGMT_EAP_SHA256 = 6;
- /**
- * @hide
- * Security key management scheme: OSEN.
- * Used for Hotspot 2.0.
- */
- @SystemApi
- public static final int KEY_MGMT_OSEN = 7;
- /**
- * @hide
- * Security key management scheme: SAE.
- */
- @SystemApi
- public static final int KEY_MGMT_SAE = 8;
- /**
- * @hide
- * Security key management scheme: OWE.
- */
- @SystemApi
- public static final int KEY_MGMT_OWE = 9;
- /**
- * @hide
- * Security key management scheme: SUITE_B_192.
- */
- @SystemApi
- public static final int KEY_MGMT_EAP_SUITE_B_192 = 10;
- /**
- * @hide
- * Security key management scheme: FT_SAE.
- */
- @SystemApi
- public static final int KEY_MGMT_FT_SAE = 11;
- /**
- * @hide
- * Security key management scheme: OWE in transition mode.
- */
- @SystemApi
- public static final int KEY_MGMT_OWE_TRANSITION = 12;
- /**
- * @hide
- * Security key management scheme: WAPI_PSK.
- */
- @SystemApi
- public static final int KEY_MGMT_WAPI_PSK = 13;
- /**
- * @hide
- * Security key management scheme: WAPI_CERT.
- */
- @SystemApi
- public static final int KEY_MGMT_WAPI_CERT = 14;
-
- /**
- * @hide
- * Security key management scheme: FILS_SHA256.
- */
- public static final int KEY_MGMT_FILS_SHA256 = 15;
- /**
- * @hide
- * Security key management scheme: FILS_SHA384.
- */
- public static final int KEY_MGMT_FILS_SHA384 = 16;
- /**
- * @hide
- * No cipher suite.
- */
- @SystemApi
- public static final int CIPHER_NONE = 0;
- /**
- * @hide
- * No group addressed, only used for group data cipher.
- */
- @SystemApi
- public static final int CIPHER_NO_GROUP_ADDRESSED = 1;
- /**
- * @hide
- * Cipher suite: TKIP
- */
- @SystemApi
- public static final int CIPHER_TKIP = 2;
- /**
- * @hide
- * Cipher suite: CCMP
- */
- @SystemApi
- public static final int CIPHER_CCMP = 3;
- /**
- * @hide
- * Cipher suite: GCMP
- */
- @SystemApi
- public static final int CIPHER_GCMP_256 = 4;
- /**
- * @hide
- * Cipher suite: SMS4
- */
- @SystemApi
- public static final int CIPHER_SMS4 = 5;
-
- /**
- * The detected signal level in dBm, also known as the RSSI.
- *
- * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into
- * an absolute signal level which can be displayed to a user.
- */
- public int level;
- /**
- * The primary 20 MHz frequency (in MHz) of the channel over which the client is communicating
- * with the access point.
- */
- public int frequency;
-
- /**
- * AP Channel bandwidth is 20 MHZ
- */
- public static final int CHANNEL_WIDTH_20MHZ = 0;
- /**
- * AP Channel bandwidth is 40 MHZ
- */
- public static final int CHANNEL_WIDTH_40MHZ = 1;
- /**
- * AP Channel bandwidth is 80 MHZ
- */
- public static final int CHANNEL_WIDTH_80MHZ = 2;
- /**
- * AP Channel bandwidth is 160 MHZ
- */
- public static final int CHANNEL_WIDTH_160MHZ = 3;
- /**
- * AP Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ
- */
- public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4;
-
- /**
- * Wi-Fi unknown standard
- */
- public static final int WIFI_STANDARD_UNKNOWN = 0;
-
- /**
- * Wi-Fi 802.11a/b/g
- */
- public static final int WIFI_STANDARD_LEGACY = 1;
-
- /**
- * Wi-Fi 802.11n
- */
- public static final int WIFI_STANDARD_11N = 4;
-
- /**
- * Wi-Fi 802.11ac
- */
- public static final int WIFI_STANDARD_11AC = 5;
-
- /**
- * Wi-Fi 802.11ax
- */
- public static final int WIFI_STANDARD_11AX = 6;
-
- /**
- * AP wifi standard.
- */
- private @WifiStandard int mWifiStandard;
-
- /**
- * return the AP wifi standard.
- */
- public @WifiStandard int getWifiStandard() {
- return mWifiStandard;
- }
-
- /**
- * sets the AP wifi standard.
- * @hide
- */
- public void setWifiStandard(@WifiStandard int standard) {
- mWifiStandard = standard;
- }
-
- /**
- * Convert Wi-Fi standard to string
- */
- private static @Nullable String wifiStandardToString(@WifiStandard int standard) {
- switch(standard) {
- case WIFI_STANDARD_LEGACY:
- return "legacy";
- case WIFI_STANDARD_11N:
- return "11n";
- case WIFI_STANDARD_11AC:
- return "11ac";
- case WIFI_STANDARD_11AX:
- return "11ax";
- case WIFI_STANDARD_UNKNOWN:
- return "unknown";
- }
- return null;
- }
-
- /**
- * AP Channel bandwidth; one of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ},
- * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ}
- * or {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}.
- */
- public @ChannelWidth int channelWidth;
-
- /**
- * Not used if the AP bandwidth is 20 MHz
- * If the AP use 40, 80 or 160 MHz, this is the center frequency (in MHz)
- * if the AP use 80 + 80 MHz, this is the center frequency of the first segment (in MHz)
- */
- public int centerFreq0;
-
- /**
- * Only used if the AP bandwidth is 80 + 80 MHz
- * if the AP use 80 + 80 MHz, this is the center frequency of the second segment (in MHz)
- */
- public int centerFreq1;
-
- /**
- * @deprecated use is80211mcResponder() instead
- * @hide
- */
- @UnsupportedAppUsage
- public boolean is80211McRTTResponder;
-
- /**
- * timestamp in microseconds (since boot) when
- * this result was last seen.
- */
- public long timestamp;
-
- /**
- * Timestamp representing date when this result was last seen, in milliseconds from 1970
- * {@hide}
- */
- @UnsupportedAppUsage
- public long seen;
-
- /**
- * On devices with multiple hardware radio chains, this class provides metadata about
- * each radio chain that was used to receive this scan result (probe response or beacon).
- * {@hide}
- */
- public static class RadioChainInfo {
- /** Vendor defined id for a radio chain. */
- public int id;
- /** Detected signal level in dBm (also known as the RSSI) on this radio chain. */
- public int level;
-
- @Override
- public String toString() {
- return "RadioChainInfo: id=" + id + ", level=" + level;
- }
-
- @Override
- public boolean equals(Object otherObj) {
- if (this == otherObj) {
- return true;
- }
- if (!(otherObj instanceof RadioChainInfo)) {
- return false;
- }
- RadioChainInfo other = (RadioChainInfo) otherObj;
- return id == other.id && level == other.level;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id, level);
- }
- };
-
- /**
- * Information about the list of the radio chains used to receive this scan result
- * (probe response or beacon).
- *
- * For Example: On devices with 2 hardware radio chains, this list could hold 1 or 2
- * entries based on whether this scan result was received using one or both the chains.
- * {@hide}
- */
- public RadioChainInfo[] radioChainInfos;
-
- /**
- * Status indicating the scan result does not correspond to a user's saved configuration
- * @hide
- * @removed
- */
- @SystemApi
- public boolean untrusted;
-
- /**
- * Number of time autojoin used it
- * @hide
- */
- @UnsupportedAppUsage
- public int numUsage;
-
- /**
- * The approximate distance to the AP in centimeter, if available. Else
- * {@link UNSPECIFIED}.
- * {@hide}
- */
- @UnsupportedAppUsage
- public int distanceCm;
-
- /**
- * The standard deviation of the distance to the access point, if available.
- * Else {@link UNSPECIFIED}.
- * {@hide}
- */
- @UnsupportedAppUsage
- public int distanceSdCm;
-
- /** {@hide} */
- public static final long FLAG_PASSPOINT_NETWORK = 0x0000000000000001;
-
- /** {@hide} */
- public static final long FLAG_80211mc_RESPONDER = 0x0000000000000002;
-
- /*
- * These flags are specific to the ScanResult class, and are not related to the |flags|
- * field of the per-BSS scan results from WPA supplicant.
- */
- /**
- * Defines flags; such as {@link #FLAG_PASSPOINT_NETWORK}.
- * {@hide}
- */
- @UnsupportedAppUsage
- public long flags;
-
- /**
- * sets a flag in {@link #flags} field
- * @param flag flag to set
- * @hide
- */
- public void setFlag(long flag) {
- flags |= flag;
- }
-
- /**
- * clears a flag in {@link #flags} field
- * @param flag flag to set
- * @hide
- */
- public void clearFlag(long flag) {
- flags &= ~flag;
- }
-
- public boolean is80211mcResponder() {
- return (flags & FLAG_80211mc_RESPONDER) != 0;
- }
-
- public boolean isPasspointNetwork() {
- return (flags & FLAG_PASSPOINT_NETWORK) != 0;
- }
-
- /**
- * Indicates venue name (such as 'San Francisco Airport') published by access point; only
- * available on Passpoint network and if published by access point.
- */
- public CharSequence venueName;
-
- /**
- * Indicates Passpoint operator name published by access point.
- */
- public CharSequence operatorFriendlyName;
-
- /**
- * {@hide}
- */
- public final static int UNSPECIFIED = -1;
-
- /**
- * 2.4 GHz band first channel number
- * @hide
- */
- public static final int BAND_24_GHZ_FIRST_CH_NUM = 1;
- /**
- * 2.4 GHz band last channel number
- * @hide
- */
- public static final int BAND_24_GHZ_LAST_CH_NUM = 14;
- /**
- * 2.4 GHz band frequency of first channel in MHz
- * @hide
- */
- public static final int BAND_24_GHZ_START_FREQ_MHZ = 2412;
- /**
- * 2.4 GHz band frequency of last channel in MHz
- * @hide
- */
- public static final int BAND_24_GHZ_END_FREQ_MHZ = 2484;
-
- /**
- * 5 GHz band first channel number
- * @hide
- */
- public static final int BAND_5_GHZ_FIRST_CH_NUM = 32;
- /**
- * 5 GHz band last channel number
- * @hide
- */
- public static final int BAND_5_GHZ_LAST_CH_NUM = 173;
- /**
- * 5 GHz band frequency of first channel in MHz
- * @hide
- */
- public static final int BAND_5_GHZ_START_FREQ_MHZ = 5160;
- /**
- * 5 GHz band frequency of last channel in MHz
- * @hide
- */
- public static final int BAND_5_GHZ_END_FREQ_MHZ = 5865;
-
- /**
- * 6 GHz band first channel number
- * @hide
- */
- public static final int BAND_6_GHZ_FIRST_CH_NUM = 1;
- /**
- * 6 GHz band last channel number
- * @hide
- */
- public static final int BAND_6_GHZ_LAST_CH_NUM = 233;
- /**
- * 6 GHz band frequency of first channel in MHz
- * @hide
- */
- public static final int BAND_6_GHZ_START_FREQ_MHZ = 5945;
- /**
- * 6 GHz band frequency of last channel in MHz
- * @hide
- */
- public static final int BAND_6_GHZ_END_FREQ_MHZ = 7105;
-
- /**
- * Utility function to check if a frequency within 2.4 GHz band
- * @param freqMhz frequency in MHz
- * @return true if within 2.4GHz, false otherwise
- *
- * @hide
- */
- public static boolean is24GHz(int freqMhz) {
- return freqMhz >= BAND_24_GHZ_START_FREQ_MHZ && freqMhz <= BAND_24_GHZ_END_FREQ_MHZ;
- }
-
- /**
- * Utility function to check if a frequency within 5 GHz band
- * @param freqMhz frequency in MHz
- * @return true if within 5GHz, false otherwise
- *
- * @hide
- */
- public static boolean is5GHz(int freqMhz) {
- return freqMhz >= BAND_5_GHZ_START_FREQ_MHZ && freqMhz <= BAND_5_GHZ_END_FREQ_MHZ;
- }
-
- /**
- * Utility function to check if a frequency within 6 GHz band
- * @param freqMhz
- * @return true if within 6GHz, false otherwise
- *
- * @hide
- */
- public static boolean is6GHz(int freqMhz) {
- return freqMhz >= BAND_6_GHZ_START_FREQ_MHZ && freqMhz <= BAND_6_GHZ_END_FREQ_MHZ;
- }
-
- /**
- * Utility function to convert channel number/band to frequency in MHz
- * @param channel number to convert
- * @param band of channel to convert
- * @return center frequency in Mhz of the channel, {@link UNSPECIFIED} if no match
- *
- * @hide
- */
- public static int convertChannelToFrequencyMhz(int channel, @WifiScanner.WifiBand int band) {
- if (band == WifiScanner.WIFI_BAND_24_GHZ) {
- // Special case
- if (channel == 14) {
- return 2484;
- } else if (channel >= BAND_24_GHZ_FIRST_CH_NUM && channel <= BAND_24_GHZ_LAST_CH_NUM) {
- return ((channel - BAND_24_GHZ_FIRST_CH_NUM) * 5) + BAND_24_GHZ_START_FREQ_MHZ;
- } else {
- return UNSPECIFIED;
- }
- }
- if (band == WifiScanner.WIFI_BAND_5_GHZ) {
- if (channel >= BAND_5_GHZ_FIRST_CH_NUM && channel <= BAND_5_GHZ_LAST_CH_NUM) {
- return ((channel - BAND_5_GHZ_FIRST_CH_NUM) * 5) + BAND_5_GHZ_START_FREQ_MHZ;
- } else {
- return UNSPECIFIED;
- }
- }
- if (band == WifiScanner.WIFI_BAND_6_GHZ) {
- if (channel >= BAND_6_GHZ_FIRST_CH_NUM && channel <= BAND_6_GHZ_LAST_CH_NUM) {
- return ((channel - BAND_6_GHZ_FIRST_CH_NUM) * 5) + BAND_6_GHZ_START_FREQ_MHZ;
- } else {
- return UNSPECIFIED;
- }
- }
- return UNSPECIFIED;
- }
-
- /**
- * Utility function to convert frequency in MHz to channel number
- * @param freqMhz frequency in MHz
- * @return channel number associated with given frequency, {@link UNSPECIFIED} if no match
- *
- * @hide
- */
- public static int convertFrequencyMhzToChannel(int freqMhz) {
- // Special case
- if (freqMhz == 2484) {
- return 14;
- } else if (is24GHz(freqMhz)) {
- return (freqMhz - BAND_24_GHZ_START_FREQ_MHZ) / 5 + BAND_24_GHZ_FIRST_CH_NUM;
- } else if (is5GHz(freqMhz)) {
- return ((freqMhz - BAND_5_GHZ_START_FREQ_MHZ) / 5) + BAND_5_GHZ_FIRST_CH_NUM;
- } else if (is6GHz(freqMhz)) {
- return ((freqMhz - BAND_6_GHZ_START_FREQ_MHZ) / 5) + BAND_6_GHZ_FIRST_CH_NUM;
- }
-
- return UNSPECIFIED;
- }
-
- /**
- * @hide
- */
- public boolean is24GHz() {
- return ScanResult.is24GHz(frequency);
- }
-
- /**
- * @hide
- */
- public boolean is5GHz() {
- return ScanResult.is5GHz(frequency);
- }
-
- /**
- * @hide
- */
- public boolean is6GHz() {
- return ScanResult.is6GHz(frequency);
- }
-
- /**
- * @hide
- * anqp lines from supplicant BSS response
- */
- @UnsupportedAppUsage
- public List<String> anqpLines;
-
- /**
- * information elements from beacon.
- */
- public static class InformationElement {
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_SSID = 0;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_SUPPORTED_RATES = 1;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_TIM = 5;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_BSS_LOAD = 11;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_ERP = 42;
- /** @hide */
- public static final int EID_HT_CAPABILITIES = 45;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_RSN = 48;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_EXTENDED_SUPPORTED_RATES = 50;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_HT_OPERATION = 61;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_INTERWORKING = 107;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_ROAMING_CONSORTIUM = 111;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_EXTENDED_CAPS = 127;
- /** @hide */
- public static final int EID_VHT_CAPABILITIES = 191;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_VHT_OPERATION = 192;
- /** @hide */
- @UnsupportedAppUsage
- public static final int EID_VSA = 221;
- /** @hide */
- public static final int EID_EXTENSION_PRESENT = 255;
-
- // Extension IDs
- /** @hide */
- public static final int EID_EXT_HE_CAPABILITIES = 35;
- /** @hide */
- public static final int EID_EXT_HE_OPERATION = 36;
-
- /** @hide */
- @UnsupportedAppUsage
- public int id;
- /** @hide */
- public int idExt;
-
- /** @hide */
- @UnsupportedAppUsage
- public byte[] bytes;
-
- /** @hide */
- public InformationElement() {
- }
-
- public InformationElement(@NonNull InformationElement rhs) {
- this.id = rhs.id;
- this.idExt = rhs.idExt;
- this.bytes = rhs.bytes.clone();
- }
-
- /**
- * The element ID of the information element. Defined in the IEEE 802.11-2016 spec
- * Table 9-77.
- */
- public int getId() {
- return id;
- }
-
- /**
- * The element ID Extension of the information element. Defined in the IEEE 802.11-2016 spec
- * Table 9-77.
- */
- public int getIdExt() {
- return idExt;
- }
-
- /**
- * Get the specific content of the information element.
- */
- @NonNull
- public ByteBuffer getBytes() {
- return ByteBuffer.wrap(bytes).asReadOnlyBuffer();
- }
- }
-
- /**
- * information elements found in the beacon.
- * @hide
- */
- @UnsupportedAppUsage
- public InformationElement[] informationElements;
- /**
- * Get all information elements found in the beacon.
- */
- @NonNull
- public List<InformationElement> getInformationElements() {
- return Collections.unmodifiableList(Arrays.asList(informationElements));
- }
-
- /** ANQP response elements.
- * @hide
- */
- public AnqpInformationElement[] anqpElements;
-
- /** {@hide} */
- public ScanResult(WifiSsid wifiSsid, String BSSID, long hessid, int anqpDomainId,
- byte[] osuProviders, String caps, int level, int frequency, long tsf) {
- this.wifiSsid = wifiSsid;
- this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiManager.UNKNOWN_SSID;
- this.BSSID = BSSID;
- this.hessid = hessid;
- this.anqpDomainId = anqpDomainId;
- if (osuProviders != null) {
- this.anqpElements = new AnqpInformationElement[1];
- this.anqpElements[0] =
- new AnqpInformationElement(AnqpInformationElement.HOTSPOT20_VENDOR_ID,
- AnqpInformationElement.HS_OSU_PROVIDERS, osuProviders);
- }
- this.capabilities = caps;
- this.level = level;
- this.frequency = frequency;
- this.timestamp = tsf;
- this.distanceCm = UNSPECIFIED;
- this.distanceSdCm = UNSPECIFIED;
- this.channelWidth = UNSPECIFIED;
- this.centerFreq0 = UNSPECIFIED;
- this.centerFreq1 = UNSPECIFIED;
- this.flags = 0;
- this.radioChainInfos = null;
- this.mWifiStandard = WIFI_STANDARD_UNKNOWN;
- }
-
- /** {@hide} */
- public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
- long tsf, int distCm, int distSdCm) {
- this.wifiSsid = wifiSsid;
- this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiManager.UNKNOWN_SSID;
- this.BSSID = BSSID;
- this.capabilities = caps;
- this.level = level;
- this.frequency = frequency;
- this.timestamp = tsf;
- this.distanceCm = distCm;
- this.distanceSdCm = distSdCm;
- this.channelWidth = UNSPECIFIED;
- this.centerFreq0 = UNSPECIFIED;
- this.centerFreq1 = UNSPECIFIED;
- this.flags = 0;
- this.radioChainInfos = null;
- this.mWifiStandard = WIFI_STANDARD_UNKNOWN;
- }
-
- /** {@hide} */
- public ScanResult(String Ssid, String BSSID, long hessid, int anqpDomainId, String caps,
- int level, int frequency,
- long tsf, int distCm, int distSdCm, int channelWidth, int centerFreq0, int centerFreq1,
- boolean is80211McRTTResponder) {
- this.SSID = Ssid;
- this.BSSID = BSSID;
- this.hessid = hessid;
- this.anqpDomainId = anqpDomainId;
- this.capabilities = caps;
- this.level = level;
- this.frequency = frequency;
- this.timestamp = tsf;
- this.distanceCm = distCm;
- this.distanceSdCm = distSdCm;
- this.channelWidth = channelWidth;
- this.centerFreq0 = centerFreq0;
- this.centerFreq1 = centerFreq1;
- if (is80211McRTTResponder) {
- this.flags = FLAG_80211mc_RESPONDER;
- } else {
- this.flags = 0;
- }
- this.radioChainInfos = null;
- this.mWifiStandard = WIFI_STANDARD_UNKNOWN;
- }
-
- /** {@hide} */
- public ScanResult(WifiSsid wifiSsid, String Ssid, String BSSID, long hessid, int anqpDomainId,
- String caps, int level,
- int frequency, long tsf, int distCm, int distSdCm, int channelWidth,
- int centerFreq0, int centerFreq1, boolean is80211McRTTResponder) {
- this(Ssid, BSSID, hessid, anqpDomainId, caps, level, frequency, tsf, distCm,
- distSdCm, channelWidth, centerFreq0, centerFreq1, is80211McRTTResponder);
- this.wifiSsid = wifiSsid;
- }
-
- /** copy constructor */
- public ScanResult(@NonNull ScanResult source) {
- if (source != null) {
- wifiSsid = source.wifiSsid;
- SSID = source.SSID;
- BSSID = source.BSSID;
- hessid = source.hessid;
- anqpDomainId = source.anqpDomainId;
- informationElements = source.informationElements;
- anqpElements = source.anqpElements;
- capabilities = source.capabilities;
- level = source.level;
- frequency = source.frequency;
- channelWidth = source.channelWidth;
- centerFreq0 = source.centerFreq0;
- centerFreq1 = source.centerFreq1;
- timestamp = source.timestamp;
- distanceCm = source.distanceCm;
- distanceSdCm = source.distanceSdCm;
- seen = source.seen;
- untrusted = source.untrusted;
- numUsage = source.numUsage;
- venueName = source.venueName;
- operatorFriendlyName = source.operatorFriendlyName;
- flags = source.flags;
- radioChainInfos = source.radioChainInfos;
- this.mWifiStandard = source.mWifiStandard;
- }
- }
-
- /** Construct an empty scan result. */
- public ScanResult() {
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- String none = "<none>";
-
- sb.append("SSID: ")
- .append(wifiSsid == null ? WifiManager.UNKNOWN_SSID : wifiSsid)
- .append(", BSSID: ")
- .append(BSSID == null ? none : BSSID)
- .append(", capabilities: ")
- .append(capabilities == null ? none : capabilities)
- .append(", level: ")
- .append(level)
- .append(", frequency: ")
- .append(frequency)
- .append(", timestamp: ")
- .append(timestamp);
- sb.append(", distance: ").append((distanceCm != UNSPECIFIED ? distanceCm : "?")).
- append("(cm)");
- sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")).
- append("(cm)");
-
- sb.append(", passpoint: ");
- sb.append(((flags & FLAG_PASSPOINT_NETWORK) != 0) ? "yes" : "no");
- sb.append(", ChannelBandwidth: ").append(channelWidth);
- sb.append(", centerFreq0: ").append(centerFreq0);
- sb.append(", centerFreq1: ").append(centerFreq1);
- sb.append(", standard: ").append(wifiStandardToString(mWifiStandard));
- sb.append(", 80211mcResponder: ");
- sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported");
- sb.append(", Radio Chain Infos: ").append(Arrays.toString(radioChainInfos));
- return sb.toString();
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- if (wifiSsid != null) {
- dest.writeInt(1);
- wifiSsid.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- dest.writeString(SSID);
- dest.writeString(BSSID);
- dest.writeLong(hessid);
- dest.writeInt(anqpDomainId);
- dest.writeString(capabilities);
- dest.writeInt(level);
- dest.writeInt(frequency);
- dest.writeLong(timestamp);
- dest.writeInt(distanceCm);
- dest.writeInt(distanceSdCm);
- dest.writeInt(channelWidth);
- dest.writeInt(centerFreq0);
- dest.writeInt(centerFreq1);
- dest.writeInt(mWifiStandard);
- dest.writeLong(seen);
- dest.writeInt(untrusted ? 1 : 0);
- dest.writeInt(numUsage);
- dest.writeString((venueName != null) ? venueName.toString() : "");
- dest.writeString((operatorFriendlyName != null) ? operatorFriendlyName.toString() : "");
- dest.writeLong(this.flags);
-
- if (informationElements != null) {
- dest.writeInt(informationElements.length);
- for (int i = 0; i < informationElements.length; i++) {
- dest.writeInt(informationElements[i].id);
- dest.writeInt(informationElements[i].idExt);
- dest.writeInt(informationElements[i].bytes.length);
- dest.writeByteArray(informationElements[i].bytes);
- }
- } else {
- dest.writeInt(0);
- }
-
- if (anqpLines != null) {
- dest.writeInt(anqpLines.size());
- for (int i = 0; i < anqpLines.size(); i++) {
- dest.writeString(anqpLines.get(i));
- }
- }
- else {
- dest.writeInt(0);
- }
- if (anqpElements != null) {
- dest.writeInt(anqpElements.length);
- for (AnqpInformationElement element : anqpElements) {
- dest.writeInt(element.getVendorId());
- dest.writeInt(element.getElementId());
- dest.writeInt(element.getPayload().length);
- dest.writeByteArray(element.getPayload());
- }
- } else {
- dest.writeInt(0);
- }
-
- if (radioChainInfos != null) {
- dest.writeInt(radioChainInfos.length);
- for (int i = 0; i < radioChainInfos.length; i++) {
- dest.writeInt(radioChainInfos[i].id);
- dest.writeInt(radioChainInfos[i].level);
- }
- } else {
- dest.writeInt(0);
- }
- }
-
- /** Implement the Parcelable interface */
- public static final @NonNull Creator<ScanResult> CREATOR =
- new Creator<ScanResult>() {
- public ScanResult createFromParcel(Parcel in) {
- WifiSsid wifiSsid = null;
- if (in.readInt() == 1) {
- wifiSsid = WifiSsid.CREATOR.createFromParcel(in);
- }
- ScanResult sr = new ScanResult(
- wifiSsid,
- in.readString(), /* SSID */
- in.readString(), /* BSSID */
- in.readLong(), /* HESSID */
- in.readInt(), /* ANQP Domain ID */
- in.readString(), /* capabilities */
- in.readInt(), /* level */
- in.readInt(), /* frequency */
- in.readLong(), /* timestamp */
- in.readInt(), /* distanceCm */
- in.readInt(), /* distanceSdCm */
- in.readInt(), /* channelWidth */
- in.readInt(), /* centerFreq0 */
- in.readInt(), /* centerFreq1 */
- false /* rtt responder,
- fixed with flags below */
- );
-
- sr.mWifiStandard = in.readInt();
- sr.seen = in.readLong();
- sr.untrusted = in.readInt() != 0;
- sr.numUsage = in.readInt();
- sr.venueName = in.readString();
- sr.operatorFriendlyName = in.readString();
- sr.flags = in.readLong();
- int n = in.readInt();
- if (n != 0) {
- sr.informationElements = new InformationElement[n];
- for (int i = 0; i < n; i++) {
- sr.informationElements[i] = new InformationElement();
- sr.informationElements[i].id = in.readInt();
- sr.informationElements[i].idExt = in.readInt();
- int len = in.readInt();
- sr.informationElements[i].bytes = new byte[len];
- in.readByteArray(sr.informationElements[i].bytes);
- }
- }
-
- n = in.readInt();
- if (n != 0) {
- sr.anqpLines = new ArrayList<String>();
- for (int i = 0; i < n; i++) {
- sr.anqpLines.add(in.readString());
- }
- }
- n = in.readInt();
- if (n != 0) {
- sr.anqpElements = new AnqpInformationElement[n];
- for (int i = 0; i < n; i++) {
- int vendorId = in.readInt();
- int elementId = in.readInt();
- int len = in.readInt();
- byte[] payload = new byte[len];
- in.readByteArray(payload);
- sr.anqpElements[i] =
- new AnqpInformationElement(vendorId, elementId, payload);
- }
- }
- n = in.readInt();
- if (n != 0) {
- sr.radioChainInfos = new RadioChainInfo[n];
- for (int i = 0; i < n; i++) {
- sr.radioChainInfos[i] = new RadioChainInfo();
- sr.radioChainInfos[i].id = in.readInt();
- sr.radioChainInfos[i].level = in.readInt();
- }
- }
- return sr;
- }
-
- public ScanResult[] newArray(int size) {
- return new ScanResult[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java
deleted file mode 100644
index dcb57ec..0000000
--- a/wifi/java/android/net/wifi/SoftApCapability.java
+++ /dev/null
@@ -1,186 +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.net.wifi;
-
-import android.annotation.LongDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * A class representing capability of the SoftAp.
- * {@see WifiManager}
- *
- * @hide
- */
-@SystemApi
-public final class SoftApCapability implements Parcelable {
-
- /**
- * Support for automatic channel selection in driver (ACS).
- * Driver will auto select best channel based on interference to optimize performance.
- *
- * flag when {@link R.bool.config_wifi_softap_acs_supported)} is true.
- *
- * <p>
- * Use {@link WifiManager.SoftApCallback#onInfoChanged(SoftApInfo)} and
- * {@link SoftApInfo#getFrequency} and {@link SoftApInfo#getBandwidth} to get
- * driver channel selection result.
- */
- public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1 << 0;
-
- /**
- * Support for client force disconnect.
- * flag when {@link R.bool.config_wifi_sofap_client_force_disconnect_supported)} is true
- *
- * <p>
- * Several Soft AP client control features, e.g. specifying the maximum number of
- * Soft AP clients, only work when this feature support is present.
- * Check feature support before invoking
- * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)}
- */
- public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1;
-
-
- /**
- * Support for WPA3 Simultaneous Authentication of Equals (WPA3-SAE).
- *
- * flag when {@link config_wifi_softap_sae_supported)} is true.
- */
- public static final long SOFTAP_FEATURE_WPA3_SAE = 1 << 2;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @LongDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = {
- SOFTAP_FEATURE_ACS_OFFLOAD,
- SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT,
- SOFTAP_FEATURE_WPA3_SAE,
- })
- public @interface HotspotFeatures {}
-
- private @HotspotFeatures long mSupportedFeatures = 0;
-
- private int mMaximumSupportedClientNumber;
-
- /**
- * Get the maximum supported client numbers which AP resides on.
- */
- public int getMaxSupportedClients() {
- return mMaximumSupportedClientNumber;
- }
-
- /**
- * Set the maximum supported client numbers which AP resides on.
- *
- * @param maxClient maximum supported client numbers for the softap.
- * @hide
- */
- public void setMaxSupportedClients(int maxClient) {
- mMaximumSupportedClientNumber = maxClient;
- }
-
- /**
- * Returns true when all of the queried features are supported, otherwise false.
- *
- * @param features One or combination of the following features:
- * {@link #SOFTAP_FEATURE_ACS_OFFLOAD}, {@link #SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} or
- * {@link #SOFTAP_FEATURE_WPA3_SAE}.
- */
- public boolean areFeaturesSupported(@HotspotFeatures long features) {
- return (mSupportedFeatures & features) == features;
- }
-
- /**
- * @hide
- */
- public SoftApCapability(@Nullable SoftApCapability source) {
- if (source != null) {
- mSupportedFeatures = source.mSupportedFeatures;
- mMaximumSupportedClientNumber = source.mMaximumSupportedClientNumber;
- }
- }
-
- /**
- * Constructor with combination of the feature.
- * Zero to no supported feature.
- *
- * @param features One or combination of the following features:
- * {@link #SOFTAP_FEATURE_ACS_OFFLOAD}, {@link #SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} or
- * {@link #SOFTAP_FEATURE_WPA3_SAE}.
- * @hide
- */
- public SoftApCapability(@HotspotFeatures long features) {
- mSupportedFeatures = features;
- }
-
- @Override
- /** Implement the Parcelable interface. */
- public int describeContents() {
- return 0;
- }
-
- @Override
- /** Implement the Parcelable interface */
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeLong(mSupportedFeatures);
- dest.writeInt(mMaximumSupportedClientNumber);
- }
-
- @NonNull
- /** Implement the Parcelable interface */
- public static final Creator<SoftApCapability> CREATOR = new Creator<SoftApCapability>() {
- public SoftApCapability createFromParcel(Parcel in) {
- long supportedFeatures = in.readLong();
- SoftApCapability capability = new SoftApCapability(supportedFeatures);
- capability.mMaximumSupportedClientNumber = in.readInt();
- return capability;
- }
-
- public SoftApCapability[] newArray(int size) {
- return new SoftApCapability[size];
- }
- };
-
- @NonNull
- @Override
- public String toString() {
- StringBuilder sbuf = new StringBuilder();
- sbuf.append("SupportedFeatures=").append(mSupportedFeatures);
- sbuf.append("MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber);
- return sbuf.toString();
- }
-
- @Override
- public boolean equals(@NonNull Object o) {
- if (this == o) return true;
- if (!(o instanceof SoftApCapability)) return false;
- SoftApCapability capability = (SoftApCapability) o;
- return mSupportedFeatures == capability.mSupportedFeatures
- && mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mSupportedFeatures, mMaximumSupportedClientNumber);
- }
-}
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
deleted file mode 100644
index a5e76e6..0000000
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ /dev/null
@@ -1,972 +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.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Configuration for a soft access point (a.k.a. Soft AP, SAP, Hotspot).
- *
- * This is input for the framework provided by a client app, i.e. it exposes knobs to instruct the
- * framework how it should configure a hotspot.
- *
- * System apps can use this to configure a tethered hotspot using
- * {@code WifiManager#startTetheredHotspot(SoftApConfiguration)} and
- * {@code WifiManager#setSoftApConfiguration(SoftApConfiguration)}
- * or local-only hotspot using
- * {@code WifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor,
- * WifiManager.LocalOnlyHotspotCallback)}.
- *
- * Instances of this class are immutable; use {@link SoftApConfiguration.Builder} and its methods to
- * create a new instance.
- *
- */
-public final class SoftApConfiguration implements Parcelable {
-
- private static final String TAG = "SoftApConfiguration";
-
- @VisibleForTesting
- static final int PSK_MIN_LEN = 8;
-
- @VisibleForTesting
- static final int PSK_MAX_LEN = 63;
-
- /**
- * 2GHz band.
- * @hide
- */
- @SystemApi
- public static final int BAND_2GHZ = 1 << 0;
-
- /**
- * 5GHz band.
- * @hide
- */
- @SystemApi
- public static final int BAND_5GHZ = 1 << 1;
-
- /**
- * 6GHz band.
- * @hide
- */
- @SystemApi
- public static final int BAND_6GHZ = 1 << 2;
-
- /**
- * Device is allowed to choose the optimal band (2Ghz, 5Ghz, 6Ghz) based on device capability,
- * operating country code and current radio conditions.
- * @hide
- */
- @SystemApi
- public static final int BAND_ANY = BAND_2GHZ | BAND_5GHZ | BAND_6GHZ;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, prefix = { "BAND_TYPE_" }, value = {
- BAND_2GHZ,
- BAND_5GHZ,
- BAND_6GHZ,
- })
- public @interface BandType {}
-
- private static boolean isBandValid(@BandType int band) {
- return ((band != 0) && ((band & ~BAND_ANY) == 0));
- }
-
- private static final int MIN_CH_2G_BAND = 1;
- private static final int MAX_CH_2G_BAND = 14;
- private static final int MIN_CH_5G_BAND = 34;
- private static final int MAX_CH_5G_BAND = 196;
- private static final int MIN_CH_6G_BAND = 1;
- private static final int MAX_CH_6G_BAND = 253;
-
-
-
- private static boolean isChannelBandPairValid(int channel, @BandType int band) {
- switch (band) {
- case BAND_2GHZ:
- if (channel < MIN_CH_2G_BAND || channel > MAX_CH_2G_BAND) {
- return false;
- }
- break;
-
- case BAND_5GHZ:
- if (channel < MIN_CH_5G_BAND || channel > MAX_CH_5G_BAND) {
- return false;
- }
- break;
-
- case BAND_6GHZ:
- if (channel < MIN_CH_6G_BAND || channel > MAX_CH_6G_BAND) {
- return false;
- }
- break;
- default:
- return false;
- }
- return true;
- }
-
- /**
- * SSID for the AP, or null for a framework-determined SSID.
- */
- private final @Nullable String mSsid;
-
- /**
- * BSSID for the AP, or null to use a framework-determined BSSID.
- */
- private final @Nullable MacAddress mBssid;
-
- /**
- * Pre-shared key for WPA2-PSK or WPA3-SAE-Transition or WPA3-SAE encryption which depends on
- * the security type.
- */
- private final @Nullable String mPassphrase;
-
- /**
- * This is a network that does not broadcast its SSID, so an
- * SSID-specific probe request must be used for scans.
- */
- private final boolean mHiddenSsid;
-
- /**
- * The operating band of the AP.
- * One or combination of the following band type:
- * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, {@link #BAND_6GHZ}.
- */
- private final @BandType int mBand;
-
- /**
- * The operating channel of the AP.
- */
- private final int mChannel;
-
- /**
- * The maximim allowed number of clients that can associate to the AP.
- */
- private final int mMaxNumberOfClients;
-
- /**
- * The operating security type of the AP.
- * One of the following security types:
- * {@link #SECURITY_TYPE_OPEN},
- * {@link #SECURITY_TYPE_WPA2_PSK},
- * {@link #SECURITY_TYPE_WPA3_SAE_TRANSITION},
- * {@link #SECURITY_TYPE_WPA3_SAE}
- */
- private final @SecurityType int mSecurityType;
-
- /**
- * The flag to indicate client need to authorize by user
- * when client is connecting to AP.
- */
- private final boolean mClientControlByUser;
-
- /**
- * The list of blocked client that can't associate to the AP.
- */
- private final List<MacAddress> mBlockedClientList;
-
- /**
- * The list of allowed client that can associate to the AP.
- */
- private final List<MacAddress> mAllowedClientList;
-
- /**
- * Whether auto shutdown of soft AP is enabled or not.
- */
- private final boolean mAutoShutdownEnabled;
-
- /**
- * Delay in milliseconds before shutting down soft AP when
- * there are no connected devices.
- */
- private final long mShutdownTimeoutMillis;
-
- /**
- * THe definition of security type OPEN.
- */
- public static final int SECURITY_TYPE_OPEN = 0;
-
- /**
- * The definition of security type WPA2-PSK.
- */
- public static final int SECURITY_TYPE_WPA2_PSK = 1;
-
- /**
- * The definition of security type WPA3-SAE Transition mode.
- */
- public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2;
-
- /**
- * The definition of security type WPA3-SAE.
- */
- public static final int SECURITY_TYPE_WPA3_SAE = 3;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "SECURITY_TYPE_" }, value = {
- SECURITY_TYPE_OPEN,
- SECURITY_TYPE_WPA2_PSK,
- SECURITY_TYPE_WPA3_SAE_TRANSITION,
- SECURITY_TYPE_WPA3_SAE,
- })
- public @interface SecurityType {}
-
- /** Private constructor for Builder and Parcelable implementation. */
- private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid,
- @Nullable String passphrase, boolean hiddenSsid, @BandType int band, int channel,
- @SecurityType int securityType, int maxNumberOfClients, boolean shutdownTimeoutEnabled,
- long shutdownTimeoutMillis, boolean clientControlByUser,
- @NonNull List<MacAddress> blockedList, @NonNull List<MacAddress> allowedList) {
- mSsid = ssid;
- mBssid = bssid;
- mPassphrase = passphrase;
- mHiddenSsid = hiddenSsid;
- mBand = band;
- mChannel = channel;
- mSecurityType = securityType;
- mMaxNumberOfClients = maxNumberOfClients;
- mAutoShutdownEnabled = shutdownTimeoutEnabled;
- mShutdownTimeoutMillis = shutdownTimeoutMillis;
- mClientControlByUser = clientControlByUser;
- mBlockedClientList = new ArrayList<>(blockedList);
- mAllowedClientList = new ArrayList<>(allowedList);
- }
-
- @Override
- public boolean equals(Object otherObj) {
- if (this == otherObj) {
- return true;
- }
- if (!(otherObj instanceof SoftApConfiguration)) {
- return false;
- }
- SoftApConfiguration other = (SoftApConfiguration) otherObj;
- return Objects.equals(mSsid, other.mSsid)
- && Objects.equals(mBssid, other.mBssid)
- && Objects.equals(mPassphrase, other.mPassphrase)
- && mHiddenSsid == other.mHiddenSsid
- && mBand == other.mBand
- && mChannel == other.mChannel
- && mSecurityType == other.mSecurityType
- && mMaxNumberOfClients == other.mMaxNumberOfClients
- && mAutoShutdownEnabled == other.mAutoShutdownEnabled
- && mShutdownTimeoutMillis == other.mShutdownTimeoutMillis
- && mClientControlByUser == other.mClientControlByUser
- && Objects.equals(mBlockedClientList, other.mBlockedClientList)
- && Objects.equals(mAllowedClientList, other.mAllowedClientList);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mSsid, mBssid, mPassphrase, mHiddenSsid,
- mBand, mChannel, mSecurityType, mMaxNumberOfClients, mAutoShutdownEnabled,
- mShutdownTimeoutMillis, mClientControlByUser, mBlockedClientList,
- mAllowedClientList);
- }
-
- @Override
- public String toString() {
- StringBuilder sbuf = new StringBuilder();
- sbuf.append("ssid=").append(mSsid);
- if (mBssid != null) sbuf.append(" \n bssid=").append(mBssid.toString());
- sbuf.append(" \n Passphrase =").append(
- TextUtils.isEmpty(mPassphrase) ? "<empty>" : "<non-empty>");
- sbuf.append(" \n HiddenSsid =").append(mHiddenSsid);
- sbuf.append(" \n Band =").append(mBand);
- sbuf.append(" \n Channel =").append(mChannel);
- sbuf.append(" \n SecurityType=").append(getSecurityType());
- sbuf.append(" \n MaxClient=").append(mMaxNumberOfClients);
- sbuf.append(" \n AutoShutdownEnabled=").append(mAutoShutdownEnabled);
- sbuf.append(" \n ShutdownTimeoutMillis=").append(mShutdownTimeoutMillis);
- sbuf.append(" \n ClientControlByUser=").append(mClientControlByUser);
- sbuf.append(" \n BlockedClientList=").append(mBlockedClientList);
- sbuf.append(" \n AllowedClientList=").append(mAllowedClientList);
- return sbuf.toString();
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString(mSsid);
- dest.writeParcelable(mBssid, flags);
- dest.writeString(mPassphrase);
- dest.writeBoolean(mHiddenSsid);
- dest.writeInt(mBand);
- dest.writeInt(mChannel);
- dest.writeInt(mSecurityType);
- dest.writeInt(mMaxNumberOfClients);
- dest.writeBoolean(mAutoShutdownEnabled);
- dest.writeLong(mShutdownTimeoutMillis);
- dest.writeBoolean(mClientControlByUser);
- dest.writeTypedList(mBlockedClientList);
- dest.writeTypedList(mAllowedClientList);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull
- public static final Creator<SoftApConfiguration> CREATOR = new Creator<SoftApConfiguration>() {
- @Override
- public SoftApConfiguration createFromParcel(Parcel in) {
- return new SoftApConfiguration(
- in.readString(),
- in.readParcelable(MacAddress.class.getClassLoader()),
- in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt(),
- in.readInt(), in.readBoolean(), in.readLong(), in.readBoolean(),
- in.createTypedArrayList(MacAddress.CREATOR),
- in.createTypedArrayList(MacAddress.CREATOR));
- }
-
- @Override
- public SoftApConfiguration[] newArray(int size) {
- return new SoftApConfiguration[size];
- }
- };
-
- /**
- * Return String set to be the SSID for the AP.
- * {@link Builder#setSsid(String)}.
- */
- @Nullable
- public String getSsid() {
- return mSsid;
- }
-
- /**
- * Returns MAC address set to be BSSID for the AP.
- * {@link Builder#setBssid(MacAddress)}.
- */
- @Nullable
- public MacAddress getBssid() {
- return mBssid;
- }
-
- /**
- * Returns String set to be passphrase for current AP.
- * {@link Builder#setPassphrase(String, int)}.
- */
- @Nullable
- public String getPassphrase() {
- return mPassphrase;
- }
-
- /**
- * Returns Boolean set to be indicate hidden (true: doesn't broadcast its SSID) or
- * not (false: broadcasts its SSID) for the AP.
- * {@link Builder#setHiddenSsid(boolean)}.
- */
- public boolean isHiddenSsid() {
- return mHiddenSsid;
- }
-
- /**
- * Returns band type set to be the band for the AP.
- *
- * One or combination of the following band type:
- * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, {@link #BAND_6GHZ}.
- *
- * {@link Builder#setBand(int)}.
- *
- * @hide
- */
- @SystemApi
- public @BandType int getBand() {
- return mBand;
- }
-
- /**
- * Returns Integer set to be the channel for the AP.
- * {@link Builder#setChannel(int)}.
- *
- * @hide
- */
- @SystemApi
- public int getChannel() {
- return mChannel;
- }
-
- /**
- * Get security type params which depends on which security passphrase to set.
- *
- * @return One of:
- * {@link #SECURITY_TYPE_OPEN},
- * {@link #SECURITY_TYPE_WPA2_PSK},
- * {@link #SECURITY_TYPE_WPA3_SAE_TRANSITION},
- * {@link #SECURITY_TYPE_WPA3_SAE}
- */
- public @SecurityType int getSecurityType() {
- return mSecurityType;
- }
-
- /**
- * Returns the maximum number of clients that can associate to the AP.
- * {@link Builder#setMaxNumberOfClients(int)}.
- *
- * @hide
- */
- @SystemApi
- public int getMaxNumberOfClients() {
- return mMaxNumberOfClients;
- }
-
- /**
- * Returns whether auto shutdown is enabled or not.
- * The Soft AP will shutdown when there are no devices associated to it for
- * the timeout duration. See {@link Builder#setAutoShutdownEnabled(boolean)}.
- *
- * @hide
- */
- @SystemApi
- public boolean isAutoShutdownEnabled() {
- return mAutoShutdownEnabled;
- }
-
- /**
- * Returns the shutdown timeout in milliseconds.
- * The Soft AP will shutdown when there are no devices associated to it for
- * the timeout duration. See {@link Builder#setShutdownTimeoutMillis(long)}.
- *
- * @hide
- */
- @SystemApi
- public long getShutdownTimeoutMillis() {
- return mShutdownTimeoutMillis;
- }
-
- /**
- * Returns a flag indicating whether clients need to be pre-approved by the user.
- * (true: authorization required) or not (false: not required).
- * {@link Builder#setClientControlByUserEnabled(Boolean)}.
- *
- * @hide
- */
- @SystemApi
- public boolean isClientControlByUserEnabled() {
- return mClientControlByUser;
- }
-
- /**
- * Returns List of clients which aren't allowed to associate to the AP.
- *
- * Clients are configured using {@link Builder#setBlockedClientList(List)}
- *
- * @hide
- */
- @NonNull
- @SystemApi
- public List<MacAddress> getBlockedClientList() {
- return mBlockedClientList;
- }
-
- /**
- * List of clients which are allowed to associate to the AP.
- * Clients are configured using {@link Builder#setAllowedClientList(List)}
- *
- * @hide
- */
- @NonNull
- @SystemApi
- public List<MacAddress> getAllowedClientList() {
- return mAllowedClientList;
- }
-
- /**
- * Returns a {@link WifiConfiguration} representation of this {@link SoftApConfiguration}.
- * Note that SoftApConfiguration may contain configuration which is cannot be represented
- * by the legacy WifiConfiguration, in such cases a null will be returned.
- *
- * <li> SoftAp band in {@link WifiConfiguration.apBand} only supports
- * 2GHz, 5GHz, 2GHz+5GHz bands, so conversion is limited to these bands. </li>
- *
- * <li> SoftAp security type in {@link WifiConfiguration.KeyMgmt} only supports
- * NONE, WPA2_PSK, so conversion is limited to these security type.</li>
- * @hide
- */
- @Nullable
- @SystemApi
- public WifiConfiguration toWifiConfiguration() {
- WifiConfiguration wifiConfig = new WifiConfiguration();
- wifiConfig.SSID = mSsid;
- wifiConfig.preSharedKey = mPassphrase;
- wifiConfig.hiddenSSID = mHiddenSsid;
- wifiConfig.apChannel = mChannel;
- switch (mSecurityType) {
- case SECURITY_TYPE_OPEN:
- wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- break;
- case SECURITY_TYPE_WPA2_PSK:
- wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
- break;
- default:
- Log.e(TAG, "Convert fail, unsupported security type :" + mSecurityType);
- return null;
- }
-
- switch (mBand) {
- case BAND_2GHZ:
- wifiConfig.apBand = WifiConfiguration.AP_BAND_2GHZ;
- break;
- case BAND_5GHZ:
- wifiConfig.apBand = WifiConfiguration.AP_BAND_5GHZ;
- break;
- case BAND_2GHZ | BAND_5GHZ:
- wifiConfig.apBand = WifiConfiguration.AP_BAND_ANY;
- break;
- case BAND_ANY:
- wifiConfig.apBand = WifiConfiguration.AP_BAND_ANY;
- break;
- default:
- Log.e(TAG, "Convert fail, unsupported band setting :" + mBand);
- return null;
- }
- return wifiConfig;
- }
-
- /**
- * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a
- * Soft AP.
- *
- * All fields are optional. By default, SSID and BSSID are automatically chosen by the
- * framework, and an open network is created.
- *
- * @hide
- */
- @SystemApi
- public static final class Builder {
- private String mSsid;
- private MacAddress mBssid;
- private String mPassphrase;
- private boolean mHiddenSsid;
- private int mBand;
- private int mChannel;
- private int mMaxNumberOfClients;
- private int mSecurityType;
- private boolean mAutoShutdownEnabled;
- private long mShutdownTimeoutMillis;
- private boolean mClientControlByUser;
- private List<MacAddress> mBlockedClientList;
- private List<MacAddress> mAllowedClientList;
-
- /**
- * Constructs a Builder with default values (see {@link Builder}).
- */
- public Builder() {
- mSsid = null;
- mBssid = null;
- mPassphrase = null;
- mHiddenSsid = false;
- mBand = BAND_2GHZ;
- mChannel = 0;
- mMaxNumberOfClients = 0;
- mSecurityType = SECURITY_TYPE_OPEN;
- mAutoShutdownEnabled = true; // enabled by default.
- mShutdownTimeoutMillis = 0;
- mClientControlByUser = false;
- mBlockedClientList = new ArrayList<>();
- mAllowedClientList = new ArrayList<>();
- }
-
- /**
- * Constructs a Builder initialized from an existing {@link SoftApConfiguration} instance.
- */
- public Builder(@NonNull SoftApConfiguration other) {
- Objects.requireNonNull(other);
-
- mSsid = other.mSsid;
- mBssid = other.mBssid;
- mPassphrase = other.mPassphrase;
- mHiddenSsid = other.mHiddenSsid;
- mBand = other.mBand;
- mChannel = other.mChannel;
- mMaxNumberOfClients = other.mMaxNumberOfClients;
- mSecurityType = other.mSecurityType;
- mAutoShutdownEnabled = other.mAutoShutdownEnabled;
- mShutdownTimeoutMillis = other.mShutdownTimeoutMillis;
- mClientControlByUser = other.mClientControlByUser;
- mBlockedClientList = new ArrayList<>(other.mBlockedClientList);
- mAllowedClientList = new ArrayList<>(other.mAllowedClientList);
- }
-
- /**
- * Builds the {@link SoftApConfiguration}.
- *
- * @return A new {@link SoftApConfiguration}, as configured by previous method calls.
- */
- @NonNull
- public SoftApConfiguration build() {
- for (MacAddress client : mAllowedClientList) {
- if (mBlockedClientList.contains(client)) {
- throw new IllegalArgumentException("A MacAddress exist in both client list");
- }
- }
- return new SoftApConfiguration(mSsid, mBssid, mPassphrase,
- mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients,
- mAutoShutdownEnabled, mShutdownTimeoutMillis, mClientControlByUser,
- mBlockedClientList, mAllowedClientList);
- }
-
- /**
- * Specifies an SSID for the AP.
- * <p>
- * Null SSID only support when configure a local-only hotspot.
- * <p>
- * <li>If not set, defaults to null.</li>
- *
- * @param ssid SSID of valid Unicode characters, or null to have the SSID automatically
- * chosen by the framework.
- * @return Builder for chaining.
- * @throws IllegalArgumentException when the SSID is empty or not valid Unicode.
- */
- @NonNull
- public Builder setSsid(@Nullable String ssid) {
- if (ssid != null) {
- Preconditions.checkStringNotEmpty(ssid);
- Preconditions.checkArgument(StandardCharsets.UTF_8.newEncoder().canEncode(ssid));
- }
- mSsid = ssid;
- return this;
- }
-
- /**
- * Specifies a BSSID for the AP.
- * <p>
- * <li>If not set, defaults to null.</li>
- * @param bssid BSSID, or null to have the BSSID chosen by the framework. The caller is
- * responsible for avoiding collisions.
- * @return Builder for chaining.
- * @throws IllegalArgumentException when the given BSSID is the all-zero or broadcast MAC
- * address.
- */
- @NonNull
- public Builder setBssid(@Nullable MacAddress bssid) {
- if (bssid != null) {
- Preconditions.checkArgument(!bssid.equals(WifiManager.ALL_ZEROS_MAC_ADDRESS));
- Preconditions.checkArgument(!bssid.equals(MacAddress.BROADCAST_ADDRESS));
- }
- mBssid = bssid;
- return this;
- }
-
- /**
- * Specifies that this AP should use specific security type with the given ASCII passphrase.
- *
- * @param securityType One of the following security types:
- * {@link #SECURITY_TYPE_OPEN},
- * {@link #SECURITY_TYPE_WPA2_PSK},
- * {@link #SECURITY_TYPE_WPA3_SAE_TRANSITION},
- * {@link #SECURITY_TYPE_WPA3_SAE}.
- * @param passphrase The passphrase to use for sepcific {@code securityType} configuration
- * or null with {@link #SECURITY_TYPE_OPEN}.
- *
- * @return Builder for chaining.
- * @throws IllegalArgumentException when the passphrase length is invalid and
- * {@code securityType} is not {@link #SECURITY_TYPE_OPEN}
- * or non-null passphrase and {@code securityType} is
- * {@link #SECURITY_TYPE_OPEN}.
- */
- @NonNull
- public Builder setPassphrase(@Nullable String passphrase, @SecurityType int securityType) {
- if (securityType == SECURITY_TYPE_OPEN) {
- if (passphrase != null) {
- throw new IllegalArgumentException(
- "passphrase should be null when security type is open");
- }
- } else {
- Preconditions.checkStringNotEmpty(passphrase);
- final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
- if (!asciiEncoder.canEncode(passphrase)) {
- throw new IllegalArgumentException("passphrase not ASCII encodable");
- }
- if (securityType == SECURITY_TYPE_WPA2_PSK
- || securityType == SECURITY_TYPE_WPA3_SAE_TRANSITION) {
- if (passphrase.length() < PSK_MIN_LEN || passphrase.length() > PSK_MAX_LEN) {
- throw new IllegalArgumentException(
- "Password size must be at least " + PSK_MIN_LEN
- + " and no more than " + PSK_MAX_LEN
- + " for WPA2_PSK and WPA3_SAE_TRANSITION Mode");
- }
- }
- }
- mSecurityType = securityType;
- mPassphrase = passphrase;
- return this;
- }
-
- /**
- * Specifies whether the AP is hidden (doesn't broadcast its SSID) or
- * not (broadcasts its SSID).
- * <p>
- * <li>If not set, defaults to false (i.e not a hidden network).</li>
- *
- * @param hiddenSsid true for a hidden SSID, false otherwise.
- * @return Builder for chaining.
- */
- @NonNull
- public Builder setHiddenSsid(boolean hiddenSsid) {
- mHiddenSsid = hiddenSsid;
- return this;
- }
-
- /**
- * Specifies the band for the AP.
- * <p>
- * <li>If not set, defaults to {@link #BAND_2GHZ}.</li>
- *
- * @param band One or combination of the following band type:
- * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, {@link #BAND_6GHZ}.
- * @return Builder for chaining.
- */
- @NonNull
- public Builder setBand(@BandType int band) {
- if (!isBandValid(band)) {
- throw new IllegalArgumentException("Invalid band type");
- }
- mBand = band;
- // Since band preference is specified, no specific channel is selected.
- mChannel = 0;
- return this;
- }
-
- /**
- * Specifies the channel and associated band for the AP.
- *
- * The channel which AP resides on. Valid channels are country dependent.
- * <p>
- * The default for the channel is a the special value 0 to have the framework
- * auto-select a valid channel from the band configured with
- * {@link #setBand(int)}.
- *
- * The channel auto selection will offload to driver when
- * {@link SoftApCapability#areFeaturesSupported(
- * SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)}
- * return true. Driver will auto select best channel which based on environment
- * interference to get best performance. Check {@link SoftApCapability} to get more detail.
- *
- * Note, since 6GHz band use the same channel numbering of 2.4GHz and 5GHZ bands,
- * the caller needs to pass the band containing the selected channel.
- *
- * <p>
- * <li>If not set, defaults to 0.</li>
- * @param channel operating channel of the AP.
- * @param band containing this channel.
- * @return Builder for chaining.
- */
- @NonNull
- public Builder setChannel(int channel, @BandType int band) {
- if (!isChannelBandPairValid(channel, band)) {
- throw new IllegalArgumentException("Invalid band type");
- }
- mBand = band;
- mChannel = channel;
- return this;
- }
-
- /**
- * Specifies the maximum number of clients that can associate to the AP.
- *
- * The maximum number of clients (STAs) which can associate to the AP.
- * The AP will reject association from any clients above this number.
- * Specify a value of 0 to have the framework automatically use the maximum number
- * which the device can support (based on hardware and carrier constraints).
- * <p>
- * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
- * {@link SoftApCapability#getMaxSupportedClients} to get the maximum number of clients
- * which the device supports (based on hardware and carrier constraints).
- *
- * <p>
- * <li>If not set, defaults to 0.</li>
- *
- * This method requires hardware support. If the method is used to set a
- * non-zero {@code maxNumberOfClients} value then
- * {@link WifiManager#startTetheredHotspot} will report error code
- * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
- *
- * <p>
- * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
- * {@link SoftApCapability#areFeaturesSupported(int)}
- * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} to determine whether
- * or not this feature is supported.
- *
- * @param maxNumberOfClients maximum client number of the AP.
- * @return Builder for chaining.
- */
- @NonNull
- public Builder setMaxNumberOfClients(@IntRange(from = 0) int maxNumberOfClients) {
- if (maxNumberOfClients < 0) {
- throw new IllegalArgumentException("maxNumberOfClients should be not negative");
- }
- mMaxNumberOfClients = maxNumberOfClients;
- return this;
- }
-
- /**
- * Specifies whether auto shutdown is enabled or not.
- * The Soft AP will shut down when there are no devices connected to it for
- * the timeout duration.
- *
- * <p>
- * <li>If not set, defaults to true</li>
- *
- * @param enable true to enable, false to disable.
- * @return Builder for chaining.
- *
- * @see #setShutdownTimeoutMillis(long)
- */
- @NonNull
- public Builder setAutoShutdownEnabled(boolean enable) {
- mAutoShutdownEnabled = enable;
- return this;
- }
-
- /**
- * Specifies the shutdown timeout in milliseconds.
- * The Soft AP will shut down when there are no devices connected to it for
- * the timeout duration.
- *
- * Specify a value of 0 to have the framework automatically use default timeout
- * setting which defined in {@link R.integer.config_wifi_framework_soft_ap_timeout_delay}
- *
- * <p>
- * <li>If not set, defaults to 0</li>
- * <li>The shut down timeout will apply when {@link #setAutoShutdownEnabled(boolean)} is
- * set to true</li>
- *
- * @param timeoutMillis milliseconds of the timeout delay.
- * @return Builder for chaining.
- *
- * @see #setAutoShutdownEnabled(boolean)
- */
- @NonNull
- public Builder setShutdownTimeoutMillis(@IntRange(from = 0) long timeoutMillis) {
- if (timeoutMillis < 0) {
- throw new IllegalArgumentException("Invalid timeout value");
- }
- mShutdownTimeoutMillis = timeoutMillis;
- return this;
- }
-
- /**
- * Configure the Soft AP to require manual user control of client association.
- * If disabled (the default) then any client which isn't in the blocked list
- * {@link #getBlockedClientList()} can associate to this Soft AP using the
- * correct credentials until the Soft AP capacity is reached (capacity is hardware, carrier,
- * or user limited - using {@link #setMaxNumberOfClients(int)}).
- *
- * If manual user control is enabled then clients will be accepted, rejected, or require
- * a user approval based on the configuration provided by
- * {@link #setBlockedClientList(List)} and {@link #setAllowedClientList(List)}.
- *
- * <p>
- * This method requires hardware support. Hardware support can be determined using
- * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
- * {@link SoftApCapability#areFeaturesSupported(int)}
- * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT}
- *
- * <p>
- * If the method is called on a device without hardware support then starting the soft AP
- * using {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} will fail with
- * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
- *
- * <p>
- * <li>If not set, defaults to false (i.e The authoriztion is not required).</li>
- *
- * @param enabled true for enabling the control by user, false otherwise.
- * @return Builder for chaining.
- */
- @NonNull
- public Builder setClientControlByUserEnabled(boolean enabled) {
- mClientControlByUser = enabled;
- return this;
- }
-
-
- /**
- * This method together with {@link setClientControlByUserEnabled(boolean)} control client
- * connections to the AP. If client control by user is disabled using the above method then
- * this API has no effect and clients are allowed to associate to the AP (within limit of
- * max number of clients).
- *
- * If client control by user is enabled then this API configures the list of clients
- * which are explicitly allowed. These are auto-accepted.
- *
- * All other clients which attempt to associate, whose MAC addresses are on neither list,
- * are:
- * <ul>
- * <li>Rejected</li>
- * <li>A callback {@link WifiManager.SoftApCallback#onBlockedClientConnecting(WifiClient)}
- * is issued (which allows the user to add them to the allowed client list if desired).<li>
- * </ul>
- *
- * @param allowedClientList list of clients which are allowed to associate to the AP
- * without user pre-approval.
- * @return Builder for chaining.
- */
- @NonNull
- public Builder setAllowedClientList(@NonNull List<MacAddress> allowedClientList) {
- mAllowedClientList = new ArrayList<>(allowedClientList);
- return this;
- }
-
- /**
- * This API configures the list of clients which are blocked and cannot associate
- * to the Soft AP.
- *
- * <p>
- * This method requires hardware support. Hardware support can be determined using
- * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
- * {@link SoftApCapability#areFeaturesSupported(int)}
- * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT}
- *
- * <p>
- * If the method is called on a device without hardware support then starting the soft AP
- * using {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} will fail with
- * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
- *
- * @param blockedClientList list of clients which are not allowed to associate to the AP.
- * @return Builder for chaining.
- */
- @NonNull
- public Builder setBlockedClientList(@NonNull List<MacAddress> blockedClientList) {
- mBlockedClientList = new ArrayList<>(blockedClientList);
- return this;
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java
deleted file mode 100644
index 24ed8ef..0000000
--- a/wifi/java/android/net/wifi/SoftApInfo.java
+++ /dev/null
@@ -1,194 +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.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * A class representing information about SoftAp.
- * {@see WifiManager}
- *
- * @hide
- */
-@SystemApi
-public final class SoftApInfo implements Parcelable {
-
- /**
- * AP Channel bandwidth is invalid.
- *
- * @see #getBandwidth()
- */
- public static final int CHANNEL_WIDTH_INVALID = 0;
-
- /**
- * AP Channel bandwidth is 20 MHZ but no HT.
- *
- * @see #getBandwidth()
- */
- public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1;
-
- /**
- * AP Channel bandwidth is 20 MHZ.
- *
- * @see #getBandwidth()
- */
- public static final int CHANNEL_WIDTH_20MHZ = 2;
-
- /**
- * AP Channel bandwidth is 40 MHZ.
- *
- * @see #getBandwidth()
- */
- public static final int CHANNEL_WIDTH_40MHZ = 3;
-
- /**
- * AP Channel bandwidth is 80 MHZ.
- *
- * @see #getBandwidth()
- */
- public static final int CHANNEL_WIDTH_80MHZ = 4;
-
- /**
- * AP Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ.
- *
- * @see #getBandwidth()
- */
- public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5;
-
- /**
- * AP Channel bandwidth is 160 MHZ.
- *
- * @see #getBandwidth()
- */
- public static final int CHANNEL_WIDTH_160MHZ = 6;
-
-
-
- /** The frequency which AP resides on. */
- private int mFrequency = 0;
-
- @WifiAnnotations.Bandwidth
- private int mBandwidth = CHANNEL_WIDTH_INVALID;
-
- /**
- * Get the frequency which AP resides on.
- */
- public int getFrequency() {
- return mFrequency;
- }
-
- /**
- * Set the frequency which AP resides on.
- * @hide
- */
- public void setFrequency(int freq) {
- mFrequency = freq;
- }
-
- /**
- * Get AP Channel bandwidth.
- *
- * @return One of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ},
- * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ},
- * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_INVALID}.
- */
- @WifiAnnotations.Bandwidth
- public int getBandwidth() {
- return mBandwidth;
- }
-
- /**
- * Set AP Channel bandwidth.
- * @hide
- */
- public void setBandwidth(@WifiAnnotations.Bandwidth int bandwidth) {
- mBandwidth = bandwidth;
- }
-
- /**
- * @hide
- */
- public SoftApInfo(@Nullable SoftApInfo source) {
- if (source != null) {
- mFrequency = source.mFrequency;
- mBandwidth = source.mBandwidth;
- }
- }
-
- /**
- * @hide
- */
- public SoftApInfo() {
- }
-
- @Override
- /** Implement the Parcelable interface. */
- public int describeContents() {
- return 0;
- }
-
- @Override
- /** Implement the Parcelable interface */
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mFrequency);
- dest.writeInt(mBandwidth);
- }
-
- @NonNull
- /** Implement the Parcelable interface */
- public static final Creator<SoftApInfo> CREATOR = new Creator<SoftApInfo>() {
- public SoftApInfo createFromParcel(Parcel in) {
- SoftApInfo info = new SoftApInfo();
- info.mFrequency = in.readInt();
- info.mBandwidth = in.readInt();
- return info;
- }
-
- public SoftApInfo[] newArray(int size) {
- return new SoftApInfo[size];
- }
- };
-
- @NonNull
- @Override
- public String toString() {
- return "SoftApInfo{"
- + "bandwidth= " + mBandwidth
- + ",frequency= " + mFrequency
- + '}';
- }
-
- @Override
- public boolean equals(@NonNull Object o) {
- if (this == o) return true;
- if (!(o instanceof SoftApInfo)) return false;
- SoftApInfo softApInfo = (SoftApInfo) o;
- return mFrequency == softApInfo.mFrequency
- && mBandwidth == softApInfo.mBandwidth;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mFrequency, mBandwidth);
- }
-}
diff --git a/wifi/java/android/net/wifi/SupplicantState.java b/wifi/java/android/net/wifi/SupplicantState.java
deleted file mode 100644
index de7e2b5..0000000
--- a/wifi/java/android/net/wifi/SupplicantState.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * From <code>defs.h</code> in <code>wpa_supplicant</code>.
- * <p/>
- * These enumeration values are used to indicate the current wpa_supplicant
- * state. This is more fine-grained than most users will be interested in.
- * In general, it is better to use
- * {@link android.net.NetworkInfo.State NetworkInfo.State}.
- * <p/>
- * Note, the order of these enum constants must match the numerical values of the
- * state constants in <code>defs.h</code> in <code>wpa_supplicant</code>.
- */
-public enum SupplicantState implements Parcelable {
- /**
- * This state indicates that client is not associated, but is likely to
- * start looking for an access point. This state is entered when a
- * connection is lost.
- */
- DISCONNECTED,
-
- /**
- * Interface is disabled
- * <p/>
- * This state is entered if the network interface is disabled.
- * wpa_supplicant refuses any new operations that would
- * use the radio until the interface has been enabled.
- */
- INTERFACE_DISABLED,
-
- /**
- * Inactive state (wpa_supplicant disabled).
- * <p/>
- * This state is entered if there are no enabled networks in the
- * configuration. wpa_supplicant is not trying to associate with a new
- * network and external interaction (e.g., ctrl_iface call to add or
- * enable a network) is needed to start association.
- */
- INACTIVE,
-
- /**
- * Scanning for a network.
- * <p/>
- * This state is entered when wpa_supplicant starts scanning for a
- * network.
- */
- SCANNING,
-
- /**
- * Trying to authenticate with a BSS/SSID
- * <p/>
- * This state is entered when wpa_supplicant has found a suitable BSS
- * to authenticate with and the driver is configured to try to
- * authenticate with this BSS.
- */
- AUTHENTICATING,
-
- /**
- * Trying to associate with a BSS/SSID.
- * <p/>
- * This state is entered when wpa_supplicant has found a suitable BSS
- * to associate with and the driver is configured to try to associate
- * with this BSS in ap_scan=1 mode. When using ap_scan=2 mode, this
- * state is entered when the driver is configured to try to associate
- * with a network using the configured SSID and security policy.
- */
- ASSOCIATING,
-
- /**
- * Association completed.
- * <p/>
- * This state is entered when the driver reports that association has
- * been successfully completed with an AP. If IEEE 802.1X is used
- * (with or without WPA/WPA2), wpa_supplicant remains in this state
- * until the IEEE 802.1X/EAPOL authentication has been completed.
- */
- ASSOCIATED,
-
- /**
- * WPA 4-Way Key Handshake in progress.
- * <p/>
- * This state is entered when WPA/WPA2 4-Way Handshake is started. In
- * case of WPA-PSK, this happens when receiving the first EAPOL-Key
- * frame after association. In case of WPA-EAP, this state is entered
- * when the IEEE 802.1X/EAPOL authentication has been completed.
- */
- FOUR_WAY_HANDSHAKE,
-
- /**
- * WPA Group Key Handshake in progress.
- * <p/>
- * This state is entered when 4-Way Key Handshake has been completed
- * (i.e., when the supplicant sends out message 4/4) and when Group
- * Key rekeying is started by the AP (i.e., when supplicant receives
- * message 1/2).
- */
- GROUP_HANDSHAKE,
-
- /**
- * All authentication completed.
- * <p/>
- * This state is entered when the full authentication process is
- * completed. In case of WPA2, this happens when the 4-Way Handshake is
- * successfully completed. With WPA, this state is entered after the
- * Group Key Handshake; with IEEE 802.1X (non-WPA) connection is
- * completed after dynamic keys are received (or if not used, after
- * the EAP authentication has been completed). With static WEP keys and
- * plaintext connections, this state is entered when an association
- * has been completed.
- * <p/>
- * This state indicates that the supplicant has completed its
- * processing for the association phase and that data connection is
- * fully configured. Note, however, that there may not be any IP
- * address associated with the connection yet. Typically, a DHCP
- * request needs to be sent at this point to obtain an address.
- */
- COMPLETED,
-
- /**
- * An Android-added state that is reported when a client issues an
- * explicit DISCONNECT command. In such a case, the supplicant is
- * not only dissociated from the current access point (as for the
- * DISCONNECTED state above), but it also does not attempt to connect
- * to any access point until a RECONNECT or REASSOCIATE command
- * is issued by the client.
- */
- DORMANT,
-
- /**
- * No connection to wpa_supplicant.
- * <p/>
- * This is an additional pseudo-state to handle the case where
- * wpa_supplicant is not running and/or we have not been able
- * to establish a connection to it.
- */
- UNINITIALIZED,
-
- /**
- * A pseudo-state that should normally never be seen.
- */
- INVALID;
-
- /**
- * Returns {@code true} if the supplicant state is valid and {@code false}
- * otherwise.
- * @param state The supplicant state
- * @return {@code true} if the supplicant state is valid and {@code false}
- * otherwise.
- */
- public static boolean isValidState(SupplicantState state) {
- return state != UNINITIALIZED && state != INVALID;
- }
-
-
- /** Supplicant associating or authenticating is considered a handshake state {@hide} */
- public static boolean isHandshakeState(SupplicantState state) {
- switch(state) {
- case AUTHENTICATING:
- case ASSOCIATING:
- case ASSOCIATED:
- case FOUR_WAY_HANDSHAKE:
- case GROUP_HANDSHAKE:
- return true;
- case COMPLETED:
- case DISCONNECTED:
- case INTERFACE_DISABLED:
- case INACTIVE:
- case SCANNING:
- case DORMANT:
- case UNINITIALIZED:
- case INVALID:
- return false;
- default:
- throw new IllegalArgumentException("Unknown supplicant state");
- }
- }
-
- /** @hide */
- public static boolean isConnecting(SupplicantState state) {
- switch(state) {
- case AUTHENTICATING:
- case ASSOCIATING:
- case ASSOCIATED:
- case FOUR_WAY_HANDSHAKE:
- case GROUP_HANDSHAKE:
- case COMPLETED:
- return true;
- case DISCONNECTED:
- case INTERFACE_DISABLED:
- case INACTIVE:
- case SCANNING:
- case DORMANT:
- case UNINITIALIZED:
- case INVALID:
- return false;
- default:
- throw new IllegalArgumentException("Unknown supplicant state");
- }
- }
-
- /** @hide */
- public static boolean isDriverActive(SupplicantState state) {
- switch(state) {
- case DISCONNECTED:
- case DORMANT:
- case INACTIVE:
- case AUTHENTICATING:
- case ASSOCIATING:
- case ASSOCIATED:
- case SCANNING:
- case FOUR_WAY_HANDSHAKE:
- case GROUP_HANDSHAKE:
- case COMPLETED:
- return true;
- case INTERFACE_DISABLED:
- case UNINITIALIZED:
- case INVALID:
- return false;
- default:
- throw new IllegalArgumentException("Unknown supplicant state");
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name());
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<SupplicantState> CREATOR =
- new Creator<SupplicantState>() {
- public SupplicantState createFromParcel(Parcel in) {
- return SupplicantState.valueOf(in.readString());
- }
-
- public SupplicantState[] newArray(int size) {
- return new SupplicantState[size];
- }
- };
-
-}
diff --git a/wifi/java/android/net/wifi/SynchronousExecutor.java b/wifi/java/android/net/wifi/SynchronousExecutor.java
deleted file mode 100644
index 9926b1b..0000000
--- a/wifi/java/android/net/wifi/SynchronousExecutor.java
+++ /dev/null
@@ -1,29 +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.net.wifi;
-
-import java.util.concurrent.Executor;
-
-/**
- * An executor implementation that runs synchronously on the current thread.
- * @hide
- */
-public class SynchronousExecutor implements Executor {
- @Override
- public void execute(Runnable r) {
- r.run();
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiAnnotations.java b/wifi/java/android/net/wifi/WifiAnnotations.java
deleted file mode 100644
index acda7e0..0000000
--- a/wifi/java/android/net/wifi/WifiAnnotations.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.StringDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Wifi annotations meant to be statically linked into client modules, since they cannot be
- * exposed as @SystemApi.
- *
- * e.g. {@link IntDef}, {@link StringDef}
- *
- * @hide
- */
-public final class WifiAnnotations {
- private WifiAnnotations() {}
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"SCAN_TYPE_"}, value = {
- WifiScanner.SCAN_TYPE_LOW_LATENCY,
- WifiScanner.SCAN_TYPE_LOW_POWER,
- WifiScanner.SCAN_TYPE_HIGH_ACCURACY})
- public @interface ScanType {}
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"WIFI_BAND_"}, value = {
- WifiScanner.WIFI_BAND_UNSPECIFIED,
- WifiScanner.WIFI_BAND_24_GHZ,
- WifiScanner.WIFI_BAND_5_GHZ,
- WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY,
- WifiScanner.WIFI_BAND_6_GHZ})
- public @interface WifiBandBasic {}
-
- @IntDef(prefix = { "CHANNEL_WIDTH_" }, value = {
- SoftApInfo.CHANNEL_WIDTH_INVALID,
- SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT,
- SoftApInfo.CHANNEL_WIDTH_20MHZ,
- SoftApInfo.CHANNEL_WIDTH_40MHZ,
- SoftApInfo.CHANNEL_WIDTH_80MHZ,
- SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ,
- SoftApInfo.CHANNEL_WIDTH_160MHZ,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Bandwidth {}
-
- @IntDef(prefix = { "CHANNEL_WIDTH_" }, value = {
- ScanResult.CHANNEL_WIDTH_20MHZ,
- ScanResult.CHANNEL_WIDTH_40MHZ,
- ScanResult.CHANNEL_WIDTH_80MHZ,
- ScanResult.CHANNEL_WIDTH_160MHZ,
- ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ChannelWidth{}
-
- @IntDef(prefix = { "WIFI_STANDARD_" }, value = {
- ScanResult.WIFI_STANDARD_UNKNOWN,
- ScanResult.WIFI_STANDARD_LEGACY,
- ScanResult.WIFI_STANDARD_11N,
- ScanResult.WIFI_STANDARD_11AC,
- ScanResult.WIFI_STANDARD_11AX,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface WifiStandard{}
-
- @IntDef(prefix = { "PROTOCOL_" }, value = {
- ScanResult.PROTOCOL_NONE,
- ScanResult.PROTOCOL_WPA,
- ScanResult.PROTOCOL_RSN,
- ScanResult.PROTOCOL_OSEN,
- ScanResult.PROTOCOL_WAPI
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Protocol {}
-
- @IntDef(prefix = { "KEY_MGMT_" }, value = {
- ScanResult.KEY_MGMT_NONE,
- ScanResult.KEY_MGMT_PSK,
- ScanResult.KEY_MGMT_EAP,
- ScanResult.KEY_MGMT_FT_PSK,
- ScanResult.KEY_MGMT_FT_EAP,
- ScanResult.KEY_MGMT_PSK_SHA256,
- ScanResult.KEY_MGMT_EAP_SHA256,
- ScanResult.KEY_MGMT_OSEN,
- ScanResult.KEY_MGMT_SAE,
- ScanResult.KEY_MGMT_OWE,
- ScanResult.KEY_MGMT_EAP_SUITE_B_192,
- ScanResult.KEY_MGMT_FT_SAE,
- ScanResult.KEY_MGMT_OWE_TRANSITION,
- ScanResult.KEY_MGMT_WAPI_PSK,
- ScanResult.KEY_MGMT_WAPI_CERT
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface KeyMgmt {}
-
- @IntDef(prefix = { "CIPHER_" }, value = {
- ScanResult.CIPHER_NONE,
- ScanResult.CIPHER_NO_GROUP_ADDRESSED,
- ScanResult.CIPHER_TKIP,
- ScanResult.CIPHER_CCMP,
- ScanResult.CIPHER_GCMP_256,
- ScanResult.CIPHER_SMS4
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Cipher {}
-}
diff --git a/wifi/java/android/net/wifi/WifiClient.java b/wifi/java/android/net/wifi/WifiClient.java
deleted file mode 100644
index 3794566..0000000
--- a/wifi/java/android/net/wifi/WifiClient.java
+++ /dev/null
@@ -1,95 +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.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/** @hide */
-@SystemApi
-public final class WifiClient implements Parcelable {
-
- private final MacAddress mMacAddress;
-
- /**
- * The mac address of this client.
- */
- @NonNull
- public MacAddress getMacAddress() {
- return mMacAddress;
- }
-
- private WifiClient(Parcel in) {
- mMacAddress = in.readParcelable(null);
- }
-
- /** @hide */
- public WifiClient(@NonNull MacAddress macAddress) {
- Objects.requireNonNull(macAddress, "mMacAddress must not be null.");
-
- this.mMacAddress = macAddress;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeParcelable(mMacAddress, flags);
- }
-
- @NonNull
- public static final Creator<WifiClient> CREATOR = new Creator<WifiClient>() {
- public WifiClient createFromParcel(Parcel in) {
- return new WifiClient(in);
- }
-
- public WifiClient[] newArray(int size) {
- return new WifiClient[size];
- }
- };
-
- @NonNull
- @Override
- public String toString() {
- return "WifiClient{"
- + "mMacAddress=" + mMacAddress
- + '}';
- }
-
- @Override
- public boolean equals(@NonNull Object o) {
- if (this == o) return true;
- if (!(o instanceof WifiClient)) return false;
- WifiClient client = (WifiClient) o;
- return mMacAddress.equals(client.mMacAddress);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mMacAddress);
- }
-}
-
-
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
deleted file mode 100644
index 71f0ab8..0000000
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ /dev/null
@@ -1,2987 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.pm.PackageManager;
-import android.net.IpConfiguration;
-import android.net.IpConfiguration.ProxySettings;
-import android.net.MacAddress;
-import android.net.NetworkSpecifier;
-import android.net.ProxyInfo;
-import android.net.StaticIpConfiguration;
-import android.net.Uri;
-import android.net.util.MacAddressUtils;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Calendar;
-import java.util.HashMap;
-
-/**
- * A class representing a configured Wi-Fi network, including the
- * security configuration.
- *
- * @deprecated Use {@link WifiNetworkSpecifier.Builder} to create {@link NetworkSpecifier} and
- * {@link WifiNetworkSuggestion.Builder} to create {@link WifiNetworkSuggestion}. This will become a
- * system use only object in the future.
- */
-@Deprecated
-public class WifiConfiguration implements Parcelable {
- private static final String TAG = "WifiConfiguration";
- /**
- * Current Version of the Backup Serializer.
- */
- private static final int BACKUP_VERSION = 3;
- /** {@hide} */
- public static final String ssidVarName = "ssid";
- /** {@hide} */
- public static final String bssidVarName = "bssid";
- /** {@hide} */
- public static final String pskVarName = "psk";
- /** {@hide} */
- @Deprecated
- @UnsupportedAppUsage
- public static final String[] wepKeyVarNames = { "wep_key0", "wep_key1", "wep_key2", "wep_key3" };
- /** {@hide} */
- @Deprecated
- public static final String wepTxKeyIdxVarName = "wep_tx_keyidx";
- /** {@hide} */
- public static final String priorityVarName = "priority";
- /** {@hide} */
- public static final String hiddenSSIDVarName = "scan_ssid";
- /** {@hide} */
- public static final String pmfVarName = "ieee80211w";
- /** {@hide} */
- public static final String updateIdentiferVarName = "update_identifier";
- /**
- * The network ID for an invalid network.
- *
- * @hide
- */
- @SystemApi
- public static final int INVALID_NETWORK_ID = -1;
- /** {@hide} */
- public static final int LOCAL_ONLY_NETWORK_ID = -2;
-
- /** {@hide} */
- private String mPasspointManagementObjectTree;
- /** {@hide} */
- private static final int MAXIMUM_RANDOM_MAC_GENERATION_RETRY = 3;
-
- /**
- * Recognized key management schemes.
- */
- public static class KeyMgmt {
- private KeyMgmt() { }
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- NONE,
- WPA_PSK,
- WPA_EAP,
- IEEE8021X,
- WPA2_PSK,
- OSEN,
- FT_PSK,
- FT_EAP,
- SAE,
- OWE,
- SUITE_B_192,
- WPA_PSK_SHA256,
- WPA_EAP_SHA256,
- WAPI_PSK,
- WAPI_CERT,
- FILS_SHA256,
- FILS_SHA384})
- public @interface KeyMgmtScheme {}
-
- /** WPA is not used; plaintext or static WEP could be used. */
- public static final int NONE = 0;
- /** WPA pre-shared key (requires {@code preSharedKey} to be specified). */
- public static final int WPA_PSK = 1;
- /** WPA using EAP authentication. Generally used with an external authentication server. */
- public static final int WPA_EAP = 2;
- /**
- * IEEE 802.1X using EAP authentication and (optionally) dynamically
- * generated WEP keys.
- */
- public static final int IEEE8021X = 3;
-
- /**
- * WPA2 pre-shared key for use with soft access point
- * (requires {@code preSharedKey} to be specified).
- * @hide
- */
- @SystemApi
- public static final int WPA2_PSK = 4;
- /**
- * Hotspot 2.0 r2 OSEN:
- * @hide
- */
- public static final int OSEN = 5;
-
- /**
- * IEEE 802.11r Fast BSS Transition with PSK authentication.
- * @hide
- */
- public static final int FT_PSK = 6;
-
- /**
- * IEEE 802.11r Fast BSS Transition with EAP authentication.
- * @hide
- */
- public static final int FT_EAP = 7;
-
- /**
- * Simultaneous Authentication of Equals
- */
- public static final int SAE = 8;
-
- /**
- * Opportunististic Wireless Encryption
- */
- public static final int OWE = 9;
-
- /**
- * SUITE_B_192 192 bit level
- */
- public static final int SUITE_B_192 = 10;
-
- /**
- * WPA pre-shared key with stronger SHA256-based algorithms.
- * @hide
- */
- public static final int WPA_PSK_SHA256 = 11;
-
- /**
- * WPA using EAP authentication with stronger SHA256-based algorithms.
- * @hide
- */
- public static final int WPA_EAP_SHA256 = 12;
-
- /**
- * WAPI pre-shared key (requires {@code preSharedKey} to be specified).
- * @hide
- */
- @SystemApi
- public static final int WAPI_PSK = 13;
-
- /**
- * WAPI certificate to be specified.
- * @hide
- */
- @SystemApi
- public static final int WAPI_CERT = 14;
-
- /**
- * IEEE 802.11ai FILS SK with SHA256
- * @hide
- */
- public static final int FILS_SHA256 = 15;
- /**
- * IEEE 802.11ai FILS SK with SHA384:
- * @hide
- */
- public static final int FILS_SHA384 = 16;
-
- public static final String varName = "key_mgmt";
-
- public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP",
- "IEEE8021X", "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP",
- "SAE", "OWE", "SUITE_B_192", "WPA_PSK_SHA256", "WPA_EAP_SHA256",
- "WAPI_PSK", "WAPI_CERT", "FILS_SHA256", "FILS_SHA384" };
- }
-
- /**
- * Recognized security protocols.
- */
- public static class Protocol {
- private Protocol() { }
-
- /** WPA/IEEE 802.11i/D3.0
- * @deprecated Due to security and performance limitations, use of WPA-1 networks
- * is discouraged. WPA-2 (RSN) should be used instead. */
- @Deprecated
- public static final int WPA = 0;
- /** RSN WPA2/WPA3/IEEE 802.11i */
- public static final int RSN = 1;
- /** HS2.0 r2 OSEN
- * @hide
- */
- public static final int OSEN = 2;
-
- /**
- * WAPI Protocol
- */
- public static final int WAPI = 3;
-
- public static final String varName = "proto";
-
- public static final String[] strings = { "WPA", "RSN", "OSEN", "WAPI" };
- }
-
- /**
- * Recognized IEEE 802.11 authentication algorithms.
- */
- public static class AuthAlgorithm {
- private AuthAlgorithm() { }
-
- /** Open System authentication (required for WPA/WPA2) */
- public static final int OPEN = 0;
- /** Shared Key authentication (requires static WEP keys)
- * @deprecated Due to security and performance limitations, use of WEP networks
- * is discouraged. */
- @Deprecated
- public static final int SHARED = 1;
- /** LEAP/Network EAP (only used with LEAP) */
- public static final int LEAP = 2;
-
- /** SAE (Used only for WPA3-Personal) */
- public static final int SAE = 3;
-
- public static final String varName = "auth_alg";
-
- public static final String[] strings = { "OPEN", "SHARED", "LEAP", "SAE" };
- }
-
- /**
- * Recognized pairwise ciphers for WPA.
- */
- public static class PairwiseCipher {
- private PairwiseCipher() { }
-
- /** Use only Group keys (deprecated) */
- public static final int NONE = 0;
- /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
- * @deprecated Due to security and performance limitations, use of WPA-1 networks
- * is discouraged. WPA-2 (RSN) should be used instead. */
- @Deprecated
- public static final int TKIP = 1;
- /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
- public static final int CCMP = 2;
- /**
- * AES in Galois/Counter Mode
- */
- public static final int GCMP_256 = 3;
- /**
- * SMS4 cipher for WAPI
- */
- public static final int SMS4 = 4;
-
- public static final String varName = "pairwise";
-
- public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256", "SMS4" };
- }
-
- /**
- * Recognized group ciphers.
- * <pre>
- * CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
- * TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
- * WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
- * WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11)
- * GCMP_256 = AES in Galois/Counter Mode
- * </pre>
- */
- public static class GroupCipher {
- private GroupCipher() { }
-
- /** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11)
- * @deprecated Due to security and performance limitations, use of WEP networks
- * is discouraged. */
- @Deprecated
- public static final int WEP40 = 0;
- /** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
- * @deprecated Due to security and performance limitations, use of WEP networks
- * is discouraged. */
- @Deprecated
- public static final int WEP104 = 1;
- /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */
- public static final int TKIP = 2;
- /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
- public static final int CCMP = 3;
- /** Hotspot 2.0 r2 OSEN
- * @hide
- */
- public static final int GTK_NOT_USED = 4;
- /**
- * AES in Galois/Counter Mode
- */
- public static final int GCMP_256 = 5;
- /**
- * SMS4 cipher for WAPI
- */
- public static final int SMS4 = 6;
-
- public static final String varName = "group";
-
- public static final String[] strings =
- { /* deprecated */ "WEP40", /* deprecated */ "WEP104",
- "TKIP", "CCMP", "GTK_NOT_USED", "GCMP_256",
- "SMS4" };
- }
-
- /**
- * Recognized group management ciphers.
- * <pre>
- * BIP_CMAC_256 = Cipher-based Message Authentication Code 256 bits
- * BIP_GMAC_128 = Galois Message Authentication Code 128 bits
- * BIP_GMAC_256 = Galois Message Authentication Code 256 bits
- * </pre>
- */
- public static class GroupMgmtCipher {
- private GroupMgmtCipher() { }
-
- /** CMAC-256 = Cipher-based Message Authentication Code */
- public static final int BIP_CMAC_256 = 0;
-
- /** GMAC-128 = Galois Message Authentication Code */
- public static final int BIP_GMAC_128 = 1;
-
- /** GMAC-256 = Galois Message Authentication Code */
- public static final int BIP_GMAC_256 = 2;
-
- private static final String varName = "groupMgmt";
-
- private static final String[] strings = { "BIP_CMAC_256",
- "BIP_GMAC_128", "BIP_GMAC_256"};
- }
-
- /**
- * Recognized suiteB ciphers.
- * <pre>
- * ECDHE_ECDSA
- * ECDHE_RSA
- * </pre>
- * @hide
- */
- public static class SuiteBCipher {
- private SuiteBCipher() { }
-
- /** Diffie-Hellman with Elliptic Curve_ECDSA signature */
- public static final int ECDHE_ECDSA = 0;
-
- /** Diffie-Hellman with_RSA signature */
- public static final int ECDHE_RSA = 1;
-
- private static final String varName = "SuiteB";
-
- private static final String[] strings = { "ECDHE_ECDSA", "ECDHE_RSA" };
- }
-
- /** Possible status of a network configuration. */
- public static class Status {
- private Status() { }
-
- /** this is the network we are currently connected to */
- public static final int CURRENT = 0;
- /** supplicant will not attempt to use this network */
- public static final int DISABLED = 1;
- /** supplicant will consider this network available for association */
- public static final int ENABLED = 2;
-
- public static final String[] strings = { "current", "disabled", "enabled" };
- }
-
- /** Security type for an open network. */
- public static final int SECURITY_TYPE_OPEN = 0;
- /** Security type for a WEP network. */
- public static final int SECURITY_TYPE_WEP = 1;
- /** Security type for a PSK network. */
- public static final int SECURITY_TYPE_PSK = 2;
- /** Security type for an EAP network. */
- public static final int SECURITY_TYPE_EAP = 3;
- /** Security type for an SAE network. */
- public static final int SECURITY_TYPE_SAE = 4;
- /** Security type for an EAP Suite B network. */
- public static final int SECURITY_TYPE_EAP_SUITE_B = 5;
- /** Security type for an OWE network. */
- public static final int SECURITY_TYPE_OWE = 6;
- /** Security type for a WAPI PSK network. */
- public static final int SECURITY_TYPE_WAPI_PSK = 7;
- /** Security type for a WAPI Certificate network. */
- public static final int SECURITY_TYPE_WAPI_CERT = 8;
-
- /**
- * Security types we support.
- * @hide
- */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "SECURITY_TYPE_" }, value = {
- SECURITY_TYPE_OPEN,
- SECURITY_TYPE_WEP,
- SECURITY_TYPE_PSK,
- SECURITY_TYPE_EAP,
- SECURITY_TYPE_SAE,
- SECURITY_TYPE_EAP_SUITE_B,
- SECURITY_TYPE_OWE,
- SECURITY_TYPE_WAPI_PSK,
- SECURITY_TYPE_WAPI_CERT
- })
- public @interface SecurityType {}
-
- /**
- * Set the various security params to correspond to the provided security type.
- * This is accomplished by setting the various BitSets exposed in WifiConfiguration.
- *
- * @param securityType One of the following security types:
- * {@link #SECURITY_TYPE_OPEN},
- * {@link #SECURITY_TYPE_WEP},
- * {@link #SECURITY_TYPE_PSK},
- * {@link #SECURITY_TYPE_EAP},
- * {@link #SECURITY_TYPE_SAE},
- * {@link #SECURITY_TYPE_EAP_SUITE_B},
- * {@link #SECURITY_TYPE_OWE},
- * {@link #SECURITY_TYPE_WAPI_PSK}, or
- * {@link #SECURITY_TYPE_WAPI_CERT}
- */
- public void setSecurityParams(@SecurityType int securityType) {
- // Clear all the bitsets.
- allowedKeyManagement.clear();
- allowedProtocols.clear();
- allowedAuthAlgorithms.clear();
- allowedPairwiseCiphers.clear();
- allowedGroupCiphers.clear();
- allowedGroupManagementCiphers.clear();
- allowedSuiteBCiphers.clear();
-
- switch (securityType) {
- case SECURITY_TYPE_OPEN:
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- break;
- case SECURITY_TYPE_WEP:
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
- allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
- break;
- case SECURITY_TYPE_PSK:
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- break;
- case SECURITY_TYPE_EAP:
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
- break;
- case SECURITY_TYPE_SAE:
- allowedProtocols.set(WifiConfiguration.Protocol.RSN);
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
- allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
- allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
- allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
- allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
- requirePmf = true;
- break;
- case SECURITY_TYPE_EAP_SUITE_B:
- allowedProtocols.set(WifiConfiguration.Protocol.RSN);
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192);
- allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
- allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
- allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
- // Note: allowedSuiteBCiphers bitset will be set by the service once the
- // certificates are attached to this profile
- requirePmf = true;
- break;
- case SECURITY_TYPE_OWE:
- allowedProtocols.set(WifiConfiguration.Protocol.RSN);
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE);
- allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
- allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
- allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
- allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
- requirePmf = true;
- break;
- case SECURITY_TYPE_WAPI_PSK:
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WAPI_PSK);
- allowedProtocols.set(WifiConfiguration.Protocol.WAPI);
- allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.SMS4);
- allowedGroupCiphers.set(WifiConfiguration.GroupCipher.SMS4);
- break;
- case SECURITY_TYPE_WAPI_CERT:
- allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WAPI_CERT);
- allowedProtocols.set(WifiConfiguration.Protocol.WAPI);
- allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.SMS4);
- allowedGroupCiphers.set(WifiConfiguration.GroupCipher.SMS4);
- break;
- default:
- throw new IllegalArgumentException("unknown security type " + securityType);
- }
- }
-
- /** @hide */
- public static final int UNKNOWN_UID = -1;
-
- /**
- * The ID number that the supplicant uses to identify this
- * network configuration entry. This must be passed as an argument
- * to most calls into the supplicant.
- */
- public int networkId;
-
- // Fixme We need remove this field to use only Quality network selection status only
- /**
- * The current status of this network configuration entry.
- * @see Status
- */
- public int status;
-
- /**
- * The network's SSID. Can either be a UTF-8 string,
- * which must be enclosed in double quotation marks
- * (e.g., {@code "MyNetwork"}), or a string of
- * hex digits, which are not enclosed in quotes
- * (e.g., {@code 01a243f405}).
- */
- public String SSID;
-
- /**
- * When set, this network configuration entry should only be used when
- * associating with the AP having the specified BSSID. The value is
- * a string in the format of an Ethernet MAC address, e.g.,
- * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit.
- */
- public String BSSID;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"AP_BAND_"}, value = {
- AP_BAND_2GHZ,
- AP_BAND_5GHZ,
- AP_BAND_ANY})
- public @interface ApBand {}
-
- /**
- * 2GHz band.
- * @hide
- */
- public static final int AP_BAND_2GHZ = 0;
-
- /**
- * 5GHz band.
- * @hide
- */
- public static final int AP_BAND_5GHZ = 1;
-
- /**
- * Device is allowed to choose the optimal band (2Ghz or 5Ghz) based on device capability,
- * operating country code and current radio conditions.
- * @hide
- */
- public static final int AP_BAND_ANY = -1;
-
- /**
- * The band which the AP resides on.
- * One of {@link #AP_BAND_2GHZ}, {@link #AP_BAND_5GHZ}, or {@link #AP_BAND_ANY}.
- * By default, {@link #AP_BAND_2GHZ} is chosen.
- *
- * @hide
- */
- @UnsupportedAppUsage
- @ApBand
- public int apBand = AP_BAND_2GHZ;
-
- /**
- * The channel which AP resides on,currently, US only
- * 2G 1-11
- * 5G 36,40,44,48,149,153,157,161,165
- * 0 - find a random available channel according to the apBand
- * @hide
- */
- @UnsupportedAppUsage
- public int apChannel = 0;
-
- /**
- * Pre-shared key for use with WPA-PSK. Either an ASCII string enclosed in
- * double quotation marks (e.g., {@code "abcdefghij"} for PSK passphrase or
- * a string of 64 hex digits for raw PSK.
- * <p/>
- * When the value of this key is read, the actual key is
- * not returned, just a "*" if the key has a value, or the null
- * string otherwise.
- */
- public String preSharedKey;
-
- /**
- * Four WEP keys. For each of the four values, provide either an ASCII
- * string enclosed in double quotation marks (e.g., {@code "abcdef"}),
- * a string of hex digits (e.g., {@code 0102030405}), or an empty string
- * (e.g., {@code ""}).
- * <p/>
- * When the value of one of these keys is read, the actual key is
- * not returned, just a "*" if the key has a value, or the null
- * string otherwise.
- * @deprecated Due to security and performance limitations, use of WEP networks
- * is discouraged.
- */
- @Deprecated
- public String[] wepKeys;
-
- /** Default WEP key index, ranging from 0 to 3.
- * @deprecated Due to security and performance limitations, use of WEP networks
- * is discouraged. */
- @Deprecated
- public int wepTxKeyIndex;
-
- /**
- * Priority determines the preference given to a network by {@code wpa_supplicant}
- * when choosing an access point with which to associate.
- * @deprecated This field does not exist anymore.
- */
- @Deprecated
- public int priority;
-
- /**
- * This is a network that does not broadcast its SSID, so an
- * SSID-specific probe request must be used for scans.
- */
- public boolean hiddenSSID;
-
- /**
- * True if the network requires Protected Management Frames (PMF), false otherwise.
- * @hide
- */
- @SystemApi
- public boolean requirePmf;
-
- /**
- * Update identifier, for Passpoint network.
- * @hide
- */
- public String updateIdentifier;
-
- /**
- * The set of key management protocols supported by this configuration.
- * See {@link KeyMgmt} for descriptions of the values.
- * Defaults to WPA-PSK WPA-EAP.
- */
- @NonNull
- public BitSet allowedKeyManagement;
- /**
- * The set of security protocols supported by this configuration.
- * See {@link Protocol} for descriptions of the values.
- * Defaults to WPA RSN.
- */
- @NonNull
- public BitSet allowedProtocols;
- /**
- * The set of authentication protocols supported by this configuration.
- * See {@link AuthAlgorithm} for descriptions of the values.
- * Defaults to automatic selection.
- */
- @NonNull
- public BitSet allowedAuthAlgorithms;
- /**
- * The set of pairwise ciphers for WPA supported by this configuration.
- * See {@link PairwiseCipher} for descriptions of the values.
- * Defaults to CCMP TKIP.
- */
- @NonNull
- public BitSet allowedPairwiseCiphers;
- /**
- * The set of group ciphers supported by this configuration.
- * See {@link GroupCipher} for descriptions of the values.
- * Defaults to CCMP TKIP WEP104 WEP40.
- */
- @NonNull
- public BitSet allowedGroupCiphers;
- /**
- * The set of group management ciphers supported by this configuration.
- * See {@link GroupMgmtCipher} for descriptions of the values.
- */
- @NonNull
- public BitSet allowedGroupManagementCiphers;
- /**
- * The set of SuiteB ciphers supported by this configuration.
- * To be used for WPA3-Enterprise mode. Set automatically by the framework based on the
- * certificate type that is used in this configuration.
- */
- @NonNull
- public BitSet allowedSuiteBCiphers;
- /**
- * The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the EAP.
- */
- public WifiEnterpriseConfig enterpriseConfig;
-
- /**
- * Fully qualified domain name of a Passpoint configuration
- */
- public String FQDN;
-
- /**
- * Name of Passpoint credential provider
- */
- public String providerFriendlyName;
-
- /**
- * Flag indicating if this network is provided by a home Passpoint provider or a roaming
- * Passpoint provider. This flag will be {@code true} if this network is provided by
- * a home Passpoint provider and {@code false} if is provided by a roaming Passpoint provider
- * or is a non-Passpoint network.
- */
- public boolean isHomeProviderNetwork;
-
- /**
- * Roaming Consortium Id list for Passpoint credential; identifies a set of networks where
- * Passpoint credential will be considered valid
- */
- public long[] roamingConsortiumIds;
-
- /**
- * True if this network configuration is visible to and usable by other users on the
- * same device, false otherwise.
- *
- * @hide
- */
- @SystemApi
- public boolean shared;
-
- /**
- * @hide
- */
- @NonNull
- @UnsupportedAppUsage
- private IpConfiguration mIpConfiguration;
-
- /**
- * @hide
- * dhcp server MAC address if known
- */
- public String dhcpServer;
-
- /**
- * @hide
- * default Gateway MAC address if known
- */
- @UnsupportedAppUsage
- public String defaultGwMacAddress;
-
- /**
- * @hide
- * last time we connected, this configuration had validated internet access
- */
- @UnsupportedAppUsage
- public boolean validatedInternetAccess;
-
- /**
- * @hide
- * The number of beacon intervals between Delivery Traffic Indication Maps (DTIM)
- * This value is populated from scan results that contain Beacon Frames, which are infrequent.
- * The value is not guaranteed to be set or current (Although it SHOULDNT change once set)
- * Valid values are from 1 - 255. Initialized here as 0, use this to check if set.
- */
- public int dtimInterval = 0;
-
- /**
- * Flag indicating if this configuration represents a legacy Passpoint configuration
- * (Release N or older). This is used for migrating Passpoint configuration from N to O.
- * This will no longer be needed after O.
- * @hide
- */
- public boolean isLegacyPasspointConfig = false;
- /**
- * @hide
- * Uid of app creating the configuration
- */
- @SystemApi
- public int creatorUid;
-
- /**
- * @hide
- * Uid of last app issuing a connection related command
- */
- @UnsupportedAppUsage
- public int lastConnectUid;
-
- /**
- * @hide
- * Uid of last app modifying the configuration
- */
- @SystemApi
- public int lastUpdateUid;
-
- /**
- * @hide
- * Universal name for app creating the configuration
- * see {@link PackageManager#getNameForUid(int)}
- */
- @SystemApi
- public String creatorName;
-
- /**
- * @hide
- * Universal name for app updating the configuration
- * see {@link PackageManager#getNameForUid(int)}
- */
- @SystemApi
- public String lastUpdateName;
-
- /**
- * The carrier ID identifies the operator who provides this network configuration.
- * see {@link TelephonyManager#getSimCarrierId()}
- * @hide
- */
- @SystemApi
- public int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
-
- /**
- * @hide
- * Auto-join is allowed by user for this network.
- * Default true.
- */
- @SystemApi
- public boolean allowAutojoin = true;
-
- /** @hide **/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public static int INVALID_RSSI = -127;
-
- /**
- * @hide
- * Number of reports indicating no Internet Access
- */
- @UnsupportedAppUsage
- public int numNoInternetAccessReports;
-
- /**
- * @hide
- * The WiFi configuration is considered to have no internet access for purpose of autojoining
- * if there has been a report of it having no internet access, and, it never have had
- * internet access in the past.
- */
- @SystemApi
- public boolean hasNoInternetAccess() {
- return numNoInternetAccessReports > 0 && !validatedInternetAccess;
- }
-
- /**
- * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a
- * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to
- * this configuration and selects "don't ask again".
- * @hide
- */
- @UnsupportedAppUsage
- public boolean noInternetAccessExpected;
-
- /**
- * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a
- * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to
- * this configuration and selects "don't ask again".
- * @hide
- */
- @SystemApi
- public boolean isNoInternetAccessExpected() {
- return noInternetAccessExpected;
- }
-
- /**
- * This Wifi configuration is expected for OSU(Online Sign Up) of Passpoint Release 2.
- * @hide
- */
- public boolean osu;
-
- /**
- * @hide
- * Last time the system was connected to this configuration.
- */
- public long lastConnected;
-
- /**
- * @hide
- * Last time the system was disconnected to this configuration.
- */
- public long lastDisconnected;
-
- /**
- * Set if the configuration was self added by the framework
- * This boolean is cleared if we get a connect/save/ update or
- * any wifiManager command that indicate the user interacted with the configuration
- * since we will now consider that the configuration belong to him.
- * @deprecated only kept for @UnsupportedAppUsage
- * @hide
- */
- @UnsupportedAppUsage
- public boolean selfAdded;
-
- /**
- * Peer WifiConfiguration this WifiConfiguration was added for
- * @hide
- */
- public String peerWifiConfiguration;
-
- /**
- * @hide
- * Indicate that a WifiConfiguration is temporary and should not be saved
- * nor considered by AutoJoin.
- */
- public boolean ephemeral;
-
- /**
- * @hide
- * Indicate that a WifiConfiguration is temporary and should not be saved
- * nor considered by AutoJoin.
- */
- @SystemApi
- public boolean isEphemeral() {
- return ephemeral;
- }
-
- /**
- * Indicate whether the network is trusted or not. Networks are considered trusted
- * if the user explicitly allowed this network connection.
- * This bit can be used by suggestion network, see
- * {@link WifiNetworkSuggestion.Builder#setUntrusted(boolean)}
- * @hide
- */
- public boolean trusted;
-
- /**
- * True if this Wifi configuration is created from a {@link WifiNetworkSuggestion},
- * false otherwise.
- *
- * @hide
- */
- @SystemApi
- public boolean fromWifiNetworkSuggestion;
-
- /**
- * True if this Wifi configuration is created from a {@link WifiNetworkSpecifier},
- * false otherwise.
- *
- * @hide
- */
- @SystemApi
- public boolean fromWifiNetworkSpecifier;
-
- /**
- * True if the creator of this configuration has expressed that it
- * should be considered metered, false otherwise.
- *
- * @see #isMetered(WifiConfiguration, WifiInfo)
- *
- * @hide
- */
- @SystemApi
- public boolean meteredHint;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"METERED_OVERRIDE_"}, value = {
- METERED_OVERRIDE_NONE,
- METERED_OVERRIDE_METERED,
- METERED_OVERRIDE_NOT_METERED})
- public @interface MeteredOverride {}
-
- /**
- * No metered override.
- * @hide
- */
- @SystemApi
- public static final int METERED_OVERRIDE_NONE = 0;
- /**
- * Override network to be metered.
- * @hide
- */
- @SystemApi
- public static final int METERED_OVERRIDE_METERED = 1;
- /**
- * Override network to be unmetered.
- * @hide
- */
- @SystemApi
- public static final int METERED_OVERRIDE_NOT_METERED = 2;
-
- /**
- * Indicates if the end user has expressed an explicit opinion about the
- * meteredness of this network, such as through the Settings app.
- * This value is one of {@link #METERED_OVERRIDE_NONE}, {@link #METERED_OVERRIDE_METERED},
- * or {@link #METERED_OVERRIDE_NOT_METERED}.
- * <p>
- * This should always override any values from {@link #meteredHint} or
- * {@link WifiInfo#getMeteredHint()}.
- *
- * By default this field is set to {@link #METERED_OVERRIDE_NONE}.
- *
- * @see #isMetered(WifiConfiguration, WifiInfo)
- * @hide
- */
- @SystemApi
- @MeteredOverride
- public int meteredOverride = METERED_OVERRIDE_NONE;
-
- /**
- * Blend together all the various opinions to decide if the given network
- * should be considered metered or not.
- *
- * @hide
- */
- @SystemApi
- public static boolean isMetered(@Nullable WifiConfiguration config, @Nullable WifiInfo info) {
- boolean metered = false;
- if (info != null && info.getMeteredHint()) {
- metered = true;
- }
- if (config != null && config.meteredHint) {
- metered = true;
- }
- if (config != null
- && config.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED) {
- metered = true;
- }
- if (config != null
- && config.meteredOverride == WifiConfiguration.METERED_OVERRIDE_NOT_METERED) {
- metered = false;
- }
- return metered;
- }
-
- /**
- * @hide
- * Returns true if this WiFi config is for an open network.
- */
- public boolean isOpenNetwork() {
- final int cardinality = allowedKeyManagement.cardinality();
- final boolean hasNoKeyMgmt = cardinality == 0
- || (cardinality == 1 && (allowedKeyManagement.get(KeyMgmt.NONE)
- || allowedKeyManagement.get(KeyMgmt.OWE)));
-
- boolean hasNoWepKeys = true;
- if (wepKeys != null) {
- for (int i = 0; i < wepKeys.length; i++) {
- if (wepKeys[i] != null) {
- hasNoWepKeys = false;
- break;
- }
- }
- }
-
- return hasNoKeyMgmt && hasNoWepKeys;
- }
-
- /**
- * @hide
- * Setting this value will force scan results associated with this configuration to
- * be included in the bucket of networks that are externally scored.
- * If not set, associated scan results will be treated as legacy saved networks and
- * will take precedence over networks in the scored category.
- */
- @SystemApi
- public boolean useExternalScores;
-
- /**
- * @hide
- * Number of time the scorer overrode a the priority based choice, when comparing two
- * WifiConfigurations, note that since comparing WifiConfiguration happens very often
- * potentially at every scan, this number might become very large, even on an idle
- * system.
- */
- @SystemApi
- public int numScorerOverride;
-
- /**
- * @hide
- * Number of time the scorer overrode a the priority based choice, and the comparison
- * triggered a network switch
- */
- @SystemApi
- public int numScorerOverrideAndSwitchedNetwork;
-
- /**
- * @hide
- * Number of time we associated to this configuration.
- */
- @SystemApi
- public int numAssociation;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"RANDOMIZATION_"}, value = {
- RANDOMIZATION_NONE,
- RANDOMIZATION_PERSISTENT})
- public @interface MacRandomizationSetting {}
-
- /**
- * Use factory MAC when connecting to this network
- * @hide
- */
- @SystemApi
- public static final int RANDOMIZATION_NONE = 0;
- /**
- * Generate a randomized MAC once and reuse it for all connections to this network
- * @hide
- */
- @SystemApi
- public static final int RANDOMIZATION_PERSISTENT = 1;
-
- /**
- * Level of MAC randomization for this network.
- * One of {@link #RANDOMIZATION_NONE} or {@link #RANDOMIZATION_PERSISTENT}.
- * By default this field is set to {@link #RANDOMIZATION_PERSISTENT}.
- * @hide
- */
- @SystemApi
- @MacRandomizationSetting
- public int macRandomizationSetting = RANDOMIZATION_PERSISTENT;
-
- /**
- * @hide
- * Randomized MAC address to use with this particular network
- */
- @NonNull
- private MacAddress mRandomizedMacAddress;
-
- /**
- * @hide
- * The wall clock time of when |mRandomizedMacAddress| should be re-randomized in aggressive
- * randomization mode.
- */
- public long randomizedMacExpirationTimeMs = 0;
-
- /**
- * @hide
- * Checks if the given MAC address can be used for Connected Mac Randomization
- * by verifying that it is non-null, unicast, locally assigned, and not default mac.
- * @param mac MacAddress to check
- * @return true if mac is good to use
- */
- public static boolean isValidMacAddressForRandomization(MacAddress mac) {
- return mac != null && !MacAddressUtils.isMulticastAddress(mac) && mac.isLocallyAssigned()
- && !MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS).equals(mac);
- }
-
- /**
- * Returns MAC address set to be the local randomized MAC address.
- * Depending on user preference, the device may or may not use the returned MAC address for
- * connections to this network.
- * <p>
- * Information is restricted to Device Owner, Profile Owner, and Carrier apps
- * (which will only obtain addresses for configurations which they create). Other callers
- * will receive a default "02:00:00:00:00:00" MAC address.
- */
- public @NonNull MacAddress getRandomizedMacAddress() {
- return mRandomizedMacAddress;
- }
-
- /**
- * @hide
- * @param mac MacAddress to change into
- */
- public void setRandomizedMacAddress(@NonNull MacAddress mac) {
- if (mac == null) {
- Log.e(TAG, "setRandomizedMacAddress received null MacAddress.");
- return;
- }
- mRandomizedMacAddress = mac;
- }
-
- /** @hide
- * Boost given to RSSI on a home network for the purpose of calculating the score
- * This adds stickiness to home networks, as defined by:
- * - less than 4 known BSSIDs
- * - PSK only
- * - TODO: add a test to verify that all BSSIDs are behind same gateway
- ***/
- public static final int HOME_NETWORK_RSSI_BOOST = 5;
-
- /**
- * This class is used to contain all the information and API used for quality network selection.
- * @hide
- */
- @SystemApi
- public static class NetworkSelectionStatus {
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = "NETWORK_SELECTION_",
- value = {
- NETWORK_SELECTION_ENABLED,
- NETWORK_SELECTION_TEMPORARY_DISABLED,
- NETWORK_SELECTION_PERMANENTLY_DISABLED})
- public @interface NetworkEnabledStatus {}
- /**
- * This network will be considered as a potential candidate to connect to during network
- * selection.
- */
- public static final int NETWORK_SELECTION_ENABLED = 0;
- /**
- * This network was temporary disabled. May be re-enabled after a time out.
- */
- public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1;
- /**
- * This network was permanently disabled.
- */
- public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2;
- /**
- * Maximum Network selection status
- * @hide
- */
- public static final int NETWORK_SELECTION_STATUS_MAX = 3;
-
- /**
- * Quality network selection status String (for debug purpose). Use Quality network
- * selection status value as index to extec the corresponding debug string
- * @hide
- */
- public static final String[] QUALITY_NETWORK_SELECTION_STATUS = {
- "NETWORK_SELECTION_ENABLED",
- "NETWORK_SELECTION_TEMPORARY_DISABLED",
- "NETWORK_SELECTION_PERMANENTLY_DISABLED"};
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = "DISABLED_", value = {
- DISABLED_NONE,
- DISABLED_ASSOCIATION_REJECTION,
- DISABLED_AUTHENTICATION_FAILURE,
- DISABLED_DHCP_FAILURE,
- DISABLED_NO_INTERNET_TEMPORARY,
- DISABLED_AUTHENTICATION_NO_CREDENTIALS,
- DISABLED_NO_INTERNET_PERMANENT,
- DISABLED_BY_WIFI_MANAGER,
- DISABLED_BY_WRONG_PASSWORD,
- DISABLED_AUTHENTICATION_NO_SUBSCRIPTION})
- public @interface NetworkSelectionDisableReason {}
-
- // Quality Network disabled reasons
- /** Default value. Means not disabled. */
- public static final int DISABLED_NONE = 0;
- /**
- * The starting index for network selection disabled reasons.
- * @hide
- */
- public static final int NETWORK_SELECTION_DISABLED_STARTING_INDEX = 1;
- /**
- * The starting index for network selection temporarily disabled reasons.
- * @hide
- */
- public static final int TEMPORARILY_DISABLED_STARTING_INDEX = 1;
- /** This network is disabled because of multiple association rejections. */
- public static final int DISABLED_ASSOCIATION_REJECTION = 1;
- /** This network is disabled because of multiple authentication failure. */
- public static final int DISABLED_AUTHENTICATION_FAILURE = 2;
- /** This network is disabled because of multiple DHCP failure. */
- public static final int DISABLED_DHCP_FAILURE = 3;
- /** This network is temporarily disabled because it has no Internet access. */
- public static final int DISABLED_NO_INTERNET_TEMPORARY = 4;
- /**
- * The starting index for network selection permanently disabled reasons.
- * @hide
- */
- public static final int PERMANENTLY_DISABLED_STARTING_INDEX = 5;
- /** This network is disabled due to absence of user credentials */
- public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 5;
- /**
- * This network is permanently disabled because it has no Internet access and the user does
- * not want to stay connected.
- */
- public static final int DISABLED_NO_INTERNET_PERMANENT = 6;
- /** This network is disabled due to WifiManager disabling it explicitly. */
- public static final int DISABLED_BY_WIFI_MANAGER = 7;
- /** This network is disabled due to wrong password. */
- public static final int DISABLED_BY_WRONG_PASSWORD = 8;
- /** This network is disabled because service is not subscribed. */
- public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 9;
- /**
- * All other disable reasons should be strictly less than this value.
- * @hide
- */
- public static final int NETWORK_SELECTION_DISABLED_MAX = 10;
-
- /**
- * Get an integer that is equal to the maximum integer value of all the
- * DISABLED_* reasons
- * e.g. {@link #DISABLED_NONE}, {@link #DISABLED_ASSOCIATION_REJECTION}, etc.
- *
- * All DISABLED_* constants will be contiguous in the range
- * 0, 1, 2, 3, ..., getMaxNetworkSelectionDisableReasons()
- *
- * <br />
- * For example, this can be used to iterate through all the network selection
- * disable reasons like so:
- * <pre>{@code
- * for (int reason = 0; reason <= getMaxNetworkSelectionDisableReasons(); reason++) {
- * ...
- * }
- * }</pre>
- */
- public static int getMaxNetworkSelectionDisableReason() {
- return NETWORK_SELECTION_DISABLED_MAX - 1;
- }
-
- /**
- * Contains info about disable reasons.
- * @hide
- */
- public static final class DisableReasonInfo {
- /**
- * String representation for the disable reason.
- * Note that these strings are persisted in
- * {@link
- * com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil#writeToXml},
- * so do not change the string values to maintain backwards compatibility.
- */
- public final String mReasonStr;
- /**
- * Network Selection disable reason threshold, used to debounce network failures before
- * we disable them.
- */
- public final int mDisableThreshold;
- /**
- * Network Selection disable timeout for the error. After the timeout milliseconds,
- * enable the network again.
- */
- public final int mDisableTimeoutMillis;
-
- /**
- * Constructor
- * @param reasonStr string representation of the error
- * @param disableThreshold number of failures before we disable the network
- * @param disableTimeoutMillis the timeout, in milliseconds, before we re-enable the
- * network after disabling it
- */
- public DisableReasonInfo(String reasonStr, int disableThreshold,
- int disableTimeoutMillis) {
- mReasonStr = reasonStr;
- mDisableThreshold = disableThreshold;
- mDisableTimeoutMillis = disableTimeoutMillis;
- }
- }
-
- /**
- * Quality network selection disable reason infos.
- * @hide
- */
- public static final SparseArray<DisableReasonInfo> DISABLE_REASON_INFOS =
- buildDisableReasonInfos();
-
- private static SparseArray<DisableReasonInfo> buildDisableReasonInfos() {
- SparseArray<DisableReasonInfo> reasons = new SparseArray<>();
-
- reasons.append(DISABLED_NONE,
- new DisableReasonInfo(
- // Note that these strings are persisted in
- // XmlUtil.NetworkSelectionStatusXmlUtil#writeToXml,
- // so do not change the string values to maintain backwards
- // compatibility.
- "NETWORK_SELECTION_ENABLE",
- -1,
- Integer.MAX_VALUE));
-
- reasons.append(DISABLED_ASSOCIATION_REJECTION,
- new DisableReasonInfo(
- // Note that there is a space at the end of this string. Cannot fix
- // since this string is persisted.
- "NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ",
- 5,
- 5 * 60 * 1000));
-
- reasons.append(DISABLED_AUTHENTICATION_FAILURE,
- new DisableReasonInfo(
- "NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE",
- 5,
- 5 * 60 * 1000));
-
- reasons.append(DISABLED_DHCP_FAILURE,
- new DisableReasonInfo(
- "NETWORK_SELECTION_DISABLED_DHCP_FAILURE",
- 5,
- 5 * 60 * 1000));
-
- reasons.append(DISABLED_NO_INTERNET_TEMPORARY,
- new DisableReasonInfo(
- "NETWORK_SELECTION_DISABLED_NO_INTERNET_TEMPORARY",
- 1,
- 10 * 60 * 1000));
-
- reasons.append(DISABLED_AUTHENTICATION_NO_CREDENTIALS,
- new DisableReasonInfo(
- "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS",
- 1,
- Integer.MAX_VALUE));
-
- reasons.append(DISABLED_NO_INTERNET_PERMANENT,
- new DisableReasonInfo(
- "NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT",
- 1,
- Integer.MAX_VALUE));
-
- reasons.append(DISABLED_BY_WIFI_MANAGER,
- new DisableReasonInfo(
- "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER",
- 1,
- Integer.MAX_VALUE));
-
- reasons.append(DISABLED_BY_WRONG_PASSWORD,
- new DisableReasonInfo(
- "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD",
- 1,
- Integer.MAX_VALUE));
-
- reasons.append(DISABLED_AUTHENTICATION_NO_SUBSCRIPTION,
- new DisableReasonInfo(
- "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_SUBSCRIPTION",
- 1,
- Integer.MAX_VALUE));
-
- return reasons;
- }
-
- /**
- * Get the {@link NetworkSelectionDisableReason} int code by its string value.
- * @return the NetworkSelectionDisableReason int code corresponding to the reason string,
- * or -1 if the reason string is unrecognized.
- * @hide
- */
- @NetworkSelectionDisableReason
- public static int getDisableReasonByString(@NonNull String reasonString) {
- for (int i = 0; i < DISABLE_REASON_INFOS.size(); i++) {
- int key = DISABLE_REASON_INFOS.keyAt(i);
- DisableReasonInfo value = DISABLE_REASON_INFOS.valueAt(i);
- if (value != null && TextUtils.equals(reasonString, value.mReasonStr)) {
- return key;
- }
- }
- Log.e(TAG, "Unrecognized network disable reason: " + reasonString);
- return -1;
- }
-
- /**
- * Invalid time stamp for network selection disable
- * @hide
- */
- public static final long INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP = -1L;
-
- /**
- * This constant indicates the current configuration has connect choice set
- */
- private static final int CONNECT_CHOICE_EXISTS = 1;
-
- /**
- * This constant indicates the current configuration does not have connect choice set
- */
- private static final int CONNECT_CHOICE_NOT_EXISTS = -1;
-
- // fields for QualityNetwork Selection
- /**
- * Network selection status, should be in one of three status: enable, temporaily disabled
- * or permanently disabled
- */
- @NetworkEnabledStatus
- private int mStatus;
-
- /**
- * Reason for disable this network
- */
- @NetworkSelectionDisableReason
- private int mNetworkSelectionDisableReason;
-
- /**
- * Last time we temporarily disabled the configuration
- */
- private long mTemporarilyDisabledTimestamp = INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP;
-
- /**
- * counter for each Network selection disable reason
- */
- private int[] mNetworkSeclectionDisableCounter = new int[NETWORK_SELECTION_DISABLED_MAX];
-
- /**
- * Connect Choice over this configuration
- *
- * When current wifi configuration is visible to the user but user explicitly choose to
- * connect to another network X, the another networks X's configure key will be stored here.
- * We will consider user has a preference of X over this network. And in the future,
- * network selection will always give X a higher preference over this configuration.
- * configKey is : "SSID"-WEP-WPA_PSK-WPA_EAP
- */
- private String mConnectChoice;
-
- /**
- * Used to cache the temporary candidate during the network selection procedure. It will be
- * kept updating once a new scan result has a higher score than current one
- */
- private ScanResult mCandidate;
-
- /**
- * Used to cache the score of the current temporary candidate during the network
- * selection procedure.
- */
- private int mCandidateScore;
-
- /**
- * Indicate whether this network is visible in latest Qualified Network Selection. This
- * means there is scan result found related to this Configuration and meet the minimum
- * requirement. The saved network need not join latest Qualified Network Selection. For
- * example, it is disabled. True means network is visible in latest Qualified Network
- * Selection and false means network is invisible
- */
- private boolean mSeenInLastQualifiedNetworkSelection;
-
- /**
- * Boolean indicating if we have ever successfully connected to this network.
- *
- * This value will be set to true upon a successful connection.
- * This value will be set to false if a previous value was not stored in the config or if
- * the credentials are updated (ex. a password change).
- */
- private boolean mHasEverConnected;
-
- /**
- * set whether this network is visible in latest Qualified Network Selection
- * @param seen value set to candidate
- * @hide
- */
- public void setSeenInLastQualifiedNetworkSelection(boolean seen) {
- mSeenInLastQualifiedNetworkSelection = seen;
- }
-
- /**
- * get whether this network is visible in latest Qualified Network Selection
- * @return returns true -- network is visible in latest Qualified Network Selection
- * false -- network is invisible in latest Qualified Network Selection
- * @hide
- */
- public boolean getSeenInLastQualifiedNetworkSelection() {
- return mSeenInLastQualifiedNetworkSelection;
- }
- /**
- * set the temporary candidate of current network selection procedure
- * @param scanCandidate {@link ScanResult} the candidate set to mCandidate
- * @hide
- */
- public void setCandidate(ScanResult scanCandidate) {
- mCandidate = scanCandidate;
- }
-
- /**
- * get the temporary candidate of current network selection procedure
- * @return returns {@link ScanResult} temporary candidate of current network selection
- * procedure
- * @hide
- */
- public ScanResult getCandidate() {
- return mCandidate;
- }
-
- /**
- * set the score of the temporary candidate of current network selection procedure
- * @param score value set to mCandidateScore
- * @hide
- */
- public void setCandidateScore(int score) {
- mCandidateScore = score;
- }
-
- /**
- * get the score of the temporary candidate of current network selection procedure
- * @return returns score of the temporary candidate of current network selection procedure
- * @hide
- */
- public int getCandidateScore() {
- return mCandidateScore;
- }
-
- /**
- * get user preferred choice over this configuration
- * @return returns configKey of user preferred choice over this configuration
- * @hide
- */
- public String getConnectChoice() {
- return mConnectChoice;
- }
-
- /**
- * set user preferred choice over this configuration
- * @param newConnectChoice, the configKey of user preferred choice over this configuration
- * @hide
- */
- public void setConnectChoice(String newConnectChoice) {
- mConnectChoice = newConnectChoice;
- }
-
- /** Get the current Quality network selection status as a String (for debugging). */
- @NonNull
- public String getNetworkStatusString() {
- return QUALITY_NETWORK_SELECTION_STATUS[mStatus];
- }
-
- /** @hide */
- public void setHasEverConnected(boolean value) {
- mHasEverConnected = value;
- }
-
- /** True if the device has ever connected to this network, false otherwise. */
- public boolean hasEverConnected() {
- return mHasEverConnected;
- }
-
- /** @hide */
- public NetworkSelectionStatus() {
- // previously stored configs will not have this parameter, so we default to false.
- mHasEverConnected = false;
- }
-
- /**
- * NetworkSelectionStatus exports an immutable public API.
- * However, test code has a need to construct a NetworkSelectionStatus in a specific state.
- * (Note that mocking using Mockito does not work if the object needs to be parceled and
- * unparceled.)
- * Export a @SystemApi Builder to allow tests to construct a NetworkSelectionStatus object
- * in the desired state, without sacrificing NetworkSelectionStatus's immutability.
- */
- @VisibleForTesting
- public static final class Builder {
- private final NetworkSelectionStatus mNetworkSelectionStatus =
- new NetworkSelectionStatus();
-
- /**
- * Set the current network selection status.
- * One of:
- * {@link #NETWORK_SELECTION_ENABLED},
- * {@link #NETWORK_SELECTION_TEMPORARY_DISABLED},
- * {@link #NETWORK_SELECTION_PERMANENTLY_DISABLED}
- * @see NetworkSelectionStatus#getNetworkSelectionStatus()
- */
- @NonNull
- public Builder setNetworkSelectionStatus(@NetworkEnabledStatus int status) {
- mNetworkSelectionStatus.setNetworkSelectionStatus(status);
- return this;
- }
-
- /**
- *
- * Set the current network's disable reason.
- * One of the {@link #DISABLED_NONE} or DISABLED_* constants.
- * e.g. {@link #DISABLED_ASSOCIATION_REJECTION}.
- * @see NetworkSelectionStatus#getNetworkSelectionDisableReason()
- */
- @NonNull
- public Builder setNetworkSelectionDisableReason(
- @NetworkSelectionDisableReason int reason) {
- mNetworkSelectionStatus.setNetworkSelectionDisableReason(reason);
- return this;
- }
-
- /**
- * Build a NetworkSelectionStatus object.
- */
- @NonNull
- public NetworkSelectionStatus build() {
- NetworkSelectionStatus status = new NetworkSelectionStatus();
- status.copy(mNetworkSelectionStatus);
- return status;
- }
- }
-
- /**
- * Get the network disable reason string for a reason code (for debugging).
- * @param reason specific error reason. One of the {@link #DISABLED_NONE} or
- * DISABLED_* constants e.g. {@link #DISABLED_ASSOCIATION_REJECTION}.
- * @return network disable reason string, or null if the reason is invalid.
- */
- @Nullable
- public static String getNetworkSelectionDisableReasonString(
- @NetworkSelectionDisableReason int reason) {
- DisableReasonInfo info = DISABLE_REASON_INFOS.get(reason);
- if (info == null) {
- return null;
- } else {
- return info.mReasonStr;
- }
- }
- /**
- * get current network disable reason
- * @return current network disable reason in String (for debug purpose)
- * @hide
- */
- public String getNetworkSelectionDisableReasonString() {
- return getNetworkSelectionDisableReasonString(mNetworkSelectionDisableReason);
- }
-
- /**
- * Get the current network network selection status.
- * One of:
- * {@link #NETWORK_SELECTION_ENABLED},
- * {@link #NETWORK_SELECTION_TEMPORARY_DISABLED},
- * {@link #NETWORK_SELECTION_PERMANENTLY_DISABLED}
- */
- @NetworkEnabledStatus
- public int getNetworkSelectionStatus() {
- return mStatus;
- }
-
- /**
- * True if the current network is enabled to join network selection, false otherwise.
- * @hide
- */
- public boolean isNetworkEnabled() {
- return mStatus == NETWORK_SELECTION_ENABLED;
- }
-
- /**
- * @return whether current network is temporary disabled
- * @hide
- */
- public boolean isNetworkTemporaryDisabled() {
- return mStatus == NETWORK_SELECTION_TEMPORARY_DISABLED;
- }
-
- /**
- * True if the current network is permanently disabled, false otherwise.
- * @hide
- */
- public boolean isNetworkPermanentlyDisabled() {
- return mStatus == NETWORK_SELECTION_PERMANENTLY_DISABLED;
- }
-
- /**
- * set current network selection status
- * @param status network selection status to set
- * @hide
- */
- public void setNetworkSelectionStatus(int status) {
- if (status >= 0 && status < NETWORK_SELECTION_STATUS_MAX) {
- mStatus = status;
- }
- }
-
- /**
- * Returns the current network's disable reason.
- * One of the {@link #DISABLED_NONE} or DISABLED_* constants
- * e.g. {@link #DISABLED_ASSOCIATION_REJECTION}.
- */
- @NetworkSelectionDisableReason
- public int getNetworkSelectionDisableReason() {
- return mNetworkSelectionDisableReason;
- }
-
- /**
- * set Network disable reason
- * @param reason Network disable reason
- * @hide
- */
- public void setNetworkSelectionDisableReason(@NetworkSelectionDisableReason int reason) {
- if (reason >= 0 && reason < NETWORK_SELECTION_DISABLED_MAX) {
- mNetworkSelectionDisableReason = reason;
- } else {
- throw new IllegalArgumentException("Illegal reason value: " + reason);
- }
- }
-
- /**
- * @param timeStamp Set when current network is disabled in millisecond since January 1,
- * 1970 00:00:00.0 UTC
- * @hide
- */
- public void setDisableTime(long timeStamp) {
- mTemporarilyDisabledTimestamp = timeStamp;
- }
-
- /**
- * Returns when the current network was disabled, in milliseconds since January 1,
- * 1970 00:00:00.0 UTC.
- */
- public long getDisableTime() {
- return mTemporarilyDisabledTimestamp;
- }
-
- /**
- * Get the disable counter of a specific reason.
- * @param reason specific failure reason. One of the {@link #DISABLED_NONE} or
- * DISABLED_* constants e.g. {@link #DISABLED_ASSOCIATION_REJECTION}.
- * @exception IllegalArgumentException for invalid reason
- * @return counter number for specific error reason.
- */
- public int getDisableReasonCounter(@NetworkSelectionDisableReason int reason) {
- if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) {
- return mNetworkSeclectionDisableCounter[reason];
- } else {
- throw new IllegalArgumentException("Illegal reason value: " + reason);
- }
- }
-
- /**
- * set the counter of a specific failure reason
- * @param reason reason for disable error
- * @param value the counter value for this specific reason
- * @exception throw IllegalArgumentException for illegal input
- * @hide
- */
- public void setDisableReasonCounter(int reason, int value) {
- if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) {
- mNetworkSeclectionDisableCounter[reason] = value;
- } else {
- throw new IllegalArgumentException("Illegal reason value: " + reason);
- }
- }
-
- /**
- * increment the counter of a specific failure reason
- * @param reason a specific failure reason
- * @exception throw IllegalArgumentException for illegal input
- * @hide
- */
- public void incrementDisableReasonCounter(int reason) {
- if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) {
- mNetworkSeclectionDisableCounter[reason]++;
- } else {
- throw new IllegalArgumentException("Illegal reason value: " + reason);
- }
- }
-
- /**
- * clear the counter of a specific failure reason
- * @param reason a specific failure reason
- * @exception throw IllegalArgumentException for illegal input
- * @hide
- */
- public void clearDisableReasonCounter(int reason) {
- if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) {
- mNetworkSeclectionDisableCounter[reason] = DISABLED_NONE;
- } else {
- throw new IllegalArgumentException("Illegal reason value: " + reason);
- }
- }
-
- /**
- * clear all the failure reason counters
- * @hide
- */
- public void clearDisableReasonCounter() {
- Arrays.fill(mNetworkSeclectionDisableCounter, DISABLED_NONE);
- }
-
- /**
- * BSSID for connection to this network (through network selection procedure)
- */
- private String mNetworkSelectionBSSID;
-
- /**
- * get current network Selection BSSID
- * @return current network Selection BSSID
- * @hide
- */
- public String getNetworkSelectionBSSID() {
- return mNetworkSelectionBSSID;
- }
-
- /**
- * set network Selection BSSID
- * @param bssid The target BSSID for assocaition
- * @hide
- */
- public void setNetworkSelectionBSSID(String bssid) {
- mNetworkSelectionBSSID = bssid;
- }
-
- /** @hide */
- public void copy(NetworkSelectionStatus source) {
- mStatus = source.mStatus;
- mNetworkSelectionDisableReason = source.mNetworkSelectionDisableReason;
- for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX;
- index++) {
- mNetworkSeclectionDisableCounter[index] =
- source.mNetworkSeclectionDisableCounter[index];
- }
- mTemporarilyDisabledTimestamp = source.mTemporarilyDisabledTimestamp;
- mNetworkSelectionBSSID = source.mNetworkSelectionBSSID;
- setSeenInLastQualifiedNetworkSelection(source.getSeenInLastQualifiedNetworkSelection());
- setCandidate(source.getCandidate());
- setCandidateScore(source.getCandidateScore());
- setConnectChoice(source.getConnectChoice());
- setHasEverConnected(source.hasEverConnected());
- }
-
- /** @hide */
- public void writeToParcel(Parcel dest) {
- dest.writeInt(getNetworkSelectionStatus());
- dest.writeInt(getNetworkSelectionDisableReason());
- for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX;
- index++) {
- dest.writeInt(getDisableReasonCounter(index));
- }
- dest.writeLong(getDisableTime());
- dest.writeString(getNetworkSelectionBSSID());
- if (getConnectChoice() != null) {
- dest.writeInt(CONNECT_CHOICE_EXISTS);
- dest.writeString(getConnectChoice());
- } else {
- dest.writeInt(CONNECT_CHOICE_NOT_EXISTS);
- }
- dest.writeInt(hasEverConnected() ? 1 : 0);
- }
-
- /** @hide */
- public void readFromParcel(Parcel in) {
- setNetworkSelectionStatus(in.readInt());
- setNetworkSelectionDisableReason(in.readInt());
- for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX;
- index++) {
- setDisableReasonCounter(index, in.readInt());
- }
- setDisableTime(in.readLong());
- setNetworkSelectionBSSID(in.readString());
- if (in.readInt() == CONNECT_CHOICE_EXISTS) {
- setConnectChoice(in.readString());
- } else {
- setConnectChoice(null);
- }
- setHasEverConnected(in.readInt() != 0);
- }
- }
-
- /**
- * @hide
- * network selection related member
- */
- private NetworkSelectionStatus mNetworkSelectionStatus = new NetworkSelectionStatus();
-
- /**
- * This class is intended to store extra failure reason information for the most recent
- * connection attempt, so that it may be surfaced to the settings UI
- * @hide
- */
- // TODO(b/148626966): called by SUW via reflection, remove once SUW is updated
- public static class RecentFailure {
-
- private RecentFailure() {}
-
- /**
- * Association Rejection Status code (NONE for success/non-association-rejection-fail)
- */
- @RecentFailureReason
- private int mAssociationStatus = RECENT_FAILURE_NONE;
-
- /**
- * @param status the association status code for the recent failure
- */
- public void setAssociationStatus(@RecentFailureReason int status) {
- mAssociationStatus = status;
- }
- /**
- * Sets the RecentFailure to NONE
- */
- public void clear() {
- mAssociationStatus = RECENT_FAILURE_NONE;
- }
- /**
- * Get the recent failure code. One of {@link #RECENT_FAILURE_NONE} or
- * {@link #RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA}.
- */
- @RecentFailureReason
- public int getAssociationStatus() {
- return mAssociationStatus;
- }
- }
-
- /**
- * RecentFailure member
- * @hide
- */
- // TODO(b/148626966): called by SUW via reflection, once SUW is updated, make private and
- // rename to mRecentFailure
- @NonNull
- public final RecentFailure recentFailure = new RecentFailure();
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = "RECENT_FAILURE_", value = {
- RECENT_FAILURE_NONE,
- RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA})
- public @interface RecentFailureReason {}
-
- /**
- * No recent failure, or no specific reason given for the recent connection failure
- * @hide
- */
- @SystemApi
- public static final int RECENT_FAILURE_NONE = 0;
- /**
- * Connection to this network recently failed due to Association Rejection Status 17
- * (AP is full)
- * @hide
- */
- @SystemApi
- public static final int RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA = 17;
-
- /**
- * Get the failure reason for the most recent connection attempt, or
- * {@link #RECENT_FAILURE_NONE} if there was no failure.
- *
- * Failure reasons include:
- * {@link #RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA}
- *
- * @hide
- */
- @RecentFailureReason
- @SystemApi
- public int getRecentFailureReason() {
- return recentFailure.getAssociationStatus();
- }
-
- /**
- * Get the network selection status.
- * @hide
- */
- @NonNull
- @SystemApi
- public NetworkSelectionStatus getNetworkSelectionStatus() {
- return mNetworkSelectionStatus;
- }
-
- /**
- * Set the network selection status.
- * @hide
- */
- @SystemApi
- public void setNetworkSelectionStatus(@NonNull NetworkSelectionStatus status) {
- mNetworkSelectionStatus = status;
- }
-
- /**
- * @hide
- * Linked Configurations: represent the set of Wificonfigurations that are equivalent
- * regarding roaming and auto-joining.
- * The linked configuration may or may not have same SSID, and may or may not have same
- * credentials.
- * For instance, linked configurations will have same defaultGwMacAddress or same dhcp server.
- */
- public HashMap<String, Integer> linkedConfigurations;
-
- public WifiConfiguration() {
- networkId = INVALID_NETWORK_ID;
- SSID = null;
- BSSID = null;
- FQDN = null;
- roamingConsortiumIds = new long[0];
- priority = 0;
- hiddenSSID = false;
- allowedKeyManagement = new BitSet();
- allowedProtocols = new BitSet();
- allowedAuthAlgorithms = new BitSet();
- allowedPairwiseCiphers = new BitSet();
- allowedGroupCiphers = new BitSet();
- allowedGroupManagementCiphers = new BitSet();
- allowedSuiteBCiphers = new BitSet();
- wepKeys = new String[4];
- for (int i = 0; i < wepKeys.length; i++) {
- wepKeys[i] = null;
- }
- enterpriseConfig = new WifiEnterpriseConfig();
- ephemeral = false;
- osu = false;
- trusted = true; // Networks are considered trusted by default.
- fromWifiNetworkSuggestion = false;
- fromWifiNetworkSpecifier = false;
- meteredHint = false;
- meteredOverride = METERED_OVERRIDE_NONE;
- useExternalScores = false;
- validatedInternetAccess = false;
- mIpConfiguration = new IpConfiguration();
- lastUpdateUid = -1;
- creatorUid = -1;
- shared = true;
- dtimInterval = 0;
- mRandomizedMacAddress = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
- }
-
- /**
- * Identify if this configuration represents a Passpoint network
- */
- public boolean isPasspoint() {
- return !TextUtils.isEmpty(FQDN)
- && !TextUtils.isEmpty(providerFriendlyName)
- && enterpriseConfig != null
- && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE
- && !TextUtils.isEmpty(mPasspointUniqueId);
- }
-
- /**
- * Helper function, identify if a configuration is linked
- * @hide
- */
- public boolean isLinked(WifiConfiguration config) {
- if (config != null) {
- if (config.linkedConfigurations != null && linkedConfigurations != null) {
- if (config.linkedConfigurations.get(getKey()) != null
- && linkedConfigurations.get(config.getKey()) != null) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Helper function, idenfity if a configuration should be treated as an enterprise network
- * @hide
- */
- @UnsupportedAppUsage
- public boolean isEnterprise() {
- return (allowedKeyManagement.get(KeyMgmt.WPA_EAP)
- || allowedKeyManagement.get(KeyMgmt.IEEE8021X)
- || allowedKeyManagement.get(KeyMgmt.SUITE_B_192)
- || allowedKeyManagement.get(KeyMgmt.WAPI_CERT))
- && enterpriseConfig != null
- && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE;
- }
-
- private static String logTimeOfDay(long millis) {
- Calendar c = Calendar.getInstance();
- if (millis >= 0) {
- c.setTimeInMillis(millis);
- return String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c);
- } else {
- return Long.toString(millis);
- }
- }
-
- @Override
- public String toString() {
- StringBuilder sbuf = new StringBuilder();
- if (this.status == WifiConfiguration.Status.CURRENT) {
- sbuf.append("* ");
- } else if (this.status == WifiConfiguration.Status.DISABLED) {
- sbuf.append("- DSBLE ");
- }
- sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID).
- append(" PROVIDER-NAME: ").append(this.providerFriendlyName).
- append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN)
- .append(" HOME-PROVIDER-NETWORK: ").append(this.isHomeProviderNetwork)
- .append(" PRIO: ").append(this.priority)
- .append(" HIDDEN: ").append(this.hiddenSSID)
- .append(" PMF: ").append(this.requirePmf)
- .append("CarrierId: ").append(this.carrierId)
- .append('\n');
-
-
- sbuf.append(" NetworkSelectionStatus ")
- .append(mNetworkSelectionStatus.getNetworkStatusString())
- .append("\n");
- if (mNetworkSelectionStatus.getNetworkSelectionDisableReason() > 0) {
- sbuf.append(" mNetworkSelectionDisableReason ")
- .append(mNetworkSelectionStatus.getNetworkSelectionDisableReasonString())
- .append("\n");
-
- for (int index = NetworkSelectionStatus.DISABLED_NONE;
- index < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; index++) {
- if (mNetworkSelectionStatus.getDisableReasonCounter(index) != 0) {
- sbuf.append(
- NetworkSelectionStatus.getNetworkSelectionDisableReasonString(index))
- .append(" counter:")
- .append(mNetworkSelectionStatus.getDisableReasonCounter(index))
- .append("\n");
- }
- }
- }
- if (mNetworkSelectionStatus.getConnectChoice() != null) {
- sbuf.append(" connect choice: ").append(mNetworkSelectionStatus.getConnectChoice());
- }
- sbuf.append(" hasEverConnected: ")
- .append(mNetworkSelectionStatus.hasEverConnected()).append("\n");
-
- if (this.numAssociation > 0) {
- sbuf.append(" numAssociation ").append(this.numAssociation).append("\n");
- }
- if (this.numNoInternetAccessReports > 0) {
- sbuf.append(" numNoInternetAccessReports ");
- sbuf.append(this.numNoInternetAccessReports).append("\n");
- }
- if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess");
- if (this.ephemeral) sbuf.append(" ephemeral");
- if (this.osu) sbuf.append(" osu");
- if (this.trusted) sbuf.append(" trusted");
- if (this.fromWifiNetworkSuggestion) sbuf.append(" fromWifiNetworkSuggestion");
- if (this.fromWifiNetworkSpecifier) sbuf.append(" fromWifiNetworkSpecifier");
- if (this.meteredHint) sbuf.append(" meteredHint");
- if (this.useExternalScores) sbuf.append(" useExternalScores");
- if (this.validatedInternetAccess || this.ephemeral || this.trusted
- || this.fromWifiNetworkSuggestion || this.fromWifiNetworkSpecifier
- || this.meteredHint || this.useExternalScores) {
- sbuf.append("\n");
- }
- if (this.meteredOverride != METERED_OVERRIDE_NONE) {
- sbuf.append(" meteredOverride ").append(meteredOverride).append("\n");
- }
- sbuf.append(" macRandomizationSetting: ").append(macRandomizationSetting).append("\n");
- sbuf.append(" mRandomizedMacAddress: ").append(mRandomizedMacAddress).append("\n");
- sbuf.append(" randomizedMacExpirationTimeMs: ")
- .append(randomizedMacExpirationTimeMs == 0 ? "<none>"
- : logTimeOfDay(randomizedMacExpirationTimeMs)).append("\n");
- sbuf.append(" KeyMgmt:");
- for (int k = 0; k < this.allowedKeyManagement.size(); k++) {
- if (this.allowedKeyManagement.get(k)) {
- sbuf.append(" ");
- if (k < KeyMgmt.strings.length) {
- sbuf.append(KeyMgmt.strings[k]);
- } else {
- sbuf.append("??");
- }
- }
- }
- sbuf.append(" Protocols:");
- for (int p = 0; p < this.allowedProtocols.size(); p++) {
- if (this.allowedProtocols.get(p)) {
- sbuf.append(" ");
- if (p < Protocol.strings.length) {
- sbuf.append(Protocol.strings[p]);
- } else {
- sbuf.append("??");
- }
- }
- }
- sbuf.append('\n');
- sbuf.append(" AuthAlgorithms:");
- for (int a = 0; a < this.allowedAuthAlgorithms.size(); a++) {
- if (this.allowedAuthAlgorithms.get(a)) {
- sbuf.append(" ");
- if (a < AuthAlgorithm.strings.length) {
- sbuf.append(AuthAlgorithm.strings[a]);
- } else {
- sbuf.append("??");
- }
- }
- }
- sbuf.append('\n');
- sbuf.append(" PairwiseCiphers:");
- for (int pc = 0; pc < this.allowedPairwiseCiphers.size(); pc++) {
- if (this.allowedPairwiseCiphers.get(pc)) {
- sbuf.append(" ");
- if (pc < PairwiseCipher.strings.length) {
- sbuf.append(PairwiseCipher.strings[pc]);
- } else {
- sbuf.append("??");
- }
- }
- }
- sbuf.append('\n');
- sbuf.append(" GroupCiphers:");
- for (int gc = 0; gc < this.allowedGroupCiphers.size(); gc++) {
- if (this.allowedGroupCiphers.get(gc)) {
- sbuf.append(" ");
- if (gc < GroupCipher.strings.length) {
- sbuf.append(GroupCipher.strings[gc]);
- } else {
- sbuf.append("??");
- }
- }
- }
- sbuf.append('\n');
- sbuf.append(" GroupMgmtCiphers:");
- for (int gmc = 0; gmc < this.allowedGroupManagementCiphers.size(); gmc++) {
- if (this.allowedGroupManagementCiphers.get(gmc)) {
- sbuf.append(" ");
- if (gmc < GroupMgmtCipher.strings.length) {
- sbuf.append(GroupMgmtCipher.strings[gmc]);
- } else {
- sbuf.append("??");
- }
- }
- }
- sbuf.append('\n');
- sbuf.append(" SuiteBCiphers:");
- for (int sbc = 0; sbc < this.allowedSuiteBCiphers.size(); sbc++) {
- if (this.allowedSuiteBCiphers.get(sbc)) {
- sbuf.append(" ");
- if (sbc < SuiteBCipher.strings.length) {
- sbuf.append(SuiteBCipher.strings[sbc]);
- } else {
- sbuf.append("??");
- }
- }
- }
- sbuf.append('\n').append(" PSK/SAE: ");
- if (this.preSharedKey != null) {
- sbuf.append('*');
- }
-
- sbuf.append("\nEnterprise config:\n");
- sbuf.append(enterpriseConfig);
-
- sbuf.append("IP config:\n");
- sbuf.append(mIpConfiguration.toString());
-
- if (mNetworkSelectionStatus.getNetworkSelectionBSSID() != null) {
- sbuf.append(" networkSelectionBSSID="
- + mNetworkSelectionStatus.getNetworkSelectionBSSID());
- }
- long now_ms = SystemClock.elapsedRealtime();
- if (mNetworkSelectionStatus.getDisableTime() != NetworkSelectionStatus
- .INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP) {
- sbuf.append('\n');
- long diff = now_ms - mNetworkSelectionStatus.getDisableTime();
- if (diff <= 0) {
- sbuf.append(" blackListed since <incorrect>");
- } else {
- sbuf.append(" blackListed: ").append(Long.toString(diff / 1000)).append("sec ");
- }
- }
- if (creatorUid != 0) sbuf.append(" cuid=" + creatorUid);
- if (creatorName != null) sbuf.append(" cname=" + creatorName);
- if (lastUpdateUid != 0) sbuf.append(" luid=" + lastUpdateUid);
- if (lastUpdateName != null) sbuf.append(" lname=" + lastUpdateName);
- if (updateIdentifier != null) sbuf.append(" updateIdentifier=" + updateIdentifier);
- sbuf.append(" lcuid=" + lastConnectUid);
- sbuf.append(" allowAutojoin=" + allowAutojoin);
- sbuf.append(" noInternetAccessExpected=" + noInternetAccessExpected);
- sbuf.append(" mostRecentlyConnected=" + isMostRecentlyConnected);
-
- sbuf.append(" ");
-
- if (this.lastConnected != 0) {
- sbuf.append('\n');
- sbuf.append("lastConnected: ").append(logTimeOfDay(this.lastConnected));
- sbuf.append(" ");
- }
- sbuf.append('\n');
- if (this.linkedConfigurations != null) {
- for (String key : this.linkedConfigurations.keySet()) {
- sbuf.append(" linked: ").append(key);
- sbuf.append('\n');
- }
- }
- sbuf.append("recentFailure: ").append("Association Rejection code: ")
- .append(recentFailure.getAssociationStatus()).append("\n");
- return sbuf.toString();
- }
-
- /**
- * Get the SSID in a human-readable format, with all additional formatting removed
- * e.g. quotation marks around the SSID, "P" prefix
- * @hide
- */
- @NonNull
- @SystemApi
- public String getPrintableSsid() {
- if (SSID == null) return "";
- final int length = SSID.length();
- if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') {
- return SSID.substring(1, length - 1);
- }
-
- /* The ascii-encoded string format is P"<ascii-encoded-string>"
- * The decoding is implemented in the supplicant for a newly configured
- * network.
- */
- if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') &&
- (SSID.charAt(length-1) == '"')) {
- WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(
- SSID.substring(2, length - 1));
- return wifiSsid.toString();
- }
- return SSID;
- }
-
- /**
- * Get an identifier for associating credentials with this config
- * @param current configuration contains values for additional fields
- * that are not part of this configuration. Used
- * when a config with some fields is passed by an application.
- * @throws IllegalStateException if config is invalid for key id generation
- * @hide
- */
- public String getKeyIdForCredentials(WifiConfiguration current) {
- String keyMgmt = "";
-
- try {
- // Get current config details for fields that are not initialized
- if (TextUtils.isEmpty(SSID)) SSID = current.SSID;
- if (allowedKeyManagement.cardinality() == 0) {
- allowedKeyManagement = current.allowedKeyManagement;
- }
- if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
- keyMgmt += KeyMgmt.strings[KeyMgmt.WPA_EAP];
- }
- if (allowedKeyManagement.get(KeyMgmt.OSEN)) {
- keyMgmt += KeyMgmt.strings[KeyMgmt.OSEN];
- }
- if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
- keyMgmt += KeyMgmt.strings[KeyMgmt.IEEE8021X];
- }
- if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
- keyMgmt += KeyMgmt.strings[KeyMgmt.SUITE_B_192];
- }
- if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) {
- keyMgmt += KeyMgmt.strings[KeyMgmt.WAPI_CERT];
- }
-
- if (TextUtils.isEmpty(keyMgmt)) {
- throw new IllegalStateException("Not an EAP network");
- }
- String keyId = trimStringForKeyId(SSID) + "_" + keyMgmt + "_"
- + trimStringForKeyId(enterpriseConfig.getKeyId(current != null
- ? current.enterpriseConfig : null));
-
- if (!fromWifiNetworkSuggestion) {
- return keyId;
- }
- return keyId + "_" + trimStringForKeyId(BSSID) + "_" + trimStringForKeyId(creatorName);
- } catch (NullPointerException e) {
- throw new IllegalStateException("Invalid config details");
- }
- }
-
- private String trimStringForKeyId(String string) {
- if (string == null) {
- return "";
- }
- // Remove quotes and spaces
- return string.replace("\"", "").replace(" ", "");
- }
-
- private static BitSet readBitSet(Parcel src) {
- int cardinality = src.readInt();
-
- BitSet set = new BitSet();
- for (int i = 0; i < cardinality; i++) {
- set.set(src.readInt());
- }
-
- return set;
- }
-
- private static void writeBitSet(Parcel dest, BitSet set) {
- int nextSetBit = -1;
-
- dest.writeInt(set.cardinality());
-
- while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
- dest.writeInt(nextSetBit);
- }
- }
-
- /**
- * Get the authentication type of the network.
- * @return One of the {@link KeyMgmt} constants. e.g. {@link KeyMgmt#WPA2_PSK}.
- * @hide
- */
- @SystemApi
- @KeyMgmt.KeyMgmtScheme
- public int getAuthType() {
- if (allowedKeyManagement.cardinality() > 1) {
- throw new IllegalStateException("More than one auth type set");
- }
- if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
- return KeyMgmt.WPA_PSK;
- } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) {
- return KeyMgmt.WPA2_PSK;
- } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
- return KeyMgmt.WPA_EAP;
- } else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
- return KeyMgmt.IEEE8021X;
- } else if (allowedKeyManagement.get(KeyMgmt.SAE)) {
- return KeyMgmt.SAE;
- } else if (allowedKeyManagement.get(KeyMgmt.OWE)) {
- return KeyMgmt.OWE;
- } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
- return KeyMgmt.SUITE_B_192;
- } else if (allowedKeyManagement.get(KeyMgmt.WAPI_PSK)) {
- return KeyMgmt.WAPI_PSK;
- } else if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) {
- return KeyMgmt.WAPI_CERT;
- }
- return KeyMgmt.NONE;
- }
-
- /**
- * Return a String that can be used to uniquely identify this WifiConfiguration.
- * <br />
- * Note: Do not persist this value! This value is not guaranteed to remain backwards compatible.
- */
- @NonNull
- public String getKey() {
- // Passpoint ephemeral networks have their unique identifier set. Return it as is to be
- // able to match internally.
- if (mPasspointUniqueId != null) {
- return mPasspointUniqueId;
- }
-
- String key = getSsidAndSecurityTypeString();
- if (!shared) {
- key += "-" + UserHandle.getUserHandleForUid(creatorUid).getIdentifier();
- }
-
- return key;
- }
-
- /** @hide
- * return the SSID + security type in String format.
- */
- public String getSsidAndSecurityTypeString() {
- String key;
- if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
- key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK];
- } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)
- || allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
- key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP];
- } else if (wepTxKeyIndex >= 0 && wepTxKeyIndex < wepKeys.length
- && wepKeys[wepTxKeyIndex] != null) {
- key = SSID + "WEP";
- } else if (allowedKeyManagement.get(KeyMgmt.OWE)) {
- key = SSID + KeyMgmt.strings[KeyMgmt.OWE];
- } else if (allowedKeyManagement.get(KeyMgmt.SAE)) {
- key = SSID + KeyMgmt.strings[KeyMgmt.SAE];
- } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
- key = SSID + KeyMgmt.strings[KeyMgmt.SUITE_B_192];
- } else if (allowedKeyManagement.get(KeyMgmt.WAPI_PSK)) {
- key = SSID + KeyMgmt.strings[KeyMgmt.WAPI_PSK];
- } else if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) {
- key = SSID + KeyMgmt.strings[KeyMgmt.WAPI_CERT];
- } else if (allowedKeyManagement.get(KeyMgmt.OSEN)) {
- key = SSID + KeyMgmt.strings[KeyMgmt.OSEN];
- } else {
- key = SSID + KeyMgmt.strings[KeyMgmt.NONE];
- }
- return key;
- }
-
- /**
- * Get the IpConfiguration object associated with this WifiConfiguration.
- * @hide
- */
- @NonNull
- @SystemApi
- public IpConfiguration getIpConfiguration() {
- return new IpConfiguration(mIpConfiguration);
- }
-
- /**
- * Set the {@link IpConfiguration} for this network.
- * @param ipConfiguration the {@link IpConfiguration} to set, or null to use the default
- * constructor {@link IpConfiguration#IpConfiguration()}.
- * @hide
- */
- @SystemApi
- public void setIpConfiguration(@Nullable IpConfiguration ipConfiguration) {
- if (ipConfiguration == null) ipConfiguration = new IpConfiguration();
- mIpConfiguration = ipConfiguration;
- }
-
- /**
- * Get the {@link StaticIpConfiguration} for this network.
- * @return the {@link StaticIpConfiguration}, or null if unset.
- * @hide
- */
- @Nullable
- @UnsupportedAppUsage
- public StaticIpConfiguration getStaticIpConfiguration() {
- return mIpConfiguration.getStaticIpConfiguration();
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) {
- mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration);
- }
-
- /**
- * Get the {@link IpConfiguration.IpAssignment} for this network.
- * @hide
- */
- @NonNull
- @UnsupportedAppUsage
- public IpConfiguration.IpAssignment getIpAssignment() {
- return mIpConfiguration.getIpAssignment();
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setIpAssignment(IpConfiguration.IpAssignment ipAssignment) {
- mIpConfiguration.setIpAssignment(ipAssignment);
- }
-
- /**
- * Get the {@link IpConfiguration.ProxySettings} for this network.
- * @hide
- */
- @NonNull
- @UnsupportedAppUsage
- public IpConfiguration.ProxySettings getProxySettings() {
- return mIpConfiguration.getProxySettings();
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setProxySettings(IpConfiguration.ProxySettings proxySettings) {
- mIpConfiguration.setProxySettings(proxySettings);
- }
-
- /**
- * Returns the HTTP proxy used by this object.
- * @return a {@link ProxyInfo httpProxy} representing the proxy specified by this
- * WifiConfiguration, or {@code null} if no proxy is specified.
- */
- public ProxyInfo getHttpProxy() {
- if (mIpConfiguration.getProxySettings() == IpConfiguration.ProxySettings.NONE) {
- return null;
- }
- return new ProxyInfo(mIpConfiguration.getHttpProxy());
- }
-
- /**
- * Set the {@link ProxyInfo} for this WifiConfiguration. This method should only be used by a
- * device owner or profile owner. When other apps attempt to save a {@link WifiConfiguration}
- * with modified proxy settings, the methods {@link WifiManager#addNetwork} and
- * {@link WifiManager#updateNetwork} fail and return {@code -1}.
- *
- * @param httpProxy {@link ProxyInfo} representing the httpProxy to be used by this
- * WifiConfiguration. Setting this to {@code null} will explicitly set no
- * proxy, removing any proxy that was previously set.
- * @exception IllegalArgumentException for invalid httpProxy
- */
- public void setHttpProxy(ProxyInfo httpProxy) {
- if (httpProxy == null) {
- mIpConfiguration.setProxySettings(IpConfiguration.ProxySettings.NONE);
- mIpConfiguration.setHttpProxy(null);
- return;
- }
- ProxyInfo httpProxyCopy;
- ProxySettings proxySettingCopy;
- if (!Uri.EMPTY.equals(httpProxy.getPacFileUrl())) {
- proxySettingCopy = IpConfiguration.ProxySettings.PAC;
- // Construct a new PAC URL Proxy
- httpProxyCopy = ProxyInfo.buildPacProxy(httpProxy.getPacFileUrl(), httpProxy.getPort());
- } else {
- proxySettingCopy = IpConfiguration.ProxySettings.STATIC;
- // Construct a new HTTP Proxy
- httpProxyCopy = ProxyInfo.buildDirectProxy(httpProxy.getHost(), httpProxy.getPort(),
- Arrays.asList(httpProxy.getExclusionList()));
- }
- if (!httpProxyCopy.isValid()) {
- throw new IllegalArgumentException("Invalid ProxyInfo: " + httpProxyCopy.toString());
- }
- mIpConfiguration.setProxySettings(proxySettingCopy);
- mIpConfiguration.setHttpProxy(httpProxyCopy);
- }
-
- /**
- * Set the {@link ProxySettings} and {@link ProxyInfo} for this network.
- * @hide
- */
- @UnsupportedAppUsage
- public void setProxy(@NonNull ProxySettings settings, @NonNull ProxyInfo proxy) {
- mIpConfiguration.setProxySettings(settings);
- mIpConfiguration.setHttpProxy(proxy);
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** @hide */
- public void setPasspointManagementObjectTree(String passpointManagementObjectTree) {
- mPasspointManagementObjectTree = passpointManagementObjectTree;
- }
-
- /** @hide */
- public String getMoTree() {
- return mPasspointManagementObjectTree;
- }
-
- /** Copy constructor */
- public WifiConfiguration(@NonNull WifiConfiguration source) {
- if (source != null) {
- networkId = source.networkId;
- status = source.status;
- SSID = source.SSID;
- BSSID = source.BSSID;
- FQDN = source.FQDN;
- roamingConsortiumIds = source.roamingConsortiumIds.clone();
- providerFriendlyName = source.providerFriendlyName;
- isHomeProviderNetwork = source.isHomeProviderNetwork;
- preSharedKey = source.preSharedKey;
-
- mNetworkSelectionStatus.copy(source.getNetworkSelectionStatus());
- apBand = source.apBand;
- apChannel = source.apChannel;
-
- wepKeys = new String[4];
- for (int i = 0; i < wepKeys.length; i++) {
- wepKeys[i] = source.wepKeys[i];
- }
-
- wepTxKeyIndex = source.wepTxKeyIndex;
- priority = source.priority;
- hiddenSSID = source.hiddenSSID;
- allowedKeyManagement = (BitSet) source.allowedKeyManagement.clone();
- allowedProtocols = (BitSet) source.allowedProtocols.clone();
- allowedAuthAlgorithms = (BitSet) source.allowedAuthAlgorithms.clone();
- allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone();
- allowedGroupCiphers = (BitSet) source.allowedGroupCiphers.clone();
- allowedGroupManagementCiphers = (BitSet) source.allowedGroupManagementCiphers.clone();
- allowedSuiteBCiphers = (BitSet) source.allowedSuiteBCiphers.clone();
- enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig);
-
- defaultGwMacAddress = source.defaultGwMacAddress;
-
- mIpConfiguration = new IpConfiguration(source.mIpConfiguration);
-
- if ((source.linkedConfigurations != null)
- && (source.linkedConfigurations.size() > 0)) {
- linkedConfigurations = new HashMap<String, Integer>();
- linkedConfigurations.putAll(source.linkedConfigurations);
- }
- validatedInternetAccess = source.validatedInternetAccess;
- isLegacyPasspointConfig = source.isLegacyPasspointConfig;
- ephemeral = source.ephemeral;
- osu = source.osu;
- trusted = source.trusted;
- fromWifiNetworkSuggestion = source.fromWifiNetworkSuggestion;
- fromWifiNetworkSpecifier = source.fromWifiNetworkSpecifier;
- meteredHint = source.meteredHint;
- meteredOverride = source.meteredOverride;
- useExternalScores = source.useExternalScores;
-
- lastConnectUid = source.lastConnectUid;
- lastUpdateUid = source.lastUpdateUid;
- creatorUid = source.creatorUid;
- creatorName = source.creatorName;
- lastUpdateName = source.lastUpdateName;
- peerWifiConfiguration = source.peerWifiConfiguration;
-
- lastConnected = source.lastConnected;
- lastDisconnected = source.lastDisconnected;
- numScorerOverride = source.numScorerOverride;
- numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork;
- numAssociation = source.numAssociation;
- allowAutojoin = source.allowAutojoin;
- numNoInternetAccessReports = source.numNoInternetAccessReports;
- noInternetAccessExpected = source.noInternetAccessExpected;
- shared = source.shared;
- recentFailure.setAssociationStatus(source.recentFailure.getAssociationStatus());
- mRandomizedMacAddress = source.mRandomizedMacAddress;
- macRandomizationSetting = source.macRandomizationSetting;
- randomizedMacExpirationTimeMs = source.randomizedMacExpirationTimeMs;
- requirePmf = source.requirePmf;
- updateIdentifier = source.updateIdentifier;
- carrierId = source.carrierId;
- mPasspointUniqueId = source.mPasspointUniqueId;
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(networkId);
- dest.writeInt(status);
- mNetworkSelectionStatus.writeToParcel(dest);
- dest.writeString(SSID);
- dest.writeString(BSSID);
- dest.writeInt(apBand);
- dest.writeInt(apChannel);
- dest.writeString(FQDN);
- dest.writeString(providerFriendlyName);
- dest.writeInt(isHomeProviderNetwork ? 1 : 0);
- dest.writeInt(roamingConsortiumIds.length);
- for (long roamingConsortiumId : roamingConsortiumIds) {
- dest.writeLong(roamingConsortiumId);
- }
- dest.writeString(preSharedKey);
- for (String wepKey : wepKeys) {
- dest.writeString(wepKey);
- }
- dest.writeInt(wepTxKeyIndex);
- dest.writeInt(priority);
- dest.writeInt(hiddenSSID ? 1 : 0);
- dest.writeInt(requirePmf ? 1 : 0);
- dest.writeString(updateIdentifier);
-
- writeBitSet(dest, allowedKeyManagement);
- writeBitSet(dest, allowedProtocols);
- writeBitSet(dest, allowedAuthAlgorithms);
- writeBitSet(dest, allowedPairwiseCiphers);
- writeBitSet(dest, allowedGroupCiphers);
- writeBitSet(dest, allowedGroupManagementCiphers);
- writeBitSet(dest, allowedSuiteBCiphers);
-
- dest.writeParcelable(enterpriseConfig, flags);
-
- dest.writeParcelable(mIpConfiguration, flags);
- dest.writeString(dhcpServer);
- dest.writeString(defaultGwMacAddress);
- dest.writeInt(validatedInternetAccess ? 1 : 0);
- dest.writeInt(isLegacyPasspointConfig ? 1 : 0);
- dest.writeInt(ephemeral ? 1 : 0);
- dest.writeInt(trusted ? 1 : 0);
- dest.writeInt(fromWifiNetworkSuggestion ? 1 : 0);
- dest.writeInt(fromWifiNetworkSpecifier ? 1 : 0);
- dest.writeInt(meteredHint ? 1 : 0);
- dest.writeInt(meteredOverride);
- dest.writeInt(useExternalScores ? 1 : 0);
- dest.writeInt(creatorUid);
- dest.writeInt(lastConnectUid);
- dest.writeInt(lastUpdateUid);
- dest.writeString(creatorName);
- dest.writeString(lastUpdateName);
- dest.writeInt(numScorerOverride);
- dest.writeInt(numScorerOverrideAndSwitchedNetwork);
- dest.writeInt(numAssociation);
- dest.writeBoolean(allowAutojoin);
- dest.writeInt(numNoInternetAccessReports);
- dest.writeInt(noInternetAccessExpected ? 1 : 0);
- dest.writeInt(shared ? 1 : 0);
- dest.writeString(mPasspointManagementObjectTree);
- dest.writeInt(recentFailure.getAssociationStatus());
- dest.writeParcelable(mRandomizedMacAddress, flags);
- dest.writeInt(macRandomizationSetting);
- dest.writeInt(osu ? 1 : 0);
- dest.writeLong(randomizedMacExpirationTimeMs);
- dest.writeInt(carrierId);
- dest.writeString(mPasspointUniqueId);
- }
-
- /** Implement the Parcelable interface {@hide} */
- @UnsupportedAppUsage
- public static final @android.annotation.NonNull Creator<WifiConfiguration> CREATOR =
- new Creator<WifiConfiguration>() {
- public WifiConfiguration createFromParcel(Parcel in) {
- WifiConfiguration config = new WifiConfiguration();
- config.networkId = in.readInt();
- config.status = in.readInt();
- config.mNetworkSelectionStatus.readFromParcel(in);
- config.SSID = in.readString();
- config.BSSID = in.readString();
- config.apBand = in.readInt();
- config.apChannel = in.readInt();
- config.FQDN = in.readString();
- config.providerFriendlyName = in.readString();
- config.isHomeProviderNetwork = in.readInt() != 0;
- int numRoamingConsortiumIds = in.readInt();
- config.roamingConsortiumIds = new long[numRoamingConsortiumIds];
- for (int i = 0; i < numRoamingConsortiumIds; i++) {
- config.roamingConsortiumIds[i] = in.readLong();
- }
- config.preSharedKey = in.readString();
- for (int i = 0; i < config.wepKeys.length; i++) {
- config.wepKeys[i] = in.readString();
- }
- config.wepTxKeyIndex = in.readInt();
- config.priority = in.readInt();
- config.hiddenSSID = in.readInt() != 0;
- config.requirePmf = in.readInt() != 0;
- config.updateIdentifier = in.readString();
-
- config.allowedKeyManagement = readBitSet(in);
- config.allowedProtocols = readBitSet(in);
- config.allowedAuthAlgorithms = readBitSet(in);
- config.allowedPairwiseCiphers = readBitSet(in);
- config.allowedGroupCiphers = readBitSet(in);
- config.allowedGroupManagementCiphers = readBitSet(in);
- config.allowedSuiteBCiphers = readBitSet(in);
-
- config.enterpriseConfig = in.readParcelable(null);
- config.setIpConfiguration(in.readParcelable(null));
- config.dhcpServer = in.readString();
- config.defaultGwMacAddress = in.readString();
- config.validatedInternetAccess = in.readInt() != 0;
- config.isLegacyPasspointConfig = in.readInt() != 0;
- config.ephemeral = in.readInt() != 0;
- config.trusted = in.readInt() != 0;
- config.fromWifiNetworkSuggestion = in.readInt() != 0;
- config.fromWifiNetworkSpecifier = in.readInt() != 0;
- config.meteredHint = in.readInt() != 0;
- config.meteredOverride = in.readInt();
- config.useExternalScores = in.readInt() != 0;
- config.creatorUid = in.readInt();
- config.lastConnectUid = in.readInt();
- config.lastUpdateUid = in.readInt();
- config.creatorName = in.readString();
- config.lastUpdateName = in.readString();
- config.numScorerOverride = in.readInt();
- config.numScorerOverrideAndSwitchedNetwork = in.readInt();
- config.numAssociation = in.readInt();
- config.allowAutojoin = in.readBoolean();
- config.numNoInternetAccessReports = in.readInt();
- config.noInternetAccessExpected = in.readInt() != 0;
- config.shared = in.readInt() != 0;
- config.mPasspointManagementObjectTree = in.readString();
- config.recentFailure.setAssociationStatus(in.readInt());
- config.mRandomizedMacAddress = in.readParcelable(null);
- config.macRandomizationSetting = in.readInt();
- config.osu = in.readInt() != 0;
- config.randomizedMacExpirationTimeMs = in.readLong();
- config.carrierId = in.readInt();
- config.mPasspointUniqueId = in.readString();
- return config;
- }
-
- public WifiConfiguration[] newArray(int size) {
- return new WifiConfiguration[size];
- }
- };
-
- /**
- * Passpoint Unique identifier
- * @hide
- */
- private String mPasspointUniqueId = null;
-
- /**
- * Set the Passpoint unique identifier
- * @param uniqueId Passpoint unique identifier to be set
- * @hide
- */
- public void setPasspointUniqueId(String uniqueId) {
- mPasspointUniqueId = uniqueId;
- }
-
- /**
- * Set the Passpoint unique identifier
- * @hide
- */
- public String getPasspointUniqueId() {
- return mPasspointUniqueId;
- }
-
- /**
- * If network is one of the most recently connected.
- * For framework internal use only. Do not parcel.
- * @hide
- */
- public boolean isMostRecentlyConnected = false;
-
- /**
- * Whether the key mgmt indicates if the WifiConfiguration needs a preSharedKey or not.
- * @return true if preSharedKey is needed, false otherwise.
- * @hide
- */
- public boolean needsPreSharedKey() {
- return allowedKeyManagement.get(KeyMgmt.WPA_PSK)
- || allowedKeyManagement.get(KeyMgmt.SAE)
- || allowedKeyManagement.get(KeyMgmt.WAPI_PSK);
- }
-
-}
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
deleted file mode 100644
index 77fa673..0000000
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ /dev/null
@@ -1,1445 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Enterprise configuration details for Wi-Fi. Stores details about the EAP method
- * and any associated credentials.
- */
-public class WifiEnterpriseConfig implements Parcelable {
-
- /** Key prefix for WAPI AS certificates. */
- public static final String WAPI_AS_CERTIFICATE = "WAPIAS_";
-
- /** Key prefix for WAPI user certificates. */
- public static final String WAPI_USER_CERTIFICATE = "WAPIUSR_";
-
- /**
- * Intent extra: name for WAPI AS certificates
- */
- public static final String EXTRA_WAPI_AS_CERTIFICATE_NAME =
- "android.net.wifi.extra.WAPI_AS_CERTIFICATE_NAME";
-
- /**
- * Intent extra: data for WAPI AS certificates
- */
- public static final String EXTRA_WAPI_AS_CERTIFICATE_DATA =
- "android.net.wifi.extra.WAPI_AS_CERTIFICATE_DATA";
-
- /**
- * Intent extra: name for WAPI USER certificates
- */
- public static final String EXTRA_WAPI_USER_CERTIFICATE_NAME =
- "android.net.wifi.extra.WAPI_USER_CERTIFICATE_NAME";
-
- /**
- * Intent extra: data for WAPI USER certificates
- */
- public static final String EXTRA_WAPI_USER_CERTIFICATE_DATA =
- "android.net.wifi.extra.WAPI_USER_CERTIFICATE_DATA";
-
- /** @hide */
- public static final String EMPTY_VALUE = "NULL";
- /** @hide */
- public static final String EAP_KEY = "eap";
- /** @hide */
- public static final String PHASE2_KEY = "phase2";
- /** @hide */
- public static final String IDENTITY_KEY = "identity";
- /** @hide */
- public static final String ANON_IDENTITY_KEY = "anonymous_identity";
- /** @hide */
- public static final String PASSWORD_KEY = "password";
- /** @hide */
- public static final String SUBJECT_MATCH_KEY = "subject_match";
- /** @hide */
- public static final String ALTSUBJECT_MATCH_KEY = "altsubject_match";
- /** @hide */
- public static final String DOM_SUFFIX_MATCH_KEY = "domain_suffix_match";
- /** @hide */
- public static final String OPP_KEY_CACHING = "proactive_key_caching";
- /** @hide */
- public static final String EAP_ERP = "eap_erp";
- /** @hide */
- public static final String OCSP = "ocsp";
-
- /**
- * String representing the keystore OpenSSL ENGINE's ID.
- * @hide
- */
- public static final String ENGINE_ID_KEYSTORE = "keystore";
-
- /**
- * String representing the keystore URI used for wpa_supplicant.
- * @hide
- */
- public static final String KEYSTORE_URI = "keystore://";
-
- /**
- * String representing the keystore URI used for wpa_supplicant,
- * Unlike #KEYSTORE_URI, this supports a list of space-delimited aliases
- * @hide
- */
- public static final String KEYSTORES_URI = "keystores://";
-
- /**
- * String to set the engine value to when it should be enabled.
- * @hide
- */
- public static final String ENGINE_ENABLE = "1";
-
- /**
- * String to set the engine value to when it should be disabled.
- * @hide
- */
- public static final String ENGINE_DISABLE = "0";
-
- /**
- * Key prefix for CA certificates.
- * Note: copied from {@link android.security.Credentials#CA_CERTIFICATE} since it is @hide.
- */
- private static final String CA_CERTIFICATE = "CACERT_";
- /**
- * Key prefix for user certificates.
- * Note: copied from {@link android.security.Credentials#USER_CERTIFICATE} since it is @hide.
- */
- private static final String USER_CERTIFICATE = "USRCERT_";
- /**
- * Key prefix for user private and secret keys.
- * Note: copied from {@link android.security.Credentials#USER_PRIVATE_KEY} since it is @hide.
- */
- private static final String USER_PRIVATE_KEY = "USRPKEY_";
-
- /** @hide */
- public static final String CA_CERT_PREFIX = KEYSTORE_URI + CA_CERTIFICATE;
- /** @hide */
- public static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + USER_CERTIFICATE;
- /** @hide */
- public static final String CLIENT_CERT_KEY = "client_cert";
- /** @hide */
- public static final String CA_CERT_KEY = "ca_cert";
- /** @hide */
- public static final String CA_PATH_KEY = "ca_path";
- /** @hide */
- public static final String ENGINE_KEY = "engine";
- /** @hide */
- public static final String ENGINE_ID_KEY = "engine_id";
- /** @hide */
- public static final String PRIVATE_KEY_ID_KEY = "key_id";
- /** @hide */
- public static final String REALM_KEY = "realm";
- /** @hide */
- public static final String PLMN_KEY = "plmn";
- /** @hide */
- public static final String CA_CERT_ALIAS_DELIMITER = " ";
- /** @hide */
- public static final String WAPI_CERT_SUITE_KEY = "wapi_cert_suite";
-
- /**
- * Do not use OCSP stapling (TLS certificate status extension)
- * @hide
- */
- @SystemApi
- public static final int OCSP_NONE = 0;
-
- /**
- * Try to use OCSP stapling, but not require response
- * @hide
- */
- @SystemApi
- public static final int OCSP_REQUEST_CERT_STATUS = 1;
-
- /**
- * Require valid OCSP stapling response
- * @hide
- */
- @SystemApi
- public static final int OCSP_REQUIRE_CERT_STATUS = 2;
-
- /**
- * Require valid OCSP stapling response for all not-trusted certificates in the server
- * certificate chain
- * @hide
- */
- @SystemApi
- public static final int OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS = 3;
-
- /** @hide */
- @IntDef(prefix = {"OCSP_"}, value = {
- OCSP_NONE,
- OCSP_REQUEST_CERT_STATUS,
- OCSP_REQUIRE_CERT_STATUS,
- OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Ocsp {}
-
- /**
- * Whether to use/require OCSP (Online Certificate Status Protocol) to check server certificate.
- * @hide
- */
- private @Ocsp int mOcsp = OCSP_NONE;
-
- // Fields to copy verbatim from wpa_supplicant.
- private static final String[] SUPPLICANT_CONFIG_KEYS = new String[] {
- IDENTITY_KEY,
- ANON_IDENTITY_KEY,
- PASSWORD_KEY,
- CLIENT_CERT_KEY,
- CA_CERT_KEY,
- SUBJECT_MATCH_KEY,
- ENGINE_KEY,
- ENGINE_ID_KEY,
- PRIVATE_KEY_ID_KEY,
- ALTSUBJECT_MATCH_KEY,
- DOM_SUFFIX_MATCH_KEY,
- CA_PATH_KEY
- };
-
- /**
- * Fields that have unquoted values in {@link #mFields}.
- */
- private static final List<String> UNQUOTED_KEYS = Arrays.asList(ENGINE_KEY, OPP_KEY_CACHING,
- EAP_ERP);
-
- @UnsupportedAppUsage
- private HashMap<String, String> mFields = new HashMap<String, String>();
- private X509Certificate[] mCaCerts;
- private PrivateKey mClientPrivateKey;
- private X509Certificate[] mClientCertificateChain;
- private int mEapMethod = Eap.NONE;
- private int mPhase2Method = Phase2.NONE;
- private boolean mIsAppInstalledDeviceKeyAndCert = false;
- private boolean mIsAppInstalledCaCert = false;
-
- private static final String TAG = "WifiEnterpriseConfig";
-
- public WifiEnterpriseConfig() {
- // Do not set defaults so that the enterprise fields that are not changed
- // by API are not changed underneath
- // This is essential because an app may not have all fields like password
- // available. It allows modification of subset of fields.
-
- }
-
- /**
- * Copy over the contents of the source WifiEnterpriseConfig object over to this object.
- *
- * @param source Source WifiEnterpriseConfig object.
- * @param ignoreMaskedPassword Set to true to ignore masked password field, false otherwise.
- * @param mask if |ignoreMaskedPassword| is set, check if the incoming password field is set
- * to this value.
- */
- private void copyFrom(WifiEnterpriseConfig source, boolean ignoreMaskedPassword, String mask) {
- for (String key : source.mFields.keySet()) {
- if (ignoreMaskedPassword && key.equals(PASSWORD_KEY)
- && TextUtils.equals(source.mFields.get(key), mask)) {
- continue;
- }
- mFields.put(key, source.mFields.get(key));
- }
- if (source.mCaCerts != null) {
- mCaCerts = Arrays.copyOf(source.mCaCerts, source.mCaCerts.length);
- } else {
- mCaCerts = null;
- }
- mClientPrivateKey = source.mClientPrivateKey;
- if (source.mClientCertificateChain != null) {
- mClientCertificateChain = Arrays.copyOf(
- source.mClientCertificateChain,
- source.mClientCertificateChain.length);
- } else {
- mClientCertificateChain = null;
- }
- mEapMethod = source.mEapMethod;
- mPhase2Method = source.mPhase2Method;
- mIsAppInstalledDeviceKeyAndCert = source.mIsAppInstalledDeviceKeyAndCert;
- mIsAppInstalledCaCert = source.mIsAppInstalledCaCert;
- mOcsp = source.mOcsp;
- }
-
- /**
- * Copy constructor.
- * This copies over all the fields verbatim (does not ignore masked password fields).
- *
- * @param source Source WifiEnterpriseConfig object.
- */
- public WifiEnterpriseConfig(WifiEnterpriseConfig source) {
- copyFrom(source, false, "");
- }
-
- /**
- * Copy fields from the provided external WifiEnterpriseConfig.
- * This is needed to handle the WifiEnterpriseConfig objects which were sent by apps with the
- * password field masked.
- *
- * @param externalConfig External WifiEnterpriseConfig object.
- * @param mask String mask to compare against.
- * @hide
- */
- public void copyFromExternal(WifiEnterpriseConfig externalConfig, String mask) {
- copyFrom(externalConfig, true, convertToQuotedString(mask));
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mFields.size());
- for (Map.Entry<String, String> entry : mFields.entrySet()) {
- dest.writeString(entry.getKey());
- dest.writeString(entry.getValue());
- }
-
- dest.writeInt(mEapMethod);
- dest.writeInt(mPhase2Method);
- ParcelUtil.writeCertificates(dest, mCaCerts);
- ParcelUtil.writePrivateKey(dest, mClientPrivateKey);
- ParcelUtil.writeCertificates(dest, mClientCertificateChain);
- dest.writeBoolean(mIsAppInstalledDeviceKeyAndCert);
- dest.writeBoolean(mIsAppInstalledCaCert);
- dest.writeInt(mOcsp);
- }
-
- public static final @android.annotation.NonNull Creator<WifiEnterpriseConfig> CREATOR =
- new Creator<WifiEnterpriseConfig>() {
- @Override
- public WifiEnterpriseConfig createFromParcel(Parcel in) {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- int count = in.readInt();
- for (int i = 0; i < count; i++) {
- String key = in.readString();
- String value = in.readString();
- enterpriseConfig.mFields.put(key, value);
- }
-
- enterpriseConfig.mEapMethod = in.readInt();
- enterpriseConfig.mPhase2Method = in.readInt();
- enterpriseConfig.mCaCerts = ParcelUtil.readCertificates(in);
- enterpriseConfig.mClientPrivateKey = ParcelUtil.readPrivateKey(in);
- enterpriseConfig.mClientCertificateChain = ParcelUtil.readCertificates(in);
- enterpriseConfig.mIsAppInstalledDeviceKeyAndCert = in.readBoolean();
- enterpriseConfig.mIsAppInstalledCaCert = in.readBoolean();
- enterpriseConfig.mOcsp = in.readInt();
- return enterpriseConfig;
- }
-
- @Override
- public WifiEnterpriseConfig[] newArray(int size) {
- return new WifiEnterpriseConfig[size];
- }
- };
-
- /** The Extensible Authentication Protocol method used */
- public static final class Eap {
- /** No EAP method used. Represents an empty config */
- public static final int NONE = -1;
- /** Protected EAP */
- public static final int PEAP = 0;
- /** EAP-Transport Layer Security */
- public static final int TLS = 1;
- /** EAP-Tunneled Transport Layer Security */
- public static final int TTLS = 2;
- /** EAP-Password */
- public static final int PWD = 3;
- /** EAP-Subscriber Identity Module [RFC-4186] */
- public static final int SIM = 4;
- /** EAP-Authentication and Key Agreement [RFC-4187] */
- public static final int AKA = 5;
- /** EAP-Authentication and Key Agreement Prime [RFC-5448] */
- public static final int AKA_PRIME = 6;
- /** Hotspot 2.0 r2 OSEN */
- public static final int UNAUTH_TLS = 7;
- /** WAPI Certificate */
- public static final int WAPI_CERT = 8;
- /** @hide */
- public static final String[] strings =
- { "PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'", "WFA-UNAUTH-TLS",
- "WAPI_CERT" };
-
- /** Prevent initialization */
- private Eap() {}
- }
-
- /** The inner authentication method used */
- public static final class Phase2 {
- public static final int NONE = 0;
- /** Password Authentication Protocol */
- public static final int PAP = 1;
- /** Microsoft Challenge Handshake Authentication Protocol */
- public static final int MSCHAP = 2;
- /** Microsoft Challenge Handshake Authentication Protocol v2 */
- public static final int MSCHAPV2 = 3;
- /** Generic Token Card */
- public static final int GTC = 4;
- /** EAP-Subscriber Identity Module [RFC-4186] */
- public static final int SIM = 5;
- /** EAP-Authentication and Key Agreement [RFC-4187] */
- public static final int AKA = 6;
- /** EAP-Authentication and Key Agreement Prime [RFC-5448] */
- public static final int AKA_PRIME = 7;
- private static final String AUTH_PREFIX = "auth=";
- private static final String AUTHEAP_PREFIX = "autheap=";
- /** @hide */
- public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP",
- "MSCHAPV2", "GTC", "SIM", "AKA", "AKA'" };
-
- /** Prevent initialization */
- private Phase2() {}
- }
-
- // Loader and saver interfaces for exchanging data with wpa_supplicant.
- // TODO: Decouple this object (which is just a placeholder of the configuration)
- // from the implementation that knows what wpa_supplicant wants.
- /**
- * Interface used for retrieving supplicant configuration from WifiEnterpriseConfig
- * @hide
- */
- public interface SupplicantSaver {
- /**
- * Set a value within wpa_supplicant configuration
- * @param key index to set within wpa_supplciant
- * @param value the value for the key
- * @return true if successful; false otherwise
- */
- boolean saveValue(String key, String value);
- }
-
- /**
- * Interface used for populating a WifiEnterpriseConfig from supplicant configuration
- * @hide
- */
- public interface SupplicantLoader {
- /**
- * Returns a value within wpa_supplicant configuration
- * @param key index to set within wpa_supplciant
- * @return string value if successful; null otherwise
- */
- String loadValue(String key);
- }
-
- /**
- * Internal use only; supply field values to wpa_supplicant config. The configuration
- * process aborts on the first failed call on {@code saver}.
- * @param saver proxy for setting configuration in wpa_supplciant
- * @return whether the save succeeded on all attempts
- * @hide
- */
- public boolean saveToSupplicant(SupplicantSaver saver) {
- if (!isEapMethodValid()) {
- return false;
- }
-
- // wpa_supplicant can update the anonymous identity for these kinds of networks after
- // framework reads them, so make sure the framework doesn't try to overwrite them.
- boolean shouldNotWriteAnonIdentity = mEapMethod == WifiEnterpriseConfig.Eap.SIM
- || mEapMethod == WifiEnterpriseConfig.Eap.AKA
- || mEapMethod == WifiEnterpriseConfig.Eap.AKA_PRIME;
- for (String key : mFields.keySet()) {
- if (shouldNotWriteAnonIdentity && ANON_IDENTITY_KEY.equals(key)) {
- continue;
- }
- if (!saver.saveValue(key, mFields.get(key))) {
- return false;
- }
- }
-
- if (!saver.saveValue(EAP_KEY, Eap.strings[mEapMethod])) {
- return false;
- }
-
- if (mEapMethod != Eap.TLS && mEapMethod != Eap.UNAUTH_TLS && mPhase2Method != Phase2.NONE) {
- boolean is_autheap = mEapMethod == Eap.TTLS && mPhase2Method == Phase2.GTC;
- String prefix = is_autheap ? Phase2.AUTHEAP_PREFIX : Phase2.AUTH_PREFIX;
- String value = convertToQuotedString(prefix + Phase2.strings[mPhase2Method]);
- return saver.saveValue(PHASE2_KEY, value);
- } else if (mPhase2Method == Phase2.NONE) {
- // By default, send a null phase 2 to clear old configuration values.
- return saver.saveValue(PHASE2_KEY, null);
- } else {
- Log.e(TAG, "WiFi enterprise configuration is invalid as it supplies a "
- + "phase 2 method but the phase1 method does not support it.");
- return false;
- }
- }
-
- /**
- * Internal use only; retrieve configuration from wpa_supplicant config.
- * @param loader proxy for retrieving configuration keys from wpa_supplicant
- * @hide
- */
- public void loadFromSupplicant(SupplicantLoader loader) {
- for (String key : SUPPLICANT_CONFIG_KEYS) {
- String value = loader.loadValue(key);
- if (value == null) {
- mFields.put(key, EMPTY_VALUE);
- } else {
- mFields.put(key, value);
- }
- }
- String eapMethod = loader.loadValue(EAP_KEY);
- mEapMethod = getStringIndex(Eap.strings, eapMethod, Eap.NONE);
-
- String phase2Method = removeDoubleQuotes(loader.loadValue(PHASE2_KEY));
- // Remove "auth=" or "autheap=" prefix.
- if (phase2Method.startsWith(Phase2.AUTH_PREFIX)) {
- phase2Method = phase2Method.substring(Phase2.AUTH_PREFIX.length());
- } else if (phase2Method.startsWith(Phase2.AUTHEAP_PREFIX)) {
- phase2Method = phase2Method.substring(Phase2.AUTHEAP_PREFIX.length());
- }
- mPhase2Method = getStringIndex(Phase2.strings, phase2Method, Phase2.NONE);
- }
-
- /**
- * Set the EAP authentication method.
- * @param eapMethod is one {@link Eap#PEAP}, {@link Eap#TLS}, {@link Eap#TTLS} or
- * {@link Eap#PWD}
- * @throws IllegalArgumentException on an invalid eap method
- */
- public void setEapMethod(int eapMethod) {
- switch (eapMethod) {
- /** Valid methods */
- case Eap.WAPI_CERT:
- mEapMethod = eapMethod;
- setPhase2Method(Phase2.NONE);
- break;
- case Eap.TLS:
- case Eap.UNAUTH_TLS:
- setPhase2Method(Phase2.NONE);
- /* fall through */
- case Eap.PEAP:
- case Eap.PWD:
- case Eap.TTLS:
- case Eap.SIM:
- case Eap.AKA:
- case Eap.AKA_PRIME:
- mEapMethod = eapMethod;
- setFieldValue(OPP_KEY_CACHING, "1");
- break;
- default:
- throw new IllegalArgumentException("Unknown EAP method");
- }
- }
-
- /**
- * Get the eap method.
- * @return eap method configured
- */
- public int getEapMethod() {
- return mEapMethod;
- }
-
- /**
- * Set Phase 2 authentication method. Sets the inner authentication method to be used in
- * phase 2 after setting up a secure channel
- * @param phase2Method is the inner authentication method and can be one of {@link Phase2#NONE},
- * {@link Phase2#PAP}, {@link Phase2#MSCHAP}, {@link Phase2#MSCHAPV2},
- * {@link Phase2#GTC}
- * @throws IllegalArgumentException on an invalid phase2 method
- *
- */
- public void setPhase2Method(int phase2Method) {
- switch (phase2Method) {
- case Phase2.NONE:
- case Phase2.PAP:
- case Phase2.MSCHAP:
- case Phase2.MSCHAPV2:
- case Phase2.GTC:
- case Phase2.SIM:
- case Phase2.AKA:
- case Phase2.AKA_PRIME:
- mPhase2Method = phase2Method;
- break;
- default:
- throw new IllegalArgumentException("Unknown Phase 2 method");
- }
- }
-
- /**
- * Get the phase 2 authentication method.
- * @return a phase 2 method defined at {@link Phase2}
- * */
- public int getPhase2Method() {
- return mPhase2Method;
- }
-
- /**
- * Set the identity
- * @param identity
- */
- public void setIdentity(String identity) {
- setFieldValue(IDENTITY_KEY, identity, "");
- }
-
- /**
- * Get the identity
- * @return the identity
- */
- public String getIdentity() {
- return getFieldValue(IDENTITY_KEY);
- }
-
- /**
- * Set anonymous identity. This is used as the unencrypted identity with
- * certain EAP types
- * @param anonymousIdentity the anonymous identity
- */
- public void setAnonymousIdentity(String anonymousIdentity) {
- setFieldValue(ANON_IDENTITY_KEY, anonymousIdentity);
- }
-
- /**
- * Get the anonymous identity
- * @return anonymous identity
- */
- public String getAnonymousIdentity() {
- return getFieldValue(ANON_IDENTITY_KEY);
- }
-
- /**
- * Set the password.
- * @param password the password
- */
- public void setPassword(String password) {
- setFieldValue(PASSWORD_KEY, password);
- }
-
- /**
- * Get the password.
- *
- * Returns locally set password value. For networks fetched from
- * framework, returns "*".
- */
- public String getPassword() {
- return getFieldValue(PASSWORD_KEY);
- }
-
- /**
- * Encode a CA certificate alias so it does not contain illegal character.
- * @hide
- */
- public static String encodeCaCertificateAlias(String alias) {
- byte[] bytes = alias.getBytes(StandardCharsets.UTF_8);
- StringBuilder sb = new StringBuilder(bytes.length * 2);
- for (byte o : bytes) {
- sb.append(String.format("%02x", o & 0xFF));
- }
- return sb.toString();
- }
-
- /**
- * Decode a previously-encoded CA certificate alias.
- * @hide
- */
- public static String decodeCaCertificateAlias(String alias) {
- byte[] data = new byte[alias.length() >> 1];
- for (int n = 0, position = 0; n < alias.length(); n += 2, position++) {
- data[position] = (byte) Integer.parseInt(alias.substring(n, n + 2), 16);
- }
- try {
- return new String(data, StandardCharsets.UTF_8);
- } catch (NumberFormatException e) {
- e.printStackTrace();
- return alias;
- }
- }
-
- /**
- * Set CA certificate alias.
- *
- * <p> See the {@link android.security.KeyChain} for details on installing or choosing
- * a certificate
- * </p>
- * @param alias identifies the certificate
- * @hide
- */
- @UnsupportedAppUsage
- public void setCaCertificateAlias(String alias) {
- setFieldValue(CA_CERT_KEY, alias, CA_CERT_PREFIX);
- }
-
- /**
- * Set CA certificate aliases. When creating installing the corresponding certificate to
- * the keystore, please use alias encoded by {@link #encodeCaCertificateAlias(String)}.
- *
- * <p> See the {@link android.security.KeyChain} for details on installing or choosing
- * a certificate.
- * </p>
- * @param aliases identifies the certificate. Can be null to indicate the absence of a
- * certificate.
- * @hide
- */
- @SystemApi
- public void setCaCertificateAliases(@Nullable String[] aliases) {
- if (aliases == null) {
- setFieldValue(CA_CERT_KEY, null, CA_CERT_PREFIX);
- } else if (aliases.length == 1) {
- // Backwards compatibility: use the original cert prefix if setting only one alias.
- setCaCertificateAlias(aliases[0]);
- } else {
- // Use KEYSTORES_URI which supports multiple aliases.
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < aliases.length; i++) {
- if (i > 0) {
- sb.append(CA_CERT_ALIAS_DELIMITER);
- }
- sb.append(encodeCaCertificateAlias(CA_CERTIFICATE + aliases[i]));
- }
- setFieldValue(CA_CERT_KEY, sb.toString(), KEYSTORES_URI);
- }
- }
-
- /**
- * Get CA certificate alias
- * @return alias to the CA certificate
- * @hide
- */
- @UnsupportedAppUsage
- public String getCaCertificateAlias() {
- return getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
- }
-
- /**
- * Get CA certificate aliases.
- * @return alias to the CA certificate, or null if unset.
- * @hide
- */
- @Nullable
- @SystemApi
- public String[] getCaCertificateAliases() {
- String value = getFieldValue(CA_CERT_KEY);
- if (value.startsWith(CA_CERT_PREFIX)) {
- // Backwards compatibility: parse the original alias prefix.
- return new String[] {getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX)};
- } else if (value.startsWith(KEYSTORES_URI)) {
- String values = value.substring(KEYSTORES_URI.length());
-
- String[] aliases = TextUtils.split(values, CA_CERT_ALIAS_DELIMITER);
- for (int i = 0; i < aliases.length; i++) {
- aliases[i] = decodeCaCertificateAlias(aliases[i]);
- if (aliases[i].startsWith(CA_CERTIFICATE)) {
- aliases[i] = aliases[i].substring(CA_CERTIFICATE.length());
- }
- }
- return aliases.length != 0 ? aliases : null;
- } else {
- return TextUtils.isEmpty(value) ? null : new String[] {value};
- }
- }
-
- /**
- * Specify a X.509 certificate that identifies the server.
- *
- * <p>A default name is automatically assigned to the certificate and used
- * with this configuration. The framework takes care of installing the
- * certificate when the config is saved and removing the certificate when
- * the config is removed.
- *
- * Note: If no certificate is set for an Enterprise configuration, either by not calling this
- * API (or the {@link #setCaCertificates(X509Certificate[])}, or by calling it with null, then
- * the server certificate validation is skipped - which means that the connection is not secure.
- *
- * @param cert X.509 CA certificate
- * @throws IllegalArgumentException if not a CA certificate
- */
- public void setCaCertificate(@Nullable X509Certificate cert) {
- if (cert != null) {
- if (cert.getBasicConstraints() >= 0) {
- mIsAppInstalledCaCert = true;
- mCaCerts = new X509Certificate[] {cert};
- } else {
- mCaCerts = null;
- throw new IllegalArgumentException("Not a CA certificate");
- }
- } else {
- mCaCerts = null;
- }
- }
-
- /**
- * Get CA certificate. If multiple CA certificates are configured previously,
- * return the first one.
- * @return X.509 CA certificate
- */
- @Nullable public X509Certificate getCaCertificate() {
- if (mCaCerts != null && mCaCerts.length > 0) {
- return mCaCerts[0];
- } else {
- return null;
- }
- }
-
- /**
- * Specify a list of X.509 certificates that identifies the server. The validation
- * passes if the CA of server certificate matches one of the given certificates.
-
- * <p>Default names are automatically assigned to the certificates and used
- * with this configuration. The framework takes care of installing the
- * certificates when the config is saved and removing the certificates when
- * the config is removed.
- *
- * Note: If no certificates are set for an Enterprise configuration, either by not calling this
- * API (or the {@link #setCaCertificate(X509Certificate)}, or by calling it with null, then the
- * server certificate validation is skipped - which means that the
- * connection is not secure.
- *
- * @param certs X.509 CA certificates
- * @throws IllegalArgumentException if any of the provided certificates is
- * not a CA certificate
- */
- public void setCaCertificates(@Nullable X509Certificate[] certs) {
- if (certs != null) {
- X509Certificate[] newCerts = new X509Certificate[certs.length];
- for (int i = 0; i < certs.length; i++) {
- if (certs[i].getBasicConstraints() >= 0) {
- newCerts[i] = certs[i];
- } else {
- mCaCerts = null;
- throw new IllegalArgumentException("Not a CA certificate");
- }
- }
- mCaCerts = newCerts;
- mIsAppInstalledCaCert = true;
- } else {
- mCaCerts = null;
- }
- }
-
- /**
- * Get CA certificates.
- */
- @Nullable public X509Certificate[] getCaCertificates() {
- if (mCaCerts != null && mCaCerts.length > 0) {
- return mCaCerts;
- } else {
- return null;
- }
- }
-
- /**
- * @hide
- */
- public void resetCaCertificate() {
- mCaCerts = null;
- }
-
- /**
- * Set the ca_path directive on wpa_supplicant.
- *
- * From wpa_supplicant documentation:
- *
- * Directory path for CA certificate files (PEM). This path may contain
- * multiple CA certificates in OpenSSL format. Common use for this is to
- * point to system trusted CA list which is often installed into directory
- * like /etc/ssl/certs. If configured, these certificates are added to the
- * list of trusted CAs. ca_cert may also be included in that case, but it is
- * not required.
- *
- * Note: If no certificate path is set for an Enterprise configuration, either by not calling
- * this API, or by calling it with null, and no certificate is set by
- * {@link #setCaCertificate(X509Certificate)} or {@link #setCaCertificates(X509Certificate[])},
- * then the server certificate validation is skipped - which means that the connection is not
- * secure.
- *
- * @param path The path for CA certificate files, or empty string to clear.
- * @hide
- */
- @SystemApi
- public void setCaPath(@NonNull String path) {
- setFieldValue(CA_PATH_KEY, path);
- }
-
- /**
- * Get the ca_path directive from wpa_supplicant.
- * @return The path for CA certificate files, or an empty string if unset.
- * @hide
- */
- @NonNull
- @SystemApi
- public String getCaPath() {
- return getFieldValue(CA_PATH_KEY);
- }
-
- /**
- * Set Client certificate alias.
- *
- * <p> See the {@link android.security.KeyChain} for details on installing or choosing
- * a certificate
- * </p>
- * @param alias identifies the certificate, or empty string to clear.
- * @hide
- */
- @SystemApi
- public void setClientCertificateAlias(@NonNull String alias) {
- setFieldValue(CLIENT_CERT_KEY, alias, CLIENT_CERT_PREFIX);
- setFieldValue(PRIVATE_KEY_ID_KEY, alias, USER_PRIVATE_KEY);
- // Also, set engine parameters
- if (TextUtils.isEmpty(alias)) {
- setFieldValue(ENGINE_KEY, ENGINE_DISABLE);
- setFieldValue(ENGINE_ID_KEY, "");
- } else {
- setFieldValue(ENGINE_KEY, ENGINE_ENABLE);
- setFieldValue(ENGINE_ID_KEY, ENGINE_ID_KEYSTORE);
- }
- }
-
- /**
- * Get client certificate alias.
- * @return alias to the client certificate, or an empty string if unset.
- * @hide
- */
- @NonNull
- @SystemApi
- public String getClientCertificateAlias() {
- return getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
- }
-
- /**
- * Specify a private key and client certificate for client authorization.
- *
- * <p>A default name is automatically assigned to the key entry and used
- * with this configuration. The framework takes care of installing the
- * key entry when the config is saved and removing the key entry when
- * the config is removed.
-
- * @param privateKey a PrivateKey instance for the end certificate.
- * @param clientCertificate an X509Certificate representing the end certificate.
- * @throws IllegalArgumentException for an invalid key or certificate.
- */
- public void setClientKeyEntry(PrivateKey privateKey, X509Certificate clientCertificate) {
- X509Certificate[] clientCertificates = null;
- if (clientCertificate != null) {
- clientCertificates = new X509Certificate[] {clientCertificate};
- }
- setClientKeyEntryWithCertificateChain(privateKey, clientCertificates);
- }
-
- /**
- * Specify a private key and client certificate chain for client authorization.
- *
- * <p>A default name is automatically assigned to the key entry and used
- * with this configuration. The framework takes care of installing the
- * key entry when the config is saved and removing the key entry when
- * the config is removed.
- *
- * @param privateKey a PrivateKey instance for the end certificate.
- * @param clientCertificateChain an array of X509Certificate instances which starts with
- * end certificate and continues with additional CA certificates necessary to
- * link the end certificate with some root certificate known by the authenticator.
- * @throws IllegalArgumentException for an invalid key or certificate.
- */
- public void setClientKeyEntryWithCertificateChain(PrivateKey privateKey,
- X509Certificate[] clientCertificateChain) {
- X509Certificate[] newCerts = null;
- if (clientCertificateChain != null && clientCertificateChain.length > 0) {
- // We validate that this is a well formed chain that starts
- // with an end-certificate and is followed by CA certificates.
- // We don't validate that each following certificate verifies
- // the previous. https://en.wikipedia.org/wiki/Chain_of_trust
- //
- // Basic constraints is an X.509 extension type that defines
- // whether a given certificate is allowed to sign additional
- // certificates and what path length restrictions may exist.
- // We use this to judge whether the certificate is an end
- // certificate or a CA certificate.
- // https://cryptography.io/en/latest/x509/reference/
- if (clientCertificateChain[0].getBasicConstraints() != -1) {
- throw new IllegalArgumentException(
- "First certificate in the chain must be a client end certificate");
- }
-
- for (int i = 1; i < clientCertificateChain.length; i++) {
- if (clientCertificateChain[i].getBasicConstraints() == -1) {
- throw new IllegalArgumentException(
- "All certificates following the first must be CA certificates");
- }
- }
- newCerts = Arrays.copyOf(clientCertificateChain,
- clientCertificateChain.length);
-
- if (privateKey == null) {
- throw new IllegalArgumentException("Client cert without a private key");
- }
- if (privateKey.getEncoded() == null) {
- throw new IllegalArgumentException("Private key cannot be encoded");
- }
- }
-
- mClientPrivateKey = privateKey;
- mClientCertificateChain = newCerts;
- mIsAppInstalledDeviceKeyAndCert = true;
- }
-
- /**
- * Get client certificate
- *
- * @return X.509 client certificate
- */
- public X509Certificate getClientCertificate() {
- if (mClientCertificateChain != null && mClientCertificateChain.length > 0) {
- return mClientCertificateChain[0];
- } else {
- return null;
- }
- }
-
- /**
- * Get the complete client certificate chain in the same order as it was last supplied.
- *
- * <p>If the chain was last supplied by a call to
- * {@link #setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate)}
- * with a non-null * certificate instance, a single-element array containing the certificate
- * will be * returned. If {@link #setClientKeyEntryWithCertificateChain(
- * java.security.PrivateKey, java.security.cert.X509Certificate[])} was last called with a
- * non-empty array, this array will be returned in the same order as it was supplied.
- * Otherwise, {@code null} will be returned.
- *
- * @return X.509 client certificates
- */
- @Nullable public X509Certificate[] getClientCertificateChain() {
- if (mClientCertificateChain != null && mClientCertificateChain.length > 0) {
- return mClientCertificateChain;
- } else {
- return null;
- }
- }
-
- /**
- * @hide
- */
- public void resetClientKeyEntry() {
- mClientPrivateKey = null;
- mClientCertificateChain = null;
- }
-
- /**
- * Get the client private key as supplied in {@link #setClientKeyEntryWithCertificateChain}, or
- * null if unset.
- */
- @Nullable
- public PrivateKey getClientPrivateKey() {
- return mClientPrivateKey;
- }
-
- /**
- * Set subject match (deprecated). This is the substring to be matched against the subject of
- * the authentication server certificate.
- * @param subjectMatch substring to be matched
- * @deprecated in favor of altSubjectMatch
- */
- public void setSubjectMatch(String subjectMatch) {
- setFieldValue(SUBJECT_MATCH_KEY, subjectMatch);
- }
-
- /**
- * Get subject match (deprecated)
- * @return the subject match string
- * @deprecated in favor of altSubjectMatch
- */
- public String getSubjectMatch() {
- return getFieldValue(SUBJECT_MATCH_KEY);
- }
-
- /**
- * Set alternate subject match. This is the substring to be matched against the
- * alternate subject of the authentication server certificate.
- *
- * Note: If no alternate subject is set for an Enterprise configuration, either by not calling
- * this API, or by calling it with null, or not setting domain suffix match using the
- * {@link #setDomainSuffixMatch(String)}, then the server certificate validation is incomplete -
- * which means that the connection is not secure.
- *
- * @param altSubjectMatch substring to be matched, for example
- * DNS:server.example.com;EMAIL:server@example.com
- */
- public void setAltSubjectMatch(String altSubjectMatch) {
- setFieldValue(ALTSUBJECT_MATCH_KEY, altSubjectMatch);
- }
-
- /**
- * Get alternate subject match
- * @return the alternate subject match string
- */
- public String getAltSubjectMatch() {
- return getFieldValue(ALTSUBJECT_MATCH_KEY);
- }
-
- /**
- * Set the domain_suffix_match directive on wpa_supplicant. This is the parameter to use
- * for Hotspot 2.0 defined matching of AAA server certs per WFA HS2.0 spec, section 7.3.3.2,
- * second paragraph.
- *
- * <p>From wpa_supplicant documentation:
- * <p>Constraint for server domain name. If set, this FQDN is used as a suffix match requirement
- * for the AAAserver certificate in SubjectAltName dNSName element(s). If a matching dNSName is
- * found, this constraint is met.
- * <p>Suffix match here means that the host/domain name is compared one label at a time starting
- * from the top-level domain and all the labels in domain_suffix_match shall be included in the
- * certificate. The certificate may include additional sub-level labels in addition to the
- * required labels.
- * <p>More than one match string can be provided by using semicolons to separate the strings
- * (e.g., example.org;example.com). When multiple strings are specified, a match with any one of
- * the values is considered a sufficient match for the certificate, i.e., the conditions are
- * ORed ogether.
- * <p>For example, domain_suffix_match=example.com would match test.example.com but would not
- * match test-example.com.
- *
- * Note: If no domain suffix is set for an Enterprise configuration, either by not calling this
- * API, or by calling it with null, or not setting alternate subject match using the
- * {@link #setAltSubjectMatch(String)}, then the server certificate
- * validation is incomplete - which means that the connection is not secure.
- *
- * @param domain The domain value
- */
- public void setDomainSuffixMatch(String domain) {
- setFieldValue(DOM_SUFFIX_MATCH_KEY, domain);
- }
-
- /**
- * Get the domain_suffix_match value. See setDomSuffixMatch.
- * @return The domain value.
- */
- public String getDomainSuffixMatch() {
- return getFieldValue(DOM_SUFFIX_MATCH_KEY);
- }
-
- /**
- * Set realm for Passpoint credential; realm identifies a set of networks where your
- * Passpoint credential can be used
- * @param realm the realm
- */
- public void setRealm(String realm) {
- setFieldValue(REALM_KEY, realm);
- }
-
- /**
- * Get realm for Passpoint credential; see {@link #setRealm(String)} for more information
- * @return the realm
- */
- public String getRealm() {
- return getFieldValue(REALM_KEY);
- }
-
- /**
- * Set plmn (Public Land Mobile Network) of the provider of Passpoint credential
- * @param plmn the plmn value derived from mcc (mobile country code) & mnc (mobile network code)
- */
- public void setPlmn(String plmn) {
- setFieldValue(PLMN_KEY, plmn);
- }
-
- /**
- * Get plmn (Public Land Mobile Network) for Passpoint credential; see {@link #setPlmn
- * (String)} for more information
- * @return the plmn
- */
- public String getPlmn() {
- return getFieldValue(PLMN_KEY);
- }
-
- /** See {@link WifiConfiguration#getKeyIdForCredentials} @hide */
- public String getKeyId(WifiEnterpriseConfig current) {
- // If EAP method is not initialized, use current config details
- if (mEapMethod == Eap.NONE) {
- return (current != null) ? current.getKeyId(null) : EMPTY_VALUE;
- }
- if (!isEapMethodValid()) {
- return EMPTY_VALUE;
- }
- return Eap.strings[mEapMethod] + "_" + Phase2.strings[mPhase2Method];
- }
-
- private String removeDoubleQuotes(String string) {
- if (TextUtils.isEmpty(string)) return "";
- int length = string.length();
- if ((length > 1) && (string.charAt(0) == '"')
- && (string.charAt(length - 1) == '"')) {
- return string.substring(1, length - 1);
- }
- return string;
- }
-
- private String convertToQuotedString(String string) {
- return "\"" + string + "\"";
- }
-
- /**
- * Returns the index at which the toBeFound string is found in the array.
- * @param arr array of strings
- * @param toBeFound string to be found
- * @param defaultIndex default index to be returned when string is not found
- * @return the index into array
- */
- private int getStringIndex(String arr[], String toBeFound, int defaultIndex) {
- if (TextUtils.isEmpty(toBeFound)) return defaultIndex;
- for (int i = 0; i < arr.length; i++) {
- if (toBeFound.equals(arr[i])) return i;
- }
- return defaultIndex;
- }
-
- /**
- * Returns the field value for the key with prefix removed.
- * @param key into the hash
- * @param prefix is the prefix that the value may have
- * @return value
- * @hide
- */
- private String getFieldValue(String key, String prefix) {
- // TODO: Should raise an exception if |key| is EAP_KEY or PHASE2_KEY since
- // neither of these keys should be retrieved in this manner.
- String value = mFields.get(key);
- // Uninitialized or known to be empty after reading from supplicant
- if (TextUtils.isEmpty(value) || EMPTY_VALUE.equals(value)) return "";
-
- value = removeDoubleQuotes(value);
- if (value.startsWith(prefix)) {
- return value.substring(prefix.length());
- } else {
- return value;
- }
- }
-
- /**
- * Returns the field value for the key.
- * @param key into the hash
- * @return value
- * @hide
- */
- public String getFieldValue(String key) {
- return getFieldValue(key, "");
- }
-
- /**
- * Set a value with an optional prefix at key
- * @param key into the hash
- * @param value to be set
- * @param prefix an optional value to be prefixed to actual value
- * @hide
- */
- private void setFieldValue(String key, String value, String prefix) {
- // TODO: Should raise an exception if |key| is EAP_KEY or PHASE2_KEY since
- // neither of these keys should be set in this manner.
- if (TextUtils.isEmpty(value)) {
- mFields.put(key, EMPTY_VALUE);
- } else {
- String valueToSet;
- if (!UNQUOTED_KEYS.contains(key)) {
- valueToSet = convertToQuotedString(prefix + value);
- } else {
- valueToSet = prefix + value;
- }
- mFields.put(key, valueToSet);
- }
- }
-
- /**
- * Set a value at key
- * @param key into the hash
- * @param value to be set
- * @hide
- */
- public void setFieldValue(String key, String value) {
- setFieldValue(key, value, "");
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- for (String key : mFields.keySet()) {
- // Don't display password in toString().
- String value = PASSWORD_KEY.equals(key) ? "<removed>" : mFields.get(key);
- sb.append(key).append(" ").append(value).append("\n");
- }
- if (mEapMethod >= 0 && mEapMethod < Eap.strings.length) {
- sb.append("eap_method: ").append(Eap.strings[mEapMethod]).append("\n");
- }
- if (mPhase2Method > 0 && mPhase2Method < Phase2.strings.length) {
- sb.append("phase2_method: ").append(Phase2.strings[mPhase2Method]).append("\n");
- }
- sb.append(" ocsp: ").append(mOcsp).append("\n");
- return sb.toString();
- }
-
- /**
- * Returns whether the EAP method data is valid, i.e., whether mEapMethod and mPhase2Method
- * are valid indices into {@code Eap.strings[]} and {@code Phase2.strings[]} respectively.
- */
- private boolean isEapMethodValid() {
- if (mEapMethod == Eap.NONE) {
- Log.e(TAG, "WiFi enterprise configuration is invalid as it supplies no EAP method.");
- return false;
- }
- if (mEapMethod < 0 || mEapMethod >= Eap.strings.length) {
- Log.e(TAG, "mEapMethod is invald for WiFi enterprise configuration: " + mEapMethod);
- return false;
- }
- if (mPhase2Method < 0 || mPhase2Method >= Phase2.strings.length) {
- Log.e(TAG, "mPhase2Method is invald for WiFi enterprise configuration: "
- + mPhase2Method);
- return false;
- }
- return true;
- }
-
- /**
- * Check if certificate was installed by an app, or manually (not by an app). If true,
- * certificate and keys will be removed from key storage when this network is removed. If not,
- * then certificates and keys remain persistent until the user manually removes them.
- *
- * @return true if certificate was installed by an app, false if certificate was installed
- * manually by the user.
- * @hide
- */
- public boolean isAppInstalledDeviceKeyAndCert() {
- return mIsAppInstalledDeviceKeyAndCert;
- }
-
- /**
- * Check if CA certificate was installed by an app, or manually (not by an app). If true,
- * CA certificate will be removed from key storage when this network is removed. If not,
- * then certificates and keys remain persistent until the user manually removes them.
- *
- * @return true if CA certificate was installed by an app, false if CA certificate was installed
- * manually by the user.
- * @hide
- */
- public boolean isAppInstalledCaCert() {
- return mIsAppInstalledCaCert;
- }
-
- /**
- * Set the OCSP type.
- * @param ocsp is one of {@link ##OCSP_NONE}, {@link #OCSP_REQUEST_CERT_STATUS},
- * {@link #OCSP_REQUIRE_CERT_STATUS} or
- * {@link #OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS}
- * @throws IllegalArgumentException if the OCSP type is invalid
- * @hide
- */
- @SystemApi
- public void setOcsp(@Ocsp int ocsp) {
- if (ocsp >= OCSP_NONE && ocsp <= OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS) {
- mOcsp = ocsp;
- } else {
- throw new IllegalArgumentException("Invalid OCSP type.");
- }
- }
-
- /**
- * Get the OCSP type.
- * @hide
- */
- @SystemApi
- public @Ocsp int getOcsp() {
- return mOcsp;
- }
-
- /**
- * Utility method to determine whether the configuration's authentication method is SIM-based.
- *
- * @return true if the credential information requires SIM card for current authentication
- * method, otherwise it returns false.
- */
- public boolean isAuthenticationSimBased() {
- if (mEapMethod == Eap.SIM || mEapMethod == Eap.AKA || mEapMethod == Eap.AKA_PRIME) {
- return true;
- }
- if (mEapMethod == Eap.PEAP) {
- return mPhase2Method == Phase2.SIM || mPhase2Method == Phase2.AKA
- || mPhase2Method == Phase2.AKA_PRIME;
- }
- return false;
- }
-
- /**
- * Set the WAPI certificate suite name on wpa_supplicant.
- *
- * If this field is not specified, WAPI-CERT uses ASU ID from WAI packet
- * as the certificate suite name automatically.
- *
- * @param wapiCertSuite The name for WAPI certificate suite, or empty string to clear.
- * @hide
- */
- @SystemApi
- public void setWapiCertSuite(@NonNull String wapiCertSuite) {
- setFieldValue(WAPI_CERT_SUITE_KEY, wapiCertSuite);
- }
-
- /**
- * Get the WAPI certificate suite name
- * @return the certificate suite name
- * @hide
- */
- @NonNull
- @SystemApi
- public String getWapiCertSuite() {
- return getFieldValue(WAPI_CERT_SUITE_KEY);
- }
-
- /**
- * Method determines whether the Enterprise configuration is insecure. An insecure
- * configuration is one where EAP method requires a CA certification, i.e. PEAP, TLS, or
- * TTLS, and any of the following conditions are met:
- * - Both certificate and CA path are not configured.
- * - Both alternative subject match and domain suffix match are not set.
- *
- * Note: this method does not exhaustively check security of the configuration - i.e. a return
- * value of {@code false} is not a guarantee that the configuration is secure.
- * @hide
- */
- public boolean isInsecure() {
- if (mEapMethod != Eap.PEAP && mEapMethod != Eap.TLS && mEapMethod != Eap.TTLS) {
- return false;
- }
- if (TextUtils.isEmpty(getAltSubjectMatch())
- && TextUtils.isEmpty(getDomainSuffixMatch())) {
- // Both subject and domain match are not set, it's insecure.
- return true;
- }
- if (mIsAppInstalledCaCert) {
- // CA certificate is installed by App, it's secure.
- return false;
- }
- if (getCaCertificateAliases() != null) {
- // CA certificate alias from keyStore is set, it's secure.
- return false;
- }
- return TextUtils.isEmpty(getCaPath());
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiFrameworkInitializer.java b/wifi/java/android/net/wifi/WifiFrameworkInitializer.java
deleted file mode 100644
index 1507199..0000000
--- a/wifi/java/android/net/wifi/WifiFrameworkInitializer.java
+++ /dev/null
@@ -1,121 +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.net.wifi;
-
-import android.annotation.SystemApi;
-import android.app.SystemServiceRegistry;
-import android.content.Context;
-import android.net.wifi.aware.IWifiAwareManager;
-import android.net.wifi.aware.WifiAwareManager;
-import android.net.wifi.p2p.IWifiP2pManager;
-import android.net.wifi.p2p.WifiP2pManager;
-import android.net.wifi.rtt.IWifiRttManager;
-import android.net.wifi.rtt.WifiRttManager;
-import android.os.HandlerThread;
-import android.os.Looper;
-
-/**
- * Class for performing registration for all Wifi services.
- *
- * @hide
- */
-@SystemApi
-public class WifiFrameworkInitializer {
-
- /**
- * A class implementing the lazy holder idiom: the unique static instance
- * of {@link #INSTANCE} is instantiated in a thread-safe way (guaranteed by
- * the language specs) the first time that NoPreloadHolder is referenced in getInstanceLooper().
- *
- * This is necessary because we can't spawn a new thread in {@link #registerServiceWrappers()}.
- * {@link #registerServiceWrappers()} is called during the Zygote phase, which disallows
- * spawning new threads. Naming the class "NoPreloadHolder" ensures that the classloader will
- * not preload this class, inadvertently spawning the thread too early.
- */
- private static class NoPreloadHolder {
- private static final HandlerThread INSTANCE = createInstance();
-
- private static HandlerThread createInstance() {
- HandlerThread thread = new HandlerThread("WifiManagerThread");
- thread.start();
- return thread;
- }
- }
-
- private static Looper getInstanceLooper() {
- return NoPreloadHolder.INSTANCE.getLooper();
- }
-
- private WifiFrameworkInitializer() {}
-
- /**
- * Called by {@link SystemServiceRegistry}'s static initializer and registers all Wifi services
- * to {@link Context}, so that {@link Context#getSystemService} can return them.
- *
- * @throws IllegalStateException if this is called from anywhere besides
- * {@link SystemServiceRegistry}
- */
- public static void registerServiceWrappers() {
- SystemServiceRegistry.registerContextAwareService(
- Context.WIFI_SERVICE,
- WifiManager.class,
- (context, serviceBinder) -> {
- IWifiManager service = IWifiManager.Stub.asInterface(serviceBinder);
- return new WifiManager(context, service, getInstanceLooper());
- }
- );
- SystemServiceRegistry.registerStaticService(
- Context.WIFI_P2P_SERVICE,
- WifiP2pManager.class,
- serviceBinder -> {
- IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(serviceBinder);
- return new WifiP2pManager(service);
- }
- );
- SystemServiceRegistry.registerContextAwareService(
- Context.WIFI_AWARE_SERVICE,
- WifiAwareManager.class,
- (context, serviceBinder) -> {
- IWifiAwareManager service = IWifiAwareManager.Stub.asInterface(serviceBinder);
- return new WifiAwareManager(context, service);
- }
- );
- SystemServiceRegistry.registerContextAwareService(
- Context.WIFI_SCANNING_SERVICE,
- WifiScanner.class,
- (context, serviceBinder) -> {
- IWifiScanner service = IWifiScanner.Stub.asInterface(serviceBinder);
- return new WifiScanner(context, service, getInstanceLooper());
- }
- );
- SystemServiceRegistry.registerContextAwareService(
- Context.WIFI_RTT_RANGING_SERVICE,
- WifiRttManager.class,
- (context, serviceBinder) -> {
- IWifiRttManager service = IWifiRttManager.Stub.asInterface(serviceBinder);
- return new WifiRttManager(context, service);
- }
- );
- SystemServiceRegistry.registerContextAwareService(
- Context.WIFI_RTT_SERVICE,
- RttManager.class,
- context -> {
- WifiRttManager wifiRttManager = context.getSystemService(WifiRttManager.class);
- return new RttManager(context, wifiRttManager);
- }
- );
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
deleted file mode 100644
index 5388367..0000000
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ /dev/null
@@ -1,1051 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.NetworkInfo.DetailedState;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import com.android.net.module.util.Inet4AddressUtils;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.EnumMap;
-import java.util.Locale;
-
-/**
- * Describes the state of any Wi-Fi connection that is active or
- * is in the process of being set up.
- */
-public class WifiInfo implements Parcelable {
- private static final String TAG = "WifiInfo";
- /**
- * This is the map described in the Javadoc comment above. The positions
- * of the elements of the array must correspond to the ordinal values
- * of <code>DetailedState</code>.
- */
- private static final EnumMap<SupplicantState, DetailedState> stateMap =
- new EnumMap<SupplicantState, DetailedState>(SupplicantState.class);
-
- /**
- * Default MAC address reported to a client that does not have the
- * android.permission.LOCAL_MAC_ADDRESS permission.
- *
- * @hide
- */
- @SystemApi
- public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
-
- static {
- stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
- stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);
- stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
- stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
- stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);
- stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);
- stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);
- stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);
- stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING);
- stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR);
- stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED);
- stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE);
- stateMap.put(SupplicantState.INVALID, DetailedState.FAILED);
- }
-
- private SupplicantState mSupplicantState;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private String mBSSID;
- @UnsupportedAppUsage
- private WifiSsid mWifiSsid;
- private int mNetworkId;
-
- /**
- * Used to indicate that the RSSI is invalid, for example if no RSSI measurements are available
- * yet.
- * @hide
- */
- @SystemApi
- public static final int INVALID_RSSI = -127;
-
- /** @hide **/
- public static final int MIN_RSSI = -126;
-
- /** @hide **/
- public static final int MAX_RSSI = 200;
-
-
- /**
- * Received Signal Strength Indicator
- */
- private int mRssi;
-
- /**
- * Wi-Fi standard for the connection
- */
- private @WifiAnnotations.WifiStandard int mWifiStandard;
-
- /**
- * The unit in which links speeds are expressed.
- */
- public static final String LINK_SPEED_UNITS = "Mbps";
- private int mLinkSpeed;
-
- /**
- * Constant for unknown link speed.
- */
- public static final int LINK_SPEED_UNKNOWN = -1;
-
- /**
- * Tx(transmit) Link speed in Mbps
- */
- private int mTxLinkSpeed;
-
- /**
- * Max supported Tx(transmit) link speed in Mbps
- */
- private int mMaxSupportedTxLinkSpeed;
-
- /**
- * Rx(receive) Link speed in Mbps
- */
- private int mRxLinkSpeed;
-
- /**
- * Max supported Rx(receive) link speed in Mbps
- */
- private int mMaxSupportedRxLinkSpeed;
-
- /**
- * Frequency in MHz
- */
- public static final String FREQUENCY_UNITS = "MHz";
- private int mFrequency;
-
- @UnsupportedAppUsage
- private InetAddress mIpAddress;
- @UnsupportedAppUsage
- private String mMacAddress = DEFAULT_MAC_ADDRESS;
-
- /**
- * Whether the network is ephemeral or not.
- */
- private boolean mEphemeral;
-
- /**
- * Whether the network is trusted or not.
- */
- private boolean mTrusted;
-
- /**
- * OSU (Online Sign Up) AP for Passpoint R2.
- */
- private boolean mOsuAp;
-
- /**
- * Fully qualified domain name of a Passpoint configuration
- */
- private String mFqdn;
-
- /**
- * Name of Passpoint credential provider
- */
- private String mProviderFriendlyName;
-
- /**
- * If connected to a network suggestion or specifier, store the package name of the app,
- * else null.
- */
- private String mRequestingPackageName;
-
- /**
- * Running total count of lost (not ACKed) transmitted unicast data packets.
- * @hide
- */
- public long txBad;
- /**
- * Running total count of transmitted unicast data retry packets.
- * @hide
- */
- public long txRetries;
- /**
- * Running total count of successfully transmitted (ACKed) unicast data packets.
- * @hide
- */
- public long txSuccess;
- /**
- * Running total count of received unicast data packets.
- * @hide
- */
- public long rxSuccess;
-
- private double mLostTxPacketsPerSecond;
-
- /**
- * Average rate of lost transmitted packets, in units of packets per second.
- * @hide
- */
- @SystemApi
- public double getLostTxPacketsPerSecond() {
- return mLostTxPacketsPerSecond;
- }
-
- /** @hide */
- public void setLostTxPacketsPerSecond(double lostTxPacketsPerSecond) {
- mLostTxPacketsPerSecond = lostTxPacketsPerSecond;
- }
-
- private double mTxRetriedTxPacketsPerSecond;
-
- /**
- * Average rate of transmitted retry packets, in units of packets per second.
- * @hide
- */
- @SystemApi
- public double getRetriedTxPacketsPerSecond() {
- return mTxRetriedTxPacketsPerSecond;
- }
-
- /** @hide */
- public void setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond) {
- mTxRetriedTxPacketsPerSecond = txRetriedTxPacketsPerSecond;
- }
-
- private double mSuccessfulTxPacketsPerSecond;
-
- /**
- * Average rate of successfully transmitted unicast packets, in units of packets per second.
- * @hide
- */
- @SystemApi
- public double getSuccessfulTxPacketsPerSecond() {
- return mSuccessfulTxPacketsPerSecond;
- }
-
- /** @hide */
- public void setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond) {
- mSuccessfulTxPacketsPerSecond = successfulTxPacketsPerSecond;
- }
-
- private double mSuccessfulRxPacketsPerSecond;
-
- /**
- * Average rate of received unicast data packets, in units of packets per second.
- * @hide
- */
- @SystemApi
- public double getSuccessfulRxPacketsPerSecond() {
- return mSuccessfulRxPacketsPerSecond;
- }
-
- /** @hide */
- public void setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond) {
- mSuccessfulRxPacketsPerSecond = successfulRxPacketsPerSecond;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public int score;
-
- /**
- * The current Wifi score.
- * NOTE: this value should only be used for debugging purposes. Do not rely on this value for
- * any computations. The meaning of this value can and will change at any time without warning.
- * @hide
- */
- @SystemApi
- public int getScore() {
- return score;
- }
-
- /** @hide */
- public void setScore(int score) {
- this.score = score;
- }
-
- /**
- * Flag indicating that AP has hinted that upstream connection is metered,
- * and sensitive to heavy data transfers.
- */
- private boolean mMeteredHint;
-
- /**
- * Passpoint unique key
- */
- private String mPasspointUniqueId;
-
- /** @hide */
- @UnsupportedAppUsage
- public WifiInfo() {
- mWifiSsid = null;
- mBSSID = null;
- mNetworkId = -1;
- mSupplicantState = SupplicantState.UNINITIALIZED;
- mRssi = INVALID_RSSI;
- mLinkSpeed = LINK_SPEED_UNKNOWN;
- mFrequency = -1;
- }
-
- /** @hide */
- public void reset() {
- setInetAddress(null);
- setBSSID(null);
- setSSID(null);
- setNetworkId(-1);
- setRssi(INVALID_RSSI);
- setLinkSpeed(LINK_SPEED_UNKNOWN);
- setTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
- setRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
- setMaxSupportedTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
- setMaxSupportedRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
- setFrequency(-1);
- setMeteredHint(false);
- setEphemeral(false);
- setOsuAp(false);
- setRequestingPackageName(null);
- setFQDN(null);
- setProviderFriendlyName(null);
- setPasspointUniqueId(null);
- txBad = 0;
- txSuccess = 0;
- rxSuccess = 0;
- txRetries = 0;
- mLostTxPacketsPerSecond = 0;
- mSuccessfulTxPacketsPerSecond = 0;
- mSuccessfulRxPacketsPerSecond = 0;
- mTxRetriedTxPacketsPerSecond = 0;
- score = 0;
- }
-
- /**
- * Copy constructor
- * @hide
- */
- public WifiInfo(WifiInfo source) {
- if (source != null) {
- mSupplicantState = source.mSupplicantState;
- mBSSID = source.mBSSID;
- mWifiSsid = source.mWifiSsid;
- mNetworkId = source.mNetworkId;
- mRssi = source.mRssi;
- mLinkSpeed = source.mLinkSpeed;
- mTxLinkSpeed = source.mTxLinkSpeed;
- mRxLinkSpeed = source.mRxLinkSpeed;
- mFrequency = source.mFrequency;
- mIpAddress = source.mIpAddress;
- mMacAddress = source.mMacAddress;
- mMeteredHint = source.mMeteredHint;
- mEphemeral = source.mEphemeral;
- mTrusted = source.mTrusted;
- mRequestingPackageName =
- source.mRequestingPackageName;
- mOsuAp = source.mOsuAp;
- mFqdn = source.mFqdn;
- mProviderFriendlyName = source.mProviderFriendlyName;
- txBad = source.txBad;
- txRetries = source.txRetries;
- txSuccess = source.txSuccess;
- rxSuccess = source.rxSuccess;
- mLostTxPacketsPerSecond = source.mLostTxPacketsPerSecond;
- mTxRetriedTxPacketsPerSecond = source.mTxRetriedTxPacketsPerSecond;
- mSuccessfulTxPacketsPerSecond = source.mSuccessfulTxPacketsPerSecond;
- mSuccessfulRxPacketsPerSecond = source.mSuccessfulRxPacketsPerSecond;
- score = source.score;
- mWifiStandard = source.mWifiStandard;
- mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed;
- mMaxSupportedRxLinkSpeed = source.mMaxSupportedRxLinkSpeed;
- mPasspointUniqueId = source.mPasspointUniqueId;
- }
- }
-
- /** Builder for WifiInfo */
- public static final class Builder {
- private final WifiInfo mWifiInfo = new WifiInfo();
-
- /**
- * Set the SSID, in the form of a raw byte array.
- * @see WifiInfo#getSSID()
- */
- @NonNull
- public Builder setSsid(@NonNull byte[] ssid) {
- mWifiInfo.setSSID(WifiSsid.createFromByteArray(ssid));
- return this;
- }
-
- /**
- * Set the BSSID.
- * @see WifiInfo#getBSSID()
- */
- @NonNull
- public Builder setBssid(@NonNull String bssid) {
- mWifiInfo.setBSSID(bssid);
- return this;
- }
-
- /**
- * Set the RSSI, in dBm.
- * @see WifiInfo#getRssi()
- */
- @NonNull
- public Builder setRssi(int rssi) {
- mWifiInfo.setRssi(rssi);
- return this;
- }
-
- /**
- * Set the network ID.
- * @see WifiInfo#getNetworkId()
- */
- @NonNull
- public Builder setNetworkId(int networkId) {
- mWifiInfo.setNetworkId(networkId);
- return this;
- }
-
- /**
- * Build a WifiInfo object.
- */
- @NonNull
- public WifiInfo build() {
- return new WifiInfo(mWifiInfo);
- }
- }
-
- /** @hide */
- public void setSSID(WifiSsid wifiSsid) {
- mWifiSsid = wifiSsid;
- }
-
- /**
- * Returns the service set identifier (SSID) of the current 802.11 network.
- * <p>
- * If the SSID can be decoded as UTF-8, it will be returned surrounded by double
- * quotation marks. Otherwise, it is returned as a string of hex digits.
- * The SSID may be {@link WifiManager#UNKNOWN_SSID}, if there is no network currently connected
- * or if the caller has insufficient permissions to access the SSID.
- * </p>
- * <p>
- * Prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method
- * always returned the SSID with no quotes around it.
- * </p>
- *
- * @return the SSID.
- */
- public String getSSID() {
- if (mWifiSsid != null) {
- String unicode = mWifiSsid.toString();
- if (!TextUtils.isEmpty(unicode)) {
- return "\"" + unicode + "\"";
- } else {
- String hex = mWifiSsid.getHexString();
- return (hex != null) ? hex : WifiManager.UNKNOWN_SSID;
- }
- }
- return WifiManager.UNKNOWN_SSID;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public WifiSsid getWifiSsid() {
- return mWifiSsid;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setBSSID(String BSSID) {
- mBSSID = BSSID;
- }
-
- /**
- * Return the basic service set identifier (BSSID) of the current access point.
- * <p>
- * The BSSID may be
- * <lt>{@code null}, if there is no network currently connected.</lt>
- * <lt>{@code "02:00:00:00:00:00"}, if the caller has insufficient permissions to access the
- * BSSID.<lt>
- * </p>
- *
- * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}
- */
- public String getBSSID() {
- return mBSSID;
- }
-
- /**
- * Returns the received signal strength indicator of the current 802.11
- * network, in dBm.
- *
- * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into
- * an absolute signal level which can be displayed to a user.
- *
- * @return the RSSI.
- */
- public int getRssi() {
- return mRssi;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setRssi(int rssi) {
- if (rssi < INVALID_RSSI)
- rssi = INVALID_RSSI;
- if (rssi > MAX_RSSI)
- rssi = MAX_RSSI;
- mRssi = rssi;
- }
-
- /**
- * Sets the Wi-Fi standard
- * @hide
- */
- public void setWifiStandard(@WifiAnnotations.WifiStandard int wifiStandard) {
- mWifiStandard = wifiStandard;
- }
-
- /**
- * Get connection Wi-Fi standard
- * @return the connection Wi-Fi standard
- */
- public @WifiAnnotations.WifiStandard int getWifiStandard() {
- return mWifiStandard;
- }
-
- /**
- * Returns the current link speed in {@link #LINK_SPEED_UNITS}.
- * @return the link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
- * @see #LINK_SPEED_UNITS
- * @see #LINK_SPEED_UNKNOWN
- */
- public int getLinkSpeed() {
- return mLinkSpeed;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setLinkSpeed(int linkSpeed) {
- mLinkSpeed = linkSpeed;
- }
-
- /**
- * Returns the current transmit link speed in Mbps.
- * @return the Tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
- * @see #LINK_SPEED_UNKNOWN
- */
- @IntRange(from = -1)
- public int getTxLinkSpeedMbps() {
- return mTxLinkSpeed;
- }
-
- /**
- * Returns the maximum supported transmit link speed in Mbps
- * @return the max supported tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
- * unknown. @see #LINK_SPEED_UNKNOWN
- */
- public int getMaxSupportedTxLinkSpeedMbps() {
- return mMaxSupportedTxLinkSpeed;
- }
-
- /**
- * Update the last transmitted packet bit rate in Mbps.
- * @hide
- */
- public void setTxLinkSpeedMbps(int txLinkSpeed) {
- mTxLinkSpeed = txLinkSpeed;
- }
-
- /**
- * Set the maximum supported transmit link speed in Mbps
- * @hide
- */
- public void setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed) {
- mMaxSupportedTxLinkSpeed = maxSupportedTxLinkSpeed;
- }
-
- /**
- * Returns the current receive link speed in Mbps.
- * @return the Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
- * @see #LINK_SPEED_UNKNOWN
- */
- @IntRange(from = -1)
- public int getRxLinkSpeedMbps() {
- return mRxLinkSpeed;
- }
-
- /**
- * Returns the maximum supported receive link speed in Mbps
- * @return the max supported Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
- * unknown. @see #LINK_SPEED_UNKNOWN
- */
- public int getMaxSupportedRxLinkSpeedMbps() {
- return mMaxSupportedRxLinkSpeed;
- }
-
- /**
- * Update the last received packet bit rate in Mbps.
- * @hide
- */
- public void setRxLinkSpeedMbps(int rxLinkSpeed) {
- mRxLinkSpeed = rxLinkSpeed;
- }
-
- /**
- * Set the maximum supported receive link speed in Mbps
- * @hide
- */
- public void setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed) {
- mMaxSupportedRxLinkSpeed = maxSupportedRxLinkSpeed;
- }
-
- /**
- * Returns the current frequency in {@link #FREQUENCY_UNITS}.
- * @return the frequency.
- * @see #FREQUENCY_UNITS
- */
- public int getFrequency() {
- return mFrequency;
- }
-
- /** @hide */
- public void setFrequency(int frequency) {
- this.mFrequency = frequency;
- }
-
- /**
- * @hide
- */
- public boolean is24GHz() {
- return ScanResult.is24GHz(mFrequency);
- }
-
- /**
- * @hide
- */
- @UnsupportedAppUsage
- public boolean is5GHz() {
- return ScanResult.is5GHz(mFrequency);
- }
-
- /**
- * @hide
- */
- public boolean is6GHz() {
- return ScanResult.is6GHz(mFrequency);
- }
-
- /**
- * Record the MAC address of the WLAN interface
- * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
- * @hide
- */
- @UnsupportedAppUsage
- public void setMacAddress(String macAddress) {
- this.mMacAddress = macAddress;
- }
-
- public String getMacAddress() {
- return mMacAddress;
- }
-
- /**
- * @return true if {@link #getMacAddress()} has a real MAC address.
- *
- * @hide
- */
- public boolean hasRealMacAddress() {
- return mMacAddress != null && !DEFAULT_MAC_ADDRESS.equals(mMacAddress);
- }
-
- /**
- * Indicates if we've dynamically detected this active network connection as
- * being metered.
- *
- * @see WifiConfiguration#isMetered(WifiConfiguration, WifiInfo)
- * @hide
- */
- public void setMeteredHint(boolean meteredHint) {
- mMeteredHint = meteredHint;
- }
-
- /** {@hide} */
- @UnsupportedAppUsage
- public boolean getMeteredHint() {
- return mMeteredHint;
- }
-
- /** {@hide} */
- public void setEphemeral(boolean ephemeral) {
- mEphemeral = ephemeral;
- }
-
- /**
- * Returns true if the current Wifi network is ephemeral, false otherwise.
- * An ephemeral network is a network that is temporary and not persisted in the system.
- * Ephemeral networks cannot be forgotten, only disabled with
- * {@link WifiManager#disableEphemeralNetwork(String)}.
- *
- * @hide
- */
- @SystemApi
- public boolean isEphemeral() {
- return mEphemeral;
- }
-
- /** {@hide} */
- public void setTrusted(boolean trusted) {
- mTrusted = trusted;
- }
-
- /** {@hide} */
- public boolean isTrusted() {
- return mTrusted;
- }
-
- /** {@hide} */
- public void setOsuAp(boolean osuAp) {
- mOsuAp = osuAp;
- }
-
- /** {@hide} */
- @SystemApi
- public boolean isOsuAp() {
- return mOsuAp;
- }
-
- /** {@hide} */
- @SystemApi
- public boolean isPasspointAp() {
- return mFqdn != null && mProviderFriendlyName != null;
- }
-
- /** {@hide} */
- public void setFQDN(@Nullable String fqdn) {
- mFqdn = fqdn;
- }
-
- /**
- * Returns the Fully Qualified Domain Name of the network if it is a Passpoint network.
- * <p>
- * The FQDN may be
- * <lt>{@code null} if no network currently connected, currently connected network is not
- * passpoint network or the caller has insufficient permissions to access the FQDN.</lt>
- * </p>
- */
- public @Nullable String getPasspointFqdn() {
- return mFqdn;
- }
-
- /** {@hide} */
- public void setProviderFriendlyName(@Nullable String providerFriendlyName) {
- mProviderFriendlyName = providerFriendlyName;
- }
-
- /**
- * Returns the Provider Friendly Name of the network if it is a Passpoint network.
- * <p>
- * The Provider Friendly Name may be
- * <lt>{@code null} if no network currently connected, currently connected network is not
- * passpoint network or the caller has insufficient permissions to access the Provider Friendly
- * Name. </lt>
- * </p>
- */
- public @Nullable String getPasspointProviderFriendlyName() {
- return mProviderFriendlyName;
- }
-
- /** {@hide} */
- public void setRequestingPackageName(@Nullable String packageName) {
- mRequestingPackageName = packageName;
- }
-
- /**
- * If this network was created in response to an app request (e.g. through Network Suggestion
- * or Network Specifier), return the package name of the app that made the request.
- * Null otherwise.
- * @hide
- */
- @SystemApi
- public @Nullable String getRequestingPackageName() {
- return mRequestingPackageName;
- }
-
-
- /** @hide */
- @UnsupportedAppUsage
- public void setNetworkId(int id) {
- mNetworkId = id;
- }
-
- /**
- * Each configured network has a unique small integer ID, used to identify
- * the network. This method returns the ID for the currently connected network.
- * <p>
- * The networkId may be {@code -1} if there is no currently connected network or if the caller
- * has insufficient permissions to access the network ID.
- * </p>
- *
- * @return the network ID.
- */
- public int getNetworkId() {
- return mNetworkId;
- }
-
- /**
- * Return the detailed state of the supplicant's negotiation with an
- * access point, in the form of a {@link SupplicantState SupplicantState} object.
- * @return the current {@link SupplicantState SupplicantState}
- */
- public SupplicantState getSupplicantState() {
- return mSupplicantState;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setSupplicantState(SupplicantState state) {
- mSupplicantState = state;
- }
-
- /** @hide */
- public void setInetAddress(InetAddress address) {
- mIpAddress = address;
- }
-
- public int getIpAddress() {
- int result = 0;
- if (mIpAddress instanceof Inet4Address) {
- result = Inet4AddressUtils.inet4AddressToIntHTL((Inet4Address) mIpAddress);
- }
- return result;
- }
-
- /**
- * @return {@code true} if this network does not broadcast its SSID, so an
- * SSID-specific probe request must be used for scans.
- */
- public boolean getHiddenSSID() {
- if (mWifiSsid == null) return false;
- return mWifiSsid.isHidden();
- }
-
- /**
- * Map a supplicant state into a fine-grained network connectivity state.
- * @param suppState the supplicant state
- * @return the corresponding {@link DetailedState}
- */
- public static DetailedState getDetailedStateOf(SupplicantState suppState) {
- return stateMap.get(suppState);
- }
-
- /**
- * Set the <code>SupplicantState</code> from the string name
- * of the state.
- * @param stateName the name of the state, as a <code>String</code> returned
- * in an event sent by {@code wpa_supplicant}.
- */
- @UnsupportedAppUsage
- void setSupplicantState(String stateName) {
- mSupplicantState = valueOf(stateName);
- }
-
- static SupplicantState valueOf(String stateName) {
- if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName))
- return SupplicantState.FOUR_WAY_HANDSHAKE;
- else {
- try {
- return SupplicantState.valueOf(stateName.toUpperCase(Locale.ROOT));
- } catch (IllegalArgumentException e) {
- return SupplicantState.INVALID;
- }
- }
- }
-
- /**
- * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the
- * string unmodified. Return null if the input string was null.
- * @hide
- */
- @Nullable
- @SystemApi
- public static String sanitizeSsid(@Nullable String string) {
- return removeDoubleQuotes(string);
- }
-
- /** @hide */
- @UnsupportedAppUsage
- @Nullable
- public static String removeDoubleQuotes(@Nullable String string) {
- if (string == null) return null;
- final int length = string.length();
- if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
- return string.substring(1, length - 1);
- }
- return string;
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- String none = "<none>";
-
- sb.append("SSID: ").append(mWifiSsid == null ? WifiManager.UNKNOWN_SSID : mWifiSsid)
- .append(", BSSID: ").append(mBSSID == null ? none : mBSSID)
- .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress)
- .append(", Supplicant state: ")
- .append(mSupplicantState == null ? none : mSupplicantState)
- .append(", Wi-Fi standard: ").append(mWifiStandard)
- .append(", RSSI: ").append(mRssi)
- .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS)
- .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS)
- .append(", Max Supported Tx Link speed: ")
- .append(mMaxSupportedTxLinkSpeed).append(LINK_SPEED_UNITS)
- .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS)
- .append(", Max Supported Rx Link speed: ")
- .append(mMaxSupportedRxLinkSpeed).append(LINK_SPEED_UNITS)
- .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS)
- .append(", Net ID: ").append(mNetworkId)
- .append(", Metered hint: ").append(mMeteredHint)
- .append(", score: ").append(Integer.toString(score));
- return sb.toString();
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mNetworkId);
- dest.writeInt(mRssi);
- dest.writeInt(mLinkSpeed);
- dest.writeInt(mTxLinkSpeed);
- dest.writeInt(mRxLinkSpeed);
- dest.writeInt(mFrequency);
- if (mIpAddress != null) {
- dest.writeByte((byte)1);
- dest.writeByteArray(mIpAddress.getAddress());
- } else {
- dest.writeByte((byte)0);
- }
- if (mWifiSsid != null) {
- dest.writeInt(1);
- mWifiSsid.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- dest.writeString(mBSSID);
- dest.writeString(mMacAddress);
- dest.writeInt(mMeteredHint ? 1 : 0);
- dest.writeInt(mEphemeral ? 1 : 0);
- dest.writeInt(mTrusted ? 1 : 0);
- dest.writeInt(score);
- dest.writeLong(txSuccess);
- dest.writeDouble(mSuccessfulTxPacketsPerSecond);
- dest.writeLong(txRetries);
- dest.writeDouble(mTxRetriedTxPacketsPerSecond);
- dest.writeLong(txBad);
- dest.writeDouble(mLostTxPacketsPerSecond);
- dest.writeLong(rxSuccess);
- dest.writeDouble(mSuccessfulRxPacketsPerSecond);
- mSupplicantState.writeToParcel(dest, flags);
- dest.writeInt(mOsuAp ? 1 : 0);
- dest.writeString(mRequestingPackageName);
- dest.writeString(mFqdn);
- dest.writeString(mProviderFriendlyName);
- dest.writeInt(mWifiStandard);
- dest.writeInt(mMaxSupportedTxLinkSpeed);
- dest.writeInt(mMaxSupportedRxLinkSpeed);
- dest.writeString(mPasspointUniqueId);
- }
-
- /** Implement the Parcelable interface {@hide} */
- @UnsupportedAppUsage
- public static final @android.annotation.NonNull Creator<WifiInfo> CREATOR =
- new Creator<WifiInfo>() {
- public WifiInfo createFromParcel(Parcel in) {
- WifiInfo info = new WifiInfo();
- info.setNetworkId(in.readInt());
- info.setRssi(in.readInt());
- info.setLinkSpeed(in.readInt());
- info.setTxLinkSpeedMbps(in.readInt());
- info.setRxLinkSpeedMbps(in.readInt());
- info.setFrequency(in.readInt());
- if (in.readByte() == 1) {
- try {
- info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
- } catch (UnknownHostException e) {}
- }
- if (in.readInt() == 1) {
- info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in);
- }
- info.mBSSID = in.readString();
- info.mMacAddress = in.readString();
- info.mMeteredHint = in.readInt() != 0;
- info.mEphemeral = in.readInt() != 0;
- info.mTrusted = in.readInt() != 0;
- info.score = in.readInt();
- info.txSuccess = in.readLong();
- info.mSuccessfulTxPacketsPerSecond = in.readDouble();
- info.txRetries = in.readLong();
- info.mTxRetriedTxPacketsPerSecond = in.readDouble();
- info.txBad = in.readLong();
- info.mLostTxPacketsPerSecond = in.readDouble();
- info.rxSuccess = in.readLong();
- info.mSuccessfulRxPacketsPerSecond = in.readDouble();
- info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in);
- info.mOsuAp = in.readInt() != 0;
- info.mRequestingPackageName = in.readString();
- info.mFqdn = in.readString();
- info.mProviderFriendlyName = in.readString();
- info.mWifiStandard = in.readInt();
- info.mMaxSupportedTxLinkSpeed = in.readInt();
- info.mMaxSupportedRxLinkSpeed = in.readInt();
- info.mPasspointUniqueId = in.readString();
- return info;
- }
-
- public WifiInfo[] newArray(int size) {
- return new WifiInfo[size];
- }
- };
-
- /**
- * Set the Passpoint unique identifier for the current connection
- *
- * @param passpointUniqueId Unique identifier
- * @hide
- */
- public void setPasspointUniqueId(@Nullable String passpointUniqueId) {
- mPasspointUniqueId = passpointUniqueId;
- }
-
- /**
- * Get the Passpoint unique identifier for the current connection
- *
- * @return Passpoint unique identifier
- * @hide
- */
- public @Nullable String getPasspointUniqueId() {
- return mPasspointUniqueId;
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
deleted file mode 100644
index fb6af5b..0000000
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ /dev/null
@@ -1,6235 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
-import static android.Manifest.permission.ACCESS_WIFI_STATE;
-import static android.Manifest.permission.READ_WIFI_CREDENTIAL;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.app.ActivityManager;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.content.pm.ParceledListSlice;
-import android.net.ConnectivityManager;
-import android.net.DhcpInfo;
-import android.net.MacAddress;
-import android.net.Network;
-import android.net.NetworkStack;
-import android.net.wifi.hotspot2.IProvisioningCallback;
-import android.net.wifi.hotspot2.OsuProvider;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.ProvisioningCallback;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.WorkSource;
-import android.os.connectivity.WifiActivityEnergyInfo;
-import android.text.TextUtils;
-import android.util.CloseGuard;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.concurrent.Executor;
-
-/**
- * This class provides the primary API for managing all aspects of Wi-Fi
- * connectivity.
- * <p>
- * On releases before {@link android.os.Build.VERSION_CODES#N}, this object
- * should only be obtained from an {@linkplain Context#getApplicationContext()
- * application context}, and not from any other derived context to avoid memory
- * leaks within the calling process.
- * <p>
- * It deals with several categories of items:
- * </p>
- * <ul>
- * <li>The list of configured networks. The list can be viewed and updated, and
- * attributes of individual entries can be modified.</li>
- * <li>The currently active Wi-Fi network, if any. Connectivity can be
- * established or torn down, and dynamic information about the state of the
- * network can be queried.</li>
- * <li>Results of access point scans, containing enough information to make
- * decisions about what access point to connect to.</li>
- * <li>It defines the names of various Intent actions that are broadcast upon
- * any sort of change in Wi-Fi state.
- * </ul>
- * <p>
- * This is the API to use when performing Wi-Fi specific operations. To perform
- * operations that pertain to network connectivity at an abstract level, use
- * {@link android.net.ConnectivityManager}.
- * </p>
- */
-@SystemService(Context.WIFI_SERVICE)
-public class WifiManager {
-
- private static final String TAG = "WifiManager";
- // Supplicant error codes:
- /**
- * The error code if there was a problem authenticating.
- * @deprecated This is no longer supported.
- */
- @Deprecated
- public static final int ERROR_AUTHENTICATING = 1;
-
- /**
- * The reason code if there is no error during authentication.
- * It could also imply that there no authentication in progress,
- * this reason code also serves as a reset value.
- * @deprecated This is no longer supported.
- * @hide
- */
- @Deprecated
- public static final int ERROR_AUTH_FAILURE_NONE = 0;
-
- /**
- * The reason code if there was a timeout authenticating.
- * @deprecated This is no longer supported.
- * @hide
- */
- @Deprecated
- public static final int ERROR_AUTH_FAILURE_TIMEOUT = 1;
-
- /**
- * The reason code if there was a wrong password while
- * authenticating.
- * @deprecated This is no longer supported.
- * @hide
- */
- @Deprecated
- public static final int ERROR_AUTH_FAILURE_WRONG_PSWD = 2;
-
- /**
- * The reason code if there was EAP failure while
- * authenticating.
- * @deprecated This is no longer supported.
- * @hide
- */
- @Deprecated
- public static final int ERROR_AUTH_FAILURE_EAP_FAILURE = 3;
-
- /** @hide */
- public static final int NETWORK_SUGGESTIONS_MAX_PER_APP_LOW_RAM = 256;
-
- /** @hide */
- public static final int NETWORK_SUGGESTIONS_MAX_PER_APP_HIGH_RAM = 1024;
-
- /**
- * Reason code if all of the network suggestions were successfully added or removed.
- */
- public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0;
-
- /**
- * Reason code if there was an internal error in the platform while processing the addition or
- * removal of suggestions.
- */
- public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1;
-
- /**
- * Reason code if the user has disallowed "android:change_wifi_state" app-ops from the app.
- * @see android.app.AppOpsManager#unsafeCheckOp(String, int, String).
- */
- public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED = 2;
-
- /**
- * Reason code if one or more of the network suggestions added already exists in platform's
- * database.
- * Note: this code will not be returned with Android 11 as in-place modification is allowed,
- * please check {@link #addNetworkSuggestions(List)}.
- * @see WifiNetworkSuggestion#equals(Object)
- */
- public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3;
-
- /**
- * Reason code if the number of network suggestions provided by the app crosses the max
- * threshold set per app.
- * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)} if
- * the total size exceeds the limit.
- * @see #getMaxNumberOfNetworkSuggestionsPerApp()
- */
- public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4;
-
- /**
- * Reason code if one or more of the network suggestions removed does not exist in platform's
- * database.
- * The framework won't remove any suggestions if one or more of suggestions provided
- * by {@link #removeNetworkSuggestions(List)} does not exist in database.
- * @see WifiNetworkSuggestion#equals(Object)
- */
- public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5;
-
- /**
- * Reason code if one or more of the network suggestions added is not allowed.
- * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)}
- * if one or more of them is not allowed.
- * This error may be caused by suggestion is using SIM-based encryption method, but calling app
- * is not carrier privileged.
- */
- public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6;
-
- /**
- * Reason code if one or more of the network suggestions added is invalid. Framework will reject
- * all the suggestions in the list.
- * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)}
- * if one or more of them is invalid.
- * Please use {@link WifiNetworkSuggestion.Builder} to create network suggestions.
- */
- public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID = 7;
-
- /** @hide */
- @IntDef(prefix = { "STATUS_NETWORK_SUGGESTIONS_" }, value = {
- STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
- STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED,
- STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE,
- STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP,
- STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
- STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED,
- STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface NetworkSuggestionsStatusCode {}
-
- /**
- * Reason code if suggested network connection attempt failed with an unknown failure.
- */
- public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0;
- /**
- * Reason code if suggested network connection attempt failed with association failure.
- */
- public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1;
- /**
- * Reason code if suggested network connection attempt failed with an authentication failure.
- */
- public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2;
- /**
- * Reason code if suggested network connection attempt failed with an IP provision failure.
- */
- public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3;
-
- /** @hide */
- @IntDef(prefix = {"STATUS_SUGGESTION_CONNECTION_FAILURE_"},
- value = {STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN,
- STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION,
- STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION,
- STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SuggestionConnectionStatusCode {}
-
- /**
- * Broadcast intent action indicating whether Wi-Fi scanning is currently available.
- * Available extras:
- * - {@link #EXTRA_SCAN_AVAILABLE}
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_WIFI_SCAN_AVAILABILITY_CHANGED =
- "android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED";
-
- /**
- * A boolean extra indicating whether scanning is currently available.
- * Sent in the broadcast {@link #ACTION_WIFI_SCAN_AVAILABILITY_CHANGED}.
- * Its value is true if scanning is currently available, false otherwise.
- */
- public static final String EXTRA_SCAN_AVAILABLE = "android.net.wifi.extra.SCAN_AVAILABLE";
-
- /**
- * Broadcast intent action indicating that the credential of a Wi-Fi network
- * has been changed. One extra provides the ssid of the network. Another
- * extra provides the event type, whether the credential is saved or forgot.
- * @hide
- */
- @SystemApi
- public static final String WIFI_CREDENTIAL_CHANGED_ACTION =
- "android.net.wifi.WIFI_CREDENTIAL_CHANGED";
- /** @hide */
- @SystemApi
- public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
- /** @hide */
- @SystemApi
- public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid";
- /** @hide */
- @SystemApi
- public static final int WIFI_CREDENTIAL_SAVED = 0;
- /** @hide */
- @SystemApi
- public static final int WIFI_CREDENTIAL_FORGOT = 1;
-
- /** @hide */
- @SystemApi
- public static final int PASSPOINT_HOME_NETWORK = 0;
-
- /** @hide */
- @SystemApi
- public static final int PASSPOINT_ROAMING_NETWORK = 1;
-
- /**
- * Broadcast intent action indicating that a Passpoint provider icon has been received.
- *
- * Included extras:
- * {@link #EXTRA_BSSID_LONG}
- * {@link #EXTRA_FILENAME}
- * {@link #EXTRA_ICON}
- *
- * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
- *
- * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
- * components will be launched.
- *
- * @hide
- */
- public static final String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
- /**
- * BSSID of an AP in long representation. The {@link #EXTRA_BSSID} contains BSSID in
- * String representation.
- *
- * Retrieve with {@link android.content.Intent#getLongExtra(String, long)}.
- *
- * @hide
- */
- public static final String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
- /**
- * Icon data.
- *
- * Retrieve with {@link android.content.Intent#getParcelableExtra(String)} and cast into
- * {@link android.graphics.drawable.Icon}.
- *
- * @hide
- */
- public static final String EXTRA_ICON = "android.net.wifi.extra.ICON";
- /**
- * Name of a file.
- *
- * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
- *
- * @hide
- */
- public static final String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
-
- /**
- * Broadcast intent action indicating a Passpoint OSU Providers List element has been received.
- *
- * Included extras:
- * {@link #EXTRA_BSSID_LONG}
- * {@link #EXTRA_ANQP_ELEMENT_DATA}
- *
- * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
- *
- * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
- * components will be launched.
- *
- * @hide
- */
- public static final String ACTION_PASSPOINT_OSU_PROVIDERS_LIST =
- "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
- /**
- * Raw binary data of an ANQP (Access Network Query Protocol) element.
- *
- * Retrieve with {@link android.content.Intent#getByteArrayExtra(String)}.
- *
- * @hide
- */
- public static final String EXTRA_ANQP_ELEMENT_DATA =
- "android.net.wifi.extra.ANQP_ELEMENT_DATA";
-
- /**
- * Broadcast intent action indicating that a Passpoint Deauth Imminent frame has been received.
- *
- * Included extras:
- * {@link #EXTRA_BSSID_LONG}
- * {@link #EXTRA_ESS}
- * {@link #EXTRA_DELAY}
- * {@link #EXTRA_URL}
- *
- * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
- *
- * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
- * components will be launched.
- *
- * @hide
- */
- public static final String ACTION_PASSPOINT_DEAUTH_IMMINENT =
- "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
- /**
- * Flag indicating BSS (Basic Service Set) or ESS (Extended Service Set). This will be set to
- * {@code true} for ESS.
- *
- * Retrieve with {@link android.content.Intent#getBooleanExtra(String, boolean)}.
- *
- * @hide
- */
- public static final String EXTRA_ESS = "android.net.wifi.extra.ESS";
- /**
- * Delay in seconds.
- *
- * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
- *
- * @hide
- */
- public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
-
- /**
- * Broadcast intent action indicating a Passpoint subscription remediation frame has been
- * received.
- *
- * Included extras:
- * {@link #EXTRA_BSSID_LONG}
- * {@link #EXTRA_SUBSCRIPTION_REMEDIATION_METHOD}
- * {@link #EXTRA_URL}
- *
- * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
- *
- * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
- * components will be launched.
- *
- * @hide
- */
- public static final String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION =
- "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
- /**
- * The protocol supported by the subscription remediation server. The possible values are:
- * 0 - OMA DM
- * 1 - SOAP XML SPP
- *
- * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
- *
- * @hide
- */
- public static final String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD =
- "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
-
- /**
- * Activity Action: Receiver should launch Passpoint OSU (Online Sign Up) view.
- * Included extras:
- *
- * {@link #EXTRA_OSU_NETWORK}: {@link Network} instance associated with OSU AP.
- * {@link #EXTRA_URL}: String representation of a server URL used for OSU process.
- *
- * @hide
- */
- @SystemApi
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW =
- "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW";
-
- /**
- * The lookup key for a {@link android.net.Network} associated with a Passpoint OSU server.
- * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast.
- *
- * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
- *
- * @hide
- */
- @SystemApi
- public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK";
-
- /**
- * String representation of an URL for Passpoint OSU.
- * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast.
- *
- * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
- *
- * @hide
- */
- @SystemApi
- public static final String EXTRA_URL = "android.net.wifi.extra.URL";
-
- /**
- * Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
- * enabling, disabling, or unknown. One extra provides this state as an int.
- * Another extra provides the previous state, if available. No network-related
- * permissions are required to subscribe to this broadcast.
- *
- * <p class="note">This broadcast is not delivered to manifest receivers in
- * applications that target API version 26 or later.
- *
- * @see #EXTRA_WIFI_STATE
- * @see #EXTRA_PREVIOUS_WIFI_STATE
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String WIFI_STATE_CHANGED_ACTION =
- "android.net.wifi.WIFI_STATE_CHANGED";
- /**
- * The lookup key for an int that indicates whether Wi-Fi is enabled,
- * disabled, enabling, disabling, or unknown. Retrieve it with
- * {@link android.content.Intent#getIntExtra(String,int)}.
- *
- * @see #WIFI_STATE_DISABLED
- * @see #WIFI_STATE_DISABLING
- * @see #WIFI_STATE_ENABLED
- * @see #WIFI_STATE_ENABLING
- * @see #WIFI_STATE_UNKNOWN
- */
- public static final String EXTRA_WIFI_STATE = "wifi_state";
- /**
- * The previous Wi-Fi state.
- *
- * @see #EXTRA_WIFI_STATE
- */
- public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
-
- /**
- * Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if
- * it finishes successfully.
- *
- * @see #WIFI_STATE_CHANGED_ACTION
- * @see #getWifiState()
- */
- public static final int WIFI_STATE_DISABLING = 0;
- /**
- * Wi-Fi is disabled.
- *
- * @see #WIFI_STATE_CHANGED_ACTION
- * @see #getWifiState()
- */
- public static final int WIFI_STATE_DISABLED = 1;
- /**
- * Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if
- * it finishes successfully.
- *
- * @see #WIFI_STATE_CHANGED_ACTION
- * @see #getWifiState()
- */
- public static final int WIFI_STATE_ENABLING = 2;
- /**
- * Wi-Fi is enabled.
- *
- * @see #WIFI_STATE_CHANGED_ACTION
- * @see #getWifiState()
- */
- public static final int WIFI_STATE_ENABLED = 3;
- /**
- * Wi-Fi is in an unknown state. This state will occur when an error happens while enabling
- * or disabling.
- *
- * @see #WIFI_STATE_CHANGED_ACTION
- * @see #getWifiState()
- */
- public static final int WIFI_STATE_UNKNOWN = 4;
-
- /**
- * Broadcast intent action indicating that Wi-Fi AP has been enabled, disabled,
- * enabling, disabling, or failed.
- *
- * @hide
- */
- @SystemApi
- public static final String WIFI_AP_STATE_CHANGED_ACTION =
- "android.net.wifi.WIFI_AP_STATE_CHANGED";
-
- /**
- * The lookup key for an int that indicates whether Wi-Fi AP is enabled,
- * disabled, enabling, disabling, or failed. Retrieve it with
- * {@link android.content.Intent#getIntExtra(String,int)}.
- *
- * @see #WIFI_AP_STATE_DISABLED
- * @see #WIFI_AP_STATE_DISABLING
- * @see #WIFI_AP_STATE_ENABLED
- * @see #WIFI_AP_STATE_ENABLING
- * @see #WIFI_AP_STATE_FAILED
- *
- * @hide
- */
- @SystemApi
- public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
-
- /**
- * An extra containing the int error code for Soft AP start failure.
- * Can be obtained from the {@link #WIFI_AP_STATE_CHANGED_ACTION} using
- * {@link android.content.Intent#getIntExtra}.
- * This extra will only be attached if {@link #EXTRA_WIFI_AP_STATE} is
- * attached and is equal to {@link #WIFI_AP_STATE_FAILED}.
- *
- * The error code will be one of:
- * {@link #SAP_START_FAILURE_GENERAL},
- * {@link #SAP_START_FAILURE_NO_CHANNEL},
- * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}
- *
- * @hide
- */
- @SystemApi
- public static final String EXTRA_WIFI_AP_FAILURE_REASON =
- "android.net.wifi.extra.WIFI_AP_FAILURE_REASON";
- /**
- * The previous Wi-Fi state.
- *
- * @see #EXTRA_WIFI_AP_STATE
- *
- * @hide
- */
- @SystemApi
- public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
- /**
- * The lookup key for a String extra that stores the interface name used for the Soft AP.
- * This extra is included in the broadcast {@link #WIFI_AP_STATE_CHANGED_ACTION}.
- * Retrieve its value with {@link android.content.Intent#getStringExtra(String)}.
- *
- * @hide
- */
- @SystemApi
- public static final String EXTRA_WIFI_AP_INTERFACE_NAME =
- "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME";
- /**
- * The lookup key for an int extra that stores the intended IP mode for this Soft AP.
- * One of {@link #IFACE_IP_MODE_TETHERED} or {@link #IFACE_IP_MODE_LOCAL_ONLY}.
- * This extra is included in the broadcast {@link #WIFI_AP_STATE_CHANGED_ACTION}.
- * Retrieve its value with {@link android.content.Intent#getIntExtra(String, int)}.
- *
- * @hide
- */
- @SystemApi
- public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE";
-
- /** @hide */
- @IntDef(flag = false, prefix = { "WIFI_AP_STATE_" }, value = {
- WIFI_AP_STATE_DISABLING,
- WIFI_AP_STATE_DISABLED,
- WIFI_AP_STATE_ENABLING,
- WIFI_AP_STATE_ENABLED,
- WIFI_AP_STATE_FAILED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface WifiApState {}
-
- /**
- * Wi-Fi AP is currently being disabled. The state will change to
- * {@link #WIFI_AP_STATE_DISABLED} if it finishes successfully.
- *
- * @see #WIFI_AP_STATE_CHANGED_ACTION
- * @see #getWifiApState()
- *
- * @hide
- */
- @SystemApi
- public static final int WIFI_AP_STATE_DISABLING = 10;
- /**
- * Wi-Fi AP is disabled.
- *
- * @see #WIFI_AP_STATE_CHANGED_ACTION
- * @see #getWifiState()
- *
- * @hide
- */
- @SystemApi
- public static final int WIFI_AP_STATE_DISABLED = 11;
- /**
- * Wi-Fi AP is currently being enabled. The state will change to
- * {@link #WIFI_AP_STATE_ENABLED} if it finishes successfully.
- *
- * @see #WIFI_AP_STATE_CHANGED_ACTION
- * @see #getWifiApState()
- *
- * @hide
- */
- @SystemApi
- public static final int WIFI_AP_STATE_ENABLING = 12;
- /**
- * Wi-Fi AP is enabled.
- *
- * @see #WIFI_AP_STATE_CHANGED_ACTION
- * @see #getWifiApState()
- *
- * @hide
- */
- @SystemApi
- public static final int WIFI_AP_STATE_ENABLED = 13;
- /**
- * Wi-Fi AP is in a failed state. This state will occur when an error occurs during
- * enabling or disabling
- *
- * @see #WIFI_AP_STATE_CHANGED_ACTION
- * @see #getWifiApState()
- *
- * @hide
- */
- @SystemApi
- public static final int WIFI_AP_STATE_FAILED = 14;
-
- /** @hide */
- @IntDef(flag = false, prefix = { "SAP_START_FAILURE_" }, value = {
- SAP_START_FAILURE_GENERAL,
- SAP_START_FAILURE_NO_CHANNEL,
- SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SapStartFailure {}
-
- /**
- * All other reasons for AP start failure besides {@link #SAP_START_FAILURE_NO_CHANNEL} and
- * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
- *
- * @hide
- */
- @SystemApi
- public static final int SAP_START_FAILURE_GENERAL= 0;
-
- /**
- * If Wi-Fi AP start failed, this reason code means that no legal channel exists on user
- * selected band due to regulatory constraints.
- *
- * @hide
- */
- @SystemApi
- public static final int SAP_START_FAILURE_NO_CHANNEL = 1;
-
- /**
- * If Wi-Fi AP start failed, this reason code means that the specified configuration
- * is not supported by the current HAL version.
- *
- * @hide
- */
- @SystemApi
- public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2;
-
-
- /** @hide */
- @IntDef(flag = false, prefix = { "SAP_CLIENT_BLOCKED_REASON_" }, value = {
- SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER,
- SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SapClientBlockedReason {}
-
- /**
- * If Soft Ap client is blocked, this reason code means that client doesn't exist in the
- * specified configuration {@link SoftApConfiguration.Builder#setBlockedClientList(List)}
- * and {@link SoftApConfiguration.Builder#setAllowedClientList(List)}
- * and the {@link SoftApConfiguration.Builder#setClientControlByUserEnabled(boolean)}
- * is configured as well.
- * @hide
- */
- @SystemApi
- public static final int SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER = 0;
-
- /**
- * If Soft Ap client is blocked, this reason code means that no more clients can be
- * associated to this AP since it reached maximum capacity. The maximum capacity is
- * the minimum of {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} and
- * {@link SoftApCapability#getMaxSupportedClients} which get from
- * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)}.
- *
- * @hide
- */
- @SystemApi
- public static final int SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS = 1;
-
- /**
- * Client disconnected for unspecified reason. This could for example be because the AP is being
- * shut down.
- * @hide
- */
- public static final int SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED = 2;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"IFACE_IP_MODE_"}, value = {
- IFACE_IP_MODE_UNSPECIFIED,
- IFACE_IP_MODE_CONFIGURATION_ERROR,
- IFACE_IP_MODE_TETHERED,
- IFACE_IP_MODE_LOCAL_ONLY})
- public @interface IfaceIpMode {}
-
- /**
- * Interface IP mode unspecified.
- *
- * @see #updateInterfaceIpState(String, int)
- *
- * @hide
- */
- @SystemApi
- public static final int IFACE_IP_MODE_UNSPECIFIED = -1;
-
- /**
- * Interface IP mode for configuration error.
- *
- * @see #updateInterfaceIpState(String, int)
- *
- * @hide
- */
- @SystemApi
- public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0;
-
- /**
- * Interface IP mode for tethering.
- *
- * @see #updateInterfaceIpState(String, int)
- *
- * @hide
- */
- @SystemApi
- public static final int IFACE_IP_MODE_TETHERED = 1;
-
- /**
- * Interface IP mode for Local Only Hotspot.
- *
- * @see #updateInterfaceIpState(String, int)
- *
- * @hide
- */
- @SystemApi
- public static final int IFACE_IP_MODE_LOCAL_ONLY = 2;
-
- /**
- * Broadcast intent action indicating that the wifi network settings
- * had been reset.
- *
- * Note: This intent is sent as a directed broadcast to each manifest registered receiver.
- * Intent will not be received by dynamically registered receivers.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING)
- public static final String ACTION_NETWORK_SETTINGS_RESET =
- "android.net.wifi.action.NETWORK_SETTINGS_RESET";
-
- /**
- * Broadcast intent action indicating that a connection to the supplicant has
- * been established (and it is now possible
- * to perform Wi-Fi operations) or the connection to the supplicant has been
- * lost. One extra provides the connection state as a boolean, where {@code true}
- * means CONNECTED.
- * @deprecated This is no longer supported.
- * @see #EXTRA_SUPPLICANT_CONNECTED
- */
- @Deprecated
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION =
- "android.net.wifi.supplicant.CONNECTION_CHANGE";
- /**
- * The lookup key for a boolean that indicates whether a connection to
- * the supplicant daemon has been gained or lost. {@code true} means
- * a connection now exists.
- * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- * @deprecated This is no longer supported.
- */
- @Deprecated
- public static final String EXTRA_SUPPLICANT_CONNECTED = "connected";
- /**
- * Broadcast intent action indicating that the state of Wi-Fi connectivity
- * has changed. An extra provides the new state
- * in the form of a {@link android.net.NetworkInfo} object. No network-related
- * permissions are required to subscribe to this broadcast.
- *
- * <p class="note">This broadcast is not delivered to manifest receivers in
- * applications that target API version 26 or later.
- * @see #EXTRA_NETWORK_INFO
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
- /**
- * The lookup key for a {@link android.net.NetworkInfo} object associated with the
- * Wi-Fi network. Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_NETWORK_INFO = "networkInfo";
- /**
- * The lookup key for a String giving the BSSID of the access point to which
- * we are connected. No longer used.
- */
- @Deprecated
- public static final String EXTRA_BSSID = "bssid";
- /**
- * The lookup key for a {@link android.net.wifi.WifiInfo} object giving the
- * information about the access point to which we are connected.
- * No longer used.
- */
- @Deprecated
- public static final String EXTRA_WIFI_INFO = "wifiInfo";
- /**
- * Broadcast intent action indicating that the state of establishing a connection to
- * an access point has changed.One extra provides the new
- * {@link SupplicantState}. Note that the supplicant state is Wi-Fi specific, and
- * is not generally the most useful thing to look at if you are just interested in
- * the overall state of connectivity.
- * @see #EXTRA_NEW_STATE
- * @see #EXTRA_SUPPLICANT_ERROR
- * @deprecated This is no longer supported.
- */
- @Deprecated
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SUPPLICANT_STATE_CHANGED_ACTION =
- "android.net.wifi.supplicant.STATE_CHANGE";
- /**
- * The lookup key for a {@link SupplicantState} describing the new state
- * Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- * @deprecated This is no longer supported.
- */
- @Deprecated
- public static final String EXTRA_NEW_STATE = "newState";
-
- /**
- * The lookup key for a {@link SupplicantState} describing the supplicant
- * error code if any
- * Retrieve with
- * {@link android.content.Intent#getIntExtra(String, int)}.
- * @see #ERROR_AUTHENTICATING
- * @deprecated This is no longer supported.
- */
- @Deprecated
- public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";
-
- /**
- * The lookup key for a {@link SupplicantState} describing the supplicant
- * error reason if any
- * Retrieve with
- * {@link android.content.Intent#getIntExtra(String, int)}.
- * @see #ERROR_AUTH_FAILURE_#REASON_CODE
- * @deprecated This is no longer supported.
- * @hide
- */
- @Deprecated
- public static final String EXTRA_SUPPLICANT_ERROR_REASON = "supplicantErrorReason";
-
- /**
- * Broadcast intent action indicating that the configured networks changed.
- * This can be as a result of adding/updating/deleting a network.
- * <br />
- * {@link #EXTRA_CHANGE_REASON} contains whether the configuration was added/changed/removed.
- * {@link #EXTRA_WIFI_CONFIGURATION} is never set starting in Android 11.
- * {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is set for backwards compatibility reasons, but
- * its value is always true, even if only a single network changed.
- * <br />
- * The {@link android.Manifest.permission#ACCESS_WIFI_STATE ACCESS_WIFI_STATE} permission is
- * required to receive this broadcast.
- *
- * @hide
- */
- @SystemApi
- public static final String CONFIGURED_NETWORKS_CHANGED_ACTION =
- "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
- /**
- * The lookup key for a {@link android.net.wifi.WifiConfiguration} object representing
- * the changed Wi-Fi configuration when the {@link #CONFIGURED_NETWORKS_CHANGED_ACTION}
- * broadcast is sent.
- * Note: this extra is never set starting in Android 11.
- * @hide
- */
- @SystemApi
- public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
- /**
- * Multiple network configurations have changed.
- * @see #CONFIGURED_NETWORKS_CHANGED_ACTION
- * Note: this extra is always true starting in Android 11.
- * @hide
- */
- @SystemApi
- public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
- /**
- * The lookup key for an integer indicating the reason a Wi-Fi network configuration
- * has changed. One of {@link #CHANGE_REASON_ADDED}, {@link #CHANGE_REASON_REMOVED},
- * {@link #CHANGE_REASON_CONFIG_CHANGE}.
- *
- * @see #CONFIGURED_NETWORKS_CHANGED_ACTION
- * @hide
- */
- @SystemApi
- public static final String EXTRA_CHANGE_REASON = "changeReason";
- /**
- * The configuration is new and was added.
- * @hide
- */
- @SystemApi
- public static final int CHANGE_REASON_ADDED = 0;
- /**
- * The configuration was removed and is no longer present in the system's list of
- * configured networks.
- * @hide
- */
- @SystemApi
- public static final int CHANGE_REASON_REMOVED = 1;
- /**
- * The configuration has changed as a result of explicit action or because the system
- * took an automated action such as disabling a malfunctioning configuration.
- * @hide
- */
- @SystemApi
- public static final int CHANGE_REASON_CONFIG_CHANGE = 2;
- /**
- * An access point scan has completed, and results are available.
- * Call {@link #getScanResults()} to obtain the results.
- * The broadcast intent may contain an extra field with the key {@link #EXTRA_RESULTS_UPDATED}
- * and a {@code boolean} value indicating if the scan was successful.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
-
- /**
- * Lookup key for a {@code boolean} extra in intent {@link #SCAN_RESULTS_AVAILABLE_ACTION}
- * representing if the scan was successful or not.
- * Scans may fail for multiple reasons, these may include:
- * <ol>
- * <li>An app requested too many scans in a certain period of time.
- * This may lead to additional scan request rejections via "scan throttling" for both
- * foreground and background apps.
- * Note: Apps holding android.Manifest.permission.NETWORK_SETTINGS permission are
- * exempted from scan throttling.
- * </li>
- * <li>The device is idle and scanning is disabled.</li>
- * <li>Wifi hardware reported a scan failure.</li>
- * </ol>
- * @return true scan was successful, results are updated
- * @return false scan was not successful, results haven't been updated since previous scan
- */
- public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated";
-
- /**
- * A batch of access point scans has been completed and the results areavailable.
- * Call {@link #getBatchedScanResults()} to obtain the results.
- * @deprecated This API is nolonger supported.
- * Use {@link android.net.wifi.WifiScanner} API
- * @hide
- */
- @Deprecated
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String BATCHED_SCAN_RESULTS_AVAILABLE_ACTION =
- "android.net.wifi.BATCHED_RESULTS";
-
- /**
- * The RSSI (signal strength) has changed.
- *
- * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
- * @see #EXTRA_NEW_RSSI
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
- /**
- * The lookup key for an {@code int} giving the new RSSI in dBm.
- */
- public static final String EXTRA_NEW_RSSI = "newRssi";
-
- /**
- * @see #ACTION_LINK_CONFIGURATION_CHANGED
- * @hide
- */
- @UnsupportedAppUsage
- public static final String LINK_CONFIGURATION_CHANGED_ACTION =
- "android.net.wifi.LINK_CONFIGURATION_CHANGED";
-
- /**
- * Broadcast intent action indicating that the link configuration changed on wifi.
- * <br />Included Extras:
- * <br />{@link #EXTRA_LINK_PROPERTIES}: {@link android.net.LinkProperties} object associated
- * with the Wi-Fi network.
- * <br /> No permissions are required to listen to this broadcast.
- * @hide
- */
- @SystemApi
- public static final String ACTION_LINK_CONFIGURATION_CHANGED =
- // should be android.net.wifi.action.LINK_CONFIGURATION_CHANGED, but due to
- // @UnsupportedAppUsage leaving it as android.net.wifi.LINK_CONFIGURATION_CHANGED.
- LINK_CONFIGURATION_CHANGED_ACTION;
-
- /**
- * The lookup key for a {@link android.net.LinkProperties} object associated with the
- * Wi-Fi network.
- * Included in the {@link #ACTION_LINK_CONFIGURATION_CHANGED} broadcast.
- *
- * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
- * @hide
- */
- @SystemApi
- public static final String EXTRA_LINK_PROPERTIES = "android.net.wifi.extra.LINK_PROPERTIES";
-
- /**
- * The lookup key for a {@link android.net.NetworkCapabilities} object associated with the
- * Wi-Fi network. Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- * @hide
- */
- public static final String EXTRA_NETWORK_CAPABILITIES = "networkCapabilities";
-
- /**
- * The network IDs of the configured networks could have changed.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
-
- /**
- * Activity Action: Show a system activity that allows the user to enable
- * scans to be available even with Wi-Fi turned off.
- *
- * <p>Notification of the result of this activity is posted using the
- * {@link android.app.Activity#onActivityResult} callback. The
- * <code>resultCode</code>
- * will be {@link android.app.Activity#RESULT_OK} if scan always mode has
- * been turned on or {@link android.app.Activity#RESULT_CANCELED} if the user
- * has rejected the request or an error has occurred.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE =
- "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
-
- /**
- * Activity Action: Pick a Wi-Fi network to connect to.
- * <p>Input: Nothing.
- * <p>Output: Nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
-
- /**
- * Activity Action: Receiver should show UI to get user approval to enable WiFi.
- * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with
- * the name of the app requesting the action.
- * <p>Output: Nothing.
- * <p>No permissions are required to send this action.
- * @hide
- */
- @SystemApi
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE";
-
- /**
- * Activity Action: Receiver should show UI to get user approval to disable WiFi.
- * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with
- * the name of the app requesting the action.
- * <p>Output: Nothing.
- * <p>No permissions are required to send this action.
- * @hide
- */
- @SystemApi
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE";
-
- /**
- * Directed broadcast intent action indicating that the device has connected to one of the
- * network suggestions provided by the app. This will be sent post connection to a network
- * which was created with {@link WifiNetworkSuggestion.Builder#setIsAppInteractionRequired(
- * boolean)}
- * flag set.
- * <p>
- * Note: The broadcast is sent to the app only if it holds
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission.
- *
- * @see #EXTRA_NETWORK_SUGGESTION
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION =
- "android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION";
- /**
- * Sent as as a part of {@link #ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} that holds
- * an instance of {@link WifiNetworkSuggestion} corresponding to the connected network.
- */
- public static final String EXTRA_NETWORK_SUGGESTION =
- "android.net.wifi.extra.NETWORK_SUGGESTION";
-
- /**
- * Internally used Wi-Fi lock mode representing the case were no locks are held.
- * @hide
- */
- public static final int WIFI_MODE_NO_LOCKS_HELD = 0;
-
- /**
- * In this Wi-Fi lock mode, Wi-Fi will be kept active,
- * and will behave normally, i.e., it will attempt to automatically
- * establish a connection to a remembered access point that is
- * within range, and will do periodic scans if there are remembered
- * access points but none are in range.
- *
- * @deprecated This API is non-functional and will have no impact.
- */
- @Deprecated
- public static final int WIFI_MODE_FULL = 1;
-
- /**
- * In this Wi-Fi lock mode, Wi-Fi will be kept active,
- * but the only operation that will be supported is initiation of
- * scans, and the subsequent reporting of scan results. No attempts
- * will be made to automatically connect to remembered access points,
- * nor will periodic scans be automatically performed looking for
- * remembered access points. Scans must be explicitly requested by
- * an application in this mode.
- *
- * @deprecated This API is non-functional and will have no impact.
- */
- @Deprecated
- public static final int WIFI_MODE_SCAN_ONLY = 2;
-
- /**
- * In this Wi-Fi lock mode, Wi-Fi will not go to power save.
- * This results in operating with low packet latency.
- * The lock is only active when the device is connected to an access point.
- * The lock is active even when the device screen is off or the acquiring application is
- * running in the background.
- * This mode will consume more power and hence should be used only
- * when there is a need for this tradeoff.
- * <p>
- * An example use case is when a voice connection needs to be
- * kept active even after the device screen goes off.
- * Holding a {@link #WIFI_MODE_FULL_HIGH_PERF} lock for the
- * duration of the voice call may improve the call quality.
- * <p>
- * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_HIGH_PERF}
- * lock will have no impact.
- */
- public static final int WIFI_MODE_FULL_HIGH_PERF = 3;
-
- /**
- * In this Wi-Fi lock mode, Wi-Fi will operate with a priority to achieve low latency.
- * {@link #WIFI_MODE_FULL_LOW_LATENCY} lock has the following limitations:
- * <ol>
- * <li>The lock is only active when the device is connected to an access point.</li>
- * <li>The lock is only active when the screen is on.</li>
- * <li>The lock is only active when the acquiring app is running in the foreground.</li>
- * </ol>
- * Low latency mode optimizes for reduced packet latency,
- * and as a result other performance measures may suffer when there are trade-offs to make:
- * <ol>
- * <li>Battery life may be reduced.</li>
- * <li>Throughput may be reduced.</li>
- * <li>Frequency of Wi-Fi scanning may be reduced. This may result in: </li>
- * <ul>
- * <li>The device may not roam or switch to the AP with highest signal quality.</li>
- * <li>Location accuracy may be reduced.</li>
- * </ul>
- * </ol>
- * <p>
- * Example use cases are real time gaming or virtual reality applications where
- * low latency is a key factor for user experience.
- * <p>
- * Note: For an app which acquires both {@link #WIFI_MODE_FULL_LOW_LATENCY} and
- * {@link #WIFI_MODE_FULL_HIGH_PERF} locks, {@link #WIFI_MODE_FULL_LOW_LATENCY}
- * lock will be effective when app is running in foreground and screen is on,
- * while the {@link #WIFI_MODE_FULL_HIGH_PERF} lock will take effect otherwise.
- */
- public static final int WIFI_MODE_FULL_LOW_LATENCY = 4;
-
-
- /** Anything worse than or equal to this will show 0 bars. */
- @UnsupportedAppUsage
- private static final int MIN_RSSI = -100;
-
- /** Anything better than or equal to this will show the max bars. */
- @UnsupportedAppUsage
- private static final int MAX_RSSI = -55;
-
- /**
- * Number of RSSI levels used in the framework to initiate {@link #RSSI_CHANGED_ACTION}
- * broadcast, where each level corresponds to a range of RSSI values.
- * The {@link #RSSI_CHANGED_ACTION} broadcast will only fire if the RSSI
- * change is significant enough to change the RSSI signal level.
- * @hide
- */
- @UnsupportedAppUsage
- public static final int RSSI_LEVELS = 5;
-
- //TODO (b/146346676): This needs to be removed, not used in the code.
- /**
- * Auto settings in the driver. The driver could choose to operate on both
- * 2.4 GHz and 5 GHz or make a dynamic decision on selecting the band.
- * @hide
- */
- @UnsupportedAppUsage
- public static final int WIFI_FREQUENCY_BAND_AUTO = 0;
-
- /**
- * Operation on 5 GHz alone
- * @hide
- */
- @UnsupportedAppUsage
- public static final int WIFI_FREQUENCY_BAND_5GHZ = 1;
-
- /**
- * Operation on 2.4 GHz alone
- * @hide
- */
- @UnsupportedAppUsage
- public static final int WIFI_FREQUENCY_BAND_2GHZ = 2;
-
- /** @hide */
- public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false;
-
- /**
- * Maximum number of active locks we allow.
- * This limit was added to prevent apps from creating a ridiculous number
- * of locks and crashing the system by overflowing the global ref table.
- */
- private static final int MAX_ACTIVE_LOCKS = 50;
-
- /** Indicates an invalid SSID. */
- public static final String UNKNOWN_SSID = "<unknown ssid>";
-
- /** @hide */
- public static final MacAddress ALL_ZEROS_MAC_ADDRESS =
- MacAddress.fromString("00:00:00:00:00:00");
-
- /* Number of currently active WifiLocks and MulticastLocks */
- @UnsupportedAppUsage
- private int mActiveLockCount;
-
- private Context mContext;
- @UnsupportedAppUsage
- IWifiManager mService;
- private final int mTargetSdkVersion;
-
- private Looper mLooper;
- private boolean mVerboseLoggingEnabled = false;
-
- private final Object mLock = new Object(); // lock guarding access to the following vars
- @GuardedBy("mLock")
- private LocalOnlyHotspotCallbackProxy mLOHSCallbackProxy;
- @GuardedBy("mLock")
- private LocalOnlyHotspotObserverProxy mLOHSObserverProxy;
-
- /**
- * Create a new WifiManager instance.
- * Applications will almost always want to use
- * {@link android.content.Context#getSystemService Context.getSystemService} to retrieve
- * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}.
- *
- * @param context the application context
- * @param service the Binder interface
- * @param looper the Looper used to deliver callbacks
- * @hide - hide this because it takes in a parameter of type IWifiManager, which
- * is a system private class.
- */
- public WifiManager(@NonNull Context context, @NonNull IWifiManager service,
- @NonNull Looper looper) {
- mContext = context;
- mService = service;
- mLooper = looper;
- mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
- updateVerboseLoggingEnabledFromService();
- }
-
- /**
- * Return a list of all the networks configured for the current foreground
- * user.
- *
- * Not all fields of WifiConfiguration are returned. Only the following
- * fields are filled in:
- * <ul>
- * <li>networkId</li>
- * <li>SSID</li>
- * <li>BSSID</li>
- * <li>priority</li>
- * <li>allowedProtocols</li>
- * <li>allowedKeyManagement</li>
- * <li>allowedAuthAlgorithms</li>
- * <li>allowedPairwiseCiphers</li>
- * <li>allowedGroupCiphers</li>
- * <li>status</li>
- * </ul>
- * @return a list of network configurations in the form of a list
- * of {@link WifiConfiguration} objects.
- *
- * @deprecated
- * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
- * mechanism to trigger connection to a Wi-Fi network.
- * b) See {@link #addNetworkSuggestions(List)},
- * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
- * when auto-connecting to wifi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return an
- * empty list.
- * <p>
- * Deprecation Exemptions:
- * <ul>
- * <li>Device Owner (DO), Profile Owner (PO) and system apps will have access to the full list.
- * <li>Callers with Carrier privilege will receive a restricted list only containing
- * configurations which they created.
- * </ul>
- */
- @Deprecated
- @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
- public List<WifiConfiguration> getConfiguredNetworks() {
- try {
- ParceledListSlice<WifiConfiguration> parceledList =
- mService.getConfiguredNetworks(mContext.getOpPackageName(),
- mContext.getAttributionTag());
- if (parceledList == null) {
- return Collections.emptyList();
- }
- return parceledList.getList();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- @SystemApi
- @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE, READ_WIFI_CREDENTIAL})
- public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
- try {
- ParceledListSlice<WifiConfiguration> parceledList =
- mService.getPrivilegedConfiguredNetworks(mContext.getOpPackageName(),
- mContext.getAttributionTag());
- if (parceledList == null) {
- return Collections.emptyList();
- }
- return parceledList.getList();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns a list of all matching WifiConfigurations for a given list of ScanResult.
- *
- * An empty list will be returned when no configurations are installed or if no configurations
- * match the ScanResult.
- *
- * @param scanResults a list of scanResult that represents the BSSID
- * @return List that consists of {@link WifiConfiguration} and corresponding scanResults per
- * network type({@link #PASSPOINT_HOME_NETWORK} and {@link #PASSPOINT_ROAMING_NETWORK}).
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD
- })
- @NonNull
- public List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> getAllMatchingWifiConfigs(
- @NonNull List<ScanResult> scanResults) {
- List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> configs = new ArrayList<>();
- try {
- Map<String, Map<Integer, List<ScanResult>>> results =
- mService.getAllMatchingPasspointProfilesForScanResults(scanResults);
- if (results.isEmpty()) {
- return configs;
- }
- List<WifiConfiguration> wifiConfigurations =
- mService.getWifiConfigsForPasspointProfiles(
- new ArrayList<>(results.keySet()));
- for (WifiConfiguration configuration : wifiConfigurations) {
- Map<Integer, List<ScanResult>> scanResultsPerNetworkType =
- results.get(configuration.getKey());
- if (scanResultsPerNetworkType != null) {
- configs.add(Pair.create(configuration, scanResultsPerNetworkType));
- }
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- return configs;
- }
-
- /**
- * Retrieve a list of {@link WifiConfiguration} for available {@link WifiNetworkSuggestion}
- * matching the given list of {@link ScanResult}.
- *
- * An available {@link WifiNetworkSuggestion} must satisfy:
- * <ul>
- * <li> Matching one of the {@link ScanResult} from the given list.
- * <li> and {@link WifiNetworkSuggestion.Builder#setIsUserAllowedToManuallyConnect(boolean)} set
- * to true.
- * </ul>
- *
- * @param scanResults a list of scanResult.
- * @return a list of @link WifiConfiguration} for available {@link WifiNetworkSuggestion}
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD
- })
- @NonNull
- public List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
- @NonNull List<ScanResult> scanResults) {
- try {
- return mService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(scanResults);
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Returns a list of unique Hotspot 2.0 OSU (Online Sign-Up) providers associated with a given
- * list of ScanResult.
- *
- * An empty list will be returned if no match is found.
- *
- * @param scanResults a list of ScanResult
- * @return Map that consists {@link OsuProvider} and a list of matching {@link ScanResult}
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD
- })
- @NonNull
- public Map<OsuProvider, List<ScanResult>> getMatchingOsuProviders(
- @Nullable List<ScanResult> scanResults) {
- if (scanResults == null) {
- return new HashMap<>();
- }
- try {
- return mService.getMatchingOsuProviders(scanResults);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns the matching Passpoint R2 configurations for given OSU (Online Sign-Up) providers.
- *
- * Given a list of OSU providers, this only returns OSU providers that already have Passpoint R2
- * configurations in the device.
- * An empty map will be returned when there is no matching Passpoint R2 configuration for the
- * given OsuProviders.
- *
- * @param osuProviders a set of {@link OsuProvider}
- * @return Map that consists of {@link OsuProvider} and matching {@link PasspointConfiguration}.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD
- })
- @NonNull
- public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(
- @NonNull Set<OsuProvider> osuProviders) {
- try {
- return mService.getMatchingPasspointConfigsForOsuProviders(
- new ArrayList<>(osuProviders));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Add a new network description to the set of configured networks.
- * The {@code networkId} field of the supplied configuration object
- * is ignored.
- * <p/>
- * The new network will be marked DISABLED by default. To enable it,
- * called {@link #enableNetwork}.
- *
- * @param config the set of variables that describe the configuration,
- * contained in a {@link WifiConfiguration} object.
- * If the {@link WifiConfiguration} has an Http Proxy set
- * the calling app must be System, or be provisioned as the Profile or Device Owner.
- * @return the ID of the newly created network description. This is used in
- * other operations to specified the network to be acted upon.
- * Returns {@code -1} on failure.
- *
- * @deprecated
- * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
- * mechanism to trigger connection to a Wi-Fi network.
- * b) See {@link #addNetworkSuggestions(List)},
- * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
- * when auto-connecting to wifi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
- * {@code -1}.
- * <p>
- * Deprecation Exemptions:
- * <ul>
- * <li>Device Owner (DO), Profile Owner (PO) and system apps.
- * </ul>
- */
- @Deprecated
- public int addNetwork(WifiConfiguration config) {
- if (config == null) {
- return -1;
- }
- config.networkId = -1;
- return addOrUpdateNetwork(config);
- }
-
- /**
- * Update the network description of an existing configured network.
- *
- * @param config the set of variables that describe the configuration,
- * contained in a {@link WifiConfiguration} object. It may
- * be sparse, so that only the items that are being changed
- * are non-<code>null</code>. The {@code networkId} field
- * must be set to the ID of the existing network being updated.
- * If the {@link WifiConfiguration} has an Http Proxy set
- * the calling app must be System, or be provisioned as the Profile or Device Owner.
- * @return Returns the {@code networkId} of the supplied
- * {@code WifiConfiguration} on success.
- * <br/>
- * Returns {@code -1} on failure, including when the {@code networkId}
- * field of the {@code WifiConfiguration} does not refer to an
- * existing network.
- *
- * @deprecated
- * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
- * mechanism to trigger connection to a Wi-Fi network.
- * b) See {@link #addNetworkSuggestions(List)},
- * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
- * when auto-connecting to wifi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
- * {@code -1}.
- * <p>
- * Deprecation Exemptions:
- * <ul>
- * <li>Device Owner (DO), Profile Owner (PO) and system apps.
- * </ul>
- */
- @Deprecated
- public int updateNetwork(WifiConfiguration config) {
- if (config == null || config.networkId < 0) {
- return -1;
- }
- return addOrUpdateNetwork(config);
- }
-
- /**
- * Internal method for doing the RPC that creates a new network description
- * or updates an existing one.
- *
- * @param config The possibly sparse object containing the variables that
- * are to set or updated in the network description.
- * @return the ID of the network on success, {@code -1} on failure.
- */
- private int addOrUpdateNetwork(WifiConfiguration config) {
- try {
- return mService.addOrUpdateNetwork(config, mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Interface for indicating user selection from the list of networks presented in the
- * {@link NetworkRequestMatchCallback#onMatch(List)}.
- *
- * The platform will implement this callback and pass it along with the
- * {@link NetworkRequestMatchCallback#onUserSelectionCallbackRegistration(
- * NetworkRequestUserSelectionCallback)}. The UI component handling
- * {@link NetworkRequestMatchCallback} will invoke {@link #select(WifiConfiguration)} or
- * {@link #reject()} to return the user's selection back to the platform via this callback.
- * @hide
- */
- @SystemApi
- public interface NetworkRequestUserSelectionCallback {
- /**
- * User selected this network to connect to.
- * @param wifiConfiguration WifiConfiguration object corresponding to the network
- * user selected.
- */
- @SuppressLint("CallbackMethodName")
- default void select(@NonNull WifiConfiguration wifiConfiguration) {}
-
- /**
- * User rejected the app's request.
- */
- @SuppressLint("CallbackMethodName")
- default void reject() {}
- }
-
- /**
- * Interface for network request callback. Should be implemented by applications and passed when
- * calling {@link #registerNetworkRequestMatchCallback(Executor,
- * WifiManager.NetworkRequestMatchCallback)}.
- *
- * This is meant to be implemented by a UI component to present the user with a list of networks
- * matching the app's request. The user is allowed to pick one of these networks to connect to
- * or reject the request by the app.
- * @hide
- */
- @SystemApi
- public interface NetworkRequestMatchCallback {
- /**
- * Invoked to register a callback to be invoked to convey user selection. The callback
- * object passed in this method is to be invoked by the UI component after the service sends
- * a list of matching scan networks using {@link #onMatch(List)} and user picks a network
- * from that list.
- *
- * @param userSelectionCallback Callback object to send back the user selection.
- */
- default void onUserSelectionCallbackRegistration(
- @NonNull NetworkRequestUserSelectionCallback userSelectionCallback) {}
-
- /**
- * Invoked when the active network request is aborted, either because
- * <li> The app released the request, OR</li>
- * <li> Request was overridden by a new request</li>
- * This signals the end of processing for the current request and should stop the UI
- * component. No subsequent calls from the UI component will be handled by the platform.
- */
- default void onAbort() {}
-
- /**
- * Invoked when a network request initiated by an app matches some networks in scan results.
- * This may be invoked multiple times for a single network request as the platform finds new
- * matching networks in scan results.
- *
- * @param scanResults List of {@link ScanResult} objects corresponding to the networks
- * matching the request.
- */
- default void onMatch(@NonNull List<ScanResult> scanResults) {}
-
- /**
- * Invoked on a successful connection with the network that the user selected
- * via {@link NetworkRequestUserSelectionCallback}.
- *
- * @param wifiConfiguration WifiConfiguration object corresponding to the network that the
- * user selected.
- */
- default void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration) {}
-
- /**
- * Invoked on failure to establish connection with the network that the user selected
- * via {@link NetworkRequestUserSelectionCallback}.
- *
- * @param wifiConfiguration WifiConfiguration object corresponding to the network
- * user selected.
- */
- default void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration) {}
- }
-
- /**
- * Callback proxy for NetworkRequestUserSelectionCallback objects.
- * @hide
- */
- private class NetworkRequestUserSelectionCallbackProxy implements
- NetworkRequestUserSelectionCallback {
- private final INetworkRequestUserSelectionCallback mCallback;
-
- NetworkRequestUserSelectionCallbackProxy(
- INetworkRequestUserSelectionCallback callback) {
- mCallback = callback;
- }
-
- @Override
- public void select(@NonNull WifiConfiguration wifiConfiguration) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: select "
- + "wificonfiguration: " + wifiConfiguration);
- }
- try {
- mCallback.select(wifiConfiguration);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to invoke onSelected", e);
- throw e.rethrowFromSystemServer();
- }
- }
-
- @Override
- public void reject() {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: reject");
- }
- try {
- mCallback.reject();
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to invoke onRejected", e);
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
- * Callback proxy for NetworkRequestMatchCallback objects.
- * @hide
- */
- private class NetworkRequestMatchCallbackProxy extends INetworkRequestMatchCallback.Stub {
- private final Executor mExecutor;
- private final NetworkRequestMatchCallback mCallback;
-
- NetworkRequestMatchCallbackProxy(Executor executor, NetworkRequestMatchCallback callback) {
- mExecutor = executor;
- mCallback = callback;
- }
-
- @Override
- public void onUserSelectionCallbackRegistration(
- INetworkRequestUserSelectionCallback userSelectionCallback) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "NetworkRequestMatchCallbackProxy: "
- + "onUserSelectionCallbackRegistration callback: " + userSelectionCallback);
- }
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onUserSelectionCallbackRegistration(
- new NetworkRequestUserSelectionCallbackProxy(userSelectionCallback));
- });
- }
-
- @Override
- public void onAbort() {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "NetworkRequestMatchCallbackProxy: onAbort");
- }
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onAbort();
- });
- }
-
- @Override
- public void onMatch(List<ScanResult> scanResults) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "NetworkRequestMatchCallbackProxy: onMatch scanResults: "
- + scanResults);
- }
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onMatch(scanResults);
- });
- }
-
- @Override
- public void onUserSelectionConnectSuccess(WifiConfiguration wifiConfiguration) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectSuccess "
- + " wificonfiguration: " + wifiConfiguration);
- }
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onUserSelectionConnectSuccess(wifiConfiguration);
- });
- }
-
- @Override
- public void onUserSelectionConnectFailure(WifiConfiguration wifiConfiguration) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectFailure"
- + " wificonfiguration: " + wifiConfiguration);
- }
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onUserSelectionConnectFailure(wifiConfiguration);
- });
- }
- }
-
- /**
- * Registers a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}.
- * Caller can unregister a previously registered callback using
- * {@link #unregisterNetworkRequestMatchCallback(NetworkRequestMatchCallback)}
- * <p>
- * Applications should have the
- * {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers
- * without the permission will trigger a {@link java.lang.SecurityException}.
- * <p>
- *
- * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
- * object.
- * @param callback Callback for network match events to register.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void registerNetworkRequestMatchCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull NetworkRequestMatchCallback callback) {
- if (executor == null) throw new IllegalArgumentException("executor cannot be null");
- if (callback == null) throw new IllegalArgumentException("callback cannot be null");
- Log.v(TAG, "registerNetworkRequestMatchCallback: callback=" + callback
- + ", executor=" + executor);
-
- Binder binder = new Binder();
- try {
- mService.registerNetworkRequestMatchCallback(
- binder, new NetworkRequestMatchCallbackProxy(executor, callback),
- callback.hashCode());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Unregisters a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}.
- * <p>
- * Applications should have the
- * {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers
- * without the permission will trigger a {@link java.lang.SecurityException}.
- * <p>
- *
- * @param callback Callback for network match events to unregister.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void unregisterNetworkRequestMatchCallback(
- @NonNull NetworkRequestMatchCallback callback) {
- if (callback == null) throw new IllegalArgumentException("callback cannot be null");
- Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback);
-
- try {
- mService.unregisterNetworkRequestMatchCallback(callback.hashCode());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Provide a list of network suggestions to the device. See {@link WifiNetworkSuggestion}
- * for a detailed explanation of the parameters.
- * When the device decides to connect to one of the provided network suggestions, platform sends
- * a directed broadcast {@link #ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} to the app if
- * the network was created with
- * {@link WifiNetworkSuggestion.Builder#setIsAppInteractionRequired(boolean)} flag set and the
- * app holds {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}
- * permission.
- *<p>
- * NOTE:
- * <li> These networks are just a suggestion to the platform. The platform will ultimately
- * decide on which network the device connects to. </li>
- * <li> When an app is uninstalled or disabled, all its suggested networks are discarded.
- * If the device is currently connected to a suggested network which is being removed then the
- * device will disconnect from that network.</li>
- * <li> If user reset network settings, all added suggestions will be discarded. Apps can use
- * {@link #getNetworkSuggestions()} to check if their suggestions are in the device.</li>
- * <li> In-place modification of existing suggestions are allowed.
- * <li> If the provided suggestions include any previously provided suggestions by the app,
- * previous suggestions will be updated.</li>
- * <li>If one of the provided suggestions marks a previously unmetered suggestion as metered and
- * the device is currently connected to that suggested network, then the device will disconnect
- * from that network. The system will immediately re-evaluate all the network candidates
- * and possibly reconnect back to the same suggestion. This disconnect is to make sure that any
- * traffic flowing over unmetered networks isn't accidentally continued over a metered network.
- * </li>
- * </li>
- *
- * @param networkSuggestions List of network suggestions provided by the app.
- * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values.
- * @throws {@link SecurityException} if the caller is missing required permissions.
- * @see WifiNetworkSuggestion#equals(Object)
- */
- @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
- public @NetworkSuggestionsStatusCode int addNetworkSuggestions(
- @NonNull List<WifiNetworkSuggestion> networkSuggestions) {
- try {
- return mService.addNetworkSuggestions(
- networkSuggestions, mContext.getOpPackageName(), mContext.getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Remove some or all of the network suggestions that were previously provided by the app.
- * If one of the suggestions being removed was used to establish connection to the current
- * network, then the device will immediately disconnect from that network.
- *
- * See {@link WifiNetworkSuggestion} for a detailed explanation of the parameters.
- * See {@link WifiNetworkSuggestion#equals(Object)} for the equivalence evaluation used.
- *
- * @param networkSuggestions List of network suggestions to be removed. Pass an empty list
- * to remove all the previous suggestions provided by the app.
- * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values.
- * Any matching suggestions are removed from the device and will not be considered for any
- * further connection attempts.
- */
- @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
- public @NetworkSuggestionsStatusCode int removeNetworkSuggestions(
- @NonNull List<WifiNetworkSuggestion> networkSuggestions) {
- try {
- return mService.removeNetworkSuggestions(
- networkSuggestions, mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get all network suggestions provided by the calling app.
- * See {@link #addNetworkSuggestions(List)}
- * See {@link #removeNetworkSuggestions(List)}
- * @return a list of {@link WifiNetworkSuggestion}
- */
- @RequiresPermission(ACCESS_WIFI_STATE)
- public @NonNull List<WifiNetworkSuggestion> getNetworkSuggestions() {
- try {
- return mService.getNetworkSuggestions(mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Returns the max number of network suggestions that are allowed per app on the device.
- * @see #addNetworkSuggestions(List)
- * @see #removeNetworkSuggestions(List)
- */
- public int getMaxNumberOfNetworkSuggestionsPerApp() {
- return getMaxNumberOfNetworkSuggestionsPerApp(
- mContext.getSystemService(ActivityManager.class).isLowRamDevice());
- }
-
- /** @hide */
- public static int getMaxNumberOfNetworkSuggestionsPerApp(boolean isLowRamDevice) {
- return isLowRamDevice
- ? NETWORK_SUGGESTIONS_MAX_PER_APP_LOW_RAM
- : NETWORK_SUGGESTIONS_MAX_PER_APP_HIGH_RAM;
- }
-
- /**
- * Add or update a Passpoint configuration. The configuration provides a credential
- * for connecting to Passpoint networks that are operated by the Passpoint
- * service provider specified in the configuration.
- *
- * Each configuration is uniquely identified by a unique key which depends on the contents of
- * the configuration. This allows the caller to install multiple profiles with the same FQDN
- * (Fully qualified domain name). Therefore, in order to update an existing profile, it is
- * first required to remove it using {@link WifiManager#removePasspointConfiguration(String)}.
- * Otherwise, a new profile will be added with both configuration.
- *
- * @param config The Passpoint configuration to be added
- * @throws IllegalArgumentException if configuration is invalid or Passpoint is not enabled on
- * the device.
- *
- * Deprecated for general app usage - except DO/PO apps.
- * See {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} to
- * create a passpoint suggestion.
- * See {@link #addNetworkSuggestions(List)}, {@link #removeNetworkSuggestions(List)} for new
- * API to add Wi-Fi networks for consideration when auto-connecting to wifi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#R} or above, this API will always fail and throw
- * {@link IllegalArgumentException}.
- * <p>
- * Deprecation Exemptions:
- * <ul>
- * <li>Device Owner (DO), Profile Owner (PO) and system apps.
- * </ul>
- */
- public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
- try {
- if (!mService.addOrUpdatePasspointConfiguration(config, mContext.getOpPackageName())) {
- throw new IllegalArgumentException();
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name) added
- * by the caller.
- *
- * @param fqdn The FQDN of the Passpoint configuration added by the caller to be removed
- * @throws IllegalArgumentException if no configuration is associated with the given FQDN or
- * Passpoint is not enabled on the device.
- * @deprecated This will be non-functional in a future release.
- */
- @Deprecated
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_CARRIER_PROVISIONING
- })
- public void removePasspointConfiguration(String fqdn) {
- try {
- if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) {
- throw new IllegalArgumentException();
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return the list of installed Passpoint configurations added by the caller.
- *
- * An empty list will be returned when no configurations are installed.
- *
- * @return A list of {@link PasspointConfiguration} added by the caller
- * @deprecated This will be non-functional in a future release.
- */
- @Deprecated
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD
- })
- public List<PasspointConfiguration> getPasspointConfigurations() {
- try {
- return mService.getPasspointConfigurations(mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Query for a Hotspot 2.0 release 2 OSU icon file. An {@link #ACTION_PASSPOINT_ICON} intent
- * will be broadcasted once the request is completed. The presence of the intent extra
- * {@link #EXTRA_ICON} will indicate the result of the request.
- * A missing intent extra {@link #EXTRA_ICON} will indicate a failure.
- *
- * @param bssid The BSSID of the AP
- * @param fileName Name of the icon file (remote file) to query from the AP
- *
- * @throws UnsupportedOperationException if Passpoint is not enabled on the device.
- * @hide
- */
- public void queryPasspointIcon(long bssid, String fileName) {
- try {
- mService.queryPasspointIcon(bssid, fileName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Match the currently associated network against the SP matching the given FQDN
- * @param fqdn FQDN of the SP
- * @return ordinal [HomeProvider, RoamingProvider, Incomplete, None, Declined]
- * @hide
- */
- public int matchProviderWithCurrentNetwork(String fqdn) {
- try {
- return mService.matchProviderWithCurrentNetwork(fqdn);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Deauthenticate and set the re-authentication hold off time for the current network
- * @param holdoff hold off time in milliseconds
- * @param ess set if the hold off pertains to an ESS rather than a BSS
- * @hide
- *
- * TODO (140167680): This needs to be removed, the implementation is empty!
- */
- public void deauthenticateNetwork(long holdoff, boolean ess) {
- try {
- mService.deauthenticateNetwork(holdoff, ess);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Remove the specified network from the list of configured networks.
- * This may result in the asynchronous delivery of state change
- * events.
- *
- * Applications are not allowed to remove networks created by other
- * applications.
- *
- * @param netId the ID of the network as returned by {@link #addNetwork} or {@link
- * #getConfiguredNetworks}.
- * @return {@code true} if the operation succeeded
- *
- * @deprecated
- * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
- * mechanism to trigger connection to a Wi-Fi network.
- * b) See {@link #addNetworkSuggestions(List)},
- * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
- * when auto-connecting to wifi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
- * {@code false}.
- * <p>
- * Deprecation Exemptions:
- * <ul>
- * <li>Device Owner (DO), Profile Owner (PO) and system apps.
- * </ul>
- */
- @Deprecated
- public boolean removeNetwork(int netId) {
- try {
- return mService.removeNetwork(netId, mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Allow a previously configured network to be associated with. If
- * <code>attemptConnect</code> is true, an attempt to connect to the selected
- * network is initiated. This may result in the asynchronous delivery
- * of state change events.
- * <p>
- * <b>Note:</b> Network communication may not use Wi-Fi even if Wi-Fi is connected;
- * traffic may instead be sent through another network, such as cellular data,
- * Bluetooth tethering, or Ethernet. For example, traffic will never use a
- * Wi-Fi network that does not provide Internet access (e.g. a wireless
- * printer), if another network that does offer Internet access (e.g.
- * cellular data) is available. Applications that need to ensure that their
- * network traffic uses Wi-Fi should use APIs such as
- * {@link Network#bindSocket(java.net.Socket)},
- * {@link Network#openConnection(java.net.URL)}, or
- * {@link ConnectivityManager#bindProcessToNetwork} to do so.
- *
- * Applications are not allowed to enable networks created by other
- * applications.
- *
- * @param netId the ID of the network as returned by {@link #addNetwork} or {@link
- * #getConfiguredNetworks}.
- * @param attemptConnect The way to select a particular network to connect to is specify
- * {@code true} for this parameter.
- * @return {@code true} if the operation succeeded
- *
- * @deprecated
- * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
- * mechanism to trigger connection to a Wi-Fi network.
- * b) See {@link #addNetworkSuggestions(List)},
- * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
- * when auto-connecting to wifi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
- * {@code false}.
- * Deprecation Exemptions:
- * <ul>
- * <li>Device Owner (DO), Profile Owner (PO) and system apps.
- * </ul>
- */
- @Deprecated
- public boolean enableNetwork(int netId, boolean attemptConnect) {
- try {
- return mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Disable a configured network. The specified network will not be
- * a candidate for associating. This may result in the asynchronous
- * delivery of state change events.
- *
- * Applications are not allowed to disable networks created by other
- * applications.
- *
- * @param netId the ID of the network as returned by {@link #addNetwork} or {@link
- * #getConfiguredNetworks}.
- * @return {@code true} if the operation succeeded
- *
- * @deprecated
- * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
- * mechanism to trigger connection to a Wi-Fi network.
- * b) See {@link #addNetworkSuggestions(List)},
- * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
- * when auto-connecting to wifi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
- * {@code false}.
- * <p>
- * Deprecation Exemptions:
- * <ul>
- * <li>Device Owner (DO), Profile Owner (PO) and system apps.
- * </ul>
- */
- @Deprecated
- public boolean disableNetwork(int netId) {
- try {
- return mService.disableNetwork(netId, mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Disassociate from the currently active access point. This may result
- * in the asynchronous delivery of state change events.
- * @return {@code true} if the operation succeeded
- *
- * @deprecated
- * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
- * mechanism to trigger connection to a Wi-Fi network.
- * b) See {@link #addNetworkSuggestions(List)},
- * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
- * when auto-connecting to wifi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
- * {@code false}.
- * <p>
- * Deprecation Exemptions:
- * <ul>
- * <li>Device Owner (DO), Profile Owner (PO) and system apps.
- * </ul>
- */
- @Deprecated
- public boolean disconnect() {
- try {
- return mService.disconnect(mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Reconnect to the currently active access point, if we are currently
- * disconnected. This may result in the asynchronous delivery of state
- * change events.
- * @return {@code true} if the operation succeeded
- *
- * @deprecated
- * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
- * mechanism to trigger connection to a Wi-Fi network.
- * b) See {@link #addNetworkSuggestions(List)},
- * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
- * when auto-connecting to wifi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
- * {@code false}.
- * <p>
- * Deprecation Exemptions:
- * <ul>
- * <li>Device Owner (DO), Profile Owner (PO) and system apps.
- * </ul>
- */
- @Deprecated
- public boolean reconnect() {
- try {
- return mService.reconnect(mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Reconnect to the currently active access point, even if we are already
- * connected. This may result in the asynchronous delivery of state
- * change events.
- * @return {@code true} if the operation succeeded
- *
- * @deprecated
- * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
- * mechanism to trigger connection to a Wi-Fi network.
- * b) See {@link #addNetworkSuggestions(List)},
- * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
- * when auto-connecting to wifi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
- */
- @Deprecated
- public boolean reassociate() {
- try {
- return mService.reassociate(mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Check that the supplicant daemon is responding to requests.
- * @return {@code true} if we were able to communicate with the supplicant and
- * it returned the expected response to the PING message.
- * @deprecated Will return the output of {@link #isWifiEnabled()} instead.
- */
- @Deprecated
- public boolean pingSupplicant() {
- return isWifiEnabled();
- }
-
- /** @hide */
- public static final long WIFI_FEATURE_INFRA = 0x0001L; // Basic infrastructure mode
- /** @hide */
- public static final long WIFI_FEATURE_PASSPOINT = 0x0004L; // Support for GAS/ANQP
- /** @hide */
- public static final long WIFI_FEATURE_P2P = 0x0008L; // Wifi-Direct
- /** @hide */
- public static final long WIFI_FEATURE_MOBILE_HOTSPOT = 0x0010L; // Soft AP
- /** @hide */
- public static final long WIFI_FEATURE_SCANNER = 0x0020L; // WifiScanner APIs
- /** @hide */
- public static final long WIFI_FEATURE_AWARE = 0x0040L; // Wi-Fi AWare networking
- /** @hide */
- public static final long WIFI_FEATURE_D2D_RTT = 0x0080L; // Device-to-device RTT
- /** @hide */
- public static final long WIFI_FEATURE_D2AP_RTT = 0x0100L; // Device-to-AP RTT
- /** @hide */
- public static final long WIFI_FEATURE_BATCH_SCAN = 0x0200L; // Batched Scan (deprecated)
- /** @hide */
- public static final long WIFI_FEATURE_PNO = 0x0400L; // Preferred network offload
- /** @hide */
- public static final long WIFI_FEATURE_ADDITIONAL_STA = 0x0800L; // Support for two STAs
- /** @hide */
- public static final long WIFI_FEATURE_TDLS = 0x1000L; // Tunnel directed link setup
- /** @hide */
- public static final long WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000L; // TDLS off channel
- /** @hide */
- public static final long WIFI_FEATURE_EPR = 0x4000L; // Enhanced power reporting
- /** @hide */
- public static final long WIFI_FEATURE_AP_STA = 0x8000L; // AP STA Concurrency
- /** @hide */
- public static final long WIFI_FEATURE_LINK_LAYER_STATS = 0x10000L; // Link layer stats
- /** @hide */
- public static final long WIFI_FEATURE_LOGGER = 0x20000L; // WiFi Logger
- /** @hide */
- public static final long WIFI_FEATURE_HAL_EPNO = 0x40000L; // Enhanced PNO
- /** @hide */
- public static final long WIFI_FEATURE_RSSI_MONITOR = 0x80000L; // RSSI Monitor
- /** @hide */
- public static final long WIFI_FEATURE_MKEEP_ALIVE = 0x100000L; // mkeep_alive
- /** @hide */
- public static final long WIFI_FEATURE_CONFIG_NDO = 0x200000L; // ND offload
- /** @hide */
- public static final long WIFI_FEATURE_TRANSMIT_POWER = 0x400000L; // Capture transmit power
- /** @hide */
- public static final long WIFI_FEATURE_CONTROL_ROAMING = 0x800000L; // Control firmware roaming
- /** @hide */
- public static final long WIFI_FEATURE_IE_WHITELIST = 0x1000000L; // Probe IE white listing
- /** @hide */
- public static final long WIFI_FEATURE_SCAN_RAND = 0x2000000L; // Random MAC & Probe seq
- /** @hide */
- public static final long WIFI_FEATURE_TX_POWER_LIMIT = 0x4000000L; // Set Tx power limit
- /** @hide */
- public static final long WIFI_FEATURE_WPA3_SAE = 0x8000000L; // WPA3-Personal SAE
- /** @hide */
- public static final long WIFI_FEATURE_WPA3_SUITE_B = 0x10000000L; // WPA3-Enterprise Suite-B
- /** @hide */
- public static final long WIFI_FEATURE_OWE = 0x20000000L; // Enhanced Open
- /** @hide */
- public static final long WIFI_FEATURE_LOW_LATENCY = 0x40000000L; // Low Latency modes
- /** @hide */
- public static final long WIFI_FEATURE_DPP = 0x80000000L; // DPP (Easy-Connect)
- /** @hide */
- public static final long WIFI_FEATURE_P2P_RAND_MAC = 0x100000000L; // Random P2P MAC
- /** @hide */
- public static final long WIFI_FEATURE_CONNECTED_RAND_MAC = 0x200000000L; // Random STA MAC
- /** @hide */
- public static final long WIFI_FEATURE_AP_RAND_MAC = 0x400000000L; // Random AP MAC
- /** @hide */
- public static final long WIFI_FEATURE_MBO = 0x800000000L; // MBO Support
- /** @hide */
- public static final long WIFI_FEATURE_OCE = 0x1000000000L; // OCE Support
- /** @hide */
- public static final long WIFI_FEATURE_WAPI = 0x2000000000L; // WAPI
-
- /** @hide */
- public static final long WIFI_FEATURE_FILS_SHA256 = 0x4000000000L; // FILS-SHA256
-
- /** @hide */
- public static final long WIFI_FEATURE_FILS_SHA384 = 0x8000000000L; // FILS-SHA384
-
- private long getSupportedFeatures() {
- try {
- return mService.getSupportedFeatures();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- private boolean isFeatureSupported(long feature) {
- return (getSupportedFeatures() & feature) == feature;
- }
-
- /**
- * @return true if this adapter supports Passpoint
- * @hide
- */
- public boolean isPasspointSupported() {
- return isFeatureSupported(WIFI_FEATURE_PASSPOINT);
- }
-
- /**
- * @return true if this adapter supports WifiP2pManager (Wi-Fi Direct)
- */
- public boolean isP2pSupported() {
- return isFeatureSupported(WIFI_FEATURE_P2P);
- }
-
- /**
- * @return true if this adapter supports portable Wi-Fi hotspot
- * @hide
- */
- @SystemApi
- public boolean isPortableHotspotSupported() {
- return isFeatureSupported(WIFI_FEATURE_MOBILE_HOTSPOT);
- }
-
- /**
- * @return true if this adapter supports WifiScanner APIs
- * @hide
- */
- @SystemApi
- public boolean isWifiScannerSupported() {
- return isFeatureSupported(WIFI_FEATURE_SCANNER);
- }
-
- /**
- * @return true if this adapter supports Neighbour Awareness Network APIs
- * @hide
- */
- public boolean isWifiAwareSupported() {
- return isFeatureSupported(WIFI_FEATURE_AWARE);
- }
-
- /**
- * Query whether the device supports Station (STA) + Access point (AP) concurrency or not.
- *
- * @return true if this device supports STA + AP concurrency, false otherwise.
- */
- public boolean isStaApConcurrencySupported() {
- return isFeatureSupported(WIFI_FEATURE_AP_STA);
- }
-
- /**
- * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)}
- * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT} and
- * {@link android.content.pm.PackageManager#FEATURE_WIFI_AWARE}.
- *
- * @return true if this adapter supports Device-to-device RTT
- * @hide
- */
- @Deprecated
- @SystemApi
- public boolean isDeviceToDeviceRttSupported() {
- return isFeatureSupported(WIFI_FEATURE_D2D_RTT);
- }
-
- /**
- * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)}
- * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT}.
- *
- * @return true if this adapter supports Device-to-AP RTT
- */
- @Deprecated
- public boolean isDeviceToApRttSupported() {
- return isFeatureSupported(WIFI_FEATURE_D2AP_RTT);
- }
-
- /**
- * @return true if this adapter supports offloaded connectivity scan
- */
- public boolean isPreferredNetworkOffloadSupported() {
- return isFeatureSupported(WIFI_FEATURE_PNO);
- }
-
- /**
- * @return true if this adapter supports multiple simultaneous connections
- * @hide
- */
- public boolean isAdditionalStaSupported() {
- return isFeatureSupported(WIFI_FEATURE_ADDITIONAL_STA);
- }
-
- /**
- * @return true if this adapter supports Tunnel Directed Link Setup
- */
- public boolean isTdlsSupported() {
- return isFeatureSupported(WIFI_FEATURE_TDLS);
- }
-
- /**
- * @return true if this adapter supports Off Channel Tunnel Directed Link Setup
- * @hide
- */
- public boolean isOffChannelTdlsSupported() {
- return isFeatureSupported(WIFI_FEATURE_TDLS_OFFCHANNEL);
- }
-
- /**
- * @return true if this adapter supports advanced power/performance counters
- */
- public boolean isEnhancedPowerReportingSupported() {
- return isFeatureSupported(WIFI_FEATURE_LINK_LAYER_STATS);
- }
-
- /**
- * @return true if this device supports connected MAC randomization.
- * @hide
- */
- @SystemApi
- public boolean isConnectedMacRandomizationSupported() {
- return isFeatureSupported(WIFI_FEATURE_CONNECTED_RAND_MAC);
- }
-
- /**
- * @return true if this device supports connected MAC randomization.
- * @hide
- */
- @SystemApi
- public boolean isApMacRandomizationSupported() {
- return isFeatureSupported(WIFI_FEATURE_AP_RAND_MAC);
- }
-
- /**
- * Check if the chipset supports 5GHz band.
- * @return {@code true} if supported, {@code false} otherwise.
- */
- public boolean is5GHzBandSupported() {
- try {
- return mService.is5GHzBandSupported();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Check if the chipset supports 6GHz band.
- * @return {@code true} if supported, {@code false} otherwise.
- */
- public boolean is6GHzBandSupported() {
- try {
- return mService.is6GHzBandSupported();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Check if the chipset supports a certain Wi-Fi standard.
- * @param standard the IEEE 802.11 standard to check on.
- * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_}
- * @return {@code true} if supported, {@code false} otherwise.
- */
- public boolean isWifiStandardSupported(@WifiAnnotations.WifiStandard int standard) {
- try {
- return mService.isWifiStandardSupported(standard);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Interface for Wi-Fi activity energy info listener. Should be implemented by applications and
- * set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}.
- *
- * @hide
- */
- @SystemApi
- public interface OnWifiActivityEnergyInfoListener {
- /**
- * Called when Wi-Fi activity energy info is available.
- * Note: this listener is triggered at most once for each call to
- * {@link #getWifiActivityEnergyInfoAsync}.
- *
- * @param info the latest {@link WifiActivityEnergyInfo}, or null if unavailable.
- */
- void onWifiActivityEnergyInfo(@Nullable WifiActivityEnergyInfo info);
- }
-
- private static class OnWifiActivityEnergyInfoProxy
- extends IOnWifiActivityEnergyInfoListener.Stub {
- private final Object mLock = new Object();
- @Nullable @GuardedBy("mLock") private Executor mExecutor;
- @Nullable @GuardedBy("mLock") private OnWifiActivityEnergyInfoListener mListener;
-
- OnWifiActivityEnergyInfoProxy(Executor executor,
- OnWifiActivityEnergyInfoListener listener) {
- mExecutor = executor;
- mListener = listener;
- }
-
- @Override
- public void onWifiActivityEnergyInfo(WifiActivityEnergyInfo info) {
- Executor executor;
- OnWifiActivityEnergyInfoListener listener;
- synchronized (mLock) {
- if (mExecutor == null || mListener == null) {
- return;
- }
- executor = mExecutor;
- listener = mListener;
- // null out to allow garbage collection, prevent triggering listener more than once
- mExecutor = null;
- mListener = null;
- }
- Binder.clearCallingIdentity();
- executor.execute(() -> listener.onWifiActivityEnergyInfo(info));
- }
- }
-
- /**
- * Request to get the current {@link WifiActivityEnergyInfo} asynchronously.
- * Note: This method will return null if {@link #isEnhancedPowerReportingSupported()} returns
- * false.
- *
- * @param executor the executor that the listener will be invoked on
- * @param listener the listener that will receive the {@link WifiActivityEnergyInfo} object
- * when it becomes available. The listener will be triggered at most once for
- * each call to this method.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(ACCESS_WIFI_STATE)
- public void getWifiActivityEnergyInfoAsync(
- @NonNull @CallbackExecutor Executor executor,
- @NonNull OnWifiActivityEnergyInfoListener listener) {
- Objects.requireNonNull(executor, "executor cannot be null");
- Objects.requireNonNull(listener, "listener cannot be null");
- try {
- mService.getWifiActivityEnergyInfoAsync(
- new OnWifiActivityEnergyInfoProxy(executor, listener));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Request a scan for access points. Returns immediately. The availability
- * of the results is made known later by means of an asynchronous event sent
- * on completion of the scan.
- * <p>
- * To initiate a Wi-Fi scan, declare the
- * {@link android.Manifest.permission#CHANGE_WIFI_STATE}
- * permission in the manifest, and perform these steps:
- * </p>
- * <ol style="1">
- * <li>Invoke the following method:
- * {@code ((WifiManager) getSystemService(WIFI_SERVICE)).startScan()}</li>
- * <li>
- * Register a BroadcastReceiver to listen to
- * {@code SCAN_RESULTS_AVAILABLE_ACTION}.</li>
- * <li>When a broadcast is received, call:
- * {@code ((WifiManager) getSystemService(WIFI_SERVICE)).getScanResults()}</li>
- * </ol>
- * @return {@code true} if the operation succeeded, i.e., the scan was initiated.
- * @deprecated The ability for apps to trigger scan requests will be removed in a future
- * release.
- */
- @Deprecated
- public boolean startScan() {
- return startScan(null);
- }
-
- /** @hide */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
- public boolean startScan(WorkSource workSource) {
- try {
- String packageName = mContext.getOpPackageName();
- String attributionTag = mContext.getAttributionTag();
- return mService.startScan(packageName, attributionTag);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * WPS has been deprecated from Client mode operation.
- *
- * @return null
- * @hide
- * @deprecated This API is deprecated
- */
- public String getCurrentNetworkWpsNfcConfigurationToken() {
- return null;
- }
-
- /**
- * Return dynamic information about the current Wi-Fi connection, if any is active.
- * <p>
- * In the connected state, access to the SSID and BSSID requires
- * the same permissions as {@link #getScanResults}. If such access is not allowed,
- * {@link WifiInfo#getSSID} will return {@link #UNKNOWN_SSID} and
- * {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}.
- * {@link WifiInfo#getPasspointFqdn()} will return null.
- * {@link WifiInfo#getPasspointProviderFriendlyName()} will return null.
- *
- * @return the Wi-Fi information, contained in {@link WifiInfo}.
- */
- public WifiInfo getConnectionInfo() {
- try {
- return mService.getConnectionInfo(mContext.getOpPackageName(),
- mContext.getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return the results of the latest access point scan.
- * @return the list of access points found in the most recent scan. An app must hold
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
- * in order to get valid results.
- */
- public List<ScanResult> getScanResults() {
- try {
- return mService.getScanResults(mContext.getOpPackageName(),
- mContext.getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get the filtered ScanResults which match the network configurations specified by the
- * {@code networkSuggestionsToMatch}. Suggestions which use {@link WifiConfiguration} use
- * SSID and the security type to match. Suggestions which use {@link PasspointConfigration}
- * use the matching rules of Hotspot 2.0.
- * @param networkSuggestionsToMatch The list of {@link WifiNetworkSuggestion} to match against.
- * These may or may not be suggestions which are installed on the device.
- * @param scanResults The scan results to be filtered. Optional - if not provided(empty list),
- * the Wi-Fi service will use the most recent scan results which the system has.
- * @return The map of {@link WifiNetworkSuggestion} to the list of {@link ScanResult}
- * corresponding to networks which match them.
- * @hide
- */
- @SystemApi
- @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
- @NonNull
- public Map<WifiNetworkSuggestion, List<ScanResult>> getMatchingScanResults(
- @NonNull List<WifiNetworkSuggestion> networkSuggestionsToMatch,
- @Nullable List<ScanResult> scanResults) {
- if (networkSuggestionsToMatch == null) {
- throw new IllegalArgumentException("networkSuggestions must not be null.");
- }
- try {
- return mService.getMatchingScanResults(
- networkSuggestionsToMatch, scanResults,
- mContext.getOpPackageName(), mContext.getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Set if scanning is always available.
- *
- * If set to {@code true}, apps can issue {@link #startScan} and fetch scan results
- * even when Wi-Fi is turned off.
- *
- * @param isAvailable true to enable, false to disable.
- * @hide
- * @see #isScanAlwaysAvailable()
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void setScanAlwaysAvailable(boolean isAvailable) {
- try {
- mService.setScanAlwaysAvailable(isAvailable);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Check if scanning is always available.
- *
- * If this return {@code true}, apps can issue {@link #startScan} and fetch scan results
- * even when Wi-Fi is turned off.
- *
- * To change this setting, see {@link #ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE}.
- * @deprecated The ability for apps to trigger scan requests will be removed in a future
- * release.
- */
- @Deprecated
- public boolean isScanAlwaysAvailable() {
- try {
- return mService.isScanAlwaysAvailable();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Tell the device to persist the current list of configured networks.
- * <p>
- * Note: It is possible for this method to change the network IDs of
- * existing networks. You should assume the network IDs can be different
- * after calling this method.
- *
- * @return {@code false}.
- * @deprecated There is no need to call this method -
- * {@link #addNetwork(WifiConfiguration)}, {@link #updateNetwork(WifiConfiguration)}
- * and {@link #removeNetwork(int)} already persist the configurations automatically.
- */
- @Deprecated
- public boolean saveConfiguration() {
- return false;
- }
-
- /**
- * Get the country code.
- * @return the country code in ISO 3166 alpha-2 (2-letter) uppercase format, or null if
- * there is no country code configured.
- * @hide
- */
- @Nullable
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public String getCountryCode() {
- try {
- return mService.getCountryCode();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return the DHCP-assigned addresses from the last successful DHCP request,
- * if any.
- * @return the DHCP information
- */
- public DhcpInfo getDhcpInfo() {
- try {
- return mService.getDhcpInfo();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Enable or disable Wi-Fi.
- * <p>
- * Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE}
- * permission to toggle wifi.
- *
- * @param enabled {@code true} to enable, {@code false} to disable.
- * @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is
- * either already in the requested state, or in progress toward the requested state.
- * @throws {@link java.lang.SecurityException} if the caller is missing required permissions.
- *
- * @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to
- * enable/disable Wi-Fi.
- * <b>Compatibility Note:</b> For applications targeting
- * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
- * {@code false}. If apps are targeting an older SDK ({@link android.os.Build.VERSION_CODES#P}
- * or below), they can continue to use this API.
- * <p>
- * Deprecation Exemptions:
- * <ul>
- * <li>Device Owner (DO), Profile Owner (PO) and system apps.
- * </ul>
- */
- @Deprecated
- public boolean setWifiEnabled(boolean enabled) {
- try {
- return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Gets the Wi-Fi enabled state.
- * @return One of {@link #WIFI_STATE_DISABLED},
- * {@link #WIFI_STATE_DISABLING}, {@link #WIFI_STATE_ENABLED},
- * {@link #WIFI_STATE_ENABLING}, {@link #WIFI_STATE_UNKNOWN}
- * @see #isWifiEnabled()
- */
- public int getWifiState() {
- try {
- return mService.getWifiEnabledState();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return whether Wi-Fi is enabled or disabled.
- * @return {@code true} if Wi-Fi is enabled
- * @see #getWifiState()
- */
- public boolean isWifiEnabled() {
- return getWifiState() == WIFI_STATE_ENABLED;
- }
-
- /**
- * Calculates the level of the signal. This should be used any time a signal
- * is being shown.
- *
- * @param rssi The power of the signal measured in RSSI.
- * @param numLevels The number of levels to consider in the calculated level.
- * @return A level of the signal, given in the range of 0 to numLevels-1 (both inclusive).
- * @deprecated Callers should use {@link #calculateSignalLevel(int)} instead to get the
- * signal level using the system default RSSI thresholds, or otherwise compute the RSSI level
- * themselves using their own formula.
- */
- @Deprecated
- public static int calculateSignalLevel(int rssi, int numLevels) {
- if (rssi <= MIN_RSSI) {
- return 0;
- } else if (rssi >= MAX_RSSI) {
- return numLevels - 1;
- } else {
- float inputRange = (MAX_RSSI - MIN_RSSI);
- float outputRange = (numLevels - 1);
- return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange);
- }
- }
-
- /**
- * Given a raw RSSI, return the RSSI signal quality rating using the system default RSSI
- * quality rating thresholds.
- * @param rssi a raw RSSI value, in dBm, usually between -55 and -90
- * @return the RSSI signal quality rating, in the range
- * [0, {@link #getMaxSignalLevel()}], where 0 is the lowest (worst signal) RSSI
- * rating and {@link #getMaxSignalLevel()} is the highest (best signal) RSSI rating.
- */
- @IntRange(from = 0)
- public int calculateSignalLevel(int rssi) {
- try {
- return mService.calculateSignalLevel(rssi);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get the system default maximum signal level.
- * This is the maximum RSSI level returned by {@link #calculateSignalLevel(int)}.
- */
- @IntRange(from = 0)
- public int getMaxSignalLevel() {
- return calculateSignalLevel(Integer.MAX_VALUE);
- }
-
- /**
- * Compares two signal strengths.
- *
- * @param rssiA The power of the first signal measured in RSSI.
- * @param rssiB The power of the second signal measured in RSSI.
- * @return Returns <0 if the first signal is weaker than the second signal,
- * 0 if the two signals have the same strength, and >0 if the first
- * signal is stronger than the second signal.
- */
- public static int compareSignalLevel(int rssiA, int rssiB) {
- return rssiA - rssiB;
- }
-
- /**
- * Call allowing ConnectivityService to update WifiService with interface mode changes.
- *
- * @param ifaceName String name of the updated interface, or null to represent all interfaces
- * @param mode int representing the new mode, one of:
- * {@link #IFACE_IP_MODE_TETHERED},
- * {@link #IFACE_IP_MODE_LOCAL_ONLY},
- * {@link #IFACE_IP_MODE_CONFIGURATION_ERROR},
- * {@link #IFACE_IP_MODE_UNSPECIFIED}
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
- })
- public void updateInterfaceIpState(@Nullable String ifaceName, @IfaceIpMode int mode) {
- try {
- mService.updateInterfaceIpState(ifaceName, mode);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Start Soft AP (hotspot) mode for tethering purposes with the specified configuration.
- * Note that starting Soft AP mode may disable station mode operation if the device does not
- * support concurrency.
- * @param wifiConfig SSID, security and channel details as part of WifiConfiguration, or null to
- * use the persisted Soft AP configuration that was previously set using
- * {@link #setWifiApConfiguration(WifiConfiguration)}.
- * @return {@code true} if the operation succeeded, {@code false} otherwise
- *
- * @hide
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
- })
- public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) {
- try {
- return mService.startSoftAp(wifiConfig);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Start Soft AP (hotspot) mode for tethering purposes with the specified configuration.
- * Note that starting Soft AP mode may disable station mode operation if the device does not
- * support concurrency.
- * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP,
- * or null to use the persisted Soft AP configuration that was previously
- * set using {@link #setSoftApConfiguration(softApConfiguration)}.
- * @return {@code true} if the operation succeeded, {@code false} otherwise
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
- })
- public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) {
- try {
- return mService.startTetheredHotspot(softApConfig);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
-
- /**
- * Stop SoftAp mode.
- * Note that stopping softap mode will restore the previous wifi mode.
- * @return {@code true} if the operation succeeds, {@code false} otherwise
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
- })
- public boolean stopSoftAp() {
- try {
- return mService.stopSoftAp();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Request a local only hotspot that an application can use to communicate between co-located
- * devices connected to the created WiFi hotspot. The network created by this method will not
- * have Internet access. Each application can make a single request for the hotspot, but
- * multiple applications could be requesting the hotspot at the same time. When multiple
- * applications have successfully registered concurrently, they will be sharing the underlying
- * hotspot. {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} is called
- * when the hotspot is ready for use by the application.
- * <p>
- * Each application can make a single active call to this method. The {@link
- * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} callback supplies the
- * requestor with a {@link LocalOnlyHotspotReservation} that contains a
- * {@link SoftApConfiguration} with the SSID, security type and credentials needed to connect
- * to the hotspot. Communicating this information is up to the application.
- * <p>
- * If the LocalOnlyHotspot cannot be created, the {@link LocalOnlyHotspotCallback#onFailed(int)}
- * method will be called. Example failures include errors bringing up the network or if
- * there is an incompatible operating mode. For example, if the user is currently using Wifi
- * Tethering to provide an upstream to another device, LocalOnlyHotspot will not start due to
- * an incompatible mode. The possible error codes include:
- * {@link LocalOnlyHotspotCallback#ERROR_NO_CHANNEL},
- * {@link LocalOnlyHotspotCallback#ERROR_GENERIC},
- * {@link LocalOnlyHotspotCallback#ERROR_INCOMPATIBLE_MODE} and
- * {@link LocalOnlyHotspotCallback#ERROR_TETHERING_DISALLOWED}.
- * <p>
- * Internally, requests will be tracked to prevent the hotspot from being torn down while apps
- * are still using it. The {@link LocalOnlyHotspotReservation} object passed in the {@link
- * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call should be closed when
- * the LocalOnlyHotspot is no longer needed using {@link LocalOnlyHotspotReservation#close()}.
- * Since the hotspot may be shared among multiple applications, removing the final registered
- * application request will trigger the hotspot teardown. This means that applications should
- * not listen to broadcasts containing wifi state to determine if the hotspot was stopped after
- * they are done using it. Additionally, once {@link LocalOnlyHotspotReservation#close()} is
- * called, applications will not receive callbacks of any kind.
- * <p>
- * Applications should be aware that the user may also stop the LocalOnlyHotspot through the
- * Settings UI; it is not guaranteed to stay up as long as there is a requesting application.
- * The requestors will be notified of this case via
- * {@link LocalOnlyHotspotCallback#onStopped()}. Other cases may arise where the hotspot is
- * torn down (Emergency mode, etc). Application developers should be aware that it can stop
- * unexpectedly, but they will receive a notification if they have properly registered.
- * <p>
- * Applications should also be aware that this network will be shared with other applications.
- * Applications are responsible for protecting their data on this network (e.g., TLS).
- * <p>
- * Applications need to have the following permissions to start LocalOnlyHotspot: {@link
- * android.Manifest.permission#CHANGE_WIFI_STATE} and {@link
- * android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}. Callers without
- * the permissions will trigger a {@link java.lang.SecurityException}.
- * <p>
- * @param callback LocalOnlyHotspotCallback for the application to receive updates about
- * operating status.
- * @param handler Handler to be used for callbacks. If the caller passes a null Handler, the
- * main thread will be used.
- */
- @RequiresPermission(allOf = {
- android.Manifest.permission.CHANGE_WIFI_STATE,
- android.Manifest.permission.ACCESS_FINE_LOCATION})
- public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback,
- @Nullable Handler handler) {
- Executor executor = handler == null ? null : new HandlerExecutor(handler);
- startLocalOnlyHotspotInternal(null, executor, callback);
- }
-
- /**
- * Starts a local-only hotspot with a specific configuration applied. See
- * {@link #startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)}.
- *
- * Applications need either {@link android.Manifest.permission#NETWORK_SETUP_WIZARD} or
- * {@link android.Manifest.permission#NETWORK_SETTINGS} to call this method.
- *
- * Since custom configuration settings may be incompatible with each other, the hotspot started
- * through this method cannot coexist with another hotspot created through
- * startLocalOnlyHotspot. If this is attempted, the first hotspot request wins and others
- * receive {@link LocalOnlyHotspotCallback#ERROR_GENERIC} through
- * {@link LocalOnlyHotspotCallback#onFailed}.
- *
- * @param config Custom configuration for the hotspot. See {@link SoftApConfiguration}.
- * @param executor Executor to run callback methods on, or null to use the main thread.
- * @param callback Callback object for updates about hotspot status, or null for no updates.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD})
- public void startLocalOnlyHotspot(@NonNull SoftApConfiguration config,
- @Nullable Executor executor,
- @Nullable LocalOnlyHotspotCallback callback) {
- Objects.requireNonNull(config);
- startLocalOnlyHotspotInternal(config, executor, callback);
- }
-
- /**
- * Common implementation of both configurable and non-configurable LOHS.
- *
- * @param config App-specified configuration, or null. When present, additional privileges are
- * required, and the hotspot cannot be shared with other clients.
- * @param executor Executor to run callback methods on, or null to use the main thread.
- * @param callback Callback object for updates about hotspot status, or null for no updates.
- */
- private void startLocalOnlyHotspotInternal(
- @Nullable SoftApConfiguration config,
- @Nullable Executor executor,
- @Nullable LocalOnlyHotspotCallback callback) {
- if (executor == null) {
- executor = mContext.getMainExecutor();
- }
- synchronized (mLock) {
- LocalOnlyHotspotCallbackProxy proxy =
- new LocalOnlyHotspotCallbackProxy(this, executor, callback);
- try {
- String packageName = mContext.getOpPackageName();
- String featureId = mContext.getAttributionTag();
- int returnCode = mService.startLocalOnlyHotspot(proxy, packageName, featureId,
- config);
- if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) {
- // Send message to the proxy to make sure we call back on the correct thread
- proxy.onHotspotFailed(returnCode);
- return;
- }
- mLOHSCallbackProxy = proxy;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
- * Cancels a pending local only hotspot request. This can be used by the calling application to
- * cancel the existing request if the provided callback has not been triggered. Calling this
- * method will be equivalent to closing the returned LocalOnlyHotspotReservation, but it is not
- * explicitly required.
- * <p>
- * When cancelling this request, application developers should be aware that there may still be
- * outstanding local only hotspot requests and the hotspot may still start, or continue running.
- * Additionally, if a callback was registered, it will no longer be triggered after calling
- * cancel.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public void cancelLocalOnlyHotspotRequest() {
- synchronized (mLock) {
- stopLocalOnlyHotspot();
- }
- }
-
- /**
- * Method used to inform WifiService that the LocalOnlyHotspot is no longer needed. This
- * method is used by WifiManager to release LocalOnlyHotspotReservations held by calling
- * applications and removes the internal tracking for the hotspot request. When all requesting
- * applications are finished using the hotspot, it will be stopped and WiFi will return to the
- * previous operational mode.
- *
- * This method should not be called by applications. Instead, they should call the close()
- * method on their LocalOnlyHotspotReservation.
- */
- private void stopLocalOnlyHotspot() {
- synchronized (mLock) {
- if (mLOHSCallbackProxy == null) {
- // nothing to do, the callback was already cleaned up.
- return;
- }
- mLOHSCallbackProxy = null;
- try {
- mService.stopLocalOnlyHotspot();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
- * Allow callers (Settings UI) to watch LocalOnlyHotspot state changes. Callers will
- * receive a {@link LocalOnlyHotspotSubscription} object as a parameter of the
- * {@link LocalOnlyHotspotObserver#onRegistered(LocalOnlyHotspotSubscription)}. The registered
- * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(SoftApConfiguration)} and
- * {@link LocalOnlyHotspotObserver#onStopped()} callbacks.
- * <p>
- * Applications should have the
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}
- * permission. Callers without the permission will trigger a
- * {@link java.lang.SecurityException}.
- * <p>
- * @param observer LocalOnlyHotspotObserver callback.
- * @param handler Handler to use for callbacks
- *
- * @hide
- */
- public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer,
- @Nullable Handler handler) {
- Executor executor = handler == null ? mContext.getMainExecutor()
- : new HandlerExecutor(handler);
- synchronized (mLock) {
- mLOHSObserverProxy =
- new LocalOnlyHotspotObserverProxy(this, executor, observer);
- try {
- mService.startWatchLocalOnlyHotspot(mLOHSObserverProxy);
- mLOHSObserverProxy.registered();
- } catch (RemoteException e) {
- mLOHSObserverProxy = null;
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
- * Allow callers to stop watching LocalOnlyHotspot state changes. After calling this method,
- * applications will no longer receive callbacks.
- *
- * @hide
- */
- public void unregisterLocalOnlyHotspotObserver() {
- synchronized (mLock) {
- if (mLOHSObserverProxy == null) {
- // nothing to do, the callback was already cleaned up
- return;
- }
- mLOHSObserverProxy = null;
- try {
- mService.stopWatchLocalOnlyHotspot();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
- * Gets the tethered Wi-Fi hotspot enabled state.
- * @return One of {@link #WIFI_AP_STATE_DISABLED},
- * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
- * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
- * @see #isWifiApEnabled()
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
- public int getWifiApState() {
- try {
- return mService.getWifiApEnabledState();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return whether tethered Wi-Fi AP is enabled or disabled.
- * @return {@code true} if tethered Wi-Fi AP is enabled
- * @see #getWifiApState()
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
- public boolean isWifiApEnabled() {
- return getWifiApState() == WIFI_AP_STATE_ENABLED;
- }
-
- /**
- * Gets the tethered Wi-Fi AP Configuration.
- * @return AP details in WifiConfiguration
- *
- * Note that AP detail may contain configuration which is cannot be represented
- * by the legacy WifiConfiguration, in such cases a null will be returned.
- *
- * @deprecated This API is deprecated. Use {@link #getSoftApConfiguration()} instead.
- * @hide
- */
- @Nullable
- @SystemApi
- @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
- @Deprecated
- public WifiConfiguration getWifiApConfiguration() {
- try {
- return mService.getWifiApConfiguration();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Gets the Wi-Fi tethered AP Configuration.
- * @return AP details in {@link SoftApConfiguration}
- *
- * @hide
- */
- @NonNull
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public SoftApConfiguration getSoftApConfiguration() {
- try {
- return mService.getSoftApConfiguration();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Sets the tethered Wi-Fi AP Configuration.
- * @return {@code true} if the operation succeeded, {@code false} otherwise
- *
- * @deprecated This API is deprecated. Use {@link #setSoftApConfiguration(SoftApConfiguration)}
- * instead.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
- @Deprecated
- public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
- try {
- return mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Sets the tethered Wi-Fi AP Configuration.
- *
- * If the API is called while the tethered soft AP is enabled, the configuration will apply to
- * the current soft AP if the new configuration only includes
- * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)}
- * or {@link SoftApConfiguration.Builder#setShutdownTimeoutMillis(long)}
- * or {@link SoftApConfiguration.Builder#setClientControlByUserEnabled(boolean)}
- * or {@link SoftApConfiguration.Builder#setBlockedClientList(List)}
- * or {@link SoftApConfiguration.Builder#setAllowedClientList(List)}
- *
- * Otherwise, the configuration changes will be applied when the Soft AP is next started
- * (the framework will not stop/start the AP).
- *
- * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP.
- * @return {@code true} if the operation succeeded, {@code false} otherwise
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public boolean setSoftApConfiguration(@NonNull SoftApConfiguration softApConfig) {
- try {
- return mService.setSoftApConfiguration(
- softApConfig, mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Enable/Disable TDLS on a specific local route.
- *
- * <p>
- * TDLS enables two wireless endpoints to talk to each other directly
- * without going through the access point that is managing the local
- * network. It saves bandwidth and improves quality of the link.
- * </p>
- * <p>
- * This API enables/disables the option of using TDLS. If enabled, the
- * underlying hardware is free to use TDLS or a hop through the access
- * point. If disabled, existing TDLS session is torn down and
- * hardware is restricted to use access point for transferring wireless
- * packets. Default value for all routes is 'disabled', meaning restricted
- * to use access point for transferring packets.
- * </p>
- *
- * @param remoteIPAddress IP address of the endpoint to setup TDLS with
- * @param enable true = setup and false = tear down TDLS
- */
- public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) {
- try {
- mService.enableTdls(remoteIPAddress.getHostAddress(), enable);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Similar to {@link #setTdlsEnabled(InetAddress, boolean) }, except
- * this version allows you to specify remote endpoint with a MAC address.
- * @param remoteMacAddress MAC address of the remote endpoint such as 00:00:0c:9f:f2:ab
- * @param enable true = setup and false = tear down TDLS
- */
- public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) {
- try {
- mService.enableTdlsWithMacAddress(remoteMacAddress, enable);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Passed with {@link ActionListener#onFailure}.
- * Indicates that the operation failed due to an internal error.
- * @hide
- */
- public static final int ERROR = 0;
-
- /**
- * Passed with {@link ActionListener#onFailure}.
- * Indicates that the operation is already in progress
- * @hide
- */
- public static final int IN_PROGRESS = 1;
-
- /**
- * Passed with {@link ActionListener#onFailure}.
- * Indicates that the operation failed because the framework is busy and
- * unable to service the request
- * @hide
- */
- public static final int BUSY = 2;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({ERROR, IN_PROGRESS, BUSY})
- public @interface ActionListenerFailureReason {}
-
- /* WPS specific errors */
- /** WPS overlap detected
- * @deprecated This is deprecated
- */
- public static final int WPS_OVERLAP_ERROR = 3;
- /** WEP on WPS is prohibited
- * @deprecated This is deprecated
- */
- public static final int WPS_WEP_PROHIBITED = 4;
- /** TKIP only prohibited
- * @deprecated This is deprecated
- */
- public static final int WPS_TKIP_ONLY_PROHIBITED = 5;
- /** Authentication failure on WPS
- * @deprecated This is deprecated
- */
- public static final int WPS_AUTH_FAILURE = 6;
- /** WPS timed out
- * @deprecated This is deprecated
- */
- public static final int WPS_TIMED_OUT = 7;
-
- /**
- * Passed with {@link ActionListener#onFailure}.
- * Indicates that the operation failed due to invalid inputs
- * @hide
- */
- public static final int INVALID_ARGS = 8;
-
- /**
- * Passed with {@link ActionListener#onFailure}.
- * Indicates that the operation failed due to user permissions.
- * @hide
- */
- public static final int NOT_AUTHORIZED = 9;
-
- /**
- * Interface for callback invocation on an application action
- * @hide
- */
- @SystemApi
- public interface ActionListener {
- /**
- * The operation succeeded.
- */
- void onSuccess();
- /**
- * The operation failed.
- * @param reason The reason for failure depends on the operation.
- */
- void onFailure(@ActionListenerFailureReason int reason);
- }
-
- /** Interface for callback invocation on a start WPS action
- * @deprecated This is deprecated
- */
- public static abstract class WpsCallback {
-
- /** WPS start succeeded
- * @deprecated This API is deprecated
- */
- public abstract void onStarted(String pin);
-
- /** WPS operation completed successfully
- * @deprecated This API is deprecated
- */
- public abstract void onSucceeded();
-
- /**
- * WPS operation failed
- * @param reason The reason for failure could be one of
- * {@link #WPS_TKIP_ONLY_PROHIBITED}, {@link #WPS_OVERLAP_ERROR},
- * {@link #WPS_WEP_PROHIBITED}, {@link #WPS_TIMED_OUT} or {@link #WPS_AUTH_FAILURE}
- * and some generic errors.
- * @deprecated This API is deprecated
- */
- public abstract void onFailed(int reason);
- }
-
- /**
- * Base class for soft AP callback. Should be extended by applications and set when calling
- * {@link WifiManager#registerSoftApCallback(Executor, SoftApCallback)}.
- *
- * @hide
- */
- @SystemApi
- public interface SoftApCallback {
- /**
- * Called when soft AP state changes.
- *
- * @param state the new AP state. One of {@link #WIFI_AP_STATE_DISABLED},
- * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
- * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
- * @param failureReason reason when in failed state. One of
- * {@link #SAP_START_FAILURE_GENERAL},
- * {@link #SAP_START_FAILURE_NO_CHANNEL},
- * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}
- */
- default void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason) {}
-
- /**
- * Called when the connected clients to soft AP changes.
- *
- * @param clients the currently connected clients
- */
- default void onConnectedClientsChanged(@NonNull List<WifiClient> clients) {}
-
- /**
- * Called when information of softap changes.
- *
- * @param softApInfo is the softap information. {@link SoftApInfo}
- */
- default void onInfoChanged(@NonNull SoftApInfo softApInfo) {
- // Do nothing: can be updated to add SoftApInfo details (e.g. channel) to the UI.
- }
-
- /**
- * Called when capability of softap changes.
- *
- * @param softApCapability is the softap capability. {@link SoftApCapability}
- */
- default void onCapabilityChanged(@NonNull SoftApCapability softApCapability) {
- // Do nothing: can be updated to add SoftApCapability details (e.g. meximum supported
- // client number) to the UI.
- }
-
- /**
- * Called when client trying to connect but device blocked the client with specific reason.
- *
- * Can be used to ask user to update client to allowed list or blocked list
- * when reason is {@link SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER}, or
- * indicate the block due to maximum supported client number limitation when reason is
- * {@link SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS}.
- *
- * @param client the currently blocked client.
- * @param blockedReason one of blocked reason from {@link SapClientBlockedReason}
- */
- default void onBlockedClientConnecting(@NonNull WifiClient client,
- @SapClientBlockedReason int blockedReason) {
- // Do nothing: can be used to ask user to update client to allowed list or blocked list.
- }
- }
-
- /**
- * Callback proxy for SoftApCallback objects.
- *
- * @hide
- */
- private class SoftApCallbackProxy extends ISoftApCallback.Stub {
- private final Executor mExecutor;
- private final SoftApCallback mCallback;
-
- SoftApCallbackProxy(Executor executor, SoftApCallback callback) {
- mExecutor = executor;
- mCallback = callback;
- }
-
- @Override
- public void onStateChanged(int state, int failureReason) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "SoftApCallbackProxy: onStateChanged: state=" + state
- + ", failureReason=" + failureReason);
- }
-
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onStateChanged(state, failureReason);
- });
- }
-
- @Override
- public void onConnectedClientsChanged(List<WifiClient> clients) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "SoftApCallbackProxy: onConnectedClientsChanged: clients="
- + clients.size() + " clients");
- }
-
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onConnectedClientsChanged(clients);
- });
- }
-
- @Override
- public void onInfoChanged(SoftApInfo softApInfo) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "SoftApCallbackProxy: onInfoChange: softApInfo=" + softApInfo);
- }
-
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onInfoChanged(softApInfo);
- });
- }
-
- @Override
- public void onCapabilityChanged(SoftApCapability capability) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "SoftApCallbackProxy: onCapabilityChanged: SoftApCapability="
- + capability);
- }
-
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onCapabilityChanged(capability);
- });
- }
-
- @Override
- public void onBlockedClientConnecting(@NonNull WifiClient client, int blockedReason) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "SoftApCallbackProxy: onBlockedClientConnecting: client=" + client
- + " with reason = " + blockedReason);
- }
-
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onBlockedClientConnecting(client, blockedReason);
- });
- }
- }
-
- /**
- * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the
- * following callbacks on registration:
- * <ul>
- * <li> {@link SoftApCallback#onStateChanged(int, int)}</li>
- * <li> {@link SoftApCallback#onConnectedClientsChanged(List<WifiClient>)}</li>
- * <li> {@link SoftApCallback#onInfoChanged(SoftApInfo)}</li>
- * <li> {@link SoftApCallback#onCapabilityChanged(SoftApCapability)}</li>
- * </ul>
- * These will be dispatched on registration to provide the caller with the current state
- * (and are not an indication of any current change). Note that receiving an immediate
- * WIFI_AP_STATE_FAILED value for soft AP state indicates that the latest attempt to start
- * soft AP has failed. Caller can unregister a previously registered callback using
- * {@link #unregisterSoftApCallback}
- * <p>
- * Applications should have the
- * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers
- * without the permission will trigger a {@link java.lang.SecurityException}.
- * <p>
- *
- * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
- * object.
- * @param callback Callback for soft AP events
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void registerSoftApCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull SoftApCallback callback) {
- if (executor == null) throw new IllegalArgumentException("executor cannot be null");
- if (callback == null) throw new IllegalArgumentException("callback cannot be null");
- Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor);
-
- Binder binder = new Binder();
- try {
- mService.registerSoftApCallback(
- binder, new SoftApCallbackProxy(executor, callback), callback.hashCode());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Allow callers to unregister a previously registered callback. After calling this method,
- * applications will no longer receive soft AP events.
- *
- * @param callback Callback to unregister for soft AP events
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void unregisterSoftApCallback(@NonNull SoftApCallback callback) {
- if (callback == null) throw new IllegalArgumentException("callback cannot be null");
- Log.v(TAG, "unregisterSoftApCallback: callback=" + callback);
-
- try {
- mService.unregisterSoftApCallback(callback.hashCode());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * LocalOnlyHotspotReservation that contains the {@link SoftApConfiguration} for the active
- * LocalOnlyHotspot request.
- * <p>
- * Applications requesting LocalOnlyHotspot for sharing will receive an instance of the
- * LocalOnlyHotspotReservation in the
- * {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call. This
- * reservation contains the relevant {@link SoftApConfiguration}.
- * When an application is done with the LocalOnlyHotspot, they should call {@link
- * LocalOnlyHotspotReservation#close()}. Once this happens, the application will not receive
- * any further callbacks. If the LocalOnlyHotspot is stopped due to a
- * user triggered mode change, applications will be notified via the {@link
- * LocalOnlyHotspotCallback#onStopped()} callback.
- */
- public class LocalOnlyHotspotReservation implements AutoCloseable {
-
- private final CloseGuard mCloseGuard = new CloseGuard();
- private final SoftApConfiguration mSoftApConfig;
- private final WifiConfiguration mWifiConfig;
- private boolean mClosed = false;
-
- /** @hide */
- @VisibleForTesting
- public LocalOnlyHotspotReservation(SoftApConfiguration config) {
- mSoftApConfig = config;
- mWifiConfig = config.toWifiConfiguration();
- mCloseGuard.open("close");
- }
-
- /**
- * Returns the {@link WifiConfiguration} of the current Local Only Hotspot (LOHS).
- * May be null if hotspot enabled and security type is not
- * {@code WifiConfiguration.KeyMgmt.None} or {@code WifiConfiguration.KeyMgmt.WPA2_PSK}.
- *
- * @deprecated Use {@code WifiManager#getSoftApConfiguration()} to get the
- * LOHS configuration.
- */
- @Deprecated
- @Nullable
- public WifiConfiguration getWifiConfiguration() {
- return mWifiConfig;
- }
-
- /**
- * Returns the {@link SoftApConfiguration} of the current Local Only Hotspot (LOHS).
- */
- @NonNull
- public SoftApConfiguration getSoftApConfiguration() {
- return mSoftApConfig;
- }
-
- @Override
- public void close() {
- try {
- synchronized (mLock) {
- if (!mClosed) {
- mClosed = true;
- stopLocalOnlyHotspot();
- mCloseGuard.close();
- }
- }
- } catch (Exception e) {
- Log.e(TAG, "Failed to stop Local Only Hotspot.");
- } finally {
- Reference.reachabilityFence(this);
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mCloseGuard != null) {
- mCloseGuard.warnIfOpen();
- }
- close();
- } finally {
- super.finalize();
- }
- }
- }
-
- /**
- * Callback class for applications to receive updates about the LocalOnlyHotspot status.
- */
- public static class LocalOnlyHotspotCallback {
- /** @hide */
- public static final int REQUEST_REGISTERED = 0;
-
- public static final int ERROR_NO_CHANNEL = 1;
- public static final int ERROR_GENERIC = 2;
- public static final int ERROR_INCOMPATIBLE_MODE = 3;
- public static final int ERROR_TETHERING_DISALLOWED = 4;
-
- /** LocalOnlyHotspot start succeeded. */
- public void onStarted(LocalOnlyHotspotReservation reservation) {};
-
- /**
- * LocalOnlyHotspot stopped.
- * <p>
- * The LocalOnlyHotspot can be disabled at any time by the user. When this happens,
- * applications will be notified that it was stopped. This will not be invoked when an
- * application calls {@link LocalOnlyHotspotReservation#close()}.
- */
- public void onStopped() {};
-
- /**
- * LocalOnlyHotspot failed to start.
- * <p>
- * Applications can attempt to call
- * {@link WifiManager#startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)} again at
- * a later time.
- * <p>
- * @param reason The reason for failure could be one of: {@link
- * #ERROR_TETHERING_DISALLOWED}, {@link #ERROR_INCOMPATIBLE_MODE},
- * {@link #ERROR_NO_CHANNEL}, or {@link #ERROR_GENERIC}.
- */
- public void onFailed(int reason) { };
- }
-
- /**
- * Callback proxy for LocalOnlyHotspotCallback objects.
- */
- private static class LocalOnlyHotspotCallbackProxy extends ILocalOnlyHotspotCallback.Stub {
- private final WeakReference<WifiManager> mWifiManager;
- private final Executor mExecutor;
- private final LocalOnlyHotspotCallback mCallback;
-
- /**
- * Constructs a {@link LocalOnlyHotspotCallbackProxy} using the specified executor. All
- * callbacks will run using the given executor.
- *
- * @param manager WifiManager
- * @param executor Executor for delivering callbacks.
- * @param callback LocalOnlyHotspotCallback to notify the calling application, or null.
- */
- LocalOnlyHotspotCallbackProxy(
- @NonNull WifiManager manager,
- @NonNull Executor executor,
- @Nullable LocalOnlyHotspotCallback callback) {
- mWifiManager = new WeakReference<>(manager);
- mExecutor = executor;
- mCallback = callback;
- }
-
- @Override
- public void onHotspotStarted(SoftApConfiguration config) {
- WifiManager manager = mWifiManager.get();
- if (manager == null) return;
-
- if (config == null) {
- Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null.");
- onHotspotFailed(LocalOnlyHotspotCallback.ERROR_GENERIC);
- return;
- }
- final LocalOnlyHotspotReservation reservation =
- manager.new LocalOnlyHotspotReservation(config);
- if (mCallback == null) return;
- mExecutor.execute(() -> mCallback.onStarted(reservation));
- }
-
- @Override
- public void onHotspotStopped() {
- WifiManager manager = mWifiManager.get();
- if (manager == null) return;
-
- Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped");
- if (mCallback == null) return;
- mExecutor.execute(() -> mCallback.onStopped());
- }
-
- @Override
- public void onHotspotFailed(int reason) {
- WifiManager manager = mWifiManager.get();
- if (manager == null) return;
-
- Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: "
- + reason);
- if (mCallback == null) return;
- mExecutor.execute(() -> mCallback.onFailed(reason));
- }
- }
-
- /**
- * LocalOnlyHotspotSubscription that is an AutoCloseable object for tracking applications
- * watching for LocalOnlyHotspot changes.
- *
- * @hide
- */
- public class LocalOnlyHotspotSubscription implements AutoCloseable {
- private final CloseGuard mCloseGuard = new CloseGuard();
-
- /** @hide */
- @VisibleForTesting
- public LocalOnlyHotspotSubscription() {
- mCloseGuard.open("close");
- }
-
- @Override
- public void close() {
- try {
- unregisterLocalOnlyHotspotObserver();
- mCloseGuard.close();
- } catch (Exception e) {
- Log.e(TAG, "Failed to unregister LocalOnlyHotspotObserver.");
- } finally {
- Reference.reachabilityFence(this);
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mCloseGuard != null) {
- mCloseGuard.warnIfOpen();
- }
- close();
- } finally {
- super.finalize();
- }
- }
- }
-
- /**
- * Class to notify calling applications that watch for changes in LocalOnlyHotspot of updates.
- *
- * @hide
- */
- public static class LocalOnlyHotspotObserver {
- /**
- * Confirm registration for LocalOnlyHotspotChanges by returning a
- * LocalOnlyHotspotSubscription.
- */
- public void onRegistered(LocalOnlyHotspotSubscription subscription) {};
-
- /**
- * LocalOnlyHotspot started with the supplied config.
- */
- public void onStarted(SoftApConfiguration config) {};
-
- /**
- * LocalOnlyHotspot stopped.
- */
- public void onStopped() {};
- }
-
- /**
- * Callback proxy for LocalOnlyHotspotObserver objects.
- */
- private static class LocalOnlyHotspotObserverProxy extends ILocalOnlyHotspotCallback.Stub {
- private final WeakReference<WifiManager> mWifiManager;
- private final Executor mExecutor;
- private final LocalOnlyHotspotObserver mObserver;
-
- /**
- * Constructs a {@link LocalOnlyHotspotObserverProxy} using the specified looper.
- * All callbacks will be delivered on the thread of the specified looper.
- *
- * @param manager WifiManager
- * @param executor Executor for delivering callbacks
- * @param observer LocalOnlyHotspotObserver to notify the calling application.
- */
- LocalOnlyHotspotObserverProxy(WifiManager manager, Executor executor,
- final LocalOnlyHotspotObserver observer) {
- mWifiManager = new WeakReference<>(manager);
- mExecutor = executor;
- mObserver = observer;
- }
-
- public void registered() throws RemoteException {
- WifiManager manager = mWifiManager.get();
- if (manager == null) return;
-
- mExecutor.execute(() ->
- mObserver.onRegistered(manager.new LocalOnlyHotspotSubscription()));
- }
-
- @Override
- public void onHotspotStarted(SoftApConfiguration config) {
- WifiManager manager = mWifiManager.get();
- if (manager == null) return;
-
- if (config == null) {
- Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null.");
- return;
- }
- mExecutor.execute(() -> mObserver.onStarted(config));
- }
-
- @Override
- public void onHotspotStopped() {
- WifiManager manager = mWifiManager.get();
- if (manager == null) return;
-
- mExecutor.execute(() -> mObserver.onStopped());
- }
-
- @Override
- public void onHotspotFailed(int reason) {
- // do nothing
- }
- }
-
- /**
- * Callback proxy for ActionListener objects.
- */
- private class ActionListenerProxy extends IActionListener.Stub {
- private final String mActionTag;
- private final Handler mHandler;
- private final ActionListener mCallback;
-
- ActionListenerProxy(String actionTag, Looper looper, ActionListener callback) {
- mActionTag = actionTag;
- mHandler = new Handler(looper);
- mCallback = callback;
- }
-
- @Override
- public void onSuccess() {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onSuccess");
- }
- mHandler.post(() -> {
- mCallback.onSuccess();
- });
- }
-
- @Override
- public void onFailure(@ActionListenerFailureReason int reason) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onFailure=" + reason);
- }
- mHandler.post(() -> {
- mCallback.onFailure(reason);
- });
- }
- }
-
- private void connectInternal(@Nullable WifiConfiguration config, int networkId,
- @Nullable ActionListener listener) {
- ActionListenerProxy listenerProxy = null;
- Binder binder = null;
- if (listener != null) {
- listenerProxy = new ActionListenerProxy("connect", mLooper, listener);
- binder = new Binder();
- }
- try {
- mService.connect(config, networkId, binder, listenerProxy,
- listener == null ? 0 : listener.hashCode());
- } catch (RemoteException e) {
- if (listenerProxy != null) listenerProxy.onFailure(ERROR);
- } catch (SecurityException e) {
- if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
- }
- }
-
- /**
- * Connect to a network with the given configuration. The network also
- * gets added to the list of configured networks for the foreground user.
- *
- * For a new network, this function is used instead of a
- * sequence of addNetwork(), enableNetwork(), and reconnect()
- *
- * @param config the set of variables that describe the configuration,
- * contained in a {@link WifiConfiguration} object.
- * @param listener for callbacks on success or failure. Can be null.
- * @throws IllegalStateException if the WifiManager instance needs to be
- * initialized again
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK
- })
- public void connect(@NonNull WifiConfiguration config, @Nullable ActionListener listener) {
- if (config == null) throw new IllegalArgumentException("config cannot be null");
- connectInternal(config, WifiConfiguration.INVALID_NETWORK_ID, listener);
- }
-
- /**
- * Connect to a network with the given networkId.
- *
- * This function is used instead of a enableNetwork() and reconnect()
- *
- * <li> This API will cause reconnect if the credentials of the current active
- * connection has been changed.</li>
- * <li> This API will cause reconnect if the current active connection is marked metered.</li>
- *
- * @param networkId the ID of the network as returned by {@link #addNetwork} or {@link
- * getConfiguredNetworks}.
- * @param listener for callbacks on success or failure. Can be null.
- * @throws IllegalStateException if the WifiManager instance needs to be
- * initialized again
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK
- })
- public void connect(int networkId, @Nullable ActionListener listener) {
- if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
- connectInternal(null, networkId, listener);
- }
-
- /**
- * Save the given network to the list of configured networks for the
- * foreground user. If the network already exists, the configuration
- * is updated. Any new network is enabled by default.
- *
- * For a new network, this function is used instead of a
- * sequence of addNetwork() and enableNetwork().
- *
- * For an existing network, it accomplishes the task of updateNetwork()
- *
- * <li> This API will cause reconnect if the credentials of the current active
- * connection has been changed.</li>
- * <li> This API will cause disconnect if the current active connection is marked metered.</li>
- *
- * @param config the set of variables that describe the configuration,
- * contained in a {@link WifiConfiguration} object.
- * @param listener for callbacks on success or failure. Can be null.
- * @throws IllegalStateException if the WifiManager instance needs to be
- * initialized again
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK
- })
- public void save(@NonNull WifiConfiguration config, @Nullable ActionListener listener) {
- if (config == null) throw new IllegalArgumentException("config cannot be null");
- ActionListenerProxy listenerProxy = null;
- Binder binder = null;
- if (listener != null) {
- listenerProxy = new ActionListenerProxy("save", mLooper, listener);
- binder = new Binder();
- }
- try {
- mService.save(config, binder, listenerProxy,
- listener == null ? 0 : listener.hashCode());
- } catch (RemoteException e) {
- if (listenerProxy != null) listenerProxy.onFailure(ERROR);
- } catch (SecurityException e) {
- if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
- }
- }
-
- /**
- * Delete the network from the list of configured networks for the
- * foreground user.
- *
- * This function is used instead of a sequence of removeNetwork()
- *
- * @param config the set of variables that describe the configuration,
- * contained in a {@link WifiConfiguration} object.
- * @param listener for callbacks on success or failure. Can be null.
- * @throws IllegalStateException if the WifiManager instance needs to be
- * initialized again
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK
- })
- public void forget(int netId, @Nullable ActionListener listener) {
- if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
- ActionListenerProxy listenerProxy = null;
- Binder binder = null;
- if (listener != null) {
- listenerProxy = new ActionListenerProxy("forget", mLooper, listener);
- binder = new Binder();
- }
- try {
- mService.forget(netId, binder, listenerProxy,
- listener == null ? 0 : listener.hashCode());
- } catch (RemoteException e) {
- if (listenerProxy != null) listenerProxy.onFailure(ERROR);
- } catch (SecurityException e) {
- if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
- }
- }
-
- /**
- * Disable network
- *
- * @param netId is the network Id
- * @param listener for callbacks on success or failure. Can be null.
- * @throws IllegalStateException if the WifiManager instance needs to be
- * initialized again
- * @deprecated This API is deprecated. Use {@link #disableNetwork(int)} instead.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK
- })
- @Deprecated
- public void disable(int netId, @Nullable ActionListener listener) {
- if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
- // Simple wrapper which forwards the call to disableNetwork. This is a temporary
- // implementation until we can remove this API completely.
- boolean status = disableNetwork(netId);
- if (listener != null) {
- if (status) {
- listener.onSuccess();
- } else {
- listener.onFailure(ERROR);
- }
- }
- }
-
- /**
- * Enable/disable auto-join globally.
- *
- * @param allowAutojoin true to allow auto-join, false to disallow auto-join
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void allowAutojoinGlobal(boolean allowAutojoin) {
- try {
- mService.allowAutojoinGlobal(allowAutojoin);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
-
- /**
- * Sets the user choice for allowing auto-join to a network.
- * The updated choice will be made available through the updated config supplied by the
- * CONFIGURED_NETWORKS_CHANGED broadcast.
- *
- * @param netId the id of the network to allow/disallow auto-join for.
- * @param allowAutojoin true to allow auto-join, false to disallow auto-join
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void allowAutojoin(int netId, boolean allowAutojoin) {
- try {
- mService.allowAutojoin(netId, allowAutojoin);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Configure auto-join settings for a Passpoint profile.
- *
- * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile.
- * @param allowAutojoin true to enable auto-join, false to disable auto-join.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void allowAutojoinPasspoint(@NonNull String fqdn, boolean allowAutojoin) {
- try {
- mService.allowAutojoinPasspoint(fqdn, allowAutojoin);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Configure MAC randomization setting for a Passpoint profile.
- * MAC randomization is enabled by default.
- *
- * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile.
- * @param enable true to enable MAC randomization, false to disable MAC randomization.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void setMacRandomizationSettingPasspointEnabled(@NonNull String fqdn, boolean enable) {
- try {
- mService.setMacRandomizationSettingPasspointEnabled(fqdn, enable);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Sets the user's choice of metered override for a Passpoint profile.
- *
- * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile.
- * @param meteredOverride One of three values: {@link WifiConfiguration#METERED_OVERRIDE_NONE},
- * {@link WifiConfiguration#METERED_OVERRIDE_METERED},
- * {@link WifiConfiguration#METERED_OVERRIDE_NOT_METERED}
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void setPasspointMeteredOverride(@NonNull String fqdn,
- @WifiConfiguration.MeteredOverride int meteredOverride) {
- try {
- mService.setPasspointMeteredOverride(fqdn, meteredOverride);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Temporarily disable a network. Should always trigger with user disconnect network.
- *
- * @param network Input can be SSID or FQDN. And caller must ensure that the SSID passed thru
- * this API matched the WifiConfiguration.SSID rules, and thus be surrounded by
- * quotes.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_STACK
- })
- public void disableEphemeralNetwork(@NonNull String network) {
- if (TextUtils.isEmpty(network)) {
- throw new IllegalArgumentException("SSID cannot be null or empty!");
- }
- try {
- mService.disableEphemeralNetwork(network, mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * WPS suport has been deprecated from Client mode and this method will immediately trigger
- * {@link WpsCallback#onFailed(int)} with a generic error.
- *
- * @param config WPS configuration (does not support {@link WpsInfo#LABEL})
- * @param listener for callbacks on success or failure. Can be null.
- * @throws IllegalStateException if the WifiManager instance needs to be initialized again
- * @deprecated This API is deprecated
- */
- public void startWps(WpsInfo config, WpsCallback listener) {
- if (listener != null ) {
- listener.onFailed(ERROR);
- }
- }
-
- /**
- * WPS support has been deprecated from Client mode and this method will immediately trigger
- * {@link WpsCallback#onFailed(int)} with a generic error.
- *
- * @param listener for callbacks on success or failure. Can be null.
- * @throws IllegalStateException if the WifiManager instance needs to be initialized again
- * @deprecated This API is deprecated
- */
- public void cancelWps(WpsCallback listener) {
- if (listener != null) {
- listener.onFailed(ERROR);
- }
- }
-
- /**
- * Allows an application to keep the Wi-Fi radio awake.
- * Normally the Wi-Fi radio may turn off when the user has not used the device in a while.
- * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple
- * applications may hold WifiLocks, and the radio will only be allowed to turn off when no
- * WifiLocks are held in any application.
- * <p>
- * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or
- * could function over a mobile network, if available. A program that needs to download large
- * files should hold a WifiLock to ensure that the download will complete, but a program whose
- * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely
- * affecting battery life.
- * <p>
- * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane
- * Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device
- * is idle.
- * <p>
- * Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK}
- * permission in an {@code <uses-permission>} element of the application's manifest.
- */
- public class WifiLock {
- private String mTag;
- private final IBinder mBinder;
- private int mRefCount;
- int mLockType;
- private boolean mRefCounted;
- private boolean mHeld;
- private WorkSource mWorkSource;
-
- private WifiLock(int lockType, String tag) {
- mTag = tag;
- mLockType = lockType;
- mBinder = new Binder();
- mRefCount = 0;
- mRefCounted = true;
- mHeld = false;
- }
-
- /**
- * Locks the Wi-Fi radio on until {@link #release} is called.
- *
- * If this WifiLock is reference-counted, each call to {@code acquire} will increment the
- * reference count, and the radio will remain locked as long as the reference count is
- * above zero.
- *
- * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock
- * the radio, but subsequent calls will be ignored. Only one call to {@link #release}
- * will be required, regardless of the number of times that {@code acquire} is called.
- */
- public void acquire() {
- synchronized (mBinder) {
- if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
- try {
- mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource);
- synchronized (WifiManager.this) {
- if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
- mService.releaseWifiLock(mBinder);
- throw new UnsupportedOperationException(
- "Exceeded maximum number of wifi locks");
- }
- mActiveLockCount++;
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- mHeld = true;
- }
- }
- }
-
- /**
- * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle.
- *
- * If this WifiLock is reference-counted, each call to {@code release} will decrement the
- * reference count, and the radio will be unlocked only when the reference count reaches
- * zero. If the reference count goes below zero (that is, if {@code release} is called
- * a greater number of times than {@link #acquire}), an exception is thrown.
- *
- * If this WifiLock is not reference-counted, the first call to {@code release} (after
- * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent
- * calls will be ignored.
- */
- public void release() {
- synchronized (mBinder) {
- if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
- try {
- mService.releaseWifiLock(mBinder);
- synchronized (WifiManager.this) {
- mActiveLockCount--;
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- mHeld = false;
- }
- if (mRefCount < 0) {
- throw new RuntimeException("WifiLock under-locked " + mTag);
- }
- }
- }
-
- /**
- * Controls whether this is a reference-counted or non-reference-counted WifiLock.
- *
- * Reference-counted WifiLocks keep track of the number of calls to {@link #acquire} and
- * {@link #release}, and only allow the radio to sleep when every call to {@link #acquire}
- * has been balanced with a call to {@link #release}. Non-reference-counted WifiLocks
- * lock the radio whenever {@link #acquire} is called and it is unlocked, and unlock the
- * radio whenever {@link #release} is called and it is locked.
- *
- * @param refCounted true if this WifiLock should keep a reference count
- */
- public void setReferenceCounted(boolean refCounted) {
- mRefCounted = refCounted;
- }
-
- /**
- * Checks whether this WifiLock is currently held.
- *
- * @return true if this WifiLock is held, false otherwise
- */
- public boolean isHeld() {
- synchronized (mBinder) {
- return mHeld;
- }
- }
-
- public void setWorkSource(WorkSource ws) {
- synchronized (mBinder) {
- if (ws != null && ws.isEmpty()) {
- ws = null;
- }
- boolean changed = true;
- if (ws == null) {
- mWorkSource = null;
- } else {
- ws = ws.withoutNames();
- if (mWorkSource == null) {
- changed = mWorkSource != null;
- mWorkSource = new WorkSource(ws);
- } else {
- changed = !mWorkSource.equals(ws);
- if (changed) {
- mWorkSource.set(ws);
- }
- }
- }
- if (changed && mHeld) {
- try {
- mService.updateWifiLockWorkSource(mBinder, mWorkSource);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
- }
-
- public String toString() {
- String s1, s2, s3;
- synchronized (mBinder) {
- s1 = Integer.toHexString(System.identityHashCode(this));
- s2 = mHeld ? "held; " : "";
- if (mRefCounted) {
- s3 = "refcounted: refcount = " + mRefCount;
- } else {
- s3 = "not refcounted";
- }
- return "WifiLock{ " + s1 + "; " + s2 + s3 + " }";
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- super.finalize();
- synchronized (mBinder) {
- if (mHeld) {
- try {
- mService.releaseWifiLock(mBinder);
- synchronized (WifiManager.this) {
- mActiveLockCount--;
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
- }
- }
-
- /**
- * Creates a new WifiLock.
- *
- * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL_HIGH_PERF}
- * and {@link #WIFI_MODE_FULL_LOW_LATENCY} for descriptions of the types of Wi-Fi locks.
- * @param tag a tag for the WifiLock to identify it in debugging messages. This string is
- * never shown to the user under normal conditions, but should be descriptive
- * enough to identify your application and the specific WifiLock within it, if it
- * holds multiple WifiLocks.
- *
- * @return a new, unacquired WifiLock with the given tag.
- *
- * @see WifiLock
- */
- public WifiLock createWifiLock(int lockType, String tag) {
- return new WifiLock(lockType, tag);
- }
-
- /**
- * Creates a new WifiLock.
- *
- * @param tag a tag for the WifiLock to identify it in debugging messages. This string is
- * never shown to the user under normal conditions, but should be descriptive
- * enough to identify your application and the specific WifiLock within it, if it
- * holds multiple WifiLocks.
- *
- * @return a new, unacquired WifiLock with the given tag.
- *
- * @see WifiLock
- *
- * @deprecated This API is non-functional.
- */
- @Deprecated
- public WifiLock createWifiLock(String tag) {
- return new WifiLock(WIFI_MODE_FULL, tag);
- }
-
- /**
- * Create a new MulticastLock
- *
- * @param tag a tag for the MulticastLock to identify it in debugging
- * messages. This string is never shown to the user under
- * normal conditions, but should be descriptive enough to
- * identify your application and the specific MulticastLock
- * within it, if it holds multiple MulticastLocks.
- *
- * @return a new, unacquired MulticastLock with the given tag.
- *
- * @see MulticastLock
- */
- public MulticastLock createMulticastLock(String tag) {
- return new MulticastLock(tag);
- }
-
- /**
- * Allows an application to receive Wifi Multicast packets.
- * Normally the Wifi stack filters out packets not explicitly
- * addressed to this device. Acquring a MulticastLock will
- * cause the stack to receive packets addressed to multicast
- * addresses. Processing these extra packets can cause a noticeable
- * battery drain and should be disabled when not needed.
- */
- public class MulticastLock {
- private String mTag;
- private final IBinder mBinder;
- private int mRefCount;
- private boolean mRefCounted;
- private boolean mHeld;
-
- private MulticastLock(String tag) {
- mTag = tag;
- mBinder = new Binder();
- mRefCount = 0;
- mRefCounted = true;
- mHeld = false;
- }
-
- /**
- * Locks Wifi Multicast on until {@link #release} is called.
- *
- * If this MulticastLock is reference-counted each call to
- * {@code acquire} will increment the reference count, and the
- * wifi interface will receive multicast packets as long as the
- * reference count is above zero.
- *
- * If this MulticastLock is not reference-counted, the first call to
- * {@code acquire} will turn on the multicast packets, but subsequent
- * calls will be ignored. Only one call to {@link #release} will
- * be required, regardless of the number of times that {@code acquire}
- * is called.
- *
- * Note that other applications may also lock Wifi Multicast on.
- * Only they can relinquish their lock.
- *
- * Also note that applications cannot leave Multicast locked on.
- * When an app exits or crashes, any Multicast locks will be released.
- */
- public void acquire() {
- synchronized (mBinder) {
- if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
- try {
- mService.acquireMulticastLock(mBinder, mTag);
- synchronized (WifiManager.this) {
- if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
- mService.releaseMulticastLock(mTag);
- throw new UnsupportedOperationException(
- "Exceeded maximum number of wifi locks");
- }
- mActiveLockCount++;
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- mHeld = true;
- }
- }
- }
-
- /**
- * Unlocks Wifi Multicast, restoring the filter of packets
- * not addressed specifically to this device and saving power.
- *
- * If this MulticastLock is reference-counted, each call to
- * {@code release} will decrement the reference count, and the
- * multicast packets will only stop being received when the reference
- * count reaches zero. If the reference count goes below zero (that
- * is, if {@code release} is called a greater number of times than
- * {@link #acquire}), an exception is thrown.
- *
- * If this MulticastLock is not reference-counted, the first call to
- * {@code release} (after the radio was multicast locked using
- * {@link #acquire}) will unlock the multicast, and subsequent calls
- * will be ignored.
- *
- * Note that if any other Wifi Multicast Locks are still outstanding
- * this {@code release} call will not have an immediate effect. Only
- * when all applications have released all their Multicast Locks will
- * the Multicast filter be turned back on.
- *
- * Also note that when an app exits or crashes all of its Multicast
- * Locks will be automatically released.
- */
- public void release() {
- synchronized (mBinder) {
- if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
- try {
- mService.releaseMulticastLock(mTag);
- synchronized (WifiManager.this) {
- mActiveLockCount--;
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- mHeld = false;
- }
- if (mRefCount < 0) {
- throw new RuntimeException("MulticastLock under-locked "
- + mTag);
- }
- }
- }
-
- /**
- * Controls whether this is a reference-counted or non-reference-
- * counted MulticastLock.
- *
- * Reference-counted MulticastLocks keep track of the number of calls
- * to {@link #acquire} and {@link #release}, and only stop the
- * reception of multicast packets when every call to {@link #acquire}
- * has been balanced with a call to {@link #release}. Non-reference-
- * counted MulticastLocks allow the reception of multicast packets
- * whenever {@link #acquire} is called and stop accepting multicast
- * packets whenever {@link #release} is called.
- *
- * @param refCounted true if this MulticastLock should keep a reference
- * count
- */
- public void setReferenceCounted(boolean refCounted) {
- mRefCounted = refCounted;
- }
-
- /**
- * Checks whether this MulticastLock is currently held.
- *
- * @return true if this MulticastLock is held, false otherwise
- */
- public boolean isHeld() {
- synchronized (mBinder) {
- return mHeld;
- }
- }
-
- public String toString() {
- String s1, s2, s3;
- synchronized (mBinder) {
- s1 = Integer.toHexString(System.identityHashCode(this));
- s2 = mHeld ? "held; " : "";
- if (mRefCounted) {
- s3 = "refcounted: refcount = " + mRefCount;
- } else {
- s3 = "not refcounted";
- }
- return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }";
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- super.finalize();
- setReferenceCounted(false);
- release();
- }
- }
-
- /**
- * Check multicast filter status.
- *
- * @return true if multicast packets are allowed.
- *
- * @hide pending API council approval
- */
- public boolean isMulticastEnabled() {
- try {
- return mService.isMulticastEnabled();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Initialize the multicast filtering to 'on'
- * @hide no intent to publish
- */
- @UnsupportedAppUsage
- public boolean initializeMulticastFiltering() {
- try {
- mService.initializeMulticastFiltering();
- return true;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Set Wi-Fi verbose logging level from developer settings.
- *
- * @param enable true to enable verbose logging, false to disable.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void setVerboseLoggingEnabled(boolean enable) {
- enableVerboseLogging(enable ? 1 : 0);
- }
-
- /** @hide */
- @UnsupportedAppUsage(
- maxTargetSdk = Build.VERSION_CODES.Q,
- publicAlternatives = "Use {@code #setVerboseLoggingEnabled(boolean)} instead."
- )
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void enableVerboseLogging (int verbose) {
- try {
- mService.enableVerboseLogging(verbose);
- } catch (Exception e) {
- //ignore any failure here
- Log.e(TAG, "enableVerboseLogging " + e.toString());
- }
- }
-
- /**
- * Get the persisted Wi-Fi verbose logging level, set by
- * {@link #setVerboseLoggingEnabled(boolean)}.
- * No permissions are required to call this method.
- *
- * @return true to indicate that verbose logging is enabled, false to indicate that verbose
- * logging is disabled.
- *
- * @hide
- */
- @SystemApi
- public boolean isVerboseLoggingEnabled() {
- return getVerboseLoggingLevel() > 0;
- }
-
- /** @hide */
- // TODO(b/145484145): remove once SUW stops calling this via reflection
- @UnsupportedAppUsage(
- maxTargetSdk = Build.VERSION_CODES.Q,
- publicAlternatives = "Use {@code #isVerboseLoggingEnabled()} instead."
- )
- public int getVerboseLoggingLevel() {
- try {
- return mService.getVerboseLoggingLevel();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Removes all saved Wi-Fi networks, Passpoint configurations, ephemeral networks, Network
- * Requests, and Network Suggestions.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void factoryReset() {
- try {
- mService.factoryReset(mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get {@link Network} object of current wifi network, or null if not connected.
- * @hide
- */
- @Nullable
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD
- })
- public Network getCurrentNetwork() {
- try {
- return mService.getCurrentNetwork();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Deprecated
- * returns false
- * @hide
- * @deprecated
- */
- public boolean setEnableAutoJoinWhenAssociated(boolean enabled) {
- return false;
- }
-
- /**
- * Deprecated
- * returns false
- * @hide
- * @deprecated
- */
- public boolean getEnableAutoJoinWhenAssociated() {
- return false;
- }
-
- /**
- * Returns a byte stream representing the data that needs to be backed up to save the
- * current Wifi state.
- * This Wifi state can be restored by calling {@link #restoreBackupData(byte[])}.
- * @hide
- */
- @NonNull
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public byte[] retrieveBackupData() {
- try {
- return mService.retrieveBackupData();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Restore state from the backed up data.
- * @param data byte stream in the same format produced by {@link #retrieveBackupData()}
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void restoreBackupData(@NonNull byte[] data) {
- try {
- mService.restoreBackupData(data);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns a byte stream representing the data that needs to be backed up to save the
- * current soft ap config data.
- *
- * This soft ap config can be restored by calling {@link #restoreSoftApBackupData(byte[])}
- * @hide
- */
- @NonNull
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public byte[] retrieveSoftApBackupData() {
- try {
- return mService.retrieveSoftApBackupData();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns soft ap config from the backed up data or null if data is invalid.
- * @param data byte stream in the same format produced by {@link #retrieveSoftApBackupData()}
- *
- * @hide
- */
- @Nullable
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public SoftApConfiguration restoreSoftApBackupData(@NonNull byte[] data) {
- try {
- return mService.restoreSoftApBackupData(data);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Restore state from the older version of back up data.
- * The old backup data was essentially a backup of wpa_supplicant.conf
- * and ipconfig.txt file.
- * @param supplicantData bytes representing wpa_supplicant.conf
- * @param ipConfigData bytes representing ipconfig.txt
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void restoreSupplicantBackupData(
- @NonNull byte[] supplicantData, @NonNull byte[] ipConfigData) {
- try {
- mService.restoreSupplicantBackupData(supplicantData, ipConfigData);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Start subscription provisioning flow
- *
- * @param provider {@link OsuProvider} to provision with
- * @param executor the Executor on which to run the callback.
- * @param callback {@link ProvisioningCallback} for updates regarding provisioning flow
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD
- })
- public void startSubscriptionProvisioning(@NonNull OsuProvider provider,
- @NonNull @CallbackExecutor Executor executor, @NonNull ProvisioningCallback callback) {
- // Verify arguments
- if (executor == null) {
- throw new IllegalArgumentException("executor must not be null");
- }
- if (callback == null) {
- throw new IllegalArgumentException("callback must not be null");
- }
- try {
- mService.startSubscriptionProvisioning(provider,
- new ProvisioningCallbackProxy(executor, callback));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Helper class to support OSU Provisioning callbacks
- */
- private static class ProvisioningCallbackProxy extends IProvisioningCallback.Stub {
- private final Executor mExecutor;
- private final ProvisioningCallback mCallback;
-
- ProvisioningCallbackProxy(Executor executor, ProvisioningCallback callback) {
- mExecutor = executor;
- mCallback = callback;
- }
-
- @Override
- public void onProvisioningStatus(int status) {
- mExecutor.execute(() -> mCallback.onProvisioningStatus(status));
- }
-
- @Override
- public void onProvisioningFailure(int status) {
- mExecutor.execute(() -> mCallback.onProvisioningFailure(status));
- }
-
- @Override
- public void onProvisioningComplete() {
- mExecutor.execute(() -> mCallback.onProvisioningComplete());
- }
- }
-
- /**
- * Interface for Traffic state callback. Should be extended by applications and set when
- * calling {@link #registerTrafficStateCallback(Executor, WifiManager.TrafficStateCallback)}.
- * @hide
- */
- @SystemApi
- public interface TrafficStateCallback {
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"DATA_ACTIVITY_"}, value = {
- DATA_ACTIVITY_NONE,
- DATA_ACTIVITY_IN,
- DATA_ACTIVITY_OUT,
- DATA_ACTIVITY_INOUT})
- @interface DataActivity {}
-
- // Lowest bit indicates data reception and the second lowest bit indicates data transmitted
- /** No data in or out */
- int DATA_ACTIVITY_NONE = 0x00;
- /** Data in, no data out */
- int DATA_ACTIVITY_IN = 0x01;
- /** Data out, no data in */
- int DATA_ACTIVITY_OUT = 0x02;
- /** Data in and out */
- int DATA_ACTIVITY_INOUT = 0x03;
-
- /**
- * Callback invoked to inform clients about the current traffic state.
- *
- * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN},
- * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}.
- */
- void onStateChanged(@DataActivity int state);
- }
-
- /**
- * Callback proxy for TrafficStateCallback objects.
- *
- * @hide
- */
- private class TrafficStateCallbackProxy extends ITrafficStateCallback.Stub {
- private final Executor mExecutor;
- private final TrafficStateCallback mCallback;
-
- TrafficStateCallbackProxy(Executor executor, TrafficStateCallback callback) {
- mExecutor = executor;
- mCallback = callback;
- }
-
- @Override
- public void onStateChanged(int state) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "TrafficStateCallbackProxy: onStateChanged state=" + state);
- }
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mCallback.onStateChanged(state);
- });
- }
- }
-
- /**
- * Registers a callback for monitoring traffic state. See {@link TrafficStateCallback}. These
- * callbacks will be invoked periodically by platform to inform clients about the current
- * traffic state. Caller can unregister a previously registered callback using
- * {@link #unregisterTrafficStateCallback(TrafficStateCallback)}
- * <p>
- * Applications should have the
- * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers
- * without the permission will trigger a {@link java.lang.SecurityException}.
- * <p>
- *
- * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
- * object.
- * @param callback Callback for traffic state events
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void registerTrafficStateCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull TrafficStateCallback callback) {
- if (executor == null) throw new IllegalArgumentException("executor cannot be null");
- if (callback == null) throw new IllegalArgumentException("callback cannot be null");
- Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", executor=" + executor);
-
- Binder binder = new Binder();
- try {
- mService.registerTrafficStateCallback(
- binder, new TrafficStateCallbackProxy(executor, callback), callback.hashCode());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Allow callers to unregister a previously registered callback. After calling this method,
- * applications will no longer receive traffic state notifications.
- *
- * @param callback Callback to unregister for traffic state events
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void unregisterTrafficStateCallback(@NonNull TrafficStateCallback callback) {
- if (callback == null) throw new IllegalArgumentException("callback cannot be null");
- Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback);
-
- try {
- mService.unregisterTrafficStateCallback(callback.hashCode());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Helper method to update the local verbose logging flag based on the verbose logging
- * level from wifi service.
- */
- private void updateVerboseLoggingEnabledFromService() {
- mVerboseLoggingEnabled = isVerboseLoggingEnabled();
- }
-
- /**
- * @return true if this device supports WPA3-Personal SAE
- */
- public boolean isWpa3SaeSupported() {
- return isFeatureSupported(WIFI_FEATURE_WPA3_SAE);
- }
-
- /**
- * @return true if this device supports WPA3-Enterprise Suite-B-192
- */
- public boolean isWpa3SuiteBSupported() {
- return isFeatureSupported(WIFI_FEATURE_WPA3_SUITE_B);
- }
-
- /**
- * @return true if this device supports Wi-Fi Enhanced Open (OWE)
- */
- public boolean isEnhancedOpenSupported() {
- return isFeatureSupported(WIFI_FEATURE_OWE);
- }
-
- /**
- * Wi-Fi Easy Connect (DPP) introduces standardized mechanisms to simplify the provisioning and
- * configuration of Wi-Fi devices.
- * For more details, visit <a href="https://www.wi-fi.org/">https://www.wi-fi.org/</a> and
- * search for "Easy Connect" or "Device Provisioning Protocol specification".
- *
- * @return true if this device supports Wi-Fi Easy-connect (Device Provisioning Protocol)
- */
- public boolean isEasyConnectSupported() {
- return isFeatureSupported(WIFI_FEATURE_DPP);
- }
-
- /**
- * @return true if this device supports WAPI.
- */
- public boolean isWapiSupported() {
- return isFeatureSupported(WIFI_FEATURE_WAPI);
- }
-
- /**
- * Gets the factory Wi-Fi MAC addresses.
- * @return Array of String representing Wi-Fi MAC addresses sorted lexically or an empty Array
- * if failed.
- * @hide
- */
- @NonNull
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public String[] getFactoryMacAddresses() {
- try {
- return mService.getFactoryMacAddresses();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"DEVICE_MOBILITY_STATE_"}, value = {
- DEVICE_MOBILITY_STATE_UNKNOWN,
- DEVICE_MOBILITY_STATE_HIGH_MVMT,
- DEVICE_MOBILITY_STATE_LOW_MVMT,
- DEVICE_MOBILITY_STATE_STATIONARY})
- public @interface DeviceMobilityState {}
-
- /**
- * Unknown device mobility state
- *
- * @see #setDeviceMobilityState(int)
- *
- * @hide
- */
- @SystemApi
- public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0;
-
- /**
- * High movement device mobility state.
- * e.g. on a bike, in a motor vehicle
- *
- * @see #setDeviceMobilityState(int)
- *
- * @hide
- */
- @SystemApi
- public static final int DEVICE_MOBILITY_STATE_HIGH_MVMT = 1;
-
- /**
- * Low movement device mobility state.
- * e.g. walking, running
- *
- * @see #setDeviceMobilityState(int)
- *
- * @hide
- */
- @SystemApi
- public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2;
-
- /**
- * Stationary device mobility state
- *
- * @see #setDeviceMobilityState(int)
- *
- * @hide
- */
- @SystemApi
- public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3;
-
- /**
- * Updates the device mobility state. Wifi uses this information to adjust the interval between
- * Wifi scans in order to balance power consumption with scan accuracy.
- * The default mobility state when the device boots is {@link #DEVICE_MOBILITY_STATE_UNKNOWN}.
- * This API should be called whenever there is a change in the mobility state.
- * @param state the updated device mobility state
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE)
- public void setDeviceMobilityState(@DeviceMobilityState int state) {
- try {
- mService.setDeviceMobilityState(state);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /* Easy Connect - AKA Device Provisioning Protocol (DPP) */
-
- /**
- * Easy Connect Network role: Station.
- *
- * @hide
- */
- @SystemApi
- public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0;
-
- /**
- * Easy Connect Network role: Access Point.
- *
- * @hide
- */
- @SystemApi
- public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1;
-
- /** @hide */
- @IntDef(prefix = {"EASY_CONNECT_NETWORK_ROLE_"}, value = {
- EASY_CONNECT_NETWORK_ROLE_STA,
- EASY_CONNECT_NETWORK_ROLE_AP,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface EasyConnectNetworkRole {
- }
-
- /**
- * Start Easy Connect (DPP) in Configurator-Initiator role. The current device will initiate
- * Easy Connect bootstrapping with a peer, and configure the peer with the SSID and password of
- * the specified network using the Easy Connect protocol on an encrypted link.
- *
- * @param enrolleeUri URI of the Enrollee obtained separately (e.g. QR code scanning)
- * @param selectedNetworkId Selected network ID to be sent to the peer
- * @param enrolleeNetworkRole The network role of the enrollee
- * @param callback Callback for status updates
- * @param executor The Executor on which to run the callback.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD})
- public void startEasyConnectAsConfiguratorInitiator(@NonNull String enrolleeUri,
- int selectedNetworkId, @EasyConnectNetworkRole int enrolleeNetworkRole,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull EasyConnectStatusCallback callback) {
- Binder binder = new Binder();
- try {
- mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId,
- enrolleeNetworkRole, new EasyConnectCallbackProxy(executor, callback));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Start Easy Connect (DPP) in Enrollee-Initiator role. The current device will initiate Easy
- * Connect bootstrapping with a peer, and receive the SSID and password from the peer
- * configurator.
- *
- * @param configuratorUri URI of the Configurator obtained separately (e.g. QR code scanning)
- * @param callback Callback for status updates
- * @param executor The Executor on which to run the callback.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD})
- public void startEasyConnectAsEnrolleeInitiator(@NonNull String configuratorUri,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull EasyConnectStatusCallback callback) {
- Binder binder = new Binder();
- try {
- mService.startDppAsEnrolleeInitiator(binder, configuratorUri,
- new EasyConnectCallbackProxy(executor, callback));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Stop or abort a current Easy Connect (DPP) session. This call, once processed, will
- * terminate any ongoing transaction, and clean up all associated resources. Caller should not
- * expect any callbacks once this call is made. However, due to the asynchronous nature of
- * this call, a callback may be fired if it was already pending in the queue.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD})
- public void stopEasyConnectSession() {
- try {
- /* Request lower layers to stop/abort and clear resources */
- mService.stopDppSession();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Helper class to support Easy Connect (DPP) callbacks
- *
- * @hide
- */
- private static class EasyConnectCallbackProxy extends IDppCallback.Stub {
- private final Executor mExecutor;
- private final EasyConnectStatusCallback mEasyConnectStatusCallback;
-
- EasyConnectCallbackProxy(Executor executor,
- EasyConnectStatusCallback easyConnectStatusCallback) {
- mExecutor = executor;
- mEasyConnectStatusCallback = easyConnectStatusCallback;
- }
-
- @Override
- public void onSuccessConfigReceived(int newNetworkId) {
- Log.d(TAG, "Easy Connect onSuccessConfigReceived callback");
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mEasyConnectStatusCallback.onEnrolleeSuccess(newNetworkId);
- });
- }
-
- @Override
- public void onSuccess(int status) {
- Log.d(TAG, "Easy Connect onSuccess callback");
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mEasyConnectStatusCallback.onConfiguratorSuccess(status);
- });
- }
-
- @Override
- public void onFailure(int status, String ssid, String channelList,
- int[] operatingClassArray) {
- Log.d(TAG, "Easy Connect onFailure callback");
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- SparseArray<int[]> channelListArray = parseDppChannelList(channelList);
- mEasyConnectStatusCallback.onFailure(status, ssid, channelListArray,
- operatingClassArray);
- });
- }
-
- @Override
- public void onProgress(int status) {
- Log.d(TAG, "Easy Connect onProgress callback");
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> {
- mEasyConnectStatusCallback.onProgress(status);
- });
- }
- }
-
- /**
- * Interface for Wi-Fi usability statistics listener. Should be implemented by applications and
- * set when calling {@link WifiManager#addOnWifiUsabilityStatsListener(Executor,
- * OnWifiUsabilityStatsListener)}.
- *
- * @hide
- */
- @SystemApi
- public interface OnWifiUsabilityStatsListener {
- /**
- * Called when Wi-Fi usability statistics is updated.
- *
- * @param seqNum The sequence number of statistics, used to derive the timing of updated
- * Wi-Fi usability statistics, set by framework and incremented by one after
- * each update.
- * @param isSameBssidAndFreq The flag to indicate whether the BSSID and the frequency of
- * network stays the same or not relative to the last update of
- * Wi-Fi usability stats.
- * @param stats The updated Wi-Fi usability statistics.
- */
- void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
- @NonNull WifiUsabilityStatsEntry stats);
- }
-
- /**
- * Adds a listener for Wi-Fi usability statistics. See {@link OnWifiUsabilityStatsListener}.
- * Multiple listeners can be added. Callers will be invoked periodically by framework to
- * inform clients about the current Wi-Fi usability statistics. Callers can remove a previously
- * added listener using {@link removeOnWifiUsabilityStatsListener}.
- *
- * @param executor The executor on which callback will be invoked.
- * @param listener Listener for Wifi usability statistics.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
- public void addOnWifiUsabilityStatsListener(@NonNull @CallbackExecutor Executor executor,
- @NonNull OnWifiUsabilityStatsListener listener) {
- if (executor == null) throw new IllegalArgumentException("executor cannot be null");
- if (listener == null) throw new IllegalArgumentException("listener cannot be null");
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "addOnWifiUsabilityStatsListener: listener=" + listener);
- }
- try {
- mService.addOnWifiUsabilityStatsListener(new Binder(),
- new IOnWifiUsabilityStatsListener.Stub() {
- @Override
- public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
- WifiUsabilityStatsEntry stats) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "OnWifiUsabilityStatsListener: "
- + "onWifiUsabilityStats: seqNum=" + seqNum);
- }
- Binder.clearCallingIdentity();
- executor.execute(() -> listener.onWifiUsabilityStats(
- seqNum, isSameBssidAndFreq, stats));
- }
- },
- listener.hashCode()
- );
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Allow callers to remove a previously registered listener. After calling this method,
- * applications will no longer receive Wi-Fi usability statistics.
- *
- * @param listener Listener to remove the Wi-Fi usability statistics.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
- public void removeOnWifiUsabilityStatsListener(@NonNull OnWifiUsabilityStatsListener listener) {
- if (listener == null) throw new IllegalArgumentException("listener cannot be null");
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "removeOnWifiUsabilityStatsListener: listener=" + listener);
- }
- try {
- mService.removeOnWifiUsabilityStatsListener(listener.hashCode());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Provide a Wi-Fi usability score information to be recorded (but not acted upon) by the
- * framework. The Wi-Fi usability score is derived from {@link OnWifiUsabilityStatsListener}
- * where a score is matched to Wi-Fi usability statistics using the sequence number. The score
- * is used to quantify whether Wi-Fi is usable in a future time.
- *
- * @param seqNum Sequence number of the Wi-Fi usability score.
- * @param score The Wi-Fi usability score, expected range: [0, 100].
- * @param predictionHorizonSec Prediction horizon of the Wi-Fi usability score in second,
- * expected range: [0, 30].
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
- public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) {
- try {
- mService.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Abstract class for scan results callback. Should be extended by applications and set when
- * calling {@link WifiManager#registerScanResultsCallback(Executor, ScanResultsCallback)}.
- */
- public abstract static class ScanResultsCallback {
- private final ScanResultsCallbackProxy mScanResultsCallbackProxy;
-
- public ScanResultsCallback() {
- mScanResultsCallbackProxy = new ScanResultsCallbackProxy();
- }
-
- /**
- * Called when new scan results are available.
- * Clients should use {@link WifiManager#getScanResults()} to get the scan results.
- */
- public abstract void onScanResultsAvailable();
-
- /*package*/ @NonNull ScanResultsCallbackProxy getProxy() {
- return mScanResultsCallbackProxy;
- }
-
- private static class ScanResultsCallbackProxy extends IScanResultsCallback.Stub {
- private final Object mLock = new Object();
- @Nullable @GuardedBy("mLock") private Executor mExecutor;
- @Nullable @GuardedBy("mLock") private ScanResultsCallback mCallback;
-
- ScanResultsCallbackProxy() {
- mCallback = null;
- mExecutor = null;
- }
-
- /*package*/ void initProxy(@NonNull Executor executor,
- @NonNull ScanResultsCallback callback) {
- synchronized (mLock) {
- mExecutor = executor;
- mCallback = callback;
- }
- }
-
- /*package*/ void cleanUpProxy() {
- synchronized (mLock) {
- mExecutor = null;
- mCallback = null;
- }
- }
-
- @Override
- public void onScanResultsAvailable() {
- ScanResultsCallback callback;
- Executor executor;
- synchronized (mLock) {
- executor = mExecutor;
- callback = mCallback;
- }
- if (callback == null || executor == null) {
- return;
- }
- Binder.clearCallingIdentity();
- executor.execute(callback::onScanResultsAvailable);
- }
- }
-
- }
-
- /**
- * Register a callback for Scan Results. See {@link ScanResultsCallback}.
- * Caller will receive the event when scan results are available.
- * Caller should use {@link WifiManager#getScanResults()} requires
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} to get the scan results.
- * Caller can remove a previously registered callback using
- * {@link WifiManager#unregisterScanResultsCallback(ScanResultsCallback)}
- * Same caller can add multiple listeners.
- * <p>
- * Applications should have the
- * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permission. Callers
- * without the permission will trigger a {@link java.lang.SecurityException}.
- * <p>
- *
- * @param executor The executor to execute the callback of the {@code callback} object.
- * @param callback callback for Scan Results events
- */
-
- @RequiresPermission(ACCESS_WIFI_STATE)
- public void registerScanResultsCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull ScanResultsCallback callback) {
- if (executor == null) throw new IllegalArgumentException("executor cannot be null");
- if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-
- Log.v(TAG, "registerScanResultsCallback: callback=" + callback
- + ", executor=" + executor);
- ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy();
- proxy.initProxy(executor, callback);
- try {
- mService.registerScanResultsCallback(proxy);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Allow callers to unregister a previously registered callback. After calling this method,
- * applications will no longer receive Scan Results events.
- *
- * @param callback callback to unregister for Scan Results events
- */
- @RequiresPermission(ACCESS_WIFI_STATE)
- public void unregisterScanResultsCallback(@NonNull ScanResultsCallback callback) {
- if (callback == null) throw new IllegalArgumentException("callback cannot be null");
- Log.v(TAG, "unregisterScanResultsCallback: Callback=" + callback);
- ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy();
- try {
- mService.unregisterScanResultsCallback(proxy);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } finally {
- proxy.cleanUpProxy();
- }
- }
-
- /**
- * Interface for suggestion connection status listener.
- * Should be implemented by applications and set when calling
- * {@link WifiManager#addSuggestionConnectionStatusListener(
- * Executor, SuggestionConnectionStatusListener)}.
- */
- public interface SuggestionConnectionStatusListener {
-
- /**
- * Called when the framework attempted to connect to a suggestion provided by the
- * registering app, but the connection to the suggestion failed.
- * @param wifiNetworkSuggestion The suggestion which failed to connect.
- * @param failureReason the connection failure reason code. One of
- * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION},
- * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION},
- * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING}
- * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN}
- */
- void onConnectionStatus(
- @NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
- @SuggestionConnectionStatusCode int failureReason);
- }
-
- private class SuggestionConnectionStatusListenerProxy extends
- ISuggestionConnectionStatusListener.Stub {
- private final Executor mExecutor;
- private final SuggestionConnectionStatusListener mListener;
-
- SuggestionConnectionStatusListenerProxy(@NonNull Executor executor,
- @NonNull SuggestionConnectionStatusListener listener) {
- mExecutor = executor;
- mListener = listener;
- }
-
- @Override
- public void onConnectionStatus(@NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
- int failureReason) {
- mExecutor.execute(() ->
- mListener.onConnectionStatus(wifiNetworkSuggestion, failureReason));
- }
-
- }
-
- /**
- * Add a listener for suggestion networks. See {@link SuggestionConnectionStatusListener}.
- * Caller will receive the event when suggested network have connection failure.
- * Caller can remove a previously registered listener using
- * {@link WifiManager#removeSuggestionConnectionStatusListener(
- * SuggestionConnectionStatusListener)}
- * Same caller can add multiple listeners to monitor the event.
- * <p>
- * Applications should have the
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
- * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permissions.
- * Callers without the permission will trigger a {@link java.lang.SecurityException}.
- * <p>
- *
- * @param executor The executor to execute the listener of the {@code listener} object.
- * @param listener listener for suggestion network connection failure.
- */
- @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
- public void addSuggestionConnectionStatusListener(@NonNull @CallbackExecutor Executor executor,
- @NonNull SuggestionConnectionStatusListener listener) {
- if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
- if (executor == null) throw new IllegalArgumentException("Executor cannot be null");
- Log.v(TAG, "addSuggestionConnectionStatusListener listener=" + listener
- + ", executor=" + executor);
- try {
- mService.registerSuggestionConnectionStatusListener(new Binder(),
- new SuggestionConnectionStatusListenerProxy(executor, listener),
- listener.hashCode(), mContext.getOpPackageName(), mContext.getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- }
-
- /**
- * Allow callers to remove a previously registered listener. After calling this method,
- * applications will no longer receive suggestion connection events through that listener.
- *
- * @param listener listener to remove.
- */
- @RequiresPermission(ACCESS_WIFI_STATE)
- public void removeSuggestionConnectionStatusListener(
- @NonNull SuggestionConnectionStatusListener listener) {
- if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
- Log.v(TAG, "removeSuggestionConnectionStatusListener: listener=" + listener);
- try {
- mService.unregisterSuggestionConnectionStatusListener(listener.hashCode(),
- mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Parse the list of channels the DPP enrollee reports when it fails to find an AP.
- *
- * @param channelList List of channels in the format defined in the DPP specification.
- * @return A parsed sparse array, where the operating class is the key.
- * @hide
- */
- @VisibleForTesting
- public static SparseArray<int[]> parseDppChannelList(String channelList) {
- SparseArray<int[]> channelListArray = new SparseArray<>();
-
- if (TextUtils.isEmpty(channelList)) {
- return channelListArray;
- }
- StringTokenizer str = new StringTokenizer(channelList, ",");
- String classStr = null;
- List<Integer> channelsInClass = new ArrayList<>();
-
- try {
- while (str.hasMoreElements()) {
- String cur = str.nextToken();
-
- /**
- * Example for a channel list:
- *
- * 81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48,118/52,56,60,64,121/100,104,108,112,
- * 116,120,124,128,132,136,140,0/144,124/149,153,157,161,125/165
- *
- * Detect operating class by the delimiter of '/' and use a string tokenizer with
- * ',' as a delimiter.
- */
- int classDelim = cur.indexOf('/');
- if (classDelim != -1) {
- if (classStr != null) {
- // Store the last channel array in the sparse array, where the operating
- // class is the key (as an integer).
- int[] channelsArray = new int[channelsInClass.size()];
- for (int i = 0; i < channelsInClass.size(); i++) {
- channelsArray[i] = channelsInClass.get(i);
- }
- channelListArray.append(Integer.parseInt(classStr), channelsArray);
- channelsInClass = new ArrayList<>();
- }
-
- // Init a new operating class and store the first channel
- classStr = cur.substring(0, classDelim);
- String channelStr = cur.substring(classDelim + 1);
- channelsInClass.add(Integer.parseInt(channelStr));
- } else {
- if (classStr == null) {
- // Invalid format
- Log.e(TAG, "Cannot parse DPP channel list");
- return new SparseArray<>();
- }
- channelsInClass.add(Integer.parseInt(cur));
- }
- }
-
- // Store the last array
- if (classStr != null) {
- int[] channelsArray = new int[channelsInClass.size()];
- for (int i = 0; i < channelsInClass.size(); i++) {
- channelsArray[i] = channelsInClass.get(i);
- }
- channelListArray.append(Integer.parseInt(classStr), channelsArray);
- }
- return channelListArray;
- } catch (NumberFormatException e) {
- Log.e(TAG, "Cannot parse DPP channel list");
- return new SparseArray<>();
- }
- }
-
- /**
- * Callback interface for framework to receive network status updates and trigger of updating
- * {@link WifiUsabilityStatsEntry}.
- *
- * @hide
- */
- @SystemApi
- public interface ScoreUpdateObserver {
- /**
- * Called by applications to indicate network status.
- *
- * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
- * {@link WifiConnectedNetworkScorer#onStart(int)}.
- * @param score The score representing link quality of current Wi-Fi network connection.
- * Populated by connected network scorer in applications..
- */
- void notifyScoreUpdate(int sessionId, int score);
-
- /**
- * Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}.
- * To receive update applications need to add WifiUsabilityStatsEntry listener. See
- * {@link addOnWifiUsabilityStatsListener(Executor, OnWifiUsabilityStatsListener)}.
- *
- * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
- * {@link WifiConnectedNetworkScorer#onStart(int)}.
- */
- void triggerUpdateOfWifiUsabilityStats(int sessionId);
- }
-
- /**
- * Callback proxy for {@link ScoreUpdateObserver} objects.
- *
- * @hide
- */
- private class ScoreUpdateObserverProxy implements ScoreUpdateObserver {
- private final IScoreUpdateObserver mScoreUpdateObserver;
-
- private ScoreUpdateObserverProxy(IScoreUpdateObserver observer) {
- mScoreUpdateObserver = observer;
- }
-
- @Override
- public void notifyScoreUpdate(int sessionId, int score) {
- try {
- mScoreUpdateObserver.notifyScoreUpdate(sessionId, score);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- @Override
- public void triggerUpdateOfWifiUsabilityStats(int sessionId) {
- try {
- mScoreUpdateObserver.triggerUpdateOfWifiUsabilityStats(sessionId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
- * Interface for Wi-Fi connected network scorer. Should be implemented by applications and set
- * when calling
- * {@link WifiManager#setWifiConnectedNetworkScorer(Executor, WifiConnectedNetworkScorer)}.
- *
- * @hide
- */
- @SystemApi
- public interface WifiConnectedNetworkScorer {
- /**
- * Called by framework to indicate the start of a network connection.
- * @param sessionId The ID to indicate current Wi-Fi network connection.
- */
- void onStart(int sessionId);
-
- /**
- * Called by framework to indicate the end of a network connection.
- * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
- * {@link WifiConnectedNetworkScorer#onStart(int)}.
- */
- void onStop(int sessionId);
-
- /**
- * Framework sets callback for score change events after application sets its scorer.
- * @param observerImpl The instance for {@link WifiManager#ScoreUpdateObserver}. Should be
- * implemented and instantiated by framework.
- */
- void onSetScoreUpdateObserver(@NonNull ScoreUpdateObserver observerImpl);
- }
-
- /**
- * Callback proxy for {@link WifiConnectedNetworkScorer} objects.
- *
- * @hide
- */
- private class WifiConnectedNetworkScorerProxy extends IWifiConnectedNetworkScorer.Stub {
- private Executor mExecutor;
- private WifiConnectedNetworkScorer mScorer;
-
- WifiConnectedNetworkScorerProxy(Executor executor, WifiConnectedNetworkScorer scorer) {
- mExecutor = executor;
- mScorer = scorer;
- }
-
- @Override
- public void onStart(int sessionId) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "WifiConnectedNetworkScorer: " + "onStart: sessionId=" + sessionId);
- }
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> mScorer.onStart(sessionId));
- }
-
- @Override
- public void onStop(int sessionId) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "WifiConnectedNetworkScorer: " + "onStop: sessionId=" + sessionId);
- }
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> mScorer.onStop(sessionId));
- }
-
- @Override
- public void onSetScoreUpdateObserver(IScoreUpdateObserver observerImpl) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "WifiConnectedNetworkScorer: "
- + "onSetScoreUpdateObserver: observerImpl=" + observerImpl);
- }
- Binder.clearCallingIdentity();
- mExecutor.execute(() -> mScorer.onSetScoreUpdateObserver(
- new ScoreUpdateObserverProxy(observerImpl)));
- }
- }
-
- /**
- * Set a callback for Wi-Fi connected network scorer. See {@link WifiConnectedNetworkScorer}.
- * Only a single scorer can be set. Caller will be invoked periodically by framework to inform
- * client about start and stop of Wi-Fi connection. Caller can clear a previously set scorer
- * using {@link clearWifiConnectedNetworkScorer()}.
- *
- * @param executor The executor on which callback will be invoked.
- * @param scorer Scorer for Wi-Fi network implemented by application.
- * @return true Scorer is set successfully.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
- public boolean setWifiConnectedNetworkScorer(@NonNull @CallbackExecutor Executor executor,
- @NonNull WifiConnectedNetworkScorer scorer) {
- if (executor == null) throw new IllegalArgumentException("executor cannot be null");
- if (scorer == null) throw new IllegalArgumentException("scorer cannot be null");
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "setWifiConnectedNetworkScorer: scorer=" + scorer);
- }
- try {
- return mService.setWifiConnectedNetworkScorer(new Binder(),
- new WifiConnectedNetworkScorerProxy(executor, scorer));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Allow caller to clear a previously set scorer. After calling this method,
- * client will no longer receive information about start and stop of Wi-Fi connection.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
- public void clearWifiConnectedNetworkScorer() {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "clearWifiConnectedNetworkScorer");
- }
- try {
- mService.clearWifiConnectedNetworkScorer();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Enable/disable wifi scan throttling from 3rd party apps.
- *
- * <p>
- * The throttling limits for apps are described in
- * <a href="Wi-Fi Scan Throttling">
- * https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling</a>
- * </p>
- *
- * @param enable true to allow scan throttling, false to disallow scan throttling.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void setScanThrottleEnabled(boolean enable) {
- try {
- mService.setScanThrottleEnabled(enable);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get the persisted Wi-Fi scan throttle state. Defaults to true, unless changed by the user via
- * Developer options.
- *
- * <p>
- * The throttling limits for apps are described in
- * <a href="Wi-Fi Scan Throttling">
- * https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling</a>
- * </p>
- *
- * @return true to indicate that scan throttling is enabled, false to indicate that scan
- * throttling is disabled.
- */
- @RequiresPermission(ACCESS_WIFI_STATE)
- public boolean isScanThrottleEnabled() {
- try {
- return mService.isScanThrottleEnabled();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Enable/disable wifi auto wakeup feature.
- *
- * <p>
- * The feature is described in
- * <a href="Wi-Fi Turn on automatically">
- * https://source.android.com/devices/tech/connect/wifi-infrastructure
- * #turn_on_wi-fi_automatically
- * </a>
- *
- * @param enable true to enable, false to disable.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void setAutoWakeupEnabled(boolean enable) {
- try {
- mService.setAutoWakeupEnabled(enable);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get the persisted Wi-Fi auto wakeup feature state. Defaults to false, unless changed by the
- * user via Settings.
- *
- * <p>
- * The feature is described in
- * <a href="Wi-Fi Turn on automatically">
- * https://source.android.com/devices/tech/connect/wifi-infrastructure
- * #turn_on_wi-fi_automatically
- * </a>
- *
- * @return true to indicate that wakeup feature is enabled, false to indicate that wakeup
- * feature is disabled.
- */
- @RequiresPermission(ACCESS_WIFI_STATE)
- public boolean isAutoWakeupEnabled() {
- try {
- return mService.isAutoWakeupEnabled();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiMigration.java b/wifi/java/android/net/wifi/WifiMigration.java
deleted file mode 100755
index 5792d27..0000000
--- a/wifi/java/android/net/wifi/WifiMigration.java
+++ /dev/null
@@ -1,558 +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.net.wifi;
-
-import static android.os.Environment.getDataMiscCeDirectory;
-import static android.os.Environment.getDataMiscDirectory;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.AtomicFile;
-import android.util.SparseArray;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Class used to provide one time hooks for existing OEM devices to migrate their config store
- * data and other settings to the wifi apex.
- * @hide
- */
-@SystemApi
-public final class WifiMigration {
- /**
- * Directory to read the wifi config store files from under.
- */
- private static final String LEGACY_WIFI_STORE_DIRECTORY_NAME = "wifi";
- /**
- * Config store file for general shared store file.
- * AOSP Path on Android 10: /data/misc/wifi/WifiConfigStore.xml
- */
- public static final int STORE_FILE_SHARED_GENERAL = 0;
- /**
- * Config store file for softap shared store file.
- * AOSP Path on Android 10: /data/misc/wifi/softap.conf
- */
- public static final int STORE_FILE_SHARED_SOFTAP = 1;
- /**
- * Config store file for general user store file.
- * AOSP Path on Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStore.xml
- */
- public static final int STORE_FILE_USER_GENERAL = 2;
- /**
- * Config store file for network suggestions user store file.
- * AOSP Path on Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStoreNetworkSuggestions.xml
- */
- public static final int STORE_FILE_USER_NETWORK_SUGGESTIONS = 3;
-
- /** @hide */
- @IntDef(prefix = { "STORE_FILE_SHARED_" }, value = {
- STORE_FILE_SHARED_GENERAL,
- STORE_FILE_SHARED_SOFTAP,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SharedStoreFileId { }
-
- /** @hide */
- @IntDef(prefix = { "STORE_FILE_USER_" }, value = {
- STORE_FILE_USER_GENERAL,
- STORE_FILE_USER_NETWORK_SUGGESTIONS
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface UserStoreFileId { }
-
- /**
- * Mapping of Store file Id to Store file names.
- *
- * NOTE: This is the default path for the files on AOSP devices. If the OEM has modified
- * the path or renamed the files, please edit this appropriately.
- */
- private static final SparseArray<String> STORE_ID_TO_FILE_NAME =
- new SparseArray<String>() {{
- put(STORE_FILE_SHARED_GENERAL, "WifiConfigStore.xml");
- put(STORE_FILE_SHARED_SOFTAP, "WifiConfigStoreSoftAp.xml");
- put(STORE_FILE_USER_GENERAL, "WifiConfigStore.xml");
- put(STORE_FILE_USER_NETWORK_SUGGESTIONS, "WifiConfigStoreNetworkSuggestions.xml");
- }};
-
- /**
- * Pre-apex wifi shared folder.
- */
- private static File getLegacyWifiSharedDirectory() {
- return new File(getDataMiscDirectory(), LEGACY_WIFI_STORE_DIRECTORY_NAME);
- }
-
- /**
- * Pre-apex wifi user folder.
- */
- private static File getLegacyWifiUserDirectory(int userId) {
- return new File(getDataMiscCeDirectory(userId), LEGACY_WIFI_STORE_DIRECTORY_NAME);
- }
-
- /**
- * Legacy files were stored as AtomicFile. So, always use AtomicFile to operate on it to ensure
- * data integrity.
- */
- private static AtomicFile getSharedAtomicFile(@SharedStoreFileId int storeFileId) {
- return new AtomicFile(new File(
- getLegacyWifiSharedDirectory(),
- STORE_ID_TO_FILE_NAME.get(storeFileId)));
- }
-
- /**
- * Legacy files were stored as AtomicFile. So, always use AtomicFile to operate on it to ensure
- * data integrity.
- */
- private static AtomicFile getUserAtomicFile(@UserStoreFileId int storeFileId, int userId) {
- return new AtomicFile(new File(
- getLegacyWifiUserDirectory(userId),
- STORE_ID_TO_FILE_NAME.get(storeFileId)));
- }
-
- private WifiMigration() { }
-
- /**
- * Load data from legacy shared wifi config store file.
- * <p>
- * Expected AOSP format is available in the sample files under {@code /frameworks/base/wifi/
- * java/android/net/wifi/migration_samples}.
- * </p>
- * <p>
- * Note:
- * <li>OEMs need to change the implementation of
- * {@link #convertAndRetrieveSharedConfigStoreFile(int)} only if their existing config store
- * format or file locations differs from the vanilla AOSP implementation.</li>
- * <li>The wifi apex will invoke
- * {@link #convertAndRetrieveSharedConfigStoreFile(int)}
- * method on every bootup, it is the responsibility of the OEM implementation to ensure that
- * they perform the necessary in place conversion of their config store file to conform to the
- * AOSP format. The OEM should ensure that the method should only return the
- * {@link InputStream} stream for the data to be migrated only on the first bootup.</li>
- * <li>Once the migration is done, the apex will invoke
- * {@link #removeSharedConfigStoreFile(int)} to delete the store file.</li>
- * <li>The only relevant invocation of {@link #convertAndRetrieveSharedConfigStoreFile(int)}
- * occurs when a previously released device upgrades to the wifi apex from an OEM
- * implementation of the wifi stack.
- * <li>Ensure that the legacy file paths are accessible to the wifi module (sepolicy rules, file
- * permissions, etc). Since the wifi service continues to run inside system_server process, this
- * method will be called from the same context (so ideally the file should still be accessible).
- * </li>
- *
- * @param storeFileId Identifier for the config store file. One of
- * {@link #STORE_FILE_SHARED_GENERAL} or {@link #STORE_FILE_SHARED_GENERAL}
- * @return Instance of {@link InputStream} for migrating data, null if no migration is
- * necessary.
- * @throws IllegalArgumentException on invalid storeFileId.
- */
- @Nullable
- public static InputStream convertAndRetrieveSharedConfigStoreFile(
- @SharedStoreFileId int storeFileId) {
- if (storeFileId != STORE_FILE_SHARED_GENERAL && storeFileId != STORE_FILE_SHARED_SOFTAP) {
- throw new IllegalArgumentException("Invalid shared store file id");
- }
- try {
- // OEMs should do conversions necessary here before returning the stream.
- return getSharedAtomicFile(storeFileId).openRead();
- } catch (FileNotFoundException e) {
- // Special handling for softap.conf.
- // Note: OEM devices upgrading from Q -> R will only have the softap.conf file.
- // Test devices running previous R builds however may have already migrated to the
- // XML format. So, check for that above before falling back to check for legacy file.
- if (storeFileId == STORE_FILE_SHARED_SOFTAP) {
- return SoftApConfToXmlMigrationUtil.convert();
- }
- return null;
- }
- }
-
- /**
- * Remove the legacy shared wifi config store file.
- *
- * @param storeFileId Identifier for the config store file. One of
- * {@link #STORE_FILE_SHARED_GENERAL} or {@link #STORE_FILE_SHARED_GENERAL}
- * @throws IllegalArgumentException on invalid storeFileId.
- */
- public static void removeSharedConfigStoreFile(@SharedStoreFileId int storeFileId) {
- if (storeFileId != STORE_FILE_SHARED_GENERAL && storeFileId != STORE_FILE_SHARED_SOFTAP) {
- throw new IllegalArgumentException("Invalid shared store file id");
- }
- AtomicFile file = getSharedAtomicFile(storeFileId);
- if (file.exists()) {
- file.delete();
- return;
- }
- // Special handling for softap.conf.
- // Note: OEM devices upgrading from Q -> R will only have the softap.conf file.
- // Test devices running previous R builds however may have already migrated to the
- // XML format. So, check for that above before falling back to check for legacy file.
- if (storeFileId == STORE_FILE_SHARED_SOFTAP) {
- SoftApConfToXmlMigrationUtil.remove();
- }
- }
-
- /**
- * Load data from legacy user wifi config store file.
- * <p>
- * Expected AOSP format is available in the sample files under {@code /frameworks/base/wifi/
- * java/android/net/wifi/migration_samples}.
- * </p>
- * <p>
- * Note:
- * <li>OEMs need to change the implementation of
- * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)} only if their existing config
- * store format or file locations differs from the vanilla AOSP implementation.</li>
- * <li>The wifi apex will invoke
- * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)}
- * method on every bootup, it is the responsibility of the OEM implementation to ensure that
- * they perform the necessary in place conversion of their config store file to conform to the
- * AOSP format. The OEM should ensure that the method should only return the
- * {@link InputStream} stream for the data to be migrated only on the first bootup.</li>
- * <li>Once the migration is done, the apex will invoke
- * {@link #removeUserConfigStoreFile(int, UserHandle)} to delete the store file.</li>
- * <li>The only relevant invocation of
- * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)} occurs when a previously
- * released device upgrades to the wifi apex from an OEM implementation of the wifi
- * stack.
- * </li>
- * <li>Ensure that the legacy file paths are accessible to the wifi module (sepolicy rules, file
- * permissions, etc). Since the wifi service continues to run inside system_server process, this
- * method will be called from the same context (so ideally the file should still be accessible).
- * </li>
- *
- * @param storeFileId Identifier for the config store file. One of
- * {@link #STORE_FILE_USER_GENERAL} or {@link #STORE_FILE_USER_NETWORK_SUGGESTIONS}
- * @param userHandle User handle.
- * @return Instance of {@link InputStream} for migrating data, null if no migration is
- * necessary.
- * @throws IllegalArgumentException on invalid storeFileId or userHandle.
- */
- @Nullable
- public static InputStream convertAndRetrieveUserConfigStoreFile(
- @UserStoreFileId int storeFileId, @NonNull UserHandle userHandle) {
- if (storeFileId != STORE_FILE_USER_GENERAL
- && storeFileId != STORE_FILE_USER_NETWORK_SUGGESTIONS) {
- throw new IllegalArgumentException("Invalid user store file id");
- }
- Objects.requireNonNull(userHandle);
- try {
- // OEMs should do conversions necessary here before returning the stream.
- return getUserAtomicFile(storeFileId, userHandle.getIdentifier()).openRead();
- } catch (FileNotFoundException e) {
- return null;
- }
- }
-
- /**
- * Remove the legacy user wifi config store file.
- *
- * @param storeFileId Identifier for the config store file. One of
- * {@link #STORE_FILE_USER_GENERAL} or {@link #STORE_FILE_USER_NETWORK_SUGGESTIONS}
- * @param userHandle User handle.
- * @throws IllegalArgumentException on invalid storeFileId or userHandle.
- */
- public static void removeUserConfigStoreFile(
- @UserStoreFileId int storeFileId, @NonNull UserHandle userHandle) {
- if (storeFileId != STORE_FILE_USER_GENERAL
- && storeFileId != STORE_FILE_USER_NETWORK_SUGGESTIONS) {
- throw new IllegalArgumentException("Invalid user store file id");
- }
- Objects.requireNonNull(userHandle);
- AtomicFile file = getUserAtomicFile(storeFileId, userHandle.getIdentifier());
- if (file.exists()) {
- file.delete();
- }
- }
-
- /**
- * Container for all the wifi settings data to migrate.
- */
- public static final class SettingsMigrationData implements Parcelable {
- private final boolean mScanAlwaysAvailable;
- private final boolean mP2pFactoryResetPending;
- private final String mP2pDeviceName;
- private final boolean mSoftApTimeoutEnabled;
- private final boolean mWakeupEnabled;
- private final boolean mScanThrottleEnabled;
- private final boolean mVerboseLoggingEnabled;
-
- private SettingsMigrationData(boolean scanAlwaysAvailable, boolean p2pFactoryResetPending,
- @Nullable String p2pDeviceName, boolean softApTimeoutEnabled, boolean wakeupEnabled,
- boolean scanThrottleEnabled, boolean verboseLoggingEnabled) {
- mScanAlwaysAvailable = scanAlwaysAvailable;
- mP2pFactoryResetPending = p2pFactoryResetPending;
- mP2pDeviceName = p2pDeviceName;
- mSoftApTimeoutEnabled = softApTimeoutEnabled;
- mWakeupEnabled = wakeupEnabled;
- mScanThrottleEnabled = scanThrottleEnabled;
- mVerboseLoggingEnabled = verboseLoggingEnabled;
- }
-
- public static final @NonNull Parcelable.Creator<SettingsMigrationData> CREATOR =
- new Parcelable.Creator<SettingsMigrationData>() {
- @Override
- public SettingsMigrationData createFromParcel(Parcel in) {
- boolean scanAlwaysAvailable = in.readBoolean();
- boolean p2pFactoryResetPending = in.readBoolean();
- String p2pDeviceName = in.readString();
- boolean softApTimeoutEnabled = in.readBoolean();
- boolean wakeupEnabled = in.readBoolean();
- boolean scanThrottleEnabled = in.readBoolean();
- boolean verboseLoggingEnabled = in.readBoolean();
- return new SettingsMigrationData(
- scanAlwaysAvailable, p2pFactoryResetPending,
- p2pDeviceName, softApTimeoutEnabled, wakeupEnabled,
- scanThrottleEnabled, verboseLoggingEnabled);
- }
-
- @Override
- public SettingsMigrationData[] newArray(int size) {
- return new SettingsMigrationData[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeBoolean(mScanAlwaysAvailable);
- dest.writeBoolean(mP2pFactoryResetPending);
- dest.writeString(mP2pDeviceName);
- dest.writeBoolean(mSoftApTimeoutEnabled);
- dest.writeBoolean(mWakeupEnabled);
- dest.writeBoolean(mScanThrottleEnabled);
- dest.writeBoolean(mVerboseLoggingEnabled);
- }
-
- /**
- * @return True if scans are allowed even when wifi is toggled off, false otherwise.
- */
- public boolean isScanAlwaysAvailable() {
- return mScanAlwaysAvailable;
- }
-
- /**
- * @return indicate whether factory reset request is pending.
- */
- public boolean isP2pFactoryResetPending() {
- return mP2pFactoryResetPending;
- }
-
- /**
- * @return the Wi-Fi peer-to-peer device name
- */
- public @Nullable String getP2pDeviceName() {
- return mP2pDeviceName;
- }
-
- /**
- * @return Whether soft AP will shut down after a timeout period when no devices are
- * connected.
- */
- public boolean isSoftApTimeoutEnabled() {
- return mSoftApTimeoutEnabled;
- }
-
- /**
- * @return whether Wi-Fi Wakeup feature is enabled.
- */
- public boolean isWakeUpEnabled() {
- return mWakeupEnabled;
- }
-
- /**
- * @return Whether wifi scan throttle is enabled or not.
- */
- public boolean isScanThrottleEnabled() {
- return mScanThrottleEnabled;
- }
-
- /**
- * @return Whether to enable verbose logging in Wi-Fi.
- */
- public boolean isVerboseLoggingEnabled() {
- return mVerboseLoggingEnabled;
- }
-
- /**
- * Builder to create instance of {@link SettingsMigrationData}.
- */
- public static final class Builder {
- private boolean mScanAlwaysAvailable;
- private boolean mP2pFactoryResetPending;
- private String mP2pDeviceName;
- private boolean mSoftApTimeoutEnabled;
- private boolean mWakeupEnabled;
- private boolean mScanThrottleEnabled;
- private boolean mVerboseLoggingEnabled;
-
- public Builder() {
- }
-
- /**
- * Setting to allow scans even when wifi is toggled off.
- *
- * @param available true if available, false otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setScanAlwaysAvailable(boolean available) {
- mScanAlwaysAvailable = available;
- return this;
- }
-
- /**
- * Indicate whether factory reset request is pending.
- *
- * @param pending true if pending, false otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setP2pFactoryResetPending(boolean pending) {
- mP2pFactoryResetPending = pending;
- return this;
- }
-
- /**
- * The Wi-Fi peer-to-peer device name
- *
- * @param name Name if set, null otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setP2pDeviceName(@Nullable String name) {
- mP2pDeviceName = name;
- return this;
- }
-
- /**
- * Whether soft AP will shut down after a timeout period when no devices are connected.
- *
- * @param enabled true if enabled, false otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setSoftApTimeoutEnabled(boolean enabled) {
- mSoftApTimeoutEnabled = enabled;
- return this;
- }
-
- /**
- * Value to specify if Wi-Fi Wakeup feature is enabled.
- *
- * @param enabled true if enabled, false otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setWakeUpEnabled(boolean enabled) {
- mWakeupEnabled = enabled;
- return this;
- }
-
- /**
- * Whether wifi scan throttle is enabled or not.
- *
- * @param enabled true if enabled, false otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setScanThrottleEnabled(boolean enabled) {
- mScanThrottleEnabled = enabled;
- return this;
- }
-
- /**
- * Setting to enable verbose logging in Wi-Fi.
- *
- * @param enabled true if enabled, false otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setVerboseLoggingEnabled(boolean enabled) {
- mVerboseLoggingEnabled = enabled;
- return this;
- }
-
- /**
- * Build an instance of {@link SettingsMigrationData}.
- *
- * @return Instance of {@link SettingsMigrationData}.
- */
- public @NonNull SettingsMigrationData build() {
- return new SettingsMigrationData(mScanAlwaysAvailable, mP2pFactoryResetPending,
- mP2pDeviceName, mSoftApTimeoutEnabled, mWakeupEnabled, mScanThrottleEnabled,
- mVerboseLoggingEnabled);
- }
- }
- }
-
- /**
- * Load data from Settings.Global values.
- *
- * <p>
- * Note:
- * <li> This is method is invoked once on the first bootup. OEM can safely delete these settings
- * once the migration is complete. The first & only relevant invocation of
- * {@link #loadFromSettings(Context)} ()} occurs when a previously released
- * device upgrades to the wifi apex from an OEM implementation of the wifi stack.
- * </li>
- *
- * @param context Context to use for loading the settings provider.
- * @return Instance of {@link SettingsMigrationData} for migrating data.
- */
- @NonNull
- public static SettingsMigrationData loadFromSettings(@NonNull Context context) {
- if (Settings.Global.getInt(
- context.getContentResolver(), Settings.Global.WIFI_MIGRATION_COMPLETED, 0) == 1) {
- // migration already complete, ignore.
- return null;
- }
- SettingsMigrationData data = new SettingsMigrationData.Builder()
- .setScanAlwaysAvailable(
- Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1)
- .setP2pFactoryResetPending(
- Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.WIFI_P2P_PENDING_FACTORY_RESET, 0) == 1)
- .setP2pDeviceName(
- Settings.Global.getString(context.getContentResolver(),
- Settings.Global.WIFI_P2P_DEVICE_NAME))
- .setSoftApTimeoutEnabled(
- Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.SOFT_AP_TIMEOUT_ENABLED, 1) == 1)
- .setWakeUpEnabled(
- Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1)
- .setScanThrottleEnabled(
- Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1) == 1)
- .setVerboseLoggingEnabled(
- Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0) == 1)
- .build();
- Settings.Global.putInt(
- context.getContentResolver(), Settings.Global.WIFI_MIGRATION_COMPLETED, 1);
- return data;
-
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
deleted file mode 100644
index 0d13805..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.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.net.wifi;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-import static com.android.internal.util.Preconditions.checkState;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.MacAddress;
-import android.net.MatchAllNetworkSpecifier;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * Network specifier object used by wifi's {@link android.net.NetworkAgent}.
- * @hide
- */
-public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements Parcelable {
- /**
- * Security credentials for the currently connected network.
- */
- private final WifiConfiguration mWifiConfiguration;
-
- public WifiNetworkAgentSpecifier(@NonNull WifiConfiguration wifiConfiguration) {
- checkNotNull(wifiConfiguration);
-
- mWifiConfiguration = wifiConfiguration;
- }
-
- /**
- * @hide
- */
- public static final @android.annotation.NonNull Creator<WifiNetworkAgentSpecifier> CREATOR =
- new Creator<WifiNetworkAgentSpecifier>() {
- @Override
- public WifiNetworkAgentSpecifier createFromParcel(@NonNull Parcel in) {
- WifiConfiguration wifiConfiguration = in.readParcelable(null);
- return new WifiNetworkAgentSpecifier(wifiConfiguration);
- }
-
- @Override
- public WifiNetworkAgentSpecifier[] newArray(int size) {
- return new WifiNetworkAgentSpecifier[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeParcelable(mWifiConfiguration, flags);
- }
-
- @Override
- public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
- if (this == other) {
- return true;
- }
- // Any generic requests should be satisifed by a specific wifi network.
- if (other == null || other instanceof MatchAllNetworkSpecifier) {
- return true;
- }
- if (other instanceof WifiNetworkSpecifier) {
- return satisfiesNetworkSpecifier((WifiNetworkSpecifier) other);
- }
- return equals(other);
- }
-
- /**
- * Match {@link WifiNetworkSpecifier} in app's {@link NetworkRequest} with the
- * {@link WifiNetworkAgentSpecifier} in wifi platform's {@link android.net.NetworkAgent}.
- */
- public boolean satisfiesNetworkSpecifier(@NonNull WifiNetworkSpecifier ns) {
- // None of these should be null by construction.
- // {@link WifiNetworkSpecifier.Builder} enforces non-null in {@link WifiNetworkSpecifier}.
- // {@link WifiNetworkFactory} ensures non-null in {@link WifiNetworkAgentSpecifier}.
- checkNotNull(ns);
- checkNotNull(ns.ssidPatternMatcher);
- checkNotNull(ns.bssidPatternMatcher);
- checkNotNull(ns.wifiConfiguration.allowedKeyManagement);
- checkNotNull(this.mWifiConfiguration.SSID);
- checkNotNull(this.mWifiConfiguration.BSSID);
- checkNotNull(this.mWifiConfiguration.allowedKeyManagement);
-
- final String ssidWithQuotes = this.mWifiConfiguration.SSID;
- checkState(ssidWithQuotes.startsWith("\"") && ssidWithQuotes.endsWith("\""));
- final String ssidWithoutQuotes = ssidWithQuotes.substring(1, ssidWithQuotes.length() - 1);
- if (!ns.ssidPatternMatcher.match(ssidWithoutQuotes)) {
- return false;
- }
- final MacAddress bssid = MacAddress.fromString(this.mWifiConfiguration.BSSID);
- final MacAddress matchBaseAddress = ns.bssidPatternMatcher.first;
- final MacAddress matchMask = ns.bssidPatternMatcher.second;
- if (!bssid.matches(matchBaseAddress, matchMask)) {
- return false;
- }
- if (!ns.wifiConfiguration.allowedKeyManagement.equals(
- this.mWifiConfiguration.allowedKeyManagement)) {
- return false;
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(
- mWifiConfiguration.SSID,
- mWifiConfiguration.BSSID,
- mWifiConfiguration.allowedKeyManagement);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof WifiNetworkAgentSpecifier)) {
- return false;
- }
- WifiNetworkAgentSpecifier lhs = (WifiNetworkAgentSpecifier) obj;
- return Objects.equals(this.mWifiConfiguration.SSID, lhs.mWifiConfiguration.SSID)
- && Objects.equals(this.mWifiConfiguration.BSSID, lhs.mWifiConfiguration.BSSID)
- && Objects.equals(this.mWifiConfiguration.allowedKeyManagement,
- lhs.mWifiConfiguration.allowedKeyManagement);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("WifiNetworkAgentSpecifier [");
- sb.append("WifiConfiguration=")
- .append(", SSID=").append(mWifiConfiguration.SSID)
- .append(", BSSID=").append(mWifiConfiguration.BSSID)
- .append("]");
- return sb.toString();
- }
-
- @Override
- public NetworkSpecifier redact() {
- return null;
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java b/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java
deleted file mode 100644
index 95b2e77..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java
+++ /dev/null
@@ -1,85 +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.
- */
-
-package android.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Connection Statistics For a WiFi Network.
- * @hide
- */
-@SystemApi
-public class WifiNetworkConnectionStatistics implements Parcelable {
- private static final String TAG = "WifiNetworkConnnectionStatistics";
-
- public int numConnection;
- public int numUsage;
-
- public WifiNetworkConnectionStatistics(int connection, int usage) {
- numConnection = connection;
- numUsage = usage;
- }
-
- public WifiNetworkConnectionStatistics() { }
-
- @NonNull
- @Override
- public String toString() {
- StringBuilder sbuf = new StringBuilder();
- sbuf.append("c=").append(numConnection);
- sbuf.append(" u=").append(numUsage);
- return sbuf.toString();
- }
-
-
- /** copy constructor*/
- public WifiNetworkConnectionStatistics(WifiNetworkConnectionStatistics source) {
- numConnection = source.numConnection;
- numUsage = source.numUsage;
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(numConnection);
- dest.writeInt(numUsage);
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<WifiNetworkConnectionStatistics> CREATOR =
- new Creator<WifiNetworkConnectionStatistics>() {
- public WifiNetworkConnectionStatistics createFromParcel(Parcel in) {
- int numConnection = in.readInt();
- int numUsage = in.readInt();
- WifiNetworkConnectionStatistics stats =
- new WifiNetworkConnectionStatistics(numConnection, numUsage);
- return stats;
- }
-
- public WifiNetworkConnectionStatistics[] newArray(int size) {
- return new WifiNetworkConnectionStatistics[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
deleted file mode 100755
index 378549d..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
+++ /dev/null
@@ -1,316 +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.
- */
-
-package android.net.wifi;
-
-import android.Manifest.permission;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.INetworkScoreCache;
-import android.net.NetworkKey;
-import android.net.ScoredNetwork;
-import android.os.Handler;
-import android.os.Process;
-import android.util.Log;
-import android.util.LruCache;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * {@link INetworkScoreCache} implementation for Wifi Networks.
- *
- * TODO: This should not be part of wifi mainline module.
- * @hide
- */
-public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
- private static final String TAG = "WifiNetworkScoreCache";
- private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
-
- // A Network scorer returns a score in the range [-128, +127]
- // We treat the lowest possible score as though there were no score, effectively allowing the
- // scorer to provide an RSSI threshold below which a network should not be used.
- public static final int INVALID_NETWORK_SCORE = Byte.MIN_VALUE;
-
- /** Default number entries to be stored in the {@link LruCache}. */
- private static final int DEFAULT_MAX_CACHE_SIZE = 100;
-
- // See {@link #CacheListener}.
- @Nullable
- @GuardedBy("mLock")
- private CacheListener mListener;
-
- private final Context mContext;
- private final Object mLock = new Object();
-
- // The key is of the form "<ssid>"<bssid>
- // TODO: What about SSIDs that can't be encoded as UTF-8?
- @GuardedBy("mLock")
- private final LruCache<String, ScoredNetwork> mCache;
-
- public WifiNetworkScoreCache(Context context) {
- this(context, null /* listener */);
- }
-
- /**
- * Instantiates a WifiNetworkScoreCache.
- *
- * @param context Application context
- * @param listener CacheListener for cache updates
- */
- public WifiNetworkScoreCache(Context context, @Nullable CacheListener listener) {
- this(context, listener, DEFAULT_MAX_CACHE_SIZE);
- }
-
- public WifiNetworkScoreCache(
- Context context, @Nullable CacheListener listener, int maxCacheSize) {
- mContext = context.getApplicationContext();
- mListener = listener;
- mCache = new LruCache<>(maxCacheSize);
- }
-
- @Override public final void updateScores(List<ScoredNetwork> networks) {
- if (networks == null || networks.isEmpty()) {
- return;
- }
- if (DBG) {
- Log.d(TAG, "updateScores list size=" + networks.size());
- }
-
- boolean changed = false;
-
- synchronized(mLock) {
- for (ScoredNetwork network : networks) {
- String networkKey = buildNetworkKey(network);
- if (networkKey == null) {
- if (DBG) {
- Log.d(TAG, "Failed to build network key for ScoredNetwork" + network);
- }
- continue;
- }
- mCache.put(networkKey, network);
- changed = true;
- }
-
- if (mListener != null && changed) {
- mListener.post(networks);
- }
- }
- }
-
- @Override public final void clearScores() {
- synchronized (mLock) {
- mCache.evictAll();
- }
- }
-
- /**
- * Returns whether there is any score info for the given ScanResult.
- *
- * This includes null-score info, so it should only be used when determining whether to request
- * scores from the network scorer.
- */
- public boolean isScoredNetwork(ScanResult result) {
- return getScoredNetwork(result) != null;
- }
-
- /**
- * Returns whether there is a non-null score curve for the given ScanResult.
- *
- * A null score curve has special meaning - we should never connect to an ephemeral network if
- * the score curve is null.
- */
- public boolean hasScoreCurve(ScanResult result) {
- ScoredNetwork network = getScoredNetwork(result);
- return network != null && network.rssiCurve != null;
- }
-
- public int getNetworkScore(ScanResult result) {
- int score = INVALID_NETWORK_SCORE;
-
- ScoredNetwork network = getScoredNetwork(result);
- if (network != null && network.rssiCurve != null) {
- score = network.rssiCurve.lookupScore(result.level);
- if (DBG) {
- Log.d(TAG, "getNetworkScore found scored network " + network.networkKey
- + " score " + Integer.toString(score)
- + " RSSI " + result.level);
- }
- }
- return score;
- }
-
- /**
- * Returns the ScoredNetwork metered hint for a given ScanResult.
- *
- * If there is no ScoredNetwork associated with the ScanResult then false will be returned.
- */
- public boolean getMeteredHint(ScanResult result) {
- ScoredNetwork network = getScoredNetwork(result);
- return network != null && network.meteredHint;
- }
-
- public int getNetworkScore(ScanResult result, boolean isActiveNetwork) {
- int score = INVALID_NETWORK_SCORE;
-
- ScoredNetwork network = getScoredNetwork(result);
- if (network != null && network.rssiCurve != null) {
- score = network.rssiCurve.lookupScore(result.level, isActiveNetwork);
- if (DBG) {
- Log.d(TAG, "getNetworkScore found scored network " + network.networkKey
- + " score " + Integer.toString(score)
- + " RSSI " + result.level
- + " isActiveNetwork " + isActiveNetwork);
- }
- }
- return score;
- }
-
- @Nullable
- public ScoredNetwork getScoredNetwork(ScanResult result) {
- String key = buildNetworkKey(result);
- if (key == null) return null;
-
- synchronized(mLock) {
- ScoredNetwork network = mCache.get(key);
- return network;
- }
- }
-
- /** Returns the ScoredNetwork for the given key. */
- @Nullable
- public ScoredNetwork getScoredNetwork(NetworkKey networkKey) {
- String key = buildNetworkKey(networkKey);
- if (key == null) {
- if (DBG) {
- Log.d(TAG, "Could not build key string for Network Key: " + networkKey);
- }
- return null;
- }
- synchronized (mLock) {
- return mCache.get(key);
- }
- }
-
- private String buildNetworkKey(ScoredNetwork network) {
- if (network == null) {
- return null;
- }
- return buildNetworkKey(network.networkKey);
- }
-
- private String buildNetworkKey(NetworkKey networkKey) {
- if (networkKey == null) {
- return null;
- }
- if (networkKey.wifiKey == null) return null;
- if (networkKey.type == NetworkKey.TYPE_WIFI) {
- String key = networkKey.wifiKey.ssid;
- if (key == null) return null;
- if (networkKey.wifiKey.bssid != null) {
- key = key + networkKey.wifiKey.bssid;
- }
- return key;
- }
- return null;
- }
-
- private String buildNetworkKey(ScanResult result) {
- if (result == null || result.SSID == null) {
- return null;
- }
- StringBuilder key = new StringBuilder("\"");
- key.append(result.SSID);
- key.append("\"");
- if (result.BSSID != null) {
- key.append(result.BSSID);
- }
- return key.toString();
- }
-
- @Override protected final void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
- String header = String.format("WifiNetworkScoreCache (%s/%d)",
- mContext.getPackageName(), Process.myUid());
- writer.println(header);
- writer.println(" All score curves:");
- synchronized (mLock) {
- for (ScoredNetwork score : mCache.snapshot().values()) {
- writer.println(" " + score);
- }
- writer.println(" Network scores for latest ScanResults:");
- WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- for (ScanResult scanResult : wifiManager.getScanResults()) {
- writer.println(
- " " + buildNetworkKey(scanResult) + ": " + getNetworkScore(scanResult));
- }
- }
- }
-
- /** Registers a CacheListener instance, replacing the previous listener if it existed. */
- public void registerListener(CacheListener listener) {
- synchronized (mLock) {
- mListener = listener;
- }
- }
-
- /** Removes the registered CacheListener. */
- public void unregisterListener() {
- synchronized (mLock) {
- mListener = null;
- }
- }
-
- /** Listener for updates to the cache inside WifiNetworkScoreCache. */
- public abstract static class CacheListener {
- private Handler mHandler;
-
- /**
- * Constructor for CacheListener.
- *
- * @param handler the Handler on which to invoke the {@link #networkCacheUpdated} method.
- * This cannot be null.
- */
- public CacheListener(@NonNull Handler handler) {
- Objects.requireNonNull(handler);
- mHandler = handler;
- }
-
- /** Invokes the {@link #networkCacheUpdated(List<ScoredNetwork>)} method on the handler. */
- void post(List<ScoredNetwork> updatedNetworks) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- networkCacheUpdated(updatedNetworks);
- }
- });
- }
-
- /**
- * Invoked whenever the cache is updated.
- *
- * <p>Clearing the cache does not invoke this method.
- *
- * @param updatedNetworks the networks that were updated
- */
- public abstract void networkCacheUpdated(List<ScoredNetwork> updatedNetworks);
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
deleted file mode 100644
index b0213b0..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ /dev/null
@@ -1,563 +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.net.wifi;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.MacAddress;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PatternMatcher;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Objects;
-
-/**
- * Network specifier object used to request a local Wi-Fi network. Apps should use the
- * {@link WifiNetworkSpecifier.Builder} class to create an instance.
- */
-public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parcelable {
- private static final String TAG = "WifiNetworkSpecifier";
-
- /**
- * Builder used to create {@link WifiNetworkSpecifier} objects.
- */
- public static final class Builder {
- private static final String MATCH_ALL_SSID_PATTERN_PATH = ".*";
- private static final String MATCH_EMPTY_SSID_PATTERN_PATH = "";
- private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN1 =
- new Pair<>(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS);
- private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN2 =
- new Pair<>(WifiManager.ALL_ZEROS_MAC_ADDRESS, MacAddress.BROADCAST_ADDRESS);
- private static final Pair<MacAddress, MacAddress> MATCH_ALL_BSSID_PATTERN =
- new Pair<>(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
- private static final MacAddress MATCH_EXACT_BSSID_PATTERN_MASK =
- MacAddress.BROADCAST_ADDRESS;
-
- /**
- * SSID pattern match specified by the app.
- */
- private @Nullable PatternMatcher mSsidPatternMatcher;
- /**
- * BSSID pattern match specified by the app.
- * Pair of <BaseAddress, Mask>.
- */
- private @Nullable Pair<MacAddress, MacAddress> mBssidPatternMatcher;
- /**
- * Whether this is an OWE network or not.
- */
- private boolean mIsEnhancedOpen;
- /**
- * Pre-shared key for use with WPA-PSK networks.
- */
- private @Nullable String mWpa2PskPassphrase;
- /**
- * Pre-shared key for use with WPA3-SAE networks.
- */
- private @Nullable String mWpa3SaePassphrase;
- /**
- * The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the WPA-EAP networks.
- */
- private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
- /**
- * The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the SuiteB networks.
- */
- private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
- /**
- * This is a network that does not broadcast its SSID, so an
- * SSID-specific probe request must be used for scans.
- */
- private boolean mIsHiddenSSID;
-
- public Builder() {
- mSsidPatternMatcher = null;
- mBssidPatternMatcher = null;
- mIsEnhancedOpen = false;
- mWpa2PskPassphrase = null;
- mWpa3SaePassphrase = null;
- mWpa2EnterpriseConfig = null;
- mWpa3EnterpriseConfig = null;
- mIsHiddenSSID = false;
- }
-
- /**
- * Set the unicode SSID match pattern to use for filtering networks from scan results.
- * <p>
- * <li>Overrides any previous value set using {@link #setSsid(String)} or
- * {@link #setSsidPattern(PatternMatcher)}.</li>
- *
- * @param ssidPattern Instance of {@link PatternMatcher} containing the UTF-8 encoded
- * string pattern to use for matching the network's SSID.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setSsidPattern(@NonNull PatternMatcher ssidPattern) {
- checkNotNull(ssidPattern);
- mSsidPatternMatcher = ssidPattern;
- return this;
- }
-
- /**
- * Set the unicode SSID for the network.
- * <p>
- * <li>Sets the SSID to use for filtering networks from scan results. Will only match
- * networks whose SSID is identical to the UTF-8 encoding of the specified value.</li>
- * <li>Overrides any previous value set using {@link #setSsid(String)} or
- * {@link #setSsidPattern(PatternMatcher)}.</li>
- *
- * @param ssid The SSID of the network. It must be valid Unicode.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if the SSID is not valid unicode.
- */
- public @NonNull Builder setSsid(@NonNull String ssid) {
- checkNotNull(ssid);
- final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
- if (!unicodeEncoder.canEncode(ssid)) {
- throw new IllegalArgumentException("SSID is not a valid unicode string");
- }
- mSsidPatternMatcher = new PatternMatcher(ssid, PatternMatcher.PATTERN_LITERAL);
- return this;
- }
-
- /**
- * Set the BSSID match pattern to use for filtering networks from scan results.
- * Will match all networks with BSSID which satisfies the following:
- * {@code BSSID & mask == baseAddress}.
- * <p>
- * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
- * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
- *
- * @param baseAddress Base address for BSSID pattern.
- * @param mask Mask for BSSID pattern.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setBssidPattern(
- @NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
- checkNotNull(baseAddress);
- checkNotNull(mask);
- mBssidPatternMatcher = Pair.create(baseAddress, mask);
- return this;
- }
-
- /**
- * Set the BSSID to use for filtering networks from scan results. Will only match network
- * whose BSSID is identical to the specified value.
- * <p>
- * <li>Sets the BSSID to use for filtering networks from scan results. Will only match
- * networks whose BSSID is identical to specified value.</li>
- * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
- * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
- *
- * @param bssid BSSID of the network.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setBssid(@NonNull MacAddress bssid) {
- checkNotNull(bssid);
- mBssidPatternMatcher = Pair.create(bssid, MATCH_EXACT_BSSID_PATTERN_MASK);
- return this;
- }
-
- /**
- * Specifies whether this represents an Enhanced Open (OWE) network.
- *
- * @param isEnhancedOpen {@code true} to indicate that the network uses enhanced open,
- * {@code false} otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setIsEnhancedOpen(boolean isEnhancedOpen) {
- mIsEnhancedOpen = isEnhancedOpen;
- return this;
- }
-
- /**
- * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to
- * WPA2-PSK networks.
- *
- * @param passphrase passphrase of the network.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
- */
- public @NonNull Builder setWpa2Passphrase(@NonNull String passphrase) {
- checkNotNull(passphrase);
- final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
- if (!asciiEncoder.canEncode(passphrase)) {
- throw new IllegalArgumentException("passphrase not ASCII encodable");
- }
- mWpa2PskPassphrase = passphrase;
- return this;
- }
-
- /**
- * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to WPA3-SAE
- * networks.
- *
- * @param passphrase passphrase of the network.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
- */
- public @NonNull Builder setWpa3Passphrase(@NonNull String passphrase) {
- checkNotNull(passphrase);
- final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
- if (!asciiEncoder.canEncode(passphrase)) {
- throw new IllegalArgumentException("passphrase not ASCII encodable");
- }
- mWpa3SaePassphrase = passphrase;
- return this;
- }
-
- /**
- * Set the associated enterprise configuration for this network. Needed for authenticating
- * to WPA2-EAP networks. See {@link WifiEnterpriseConfig} for description.
- *
- * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setWpa2EnterpriseConfig(
- @NonNull WifiEnterpriseConfig enterpriseConfig) {
- checkNotNull(enterpriseConfig);
- mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
- return this;
- }
-
- /**
- * Set the associated enterprise configuration for this network. Needed for authenticating
- * to WPA3-SuiteB networks. See {@link WifiEnterpriseConfig} for description.
- *
- * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setWpa3EnterpriseConfig(
- @NonNull WifiEnterpriseConfig enterpriseConfig) {
- checkNotNull(enterpriseConfig);
- mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
- return this;
- }
-
- /**
- * Specifies whether this represents a hidden network.
- * <p>
- * <li>Setting this disallows the usage of {@link #setSsidPattern(PatternMatcher)} since
- * hidden networks need to be explicitly probed for.</li>
- * <li>If not set, defaults to false (i.e not a hidden network).</li>
- *
- * @param isHiddenSsid {@code true} to indicate that the network is hidden, {@code false}
- * otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setIsHiddenSsid(boolean isHiddenSsid) {
- mIsHiddenSSID = isHiddenSsid;
- return this;
- }
-
- private void setSecurityParamsInWifiConfiguration(
- @NonNull WifiConfiguration configuration) {
- if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
- // WifiConfiguration.preSharedKey needs quotes around ASCII password.
- configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\"";
- } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network.
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
- // WifiConfiguration.preSharedKey needs quotes around ASCII password.
- configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\"";
- } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
- configuration.enterpriseConfig = mWpa2EnterpriseConfig;
- } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
- configuration.enterpriseConfig = mWpa3EnterpriseConfig;
- } else if (mIsEnhancedOpen) { // OWE network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
- } else { // Open network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
- }
- }
-
- /**
- * Helper method to build WifiConfiguration object from the builder.
- * @return Instance of {@link WifiConfiguration}.
- */
- private WifiConfiguration buildWifiConfiguration() {
- final WifiConfiguration wifiConfiguration = new WifiConfiguration();
- // WifiConfiguration.SSID needs quotes around unicode SSID.
- if (mSsidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) {
- wifiConfiguration.SSID = "\"" + mSsidPatternMatcher.getPath() + "\"";
- }
- if (mBssidPatternMatcher.second == MATCH_EXACT_BSSID_PATTERN_MASK) {
- wifiConfiguration.BSSID = mBssidPatternMatcher.first.toString();
- }
- setSecurityParamsInWifiConfiguration(wifiConfiguration);
- wifiConfiguration.hiddenSSID = mIsHiddenSSID;
- return wifiConfiguration;
- }
-
- private boolean hasSetAnyPattern() {
- return mSsidPatternMatcher != null || mBssidPatternMatcher != null;
- }
-
- private void setMatchAnyPatternIfUnset() {
- if (mSsidPatternMatcher == null) {
- mSsidPatternMatcher = new PatternMatcher(MATCH_ALL_SSID_PATTERN_PATH,
- PatternMatcher.PATTERN_SIMPLE_GLOB);
- }
- if (mBssidPatternMatcher == null) {
- mBssidPatternMatcher = MATCH_ALL_BSSID_PATTERN;
- }
- }
-
- private boolean hasSetMatchNonePattern() {
- if (mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_PREFIX
- && mSsidPatternMatcher.getPath().equals(MATCH_EMPTY_SSID_PATTERN_PATH)) {
- return true;
- }
- if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN1)) {
- return true;
- }
- if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN2)) {
- return true;
- }
- return false;
- }
-
- private boolean hasSetMatchAllPattern() {
- if ((mSsidPatternMatcher.match(MATCH_EMPTY_SSID_PATTERN_PATH))
- && mBssidPatternMatcher.equals(MATCH_ALL_BSSID_PATTERN)) {
- return true;
- }
- return false;
- }
-
- private void validateSecurityParams() {
- int numSecurityTypes = 0;
- numSecurityTypes += mIsEnhancedOpen ? 1 : 0;
- numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0;
- numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0;
- numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0;
- numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0;
- if (numSecurityTypes > 1) {
- throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase,"
- + "setWpa3Passphrase, setWpa2EnterpriseConfig or setWpa3EnterpriseConfig"
- + " can be invoked for network specifier");
- }
- }
-
- /**
- * Create a specifier object used to request a local Wi-Fi network. The generated
- * {@link NetworkSpecifier} should be used in
- * {@link NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} when building
- * the {@link NetworkRequest}. These specifiers can only be used to request a local wifi
- * network (i.e no internet capability). So, the device will not switch it's default route
- * to wifi if there are other transports (cellular for example) available.
- *<p>
- * Note: Apps can set a combination of network match params:
- * <li> SSID Pattern using {@link #setSsidPattern(PatternMatcher)} OR Specific SSID using
- * {@link #setSsid(String)}. </li>
- * AND/OR
- * <li> BSSID Pattern using {@link #setBssidPattern(MacAddress, MacAddress)} OR Specific
- * BSSID using {@link #setBssid(MacAddress)} </li>
- * to trigger connection to a network that matches the set params.
- * The system will find the set of networks matching the request and present the user
- * with a system dialog which will allow the user to select a specific Wi-Fi network to
- * connect to or to deny the request.
- *</p>
- *
- * For example:
- * To connect to an open network with a SSID prefix of "test" and a BSSID OUI of "10:03:23":
- *
- * <pre>{@code
- * final NetworkSpecifier specifier =
- * new Builder()
- * .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
- * .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"),
- * MacAddress.fromString("ff:ff:ff:00:00:00"))
- * .build()
- * final NetworkRequest request =
- * new NetworkRequest.Builder()
- * .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
- * .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- * .setNetworkSpecifier(specifier)
- * .build();
- * final ConnectivityManager connectivityManager =
- * context.getSystemService(Context.CONNECTIVITY_SERVICE);
- * final NetworkCallback networkCallback = new NetworkCallback() {
- * ...
- * {@literal @}Override
- * void onAvailable(...) {}
- * // etc.
- * };
- * connectivityManager.requestNetwork(request, networkCallback);
- * }</pre>
- *
- * @return Instance of {@link NetworkSpecifier}.
- * @throws IllegalStateException on invalid params set.
- */
- public @NonNull WifiNetworkSpecifier build() {
- if (!hasSetAnyPattern()) {
- throw new IllegalStateException("one of setSsidPattern/setSsid/setBssidPattern/"
- + "setBssid should be invoked for specifier");
- }
- setMatchAnyPatternIfUnset();
- if (hasSetMatchNonePattern()) {
- throw new IllegalStateException("cannot set match-none pattern for specifier");
- }
- if (hasSetMatchAllPattern()) {
- throw new IllegalStateException("cannot set match-all pattern for specifier");
- }
- if (mIsHiddenSSID && mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL) {
- throw new IllegalStateException("setSsid should also be invoked when "
- + "setIsHiddenSsid is invoked for network specifier");
- }
- validateSecurityParams();
-
- return new WifiNetworkSpecifier(
- mSsidPatternMatcher,
- mBssidPatternMatcher,
- buildWifiConfiguration());
- }
- }
-
- /**
- * SSID pattern match specified by the app.
- * @hide
- */
- public final PatternMatcher ssidPatternMatcher;
-
- /**
- * BSSID pattern match specified by the app.
- * Pair of <BaseAddress, Mask>.
- * @hide
- */
- public final Pair<MacAddress, MacAddress> bssidPatternMatcher;
-
- /**
- * Security credentials for the network.
- * <p>
- * Note: {@link WifiConfiguration#SSID} & {@link WifiConfiguration#BSSID} fields from
- * WifiConfiguration are not used. Instead we use the {@link #ssidPatternMatcher} &
- * {@link #bssidPatternMatcher} fields embedded directly
- * within {@link WifiNetworkSpecifier}.
- * @hide
- */
- public final WifiConfiguration wifiConfiguration;
-
- /** @hide */
- public WifiNetworkSpecifier() throws IllegalAccessException {
- throw new IllegalAccessException("Use the builder to create an instance");
- }
-
- /** @hide */
- public WifiNetworkSpecifier(@NonNull PatternMatcher ssidPatternMatcher,
- @NonNull Pair<MacAddress, MacAddress> bssidPatternMatcher,
- @NonNull WifiConfiguration wifiConfiguration) {
- checkNotNull(ssidPatternMatcher);
- checkNotNull(bssidPatternMatcher);
- checkNotNull(wifiConfiguration);
-
- this.ssidPatternMatcher = ssidPatternMatcher;
- this.bssidPatternMatcher = bssidPatternMatcher;
- this.wifiConfiguration = wifiConfiguration;
- }
-
- public static final @NonNull Creator<WifiNetworkSpecifier> CREATOR =
- new Creator<WifiNetworkSpecifier>() {
- @Override
- public WifiNetworkSpecifier createFromParcel(Parcel in) {
- PatternMatcher ssidPatternMatcher = in.readParcelable(/* classLoader */null);
- MacAddress baseAddress = in.readParcelable(null);
- MacAddress mask = in.readParcelable(null);
- Pair<MacAddress, MacAddress> bssidPatternMatcher =
- Pair.create(baseAddress, mask);
- WifiConfiguration wifiConfiguration = in.readParcelable(null);
- return new WifiNetworkSpecifier(ssidPatternMatcher, bssidPatternMatcher,
- wifiConfiguration);
- }
-
- @Override
- public WifiNetworkSpecifier[] newArray(int size) {
- return new WifiNetworkSpecifier[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(ssidPatternMatcher, flags);
- dest.writeParcelable(bssidPatternMatcher.first, flags);
- dest.writeParcelable(bssidPatternMatcher.second, flags);
- dest.writeParcelable(wifiConfiguration, flags);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(
- ssidPatternMatcher.getPath(), ssidPatternMatcher.getType(), bssidPatternMatcher,
- wifiConfiguration.allowedKeyManagement);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof WifiNetworkSpecifier)) {
- return false;
- }
- WifiNetworkSpecifier lhs = (WifiNetworkSpecifier) obj;
- return Objects.equals(this.ssidPatternMatcher.getPath(),
- lhs.ssidPatternMatcher.getPath())
- && Objects.equals(this.ssidPatternMatcher.getType(),
- lhs.ssidPatternMatcher.getType())
- && Objects.equals(this.bssidPatternMatcher,
- lhs.bssidPatternMatcher)
- && Objects.equals(this.wifiConfiguration.allowedKeyManagement,
- lhs.wifiConfiguration.allowedKeyManagement);
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("WifiNetworkSpecifier [")
- .append(", SSID Match pattern=").append(ssidPatternMatcher)
- .append(", BSSID Match pattern=").append(bssidPatternMatcher)
- .append(", SSID=").append(wifiConfiguration.SSID)
- .append(", BSSID=").append(wifiConfiguration.BSSID)
- .append("]")
- .toString();
- }
-
- /** @hide */
- @Override
- public boolean canBeSatisfiedBy(NetworkSpecifier other) {
- if (other instanceof WifiNetworkAgentSpecifier) {
- return ((WifiNetworkAgentSpecifier) other).satisfiesNetworkSpecifier(this);
- }
- // Specific requests are checked for equality although testing for equality of 2 patterns do
- // not make much sense!
- return equals(other);
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
deleted file mode 100644
index 4d3a2c0..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ /dev/null
@@ -1,962 +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.net.wifi;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * The Network Suggestion object is used to provide a Wi-Fi network for consideration when
- * auto-connecting to networks. Apps cannot directly create this object, they must use
- * {@link WifiNetworkSuggestion.Builder#build()} to obtain an instance of this object.
- *<p>
- * Apps can provide a list of such networks to the platform using
- * {@link WifiManager#addNetworkSuggestions(List)}.
- */
-public final class WifiNetworkSuggestion implements Parcelable {
- /**
- * Builder used to create {@link WifiNetworkSuggestion} objects.
- */
- public static final class Builder {
- private static final int UNASSIGNED_PRIORITY = -1;
-
- /**
- * SSID of the network.
- */
- private String mSsid;
- /**
- * Optional BSSID within the network.
- */
- private MacAddress mBssid;
- /**
- * Whether this is an OWE network or not.
- */
- private boolean mIsEnhancedOpen;
- /**
- * Pre-shared key for use with WPA-PSK networks.
- */
- private @Nullable String mWpa2PskPassphrase;
- /**
- * Pre-shared key for use with WPA3-SAE networks.
- */
- private @Nullable String mWpa3SaePassphrase;
- /**
- * The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the WPA-EAP networks.
- */
- private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
- /**
- * The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the SuiteB networks.
- */
- private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
- /**
- * The passpoint config for use with Hotspot 2.0 network
- */
- private @Nullable PasspointConfiguration mPasspointConfiguration;
- /**
- * This is a network that does not broadcast its SSID, so an
- * SSID-specific probe request must be used for scans.
- */
- private boolean mIsHiddenSSID;
- /**
- * Whether app needs to log in to captive portal to obtain Internet access.
- */
- private boolean mIsAppInteractionRequired;
- /**
- * Whether user needs to log in to captive portal to obtain Internet access.
- */
- private boolean mIsUserInteractionRequired;
- /**
- * Whether this network is metered or not.
- */
- private int mMeteredOverride;
- /**
- * Priority of this network among other network suggestions provided by the app.
- * The lower the number, the higher the priority (i.e value of 0 = highest priority).
- */
- private int mPriority;
-
- /**
- * The carrier ID identifies the operator who provides this network configuration.
- * see {@link TelephonyManager#getSimCarrierId()}
- */
- private int mCarrierId;
-
- /**
- * Whether this network is shared credential with user to allow user manually connect.
- */
- private boolean mIsSharedWithUser;
-
- /**
- * Whether the setCredentialSharedWithUser have been called.
- */
- private boolean mIsSharedWithUserSet;
-
- /**
- * Whether this network is initialized with auto-join enabled (the default) or not.
- */
- private boolean mIsInitialAutojoinEnabled;
-
- /**
- * Pre-shared key for use with WAPI-PSK networks.
- */
- private @Nullable String mWapiPskPassphrase;
-
- /**
- * The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the WAPI networks.
- */
- private @Nullable WifiEnterpriseConfig mWapiEnterpriseConfig;
-
- /**
- * Whether this network will be brought up as untrusted (TRUSTED capability bit removed).
- */
- private boolean mIsNetworkUntrusted;
-
- public Builder() {
- mSsid = null;
- mBssid = null;
- mIsEnhancedOpen = false;
- mWpa2PskPassphrase = null;
- mWpa3SaePassphrase = null;
- mWpa2EnterpriseConfig = null;
- mWpa3EnterpriseConfig = null;
- mPasspointConfiguration = null;
- mIsHiddenSSID = false;
- mIsAppInteractionRequired = false;
- mIsUserInteractionRequired = false;
- mMeteredOverride = WifiConfiguration.METERED_OVERRIDE_NONE;
- mIsSharedWithUser = true;
- mIsSharedWithUserSet = false;
- mIsInitialAutojoinEnabled = true;
- mPriority = UNASSIGNED_PRIORITY;
- mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
- mWapiPskPassphrase = null;
- mWapiEnterpriseConfig = null;
- mIsNetworkUntrusted = false;
- }
-
- /**
- * Set the unicode SSID for the network.
- * <p>
- * <li>Overrides any previous value set using {@link #setSsid(String)}.</li>
- *
- * @param ssid The SSID of the network. It must be valid Unicode.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if the SSID is not valid unicode.
- */
- public @NonNull Builder setSsid(@NonNull String ssid) {
- checkNotNull(ssid);
- final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
- if (!unicodeEncoder.canEncode(ssid)) {
- throw new IllegalArgumentException("SSID is not a valid unicode string");
- }
- mSsid = new String(ssid);
- return this;
- }
-
- /**
- * Set the BSSID to use for filtering networks from scan results. Will only match network
- * whose BSSID is identical to the specified value.
- * <p>
- * <li Sets a specific BSSID for the network suggestion. If set, only the specified BSSID
- * with the specified SSID will be considered for connection.
- * <li>If set, only the specified BSSID with the specified SSID will be considered for
- * connection.</li>
- * <li>If not set, all BSSIDs with the specified SSID will be considered for connection.
- * </li>
- * <li>Overrides any previous value set using {@link #setBssid(MacAddress)}.</li>
- *
- * @param bssid BSSID of the network.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setBssid(@NonNull MacAddress bssid) {
- checkNotNull(bssid);
- mBssid = MacAddress.fromBytes(bssid.toByteArray());
- return this;
- }
-
- /**
- * Specifies whether this represents an Enhanced Open (OWE) network.
- *
- * @param isEnhancedOpen {@code true} to indicate that the network used enhanced open,
- * {@code false} otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setIsEnhancedOpen(boolean isEnhancedOpen) {
- mIsEnhancedOpen = isEnhancedOpen;
- return this;
- }
-
- /**
- * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to
- * WPA2-PSK networks.
- *
- * @param passphrase passphrase of the network.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
- */
- public @NonNull Builder setWpa2Passphrase(@NonNull String passphrase) {
- checkNotNull(passphrase);
- final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
- if (!asciiEncoder.canEncode(passphrase)) {
- throw new IllegalArgumentException("passphrase not ASCII encodable");
- }
- mWpa2PskPassphrase = passphrase;
- return this;
- }
-
- /**
- * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to WPA3-SAE
- * networks.
- *
- * @param passphrase passphrase of the network.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
- */
- public @NonNull Builder setWpa3Passphrase(@NonNull String passphrase) {
- checkNotNull(passphrase);
- final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
- if (!asciiEncoder.canEncode(passphrase)) {
- throw new IllegalArgumentException("passphrase not ASCII encodable");
- }
- mWpa3SaePassphrase = passphrase;
- return this;
- }
-
- /**
- * Set the associated enterprise configuration for this network. Needed for authenticating
- * to WPA2 enterprise networks. See {@link WifiEnterpriseConfig} for description.
- *
- * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if configuration CA certificate or
- * AltSubjectMatch/DomainSuffixMatch is not set.
- */
- public @NonNull Builder setWpa2EnterpriseConfig(
- @NonNull WifiEnterpriseConfig enterpriseConfig) {
- checkNotNull(enterpriseConfig);
- if (enterpriseConfig.isInsecure()) {
- throw new IllegalArgumentException("Enterprise configuration is insecure");
- }
- mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
- return this;
- }
-
- /**
- * Set the associated enterprise configuration for this network. Needed for authenticating
- * to WPA3 enterprise networks. See {@link WifiEnterpriseConfig} for description.
- *
- * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if configuration CA certificate or
- * AltSubjectMatch/DomainSuffixMatch is not set.
- */
- public @NonNull Builder setWpa3EnterpriseConfig(
- @NonNull WifiEnterpriseConfig enterpriseConfig) {
- checkNotNull(enterpriseConfig);
- if (enterpriseConfig.isInsecure()) {
- throw new IllegalArgumentException("Enterprise configuration is insecure");
- }
- mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
- return this;
- }
-
- /**
- * Set the associated Passpoint configuration for this network. Needed for authenticating
- * to Hotspot 2.0 networks. See {@link PasspointConfiguration} for description.
- *
- * @param passpointConfig Instance of {@link PasspointConfiguration}.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if passpoint configuration is invalid.
- */
- public @NonNull Builder setPasspointConfig(
- @NonNull PasspointConfiguration passpointConfig) {
- checkNotNull(passpointConfig);
- if (!passpointConfig.validate()) {
- throw new IllegalArgumentException("Passpoint configuration is invalid");
- }
- mPasspointConfiguration = passpointConfig;
- return this;
- }
-
- /**
- * Set the carrier ID of the network operator. The carrier ID associates a Suggested
- * network with a specific carrier (and therefore SIM). The carrier ID must be provided
- * for any network which uses the SIM-based authentication: e.g. EAP-SIM, EAP-AKA,
- * EAP-AKA', and EAP-PEAP with SIM-based phase 2 authentication.
- * @param carrierId see {@link TelephonyManager#getSimCarrierId()}.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING)
- public @NonNull Builder setCarrierId(int carrierId) {
- mCarrierId = carrierId;
- return this;
- }
-
- /**
- * Set the ASCII WAPI passphrase for this network. Needed for authenticating to
- * WAPI-PSK networks.
- *
- * @param passphrase passphrase of the network.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
- *
- */
- public @NonNull Builder setWapiPassphrase(@NonNull String passphrase) {
- checkNotNull(passphrase);
- final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
- if (!asciiEncoder.canEncode(passphrase)) {
- throw new IllegalArgumentException("passphrase not ASCII encodable");
- }
- mWapiPskPassphrase = passphrase;
- return this;
- }
-
- /**
- * Set the associated enterprise configuration for this network. Needed for authenticating
- * to WAPI-CERT networks. See {@link WifiEnterpriseConfig} for description.
- *
- * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setWapiEnterpriseConfig(
- @NonNull WifiEnterpriseConfig enterpriseConfig) {
- checkNotNull(enterpriseConfig);
- mWapiEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
- return this;
- }
-
- /**
- * Specifies whether this represents a hidden network.
- * <p>
- * <li>If not set, defaults to false (i.e not a hidden network).</li>
- *
- * @param isHiddenSsid {@code true} to indicate that the network is hidden, {@code false}
- * otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setIsHiddenSsid(boolean isHiddenSsid) {
- mIsHiddenSSID = isHiddenSsid;
- return this;
- }
-
- /**
- * Specifies whether the app needs to log in to a captive portal to obtain Internet access.
- * <p>
- * This will dictate if the directed broadcast
- * {@link WifiManager#ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} will be sent to the
- * app after successfully connecting to the network.
- * Use this for captive portal type networks where the app needs to authenticate the user
- * before the device can access the network.
- * <p>
- * <li>If not set, defaults to false (i.e no app interaction required).</li>
- *
- * @param isAppInteractionRequired {@code true} to indicate that app interaction is
- * required, {@code false} otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setIsAppInteractionRequired(boolean isAppInteractionRequired) {
- mIsAppInteractionRequired = isAppInteractionRequired;
- return this;
- }
-
- /**
- * Specifies whether the user needs to log in to a captive portal to obtain Internet access.
- * <p>
- * <li>If not set, defaults to false (i.e no user interaction required).</li>
- *
- * @param isUserInteractionRequired {@code true} to indicate that user interaction is
- * required, {@code false} otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setIsUserInteractionRequired(boolean isUserInteractionRequired) {
- mIsUserInteractionRequired = isUserInteractionRequired;
- return this;
- }
-
- /**
- * Specify the priority of this network among other network suggestions provided by the same
- * app (priorities have no impact on suggestions by different apps). The higher the number,
- * the higher the priority (i.e value of 0 = lowest priority).
- * <p>
- * <li>If not set, defaults a lower priority than any assigned priority.</li>
- *
- * @param priority Integer number representing the priority among suggestions by the app.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- * @throws IllegalArgumentException if the priority value is negative.
- */
- public @NonNull Builder setPriority(@IntRange(from = 0) int priority) {
- if (priority < 0) {
- throw new IllegalArgumentException("Invalid priority value " + priority);
- }
- mPriority = priority;
- return this;
- }
-
- /**
- * Specifies whether this network is metered.
- * <p>
- * <li>If not set, defaults to detect automatically.</li>
- *
- * @param isMetered {@code true} to indicate that the network is metered, {@code false}
- * for not metered.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setIsMetered(boolean isMetered) {
- if (isMetered) {
- mMeteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
- } else {
- mMeteredOverride = WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
- }
- return this;
- }
-
- /**
- * Specifies whether the network credentials provided with this suggestion can be used by
- * the user to explicitly (manually) connect to this network. If true this network will
- * appear in the Wi-Fi Picker (in Settings) and the user will be able to select and connect
- * to it with the provided credentials. If false, the user will need to enter network
- * credentials and the resulting configuration will become a user saved network.
- * <p>
- * <li>Note: Only valid for secure (non-open) networks.
- * <li>If not set, defaults to true (i.e. allow user to manually connect) for secure
- * networks and false for open networks.</li>
- *
- * @param isShared {@code true} to indicate that the credentials may be used by the user to
- * manually connect to the network, {@code false} otherwise.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setCredentialSharedWithUser(boolean isShared) {
- mIsSharedWithUser = isShared;
- mIsSharedWithUserSet = true;
- return this;
- }
-
- /**
- * Specifies whether the suggestion is created with auto-join enabled or disabled. The
- * user may modify the auto-join configuration of a suggestion directly once the device
- * associates to the network.
- * <p>
- * If auto-join is initialized as disabled the user may still be able to manually connect
- * to the network. Therefore, disabling auto-join only makes sense if
- * {@link #setCredentialSharedWithUser(boolean)} is set to true (the default) which
- * itself implies a secure (non-open) network.
- * <p>
- * If not set, defaults to true (i.e. auto-join is initialized as enabled).
- *
- * @param enabled true for initializing with auto-join enabled (the default), false to
- * initializing with auto-join disabled.
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setIsInitialAutojoinEnabled(boolean enabled) {
- mIsInitialAutojoinEnabled = enabled;
- return this;
- }
-
- /**
- * Specifies whether the system will bring up the network (if selected) as untrusted. An
- * untrusted network has its {@link android.net.NetworkCapabilities#NET_CAPABILITY_TRUSTED}
- * capability removed. The Wi-Fi network selection process may use this information to
- * influence priority of the suggested network for Wi-Fi network selection (most likely to
- * reduce it). The connectivity service may use this information to influence the overall
- * network configuration of the device.
- * <p>
- * <li> An untrusted network's credentials may not be shared with the user using
- * {@link #setCredentialSharedWithUser(boolean)}.</li>
- * <li> If not set, defaults to false (i.e. network is trusted).</li>
- *
- * @param isUntrusted Boolean indicating whether the network should be brought up untrusted
- * (if true) or trusted (if false).
- * @return Instance of {@link Builder} to enable chaining of the builder method.
- */
- public @NonNull Builder setUntrusted(boolean isUntrusted) {
- mIsNetworkUntrusted = isUntrusted;
- return this;
- }
-
- private void setSecurityParamsInWifiConfiguration(
- @NonNull WifiConfiguration configuration) {
- if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
- // WifiConfiguration.preSharedKey needs quotes around ASCII password.
- configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\"";
- } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network.
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
- // WifiConfiguration.preSharedKey needs quotes around ASCII password.
- configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\"";
- } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
- configuration.enterpriseConfig = mWpa2EnterpriseConfig;
- } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
- configuration.enterpriseConfig = mWpa3EnterpriseConfig;
- } else if (mIsEnhancedOpen) { // OWE network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
- } else if (!TextUtils.isEmpty(mWapiPskPassphrase)) { // WAPI-PSK network.
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WAPI_PSK);
- // WifiConfiguration.preSharedKey needs quotes around ASCII password.
- configuration.preSharedKey = "\"" + mWapiPskPassphrase + "\"";
- } else if (mWapiEnterpriseConfig != null) { // WAPI-CERT network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WAPI_CERT);
- configuration.enterpriseConfig = mWapiEnterpriseConfig;
- } else { // Open network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
- }
- }
-
- /**
- * Helper method to build WifiConfiguration object from the builder.
- * @return Instance of {@link WifiConfiguration}.
- */
- private WifiConfiguration buildWifiConfiguration() {
- final WifiConfiguration wifiConfiguration = new WifiConfiguration();
- // WifiConfiguration.SSID needs quotes around unicode SSID.
- wifiConfiguration.SSID = "\"" + mSsid + "\"";
- if (mBssid != null) {
- wifiConfiguration.BSSID = mBssid.toString();
- }
-
- setSecurityParamsInWifiConfiguration(wifiConfiguration);
-
- wifiConfiguration.hiddenSSID = mIsHiddenSSID;
- wifiConfiguration.priority = mPriority;
- wifiConfiguration.meteredOverride = mMeteredOverride;
- wifiConfiguration.carrierId = mCarrierId;
- wifiConfiguration.trusted = !mIsNetworkUntrusted;
- return wifiConfiguration;
- }
-
- private void validateSecurityParams() {
- int numSecurityTypes = 0;
- numSecurityTypes += mIsEnhancedOpen ? 1 : 0;
- numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0;
- numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0;
- numSecurityTypes += !TextUtils.isEmpty(mWapiPskPassphrase) ? 1 : 0;
- numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0;
- numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0;
- numSecurityTypes += mWapiEnterpriseConfig != null ? 1 : 0;
- numSecurityTypes += mPasspointConfiguration != null ? 1 : 0;
- if (numSecurityTypes > 1) {
- throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase,"
- + " setWpa3Passphrase, setWpa2EnterpriseConfig, setWpa3EnterpriseConfig"
- + " setWapiPassphrase, setWapiCertSuite, setIsWapiCertSuiteAuto"
- + " or setPasspointConfig can be invoked for network suggestion");
- }
- }
-
- private WifiConfiguration buildWifiConfigurationForPasspoint() {
- WifiConfiguration wifiConfiguration = new WifiConfiguration();
- wifiConfiguration.FQDN = mPasspointConfiguration.getHomeSp().getFqdn();
- wifiConfiguration.setPasspointUniqueId(mPasspointConfiguration.getUniqueId());
- wifiConfiguration.priority = mPriority;
- wifiConfiguration.meteredOverride = mMeteredOverride;
- wifiConfiguration.trusted = !mIsNetworkUntrusted;
- mPasspointConfiguration.setCarrierId(mCarrierId);
- mPasspointConfiguration.setMeteredOverride(wifiConfiguration.meteredOverride);
- return wifiConfiguration;
- }
-
- /**
- * Create a network suggestion object for use in
- * {@link WifiManager#addNetworkSuggestions(List)}.
- *
- *<p class="note">
- * <b>Note:</b> Apps can set a combination of SSID using {@link #setSsid(String)} and BSSID
- * using {@link #setBssid(MacAddress)} to provide more fine grained network suggestions to
- * the platform.
- * </p>
- *
- * For example:
- * To provide credentials for one open, one WPA2, one WPA3 network with their
- * corresponding SSID's and one with Passpoint config:
- *
- * <pre>{@code
- * final WifiNetworkSuggestion suggestion1 =
- * new Builder()
- * .setSsid("test111111")
- * .build();
- * final WifiNetworkSuggestion suggestion2 =
- * new Builder()
- * .setSsid("test222222")
- * .setWpa2Passphrase("test123456")
- * .build();
- * final WifiNetworkSuggestion suggestion3 =
- * new Builder()
- * .setSsid("test333333")
- * .setWpa3Passphrase("test6789")
- * .build();
- * final PasspointConfiguration passpointConfig= new PasspointConfiguration();
- * // configure passpointConfig to include a valid Passpoint configuration
- * final WifiNetworkSuggestion suggestion4 =
- * new Builder()
- * .setPasspointConfig(passpointConfig)
- * .build();
- * final List<WifiNetworkSuggestion> suggestionsList =
- * new ArrayList<WifiNetworkSuggestion> { {
- * add(suggestion1);
- * add(suggestion2);
- * add(suggestion3);
- * add(suggestion4);
- * } };
- * final WifiManager wifiManager =
- * context.getSystemService(Context.WIFI_SERVICE);
- * wifiManager.addNetworkSuggestions(suggestionsList);
- * // ...
- * }</pre>
- *
- * @return Instance of {@link WifiNetworkSuggestion}
- * @throws IllegalStateException on invalid params set
- * @see WifiNetworkSuggestion
- */
- public @NonNull WifiNetworkSuggestion build() {
- validateSecurityParams();
- WifiConfiguration wifiConfiguration;
- if (mPasspointConfiguration != null) {
- if (mSsid != null) {
- throw new IllegalStateException("setSsid should not be invoked for suggestion "
- + "with Passpoint configuration");
- }
- if (mIsHiddenSSID) {
- throw new IllegalStateException("setIsHiddenSsid should not be invoked for "
- + "suggestion with Passpoint configuration");
- }
- wifiConfiguration = buildWifiConfigurationForPasspoint();
- } else {
- if (mSsid == null) {
- throw new IllegalStateException("setSsid should be invoked for suggestion");
- }
- if (TextUtils.isEmpty(mSsid)) {
- throw new IllegalStateException("invalid ssid for suggestion");
- }
- if (mBssid != null
- && (mBssid.equals(MacAddress.BROADCAST_ADDRESS)
- || mBssid.equals(WifiManager.ALL_ZEROS_MAC_ADDRESS))) {
- throw new IllegalStateException("invalid bssid for suggestion");
- }
- wifiConfiguration = buildWifiConfiguration();
- if (wifiConfiguration.isOpenNetwork()) {
- if (mIsSharedWithUserSet && mIsSharedWithUser) {
- throw new IllegalStateException("Open network should not be "
- + "setCredentialSharedWithUser to true");
- }
- mIsSharedWithUser = false;
- }
- }
- if (!mIsSharedWithUser && !mIsInitialAutojoinEnabled) {
- throw new IllegalStateException("Should have not a network with both "
- + "setCredentialSharedWithUser and "
- + "setIsAutojoinEnabled set to false");
- }
- if (mIsNetworkUntrusted) {
- if (mIsSharedWithUserSet && mIsSharedWithUser) {
- throw new IllegalStateException("Should not be both"
- + "setCredentialSharedWithUser and +"
- + "setIsNetworkAsUntrusted to true");
- }
- mIsSharedWithUser = false;
- }
- return new WifiNetworkSuggestion(
- wifiConfiguration,
- mPasspointConfiguration,
- mIsAppInteractionRequired,
- mIsUserInteractionRequired,
- mIsSharedWithUser,
- mIsInitialAutojoinEnabled);
- }
- }
-
- /**
- * Network configuration for the provided network.
- * @hide
- */
- @NonNull
- public final WifiConfiguration wifiConfiguration;
-
- /**
- * Passpoint configuration for the provided network.
- * @hide
- */
- @Nullable
- public final PasspointConfiguration passpointConfiguration;
-
- /**
- * Whether app needs to log in to captive portal to obtain Internet access.
- * @hide
- */
- public final boolean isAppInteractionRequired;
-
- /**
- * Whether user needs to log in to captive portal to obtain Internet access.
- * @hide
- */
- public final boolean isUserInteractionRequired;
-
- /**
- * Whether app share credential with the user, allow user use provided credential to
- * connect network manually.
- * @hide
- */
- public final boolean isUserAllowedToManuallyConnect;
-
- /**
- * Whether the suggestion will be initialized as auto-joined or not.
- * @hide
- */
- public final boolean isInitialAutoJoinEnabled;
-
- /** @hide */
- public WifiNetworkSuggestion() {
- this.wifiConfiguration = new WifiConfiguration();
- this.passpointConfiguration = null;
- this.isAppInteractionRequired = false;
- this.isUserInteractionRequired = false;
- this.isUserAllowedToManuallyConnect = true;
- this.isInitialAutoJoinEnabled = true;
- }
-
- /** @hide */
- public WifiNetworkSuggestion(@NonNull WifiConfiguration networkConfiguration,
- @Nullable PasspointConfiguration passpointConfiguration,
- boolean isAppInteractionRequired,
- boolean isUserInteractionRequired,
- boolean isUserAllowedToManuallyConnect,
- boolean isInitialAutoJoinEnabled) {
- checkNotNull(networkConfiguration);
- this.wifiConfiguration = networkConfiguration;
- this.passpointConfiguration = passpointConfiguration;
-
- this.isAppInteractionRequired = isAppInteractionRequired;
- this.isUserInteractionRequired = isUserInteractionRequired;
- this.isUserAllowedToManuallyConnect = isUserAllowedToManuallyConnect;
- this.isInitialAutoJoinEnabled = isInitialAutoJoinEnabled;
- }
-
- public static final @NonNull Creator<WifiNetworkSuggestion> CREATOR =
- new Creator<WifiNetworkSuggestion>() {
- @Override
- public WifiNetworkSuggestion createFromParcel(Parcel in) {
- return new WifiNetworkSuggestion(
- in.readParcelable(null), // wifiConfiguration
- in.readParcelable(null), // PasspointConfiguration
- in.readBoolean(), // isAppInteractionRequired
- in.readBoolean(), // isUserInteractionRequired
- in.readBoolean(), // isSharedCredentialWithUser
- in.readBoolean() // isAutojoinEnabled
- );
- }
-
- @Override
- public WifiNetworkSuggestion[] newArray(int size) {
- return new WifiNetworkSuggestion[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(wifiConfiguration, flags);
- dest.writeParcelable(passpointConfiguration, flags);
- dest.writeBoolean(isAppInteractionRequired);
- dest.writeBoolean(isUserInteractionRequired);
- dest.writeBoolean(isUserAllowedToManuallyConnect);
- dest.writeBoolean(isInitialAutoJoinEnabled);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.BSSID,
- wifiConfiguration.allowedKeyManagement, wifiConfiguration.getKey());
- }
-
- /**
- * Equals for network suggestions.
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof WifiNetworkSuggestion)) {
- return false;
- }
- WifiNetworkSuggestion lhs = (WifiNetworkSuggestion) obj;
- if (this.passpointConfiguration == null ^ lhs.passpointConfiguration == null) {
- return false;
- }
-
- return TextUtils.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID)
- && TextUtils.equals(this.wifiConfiguration.BSSID, lhs.wifiConfiguration.BSSID)
- && Objects.equals(this.wifiConfiguration.allowedKeyManagement,
- lhs.wifiConfiguration.allowedKeyManagement)
- && TextUtils.equals(this.wifiConfiguration.getKey(),
- lhs.wifiConfiguration.getKey());
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("WifiNetworkSuggestion[ ")
- .append("SSID=").append(wifiConfiguration.SSID)
- .append(", BSSID=").append(wifiConfiguration.BSSID)
- .append(", FQDN=").append(wifiConfiguration.FQDN)
- .append(", isAppInteractionRequired=").append(isAppInteractionRequired)
- .append(", isUserInteractionRequired=").append(isUserInteractionRequired)
- .append(", isCredentialSharedWithUser=").append(isUserAllowedToManuallyConnect)
- .append(", isInitialAutoJoinEnabled=").append(isInitialAutoJoinEnabled)
- .append(", isUnTrusted=").append(!wifiConfiguration.trusted)
- .append(" ]");
- return sb.toString();
- }
-
- /**
- * Get the {@link WifiConfiguration} associated with this Suggestion.
- * @hide
- */
- @SystemApi
- @NonNull
- public WifiConfiguration getWifiConfiguration() {
- return wifiConfiguration;
- }
-
- /**
- * Get the BSSID, or null if unset.
- * @see Builder#setBssid(MacAddress)
- */
- @Nullable
- public MacAddress getBssid() {
- if (wifiConfiguration.BSSID == null) {
- return null;
- }
- return MacAddress.fromString(wifiConfiguration.BSSID);
- }
-
- /** @see Builder#setCredentialSharedWithUser(boolean) */
- public boolean isCredentialSharedWithUser() {
- return isUserAllowedToManuallyConnect;
- }
-
- /** @see Builder#setIsAppInteractionRequired(boolean) */
- public boolean isAppInteractionRequired() {
- return isAppInteractionRequired;
- }
-
- /** @see Builder#setIsEnhancedOpen(boolean) */
- public boolean isEnhancedOpen() {
- return wifiConfiguration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE);
- }
-
- /** @see Builder#setIsHiddenSsid(boolean) */
- public boolean isHiddenSsid() {
- return wifiConfiguration.hiddenSSID;
- }
-
- /** @see Builder#setIsInitialAutojoinEnabled(boolean) */
- public boolean isInitialAutojoinEnabled() {
- return isInitialAutoJoinEnabled;
- }
-
- /** @see Builder#setIsMetered(boolean) */
- public boolean isMetered() {
- return wifiConfiguration.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED;
- }
-
- /** @see Builder#setIsUserInteractionRequired(boolean) */
- public boolean isUserInteractionRequired() {
- return isUserInteractionRequired;
- }
-
- /**
- * Get the {@link PasspointConfiguration} associated with this Suggestion, or null if this
- * Suggestion is not for a Passpoint network.
- */
- @Nullable
- public PasspointConfiguration getPasspointConfig() {
- return passpointConfiguration;
- }
-
- /** @see Builder#setPriority(int) */
- @IntRange(from = 0)
- public int getPriority() {
- return wifiConfiguration.priority;
- }
-
- /**
- * Return the SSID of the network, or null if this is a Passpoint network.
- * @see Builder#setSsid(String)
- */
- @Nullable
- public String getSsid() {
- if (wifiConfiguration.SSID == null) {
- return null;
- }
- return WifiInfo.sanitizeSsid(wifiConfiguration.SSID);
- }
-
- /** @see Builder#setUntrusted(boolean) */
- public boolean isUntrusted() {
- return !wifiConfiguration.trusted;
- }
-
- /**
- * Get the WifiEnterpriseConfig, or null if unset.
- * @see Builder#setWapiEnterpriseConfig(WifiEnterpriseConfig)
- * @see Builder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)
- * @see Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)
- */
- @Nullable
- public WifiEnterpriseConfig getEnterpriseConfig() {
- return wifiConfiguration.enterpriseConfig;
- }
-
- /**
- * Get the passphrase, or null if unset.
- * @see Builder#setWapiPassphrase(String)
- * @see Builder#setWpa2Passphrase(String)
- * @see Builder#setWpa3Passphrase(String)
- */
- @Nullable
- public String getPassphrase() {
- if (wifiConfiguration.preSharedKey == null) {
- return null;
- }
- return WifiInfo.removeDoubleQuotes(wifiConfiguration.preSharedKey);
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
deleted file mode 100644
index 94771ac..0000000
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.content.Context;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.os.WorkSource;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * This class provides a way to scan the Wifi universe around the device
- * @hide
- */
-@SystemApi
-@SystemService(Context.WIFI_SCANNING_SERVICE)
-public class WifiScanner {
-
- /** @hide */
- public static final int WIFI_BAND_INDEX_24_GHZ = 0;
- /** @hide */
- public static final int WIFI_BAND_INDEX_5_GHZ = 1;
- /** @hide */
- public static final int WIFI_BAND_INDEX_5_GHZ_DFS_ONLY = 2;
- /** @hide */
- public static final int WIFI_BAND_INDEX_6_GHZ = 3;
- /** @hide */
- public static final int WIFI_BAND_COUNT = 4;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"WIFI_BAND_INDEX_"}, value = {
- WIFI_BAND_INDEX_24_GHZ,
- WIFI_BAND_INDEX_5_GHZ,
- WIFI_BAND_INDEX_5_GHZ_DFS_ONLY,
- WIFI_BAND_INDEX_6_GHZ})
- public @interface WifiBandIndex {}
-
- /** no band specified; use channel list instead */
- public static final int WIFI_BAND_UNSPECIFIED = 0;
- /** 2.4 GHz band */
- public static final int WIFI_BAND_24_GHZ = 1 << WIFI_BAND_INDEX_24_GHZ;
- /** 5 GHz band excluding DFS channels */
- public static final int WIFI_BAND_5_GHZ = 1 << WIFI_BAND_INDEX_5_GHZ;
- /** DFS channels from 5 GHz band only */
- public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 1 << WIFI_BAND_INDEX_5_GHZ_DFS_ONLY;
- /** 6 GHz band */
- public static final int WIFI_BAND_6_GHZ = 1 << WIFI_BAND_INDEX_6_GHZ;
-
- /**
- * Combination of bands
- * Note that those are only the common band combinations,
- * other combinations can be created by combining any of the basic bands above
- */
- /** Both 2.4 GHz band and 5 GHz band; no DFS channels */
- public static final int WIFI_BAND_BOTH = WIFI_BAND_24_GHZ | WIFI_BAND_5_GHZ;
- /**
- * 2.4Ghz band + DFS channels from 5 GHz band only
- * @hide
- */
- public static final int WIFI_BAND_24_GHZ_WITH_5GHZ_DFS =
- WIFI_BAND_24_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY;
- /** 5 GHz band including DFS channels */
- public static final int WIFI_BAND_5_GHZ_WITH_DFS = WIFI_BAND_5_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY;
- /** Both 2.4 GHz band and 5 GHz band; with DFS channels */
- public static final int WIFI_BAND_BOTH_WITH_DFS =
- WIFI_BAND_24_GHZ | WIFI_BAND_5_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY;
- /** 2.4 GHz band and 5 GHz band (no DFS channels) and 6 GHz */
- public static final int WIFI_BAND_24_5_6_GHZ = WIFI_BAND_BOTH | WIFI_BAND_6_GHZ;
- /** 2.4 GHz band and 5 GHz band; with DFS channels and 6 GHz */
- public static final int WIFI_BAND_24_5_WITH_DFS_6_GHZ =
- WIFI_BAND_BOTH_WITH_DFS | WIFI_BAND_6_GHZ;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"WIFI_BAND_"}, value = {
- WIFI_BAND_UNSPECIFIED,
- WIFI_BAND_24_GHZ,
- WIFI_BAND_5_GHZ,
- WIFI_BAND_BOTH,
- WIFI_BAND_5_GHZ_DFS_ONLY,
- WIFI_BAND_24_GHZ_WITH_5GHZ_DFS,
- WIFI_BAND_5_GHZ_WITH_DFS,
- WIFI_BAND_BOTH_WITH_DFS,
- WIFI_BAND_6_GHZ,
- WIFI_BAND_24_5_6_GHZ,
- WIFI_BAND_24_5_WITH_DFS_6_GHZ})
- public @interface WifiBand {}
-
- /**
- * All bands
- * @hide
- */
- public static final int WIFI_BAND_ALL = (1 << WIFI_BAND_COUNT) - 1;
-
- /** Minimum supported scanning period */
- public static final int MIN_SCAN_PERIOD_MS = 1000;
- /** Maximum supported scanning period */
- public static final int MAX_SCAN_PERIOD_MS = 1024000;
-
- /** No Error */
- public static final int REASON_SUCCEEDED = 0;
- /** Unknown error */
- public static final int REASON_UNSPECIFIED = -1;
- /** Invalid listener */
- public static final int REASON_INVALID_LISTENER = -2;
- /** Invalid request */
- public static final int REASON_INVALID_REQUEST = -3;
- /** Invalid request */
- public static final int REASON_NOT_AUTHORIZED = -4;
- /** An outstanding request with the same listener hasn't finished yet. */
- public static final int REASON_DUPLICATE_REQEUST = -5;
-
- /** @hide */
- public static final String GET_AVAILABLE_CHANNELS_EXTRA = "Channels";
-
- /**
- * Generic action callback invocation interface
- * @hide
- */
- @SystemApi
- public static interface ActionListener {
- public void onSuccess();
- public void onFailure(int reason, String description);
- }
-
- /**
- * Test if scan is a full scan. i.e. scanning all available bands.
- * For backward compatibility, since some apps don't include 6GHz in their requests yet,
- * lacking 6GHz band does not cause the result to be false.
- *
- * @param bandScanned bands that are fully scanned
- * @param excludeDfs when true, DFS band is excluded from the check
- * @return true if all bands are scanned, false otherwise
- *
- * @hide
- */
- public static boolean isFullBandScan(@WifiBand int bandScanned, boolean excludeDfs) {
- return (bandScanned | WIFI_BAND_6_GHZ | (excludeDfs ? WIFI_BAND_5_GHZ_DFS_ONLY : 0))
- == WIFI_BAND_ALL;
- }
-
- /**
- * Returns a list of all the possible channels for the given band(s).
- *
- * @param band one of the WifiScanner#WIFI_BAND_* constants, e.g. {@link #WIFI_BAND_24_GHZ}
- * @return a list of all the frequencies, in MHz, for the given band(s) e.g. channel 1 is
- * 2412, or null if an error occurred.
- *
- * @hide
- */
- @SystemApi
- @NonNull
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public List<Integer> getAvailableChannels(int band) {
- try {
- Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName(),
- mContext.getAttributionTag());
- List<Integer> channels = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
- return channels == null ? new ArrayList<>() : channels;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * provides channel specification for scanning
- */
- public static class ChannelSpec {
- /**
- * channel frequency in MHz; for example channel 1 is specified as 2412
- */
- public int frequency;
- /**
- * if true, scan this channel in passive fashion.
- * This flag is ignored on DFS channel specification.
- * @hide
- */
- public boolean passive; /* ignored on DFS channels */
- /**
- * how long to dwell on this channel
- * @hide
- */
- public int dwellTimeMS; /* not supported for now */
-
- /**
- * default constructor for channel spec
- */
- public ChannelSpec(int frequency) {
- this.frequency = frequency;
- passive = false;
- dwellTimeMS = 0;
- }
- }
-
- /**
- * reports {@link ScanListener#onResults} when underlying buffers are full
- * this is simply the lack of the {@link #REPORT_EVENT_AFTER_EACH_SCAN} flag
- * @deprecated It is not supported anymore.
- */
- @Deprecated
- public static final int REPORT_EVENT_AFTER_BUFFER_FULL = 0;
- /**
- * reports {@link ScanListener#onResults} after each scan
- */
- public static final int REPORT_EVENT_AFTER_EACH_SCAN = (1 << 0);
- /**
- * reports {@link ScanListener#onFullResult} whenever each beacon is discovered
- */
- public static final int REPORT_EVENT_FULL_SCAN_RESULT = (1 << 1);
- /**
- * Do not place scans in the chip's scan history buffer
- */
- public static final int REPORT_EVENT_NO_BATCH = (1 << 2);
-
- /**
- * Optimize the scan for lower latency.
- * @see ScanSettings#type
- */
- public static final int SCAN_TYPE_LOW_LATENCY = 0;
- /**
- * Optimize the scan for lower power usage.
- * @see ScanSettings#type
- */
- public static final int SCAN_TYPE_LOW_POWER = 1;
- /**
- * Optimize the scan for higher accuracy.
- * @see ScanSettings#type
- */
- public static final int SCAN_TYPE_HIGH_ACCURACY = 2;
-
- /** {@hide} */
- public static final String SCAN_PARAMS_SCAN_SETTINGS_KEY = "ScanSettings";
- /** {@hide} */
- public static final String SCAN_PARAMS_WORK_SOURCE_KEY = "WorkSource";
- /** {@hide} */
- public static final String REQUEST_PACKAGE_NAME_KEY = "PackageName";
- /** {@hide} */
- public static final String REQUEST_FEATURE_ID_KEY = "FeatureId";
-
- /**
- * scan configuration parameters to be sent to {@link #startBackgroundScan}
- */
- public static class ScanSettings implements Parcelable {
- /** Hidden network to be scanned for. */
- public static class HiddenNetwork {
- /** SSID of the network */
- @NonNull
- public final String ssid;
-
- /** Default constructor for HiddenNetwork. */
- public HiddenNetwork(@NonNull String ssid) {
- this.ssid = ssid;
- }
- }
-
- /** one of the WIFI_BAND values */
- public int band;
- /** list of channels; used when band is set to WIFI_BAND_UNSPECIFIED */
- public ChannelSpec[] channels;
- /**
- * List of hidden networks to scan for. Explicit probe requests are sent out for such
- * networks during scan. Only valid for single scan requests.
- */
- @NonNull
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public final List<HiddenNetwork> hiddenNetworks = new ArrayList<>();
- /**
- * period of background scan; in millisecond, 0 => single shot scan
- * @deprecated Background scan support has always been hardware vendor dependent. This
- * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
- * ScanListener)} instead for single scans.
- */
- @Deprecated
- public int periodInMs;
- /**
- * must have a valid REPORT_EVENT value
- * @deprecated Background scan support has always been hardware vendor dependent. This
- * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
- * ScanListener)} instead for single scans.
- */
- @Deprecated
- public int reportEvents;
- /**
- * defines number of bssids to cache from each scan
- * @deprecated Background scan support has always been hardware vendor dependent. This
- * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
- * ScanListener)} instead for single scans.
- */
- @Deprecated
- public int numBssidsPerScan;
- /**
- * defines number of scans to cache; use it with REPORT_EVENT_AFTER_BUFFER_FULL
- * to wake up at fixed interval
- * @deprecated Background scan support has always been hardware vendor dependent. This
- * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
- * ScanListener)} instead for single scans.
- */
- @Deprecated
- public int maxScansToCache;
- /**
- * if maxPeriodInMs is non zero or different than period, then this bucket is
- * a truncated binary exponential backoff bucket and the scan period will grow
- * exponentially as per formula: actual_period(N) = period * (2 ^ (N/stepCount))
- * to maxPeriodInMs
- * @deprecated Background scan support has always been hardware vendor dependent. This
- * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
- * ScanListener)} instead for single scans.
- */
- @Deprecated
- public int maxPeriodInMs;
- /**
- * for truncated binary exponential back off bucket, number of scans to perform
- * for a given period
- * @deprecated Background scan support has always been hardware vendor dependent. This
- * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
- * ScanListener)} instead for single scans.
- */
- @Deprecated
- public int stepCount;
- /**
- * Flag to indicate if the scan settings are targeted for PNO scan.
- * {@hide}
- */
- public boolean isPnoScan;
- /**
- * Indicate the type of scan to be performed by the wifi chip.
- *
- * On devices with multiple hardware radio chains (and hence different modes of scan),
- * this type serves as an indication to the hardware on what mode of scan to perform.
- * Only apps holding {@link android.Manifest.permission.NETWORK_STACK} permission can set
- * this value.
- *
- * Note: This serves as an intent and not as a stipulation, the wifi chip
- * might honor or ignore the indication based on the current radio conditions. Always
- * use the {@link ScanResult#radioChainInfos} to figure out the radio chain configuration
- * used to receive the corresponding scan result.
- *
- * One of {@link #SCAN_TYPE_LOW_LATENCY}, {@link #SCAN_TYPE_LOW_POWER},
- * {@link #SCAN_TYPE_HIGH_ACCURACY}.
- * Default value: {@link #SCAN_TYPE_LOW_LATENCY}.
- */
- @WifiAnnotations.ScanType
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public int type = SCAN_TYPE_LOW_LATENCY;
- /**
- * This scan request may ignore location settings while receiving scans. This should only
- * be used in emergency situations.
- * {@hide}
- */
- @SystemApi
- public boolean ignoreLocationSettings;
- /**
- * This scan request will be hidden from app-ops noting for location information. This
- * should only be used by FLP/NLP module on the device which is using the scan results to
- * compute results for behalf on their clients. FLP/NLP module using this flag should ensure
- * that they note in app-ops the eventual delivery of location information computed using
- * these results to their client .
- * {@hide}
- */
- @SystemApi
- public boolean hideFromAppOps;
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(band);
- dest.writeInt(periodInMs);
- dest.writeInt(reportEvents);
- dest.writeInt(numBssidsPerScan);
- dest.writeInt(maxScansToCache);
- dest.writeInt(maxPeriodInMs);
- dest.writeInt(stepCount);
- dest.writeInt(isPnoScan ? 1 : 0);
- dest.writeInt(type);
- dest.writeInt(ignoreLocationSettings ? 1 : 0);
- dest.writeInt(hideFromAppOps ? 1 : 0);
- if (channels != null) {
- dest.writeInt(channels.length);
- for (int i = 0; i < channels.length; i++) {
- dest.writeInt(channels[i].frequency);
- dest.writeInt(channels[i].dwellTimeMS);
- dest.writeInt(channels[i].passive ? 1 : 0);
- }
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(hiddenNetworks.size());
- for (HiddenNetwork hiddenNetwork : hiddenNetworks) {
- dest.writeString(hiddenNetwork.ssid);
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @NonNull Creator<ScanSettings> CREATOR =
- new Creator<ScanSettings>() {
- public ScanSettings createFromParcel(Parcel in) {
- ScanSettings settings = new ScanSettings();
- settings.band = in.readInt();
- settings.periodInMs = in.readInt();
- settings.reportEvents = in.readInt();
- settings.numBssidsPerScan = in.readInt();
- settings.maxScansToCache = in.readInt();
- settings.maxPeriodInMs = in.readInt();
- settings.stepCount = in.readInt();
- settings.isPnoScan = in.readInt() == 1;
- settings.type = in.readInt();
- settings.ignoreLocationSettings = in.readInt() == 1;
- settings.hideFromAppOps = in.readInt() == 1;
- int num_channels = in.readInt();
- settings.channels = new ChannelSpec[num_channels];
- for (int i = 0; i < num_channels; i++) {
- int frequency = in.readInt();
- ChannelSpec spec = new ChannelSpec(frequency);
- spec.dwellTimeMS = in.readInt();
- spec.passive = in.readInt() == 1;
- settings.channels[i] = spec;
- }
- int numNetworks = in.readInt();
- settings.hiddenNetworks.clear();
- for (int i = 0; i < numNetworks; i++) {
- String ssid = in.readString();
- settings.hiddenNetworks.add(new HiddenNetwork(ssid));
- }
- return settings;
- }
-
- public ScanSettings[] newArray(int size) {
- return new ScanSettings[size];
- }
- };
- }
-
- /**
- * all the information garnered from a single scan
- */
- public static class ScanData implements Parcelable {
- /** scan identifier */
- private int mId;
- /** additional information about scan
- * 0 => no special issues encountered in the scan
- * non-zero => scan was truncated, so results may not be complete
- */
- private int mFlags;
- /**
- * Indicates the buckets that were scanned to generate these results.
- * This is not relevant to WifiScanner API users and is used internally.
- * {@hide}
- */
- private int mBucketsScanned;
- /**
- * Bands scanned. One of the WIFI_BAND values.
- * Will be {@link #WIFI_BAND_UNSPECIFIED} if the list of channels do not fully cover
- * any of the bands.
- * {@hide}
- */
- private int mBandScanned;
- /** all scan results discovered in this scan, sorted by timestamp in ascending order */
- private final List<ScanResult> mResults;
-
- ScanData() {
- mResults = new ArrayList<>();
- }
-
- public ScanData(int id, int flags, ScanResult[] results) {
- mId = id;
- mFlags = flags;
- mResults = new ArrayList<>(Arrays.asList(results));
- }
-
- /** {@hide} */
- public ScanData(int id, int flags, int bucketsScanned, int bandScanned,
- ScanResult[] results) {
- this(id, flags, bucketsScanned, bandScanned, new ArrayList<>(Arrays.asList(results)));
- }
-
- /** {@hide} */
- public ScanData(int id, int flags, int bucketsScanned, int bandScanned,
- List<ScanResult> results) {
- mId = id;
- mFlags = flags;
- mBucketsScanned = bucketsScanned;
- mBandScanned = bandScanned;
- mResults = results;
- }
-
- public ScanData(ScanData s) {
- mId = s.mId;
- mFlags = s.mFlags;
- mBucketsScanned = s.mBucketsScanned;
- mBandScanned = s.mBandScanned;
- mResults = new ArrayList<>();
- for (ScanResult scanResult : s.mResults) {
- mResults.add(new ScanResult(scanResult));
- }
- }
-
- public int getId() {
- return mId;
- }
-
- public int getFlags() {
- return mFlags;
- }
-
- /** {@hide} */
- public int getBucketsScanned() {
- return mBucketsScanned;
- }
-
- /** {@hide} */
- public int getBandScanned() {
- return mBandScanned;
- }
-
- public ScanResult[] getResults() {
- return mResults.toArray(new ScanResult[0]);
- }
-
- /** {@hide} */
- public void addResults(@NonNull ScanResult[] newResults) {
- for (ScanResult result : newResults) {
- mResults.add(new ScanResult(result));
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mId);
- dest.writeInt(mFlags);
- dest.writeInt(mBucketsScanned);
- dest.writeInt(mBandScanned);
- dest.writeParcelableList(mResults, 0);
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @NonNull Creator<ScanData> CREATOR =
- new Creator<ScanData>() {
- public ScanData createFromParcel(Parcel in) {
- int id = in.readInt();
- int flags = in.readInt();
- int bucketsScanned = in.readInt();
- int bandScanned = in.readInt();
- List<ScanResult> results = new ArrayList<>();
- in.readParcelableList(results, ScanResult.class.getClassLoader());
- return new ScanData(id, flags, bucketsScanned, bandScanned, results);
- }
-
- public ScanData[] newArray(int size) {
- return new ScanData[size];
- }
- };
- }
-
- public static class ParcelableScanData implements Parcelable {
-
- public ScanData mResults[];
-
- public ParcelableScanData(ScanData[] results) {
- mResults = results;
- }
-
- public ScanData[] getResults() {
- return mResults;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- if (mResults != null) {
- dest.writeInt(mResults.length);
- for (int i = 0; i < mResults.length; i++) {
- ScanData result = mResults[i];
- result.writeToParcel(dest, flags);
- }
- } else {
- dest.writeInt(0);
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @NonNull Creator<ParcelableScanData> CREATOR =
- new Creator<ParcelableScanData>() {
- public ParcelableScanData createFromParcel(Parcel in) {
- int n = in.readInt();
- ScanData results[] = new ScanData[n];
- for (int i = 0; i < n; i++) {
- results[i] = ScanData.CREATOR.createFromParcel(in);
- }
- return new ParcelableScanData(results);
- }
-
- public ParcelableScanData[] newArray(int size) {
- return new ParcelableScanData[size];
- }
- };
- }
-
- public static class ParcelableScanResults implements Parcelable {
-
- public ScanResult mResults[];
-
- public ParcelableScanResults(ScanResult[] results) {
- mResults = results;
- }
-
- public ScanResult[] getResults() {
- return mResults;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- if (mResults != null) {
- dest.writeInt(mResults.length);
- for (int i = 0; i < mResults.length; i++) {
- ScanResult result = mResults[i];
- result.writeToParcel(dest, flags);
- }
- } else {
- dest.writeInt(0);
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @NonNull Creator<ParcelableScanResults> CREATOR =
- new Creator<ParcelableScanResults>() {
- public ParcelableScanResults createFromParcel(Parcel in) {
- int n = in.readInt();
- ScanResult results[] = new ScanResult[n];
- for (int i = 0; i < n; i++) {
- results[i] = ScanResult.CREATOR.createFromParcel(in);
- }
- return new ParcelableScanResults(results);
- }
-
- public ParcelableScanResults[] newArray(int size) {
- return new ParcelableScanResults[size];
- }
- };
- }
-
- /** {@hide} */
- public static final String PNO_PARAMS_PNO_SETTINGS_KEY = "PnoSettings";
- /** {@hide} */
- public static final String PNO_PARAMS_SCAN_SETTINGS_KEY = "ScanSettings";
- /**
- * PNO scan configuration parameters to be sent to {@link #startPnoScan}.
- * Note: This structure needs to be in sync with |wifi_epno_params| struct in gscan HAL API.
- * {@hide}
- */
- public static class PnoSettings implements Parcelable {
- /**
- * Pno network to be added to the PNO scan filtering.
- * {@hide}
- */
- public static class PnoNetwork {
- /*
- * Pno flags bitmask to be set in {@link #PnoNetwork.flags}
- */
- /** Whether directed scan needs to be performed (for hidden SSIDs) */
- public static final byte FLAG_DIRECTED_SCAN = (1 << 0);
- /** Whether PNO event shall be triggered if the network is found on A band */
- public static final byte FLAG_A_BAND = (1 << 1);
- /** Whether PNO event shall be triggered if the network is found on G band */
- public static final byte FLAG_G_BAND = (1 << 2);
- /**
- * Whether strict matching is required
- * If required then the firmware must store the network's SSID and not just a hash
- */
- public static final byte FLAG_STRICT_MATCH = (1 << 3);
- /**
- * If this SSID should be considered the same network as the currently connected
- * one for scoring.
- */
- public static final byte FLAG_SAME_NETWORK = (1 << 4);
-
- /*
- * Code for matching the beacon AUTH IE - additional codes. Bitmask to be set in
- * {@link #PnoNetwork.authBitField}
- */
- /** Open Network */
- public static final byte AUTH_CODE_OPEN = (1 << 0);
- /** WPA_PSK or WPA2PSK */
- public static final byte AUTH_CODE_PSK = (1 << 1);
- /** any EAPOL */
- public static final byte AUTH_CODE_EAPOL = (1 << 2);
-
- /** SSID of the network */
- public String ssid;
- /** Bitmask of the FLAG_XXX */
- public byte flags = 0;
- /** Bitmask of the ATUH_XXX */
- public byte authBitField = 0;
- /** frequencies on which the particular network needs to be scanned for */
- public int[] frequencies = {};
-
- /**
- * default constructor for PnoNetwork
- */
- public PnoNetwork(String ssid) {
- this.ssid = ssid;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(ssid, flags, authBitField);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof PnoNetwork)) {
- return false;
- }
- PnoNetwork lhs = (PnoNetwork) obj;
- return TextUtils.equals(this.ssid, lhs.ssid)
- && this.flags == lhs.flags
- && this.authBitField == lhs.authBitField;
- }
- }
-
- /** Connected vs Disconnected PNO flag {@hide} */
- public boolean isConnected;
- /** Minimum 5GHz RSSI for a BSSID to be considered */
- public int min5GHzRssi;
- /** Minimum 2.4GHz RSSI for a BSSID to be considered */
- public int min24GHzRssi;
- /** Minimum 6GHz RSSI for a BSSID to be considered */
- public int min6GHzRssi;
- /** Pno Network filter list */
- public PnoNetwork[] networkList;
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(isConnected ? 1 : 0);
- dest.writeInt(min5GHzRssi);
- dest.writeInt(min24GHzRssi);
- dest.writeInt(min6GHzRssi);
- if (networkList != null) {
- dest.writeInt(networkList.length);
- for (int i = 0; i < networkList.length; i++) {
- dest.writeString(networkList[i].ssid);
- dest.writeByte(networkList[i].flags);
- dest.writeByte(networkList[i].authBitField);
- dest.writeIntArray(networkList[i].frequencies);
- }
- } else {
- dest.writeInt(0);
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @NonNull Creator<PnoSettings> CREATOR =
- new Creator<PnoSettings>() {
- public PnoSettings createFromParcel(Parcel in) {
- PnoSettings settings = new PnoSettings();
- settings.isConnected = in.readInt() == 1;
- settings.min5GHzRssi = in.readInt();
- settings.min24GHzRssi = in.readInt();
- settings.min6GHzRssi = in.readInt();
- int numNetworks = in.readInt();
- settings.networkList = new PnoNetwork[numNetworks];
- for (int i = 0; i < numNetworks; i++) {
- String ssid = in.readString();
- PnoNetwork network = new PnoNetwork(ssid);
- network.flags = in.readByte();
- network.authBitField = in.readByte();
- network.frequencies = in.createIntArray();
- settings.networkList[i] = network;
- }
- return settings;
- }
-
- public PnoSettings[] newArray(int size) {
- return new PnoSettings[size];
- }
- };
-
- }
-
- /**
- * interface to get scan events on; specify this on {@link #startBackgroundScan} or
- * {@link #startScan}
- */
- public interface ScanListener extends ActionListener {
- /**
- * Framework co-ordinates scans across multiple apps; so it may not give exactly the
- * same period requested. If period of a scan is changed; it is reported by this event.
- * @deprecated Background scan support has always been hardware vendor dependent. This
- * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
- * ScanListener)} instead for single scans.
- */
- @Deprecated
- public void onPeriodChanged(int periodInMs);
- /**
- * reports results retrieved from background scan and single shot scans
- */
- public void onResults(ScanData[] results);
- /**
- * reports full scan result for each access point found in scan
- */
- public void onFullResult(ScanResult fullScanResult);
- }
-
- /**
- * interface to get PNO scan events on; specify this on {@link #startDisconnectedPnoScan} and
- * {@link #startConnectedPnoScan}.
- * {@hide}
- */
- public interface PnoScanListener extends ScanListener {
- /**
- * Invoked when one of the PNO networks are found in scan results.
- */
- void onPnoNetworkFound(ScanResult[] results);
- }
-
- /**
- * Enable/Disable wifi scanning.
- *
- * @param enable set to true to enable scanning, set to false to disable all types of scanning.
- *
- * @see WifiManager#ACTION_WIFI_SCAN_AVAILABILITY_CHANGED
- * {@hide}
- */
- @SystemApi
- @RequiresPermission(Manifest.permission.NETWORK_STACK)
- public void setScanningEnabled(boolean enable) {
- validateChannel();
- mAsyncChannel.sendMessage(enable ? CMD_ENABLE : CMD_DISABLE);
- }
-
- /**
- * Register a listener that will receive results from all single scans.
- * Either the {@link ScanListener#onSuccess()} or {@link ScanListener#onFailure(int, String)}
- * method will be called once when the listener is registered.
- * Afterwards (assuming onSuccess was called), all subsequent single scan results will be
- * delivered to the listener. It is possible that onFullResult will not be called for all
- * results of the first scan if the listener was registered during the scan.
- *
- * @param executor the Executor on which to run the callback.
- * @param listener specifies the object to report events to. This object is also treated as a
- * key for this request, and must also be specified to cancel the request.
- * Multiple requests should also not share this object.
- */
- @RequiresPermission(Manifest.permission.NETWORK_STACK)
- public void registerScanListener(@NonNull @CallbackExecutor Executor executor,
- @NonNull ScanListener listener) {
- Objects.requireNonNull(executor, "executor cannot be null");
- Objects.requireNonNull(listener, "listener cannot be null");
- int key = addListener(listener, executor);
- if (key == INVALID_KEY) return;
- validateChannel();
- mAsyncChannel.sendMessage(CMD_REGISTER_SCAN_LISTENER, 0, key);
- }
-
- /**
- * Overload of {@link #registerScanListener(Executor, ScanListener)} that executes the callback
- * synchronously.
- * @hide
- */
- @RequiresPermission(Manifest.permission.NETWORK_STACK)
- public void registerScanListener(@NonNull ScanListener listener) {
- registerScanListener(new SynchronousExecutor(), listener);
- }
-
- /**
- * Deregister a listener for ongoing single scans
- * @param listener specifies which scan to cancel; must be same object as passed in {@link
- * #registerScanListener}
- */
- public void unregisterScanListener(@NonNull ScanListener listener) {
- Objects.requireNonNull(listener, "listener cannot be null");
- int key = removeListener(listener);
- if (key == INVALID_KEY) return;
- validateChannel();
- mAsyncChannel.sendMessage(CMD_DEREGISTER_SCAN_LISTENER, 0, key);
- }
-
- /** start wifi scan in background
- * @param settings specifies various parameters for the scan; for more information look at
- * {@link ScanSettings}
- * @param listener specifies the object to report events to. This object is also treated as a
- * key for this scan, and must also be specified to cancel the scan. Multiple
- * scans should also not share this object.
- */
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void startBackgroundScan(ScanSettings settings, ScanListener listener) {
- startBackgroundScan(settings, listener, null);
- }
-
- /** start wifi scan in background
- * @param settings specifies various parameters for the scan; for more information look at
- * {@link ScanSettings}
- * @param workSource WorkSource to blame for power usage
- * @param listener specifies the object to report events to. This object is also treated as a
- * key for this scan, and must also be specified to cancel the scan. Multiple
- * scans should also not share this object.
- * @deprecated Background scan support has always been hardware vendor dependent. This support
- * may not be present on newer devices. Use {@link #startScan(ScanSettings, ScanListener)}
- * instead for single scans.
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void startBackgroundScan(ScanSettings settings, ScanListener listener,
- WorkSource workSource) {
- Objects.requireNonNull(listener, "listener cannot be null");
- int key = addListener(listener);
- if (key == INVALID_KEY) return;
- validateChannel();
- Bundle scanParams = new Bundle();
- scanParams.putParcelable(SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
- scanParams.putParcelable(SCAN_PARAMS_WORK_SOURCE_KEY, workSource);
- scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
- scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
- mAsyncChannel.sendMessage(CMD_START_BACKGROUND_SCAN, 0, key, scanParams);
- }
-
- /**
- * stop an ongoing wifi scan
- * @param listener specifies which scan to cancel; must be same object as passed in {@link
- * #startBackgroundScan}
- * @deprecated Background scan support has always been hardware vendor dependent. This support
- * may not be present on newer devices. Use {@link #startScan(ScanSettings, ScanListener)}
- * instead for single scans.
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void stopBackgroundScan(ScanListener listener) {
- Objects.requireNonNull(listener, "listener cannot be null");
- int key = removeListener(listener);
- if (key == INVALID_KEY) return;
- validateChannel();
- Bundle scanParams = new Bundle();
- scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
- scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
- mAsyncChannel.sendMessage(CMD_STOP_BACKGROUND_SCAN, 0, key, scanParams);
- }
-
- /**
- * reports currently available scan results on appropriate listeners
- * @return true if all scan results were reported correctly
- * @deprecated Background scan support has always been hardware vendor dependent. This support
- * may not be present on newer devices. Use {@link #startScan(ScanSettings, ScanListener)}
- * instead for single scans.
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public boolean getScanResults() {
- validateChannel();
- Bundle scanParams = new Bundle();
- scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
- scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
- Message reply =
- mAsyncChannel.sendMessageSynchronously(CMD_GET_SCAN_RESULTS, 0, 0, scanParams);
- return reply.what == CMD_OP_SUCCEEDED;
- }
-
- /**
- * starts a single scan and reports results asynchronously
- * @param settings specifies various parameters for the scan; for more information look at
- * {@link ScanSettings}
- * @param listener specifies the object to report events to. This object is also treated as a
- * key for this scan, and must also be specified to cancel the scan. Multiple
- * scans should also not share this object.
- */
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void startScan(ScanSettings settings, ScanListener listener) {
- startScan(settings, listener, null);
- }
-
- /**
- * starts a single scan and reports results asynchronously
- * @param settings specifies various parameters for the scan; for more information look at
- * {@link ScanSettings}
- * @param listener specifies the object to report events to. This object is also treated as a
- * key for this scan, and must also be specified to cancel the scan. Multiple
- * scans should also not share this object.
- * @param workSource WorkSource to blame for power usage
- */
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void startScan(ScanSettings settings, ScanListener listener, WorkSource workSource) {
- startScan(settings, null, listener, workSource);
- }
-
- /**
- * starts a single scan and reports results asynchronously
- * @param settings specifies various parameters for the scan; for more information look at
- * {@link ScanSettings}
- * @param executor the Executor on which to run the callback.
- * @param listener specifies the object to report events to. This object is also treated as a
- * key for this scan, and must also be specified to cancel the scan. Multiple
- * scans should also not share this object.
- * @param workSource WorkSource to blame for power usage
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void startScan(ScanSettings settings, @Nullable @CallbackExecutor Executor executor,
- ScanListener listener, WorkSource workSource) {
- Objects.requireNonNull(listener, "listener cannot be null");
- int key = addListener(listener, executor);
- if (key == INVALID_KEY) return;
- validateChannel();
- Bundle scanParams = new Bundle();
- scanParams.putParcelable(SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
- scanParams.putParcelable(SCAN_PARAMS_WORK_SOURCE_KEY, workSource);
- scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
- scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
- mAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, key, scanParams);
- }
-
- /**
- * stops an ongoing single shot scan; only useful after {@link #startScan} if onResults()
- * hasn't been called on the listener, ignored otherwise
- * @param listener
- */
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public void stopScan(ScanListener listener) {
- Objects.requireNonNull(listener, "listener cannot be null");
- int key = removeListener(listener);
- if (key == INVALID_KEY) return;
- validateChannel();
- Bundle scanParams = new Bundle();
- scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
- scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
- mAsyncChannel.sendMessage(CMD_STOP_SINGLE_SCAN, 0, key, scanParams);
- }
-
- /**
- * Retrieve the most recent scan results from a single scan request.
- */
- @NonNull
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
- public List<ScanResult> getSingleScanResults() {
- validateChannel();
- Bundle scanParams = new Bundle();
- scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
- scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
- Message reply = mAsyncChannel.sendMessageSynchronously(CMD_GET_SINGLE_SCAN_RESULTS, 0, 0,
- scanParams);
- if (reply.what == WifiScanner.CMD_OP_SUCCEEDED) {
- return Arrays.asList(((ParcelableScanResults) reply.obj).getResults());
- }
- OperationResult result = (OperationResult) reply.obj;
- Log.e(TAG, "Error retrieving SingleScan results reason: " + result.reason
- + " description: " + result.description);
- return new ArrayList<>();
- }
-
- private void startPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, int key) {
- // Bundle up both the settings and send it across.
- Bundle pnoParams = new Bundle();
- // Set the PNO scan flag.
- scanSettings.isPnoScan = true;
- pnoParams.putParcelable(PNO_PARAMS_SCAN_SETTINGS_KEY, scanSettings);
- pnoParams.putParcelable(PNO_PARAMS_PNO_SETTINGS_KEY, pnoSettings);
- mAsyncChannel.sendMessage(CMD_START_PNO_SCAN, 0, key, pnoParams);
- }
- /**
- * Start wifi connected PNO scan
- * @param scanSettings specifies various parameters for the scan; for more information look at
- * {@link ScanSettings}
- * @param pnoSettings specifies various parameters for PNO; for more information look at
- * {@link PnoSettings}
- * @param executor the Executor on which to run the callback.
- * @param listener specifies the object to report events to. This object is also treated as a
- * key for this scan, and must also be specified to cancel the scan. Multiple
- * scans should also not share this object.
- * {@hide}
- */
- public void startConnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings,
- @NonNull @CallbackExecutor Executor executor, PnoScanListener listener) {
- Objects.requireNonNull(listener, "listener cannot be null");
- Objects.requireNonNull(pnoSettings, "pnoSettings cannot be null");
- int key = addListener(listener, executor);
- if (key == INVALID_KEY) return;
- validateChannel();
- pnoSettings.isConnected = true;
- startPnoScan(scanSettings, pnoSettings, key);
- }
- /**
- * Start wifi disconnected PNO scan
- * @param scanSettings specifies various parameters for the scan; for more information look at
- * {@link ScanSettings}
- * @param pnoSettings specifies various parameters for PNO; for more information look at
- * {@link PnoSettings}
- * @param listener specifies the object to report events to. This object is also treated as a
- * key for this scan, and must also be specified to cancel the scan. Multiple
- * scans should also not share this object.
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public void startDisconnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings,
- @NonNull @CallbackExecutor Executor executor, PnoScanListener listener) {
- Objects.requireNonNull(listener, "listener cannot be null");
- Objects.requireNonNull(pnoSettings, "pnoSettings cannot be null");
- int key = addListener(listener, executor);
- if (key == INVALID_KEY) return;
- validateChannel();
- pnoSettings.isConnected = false;
- startPnoScan(scanSettings, pnoSettings, key);
- }
- /**
- * Stop an ongoing wifi PNO scan
- * @param listener specifies which scan to cancel; must be same object as passed in {@link
- * #startPnoScan}
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public void stopPnoScan(ScanListener listener) {
- Objects.requireNonNull(listener, "listener cannot be null");
- int key = removeListener(listener);
- if (key == INVALID_KEY) return;
- validateChannel();
- mAsyncChannel.sendMessage(CMD_STOP_PNO_SCAN, 0, key);
- }
-
- /** specifies information about an access point of interest */
- @Deprecated
- public static class BssidInfo {
- /** bssid of the access point; in XX:XX:XX:XX:XX:XX format */
- public String bssid;
- /** low signal strength threshold; more information at {@link ScanResult#level} */
- public int low; /* minimum RSSI */
- /** high signal threshold; more information at {@link ScanResult#level} */
- public int high; /* maximum RSSI */
- /** channel frequency (in KHz) where you may find this BSSID */
- public int frequencyHint;
- }
-
- /** @hide */
- @SystemApi
- @Deprecated
- public static class WifiChangeSettings implements Parcelable {
- public int rssiSampleSize; /* sample size for RSSI averaging */
- public int lostApSampleSize; /* samples to confirm AP's loss */
- public int unchangedSampleSize; /* samples to confirm no change */
- public int minApsBreachingThreshold; /* change threshold to trigger event */
- public int periodInMs; /* scan period in millisecond */
- public BssidInfo[] bssidInfos;
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @NonNull Creator<WifiChangeSettings> CREATOR =
- new Creator<WifiChangeSettings>() {
- public WifiChangeSettings createFromParcel(Parcel in) {
- return new WifiChangeSettings();
- }
-
- public WifiChangeSettings[] newArray(int size) {
- return new WifiChangeSettings[size];
- }
- };
-
- }
-
- /** configure WifiChange detection
- * @param rssiSampleSize number of samples used for RSSI averaging
- * @param lostApSampleSize number of samples to confirm an access point's loss
- * @param unchangedSampleSize number of samples to confirm there are no changes
- * @param minApsBreachingThreshold minimum number of access points that need to be
- * out of range to detect WifiChange
- * @param periodInMs indicates period of scan to find changes
- * @param bssidInfos access points to watch
- */
- @Deprecated
- @SuppressLint("Doclava125")
- public void configureWifiChange(
- int rssiSampleSize, /* sample size for RSSI averaging */
- int lostApSampleSize, /* samples to confirm AP's loss */
- int unchangedSampleSize, /* samples to confirm no change */
- int minApsBreachingThreshold, /* change threshold to trigger event */
- int periodInMs, /* period of scan */
- BssidInfo[] bssidInfos /* signal thresholds to cross */
- )
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * interface to get wifi change events on; use this on {@link #startTrackingWifiChange}
- */
- @Deprecated
- public interface WifiChangeListener extends ActionListener {
- /** indicates that changes were detected in wifi environment
- * @param results indicate the access points that exhibited change
- */
- public void onChanging(ScanResult[] results); /* changes are found */
- /** indicates that no wifi changes are being detected for a while
- * @param results indicate the access points that are bing monitored for change
- */
- public void onQuiescence(ScanResult[] results); /* changes settled down */
- }
-
- /**
- * track changes in wifi environment
- * @param listener object to report events on; this object must be unique and must also be
- * provided on {@link #stopTrackingWifiChange}
- */
- @Deprecated
- @SuppressLint("Doclava125")
- public void startTrackingWifiChange(WifiChangeListener listener) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * stop tracking changes in wifi environment
- * @param listener object that was provided to report events on {@link
- * #stopTrackingWifiChange}
- */
- @Deprecated
- @SuppressLint("Doclava125")
- public void stopTrackingWifiChange(WifiChangeListener listener) {
- throw new UnsupportedOperationException();
- }
-
- /** @hide */
- @SystemApi
- @Deprecated
- @SuppressLint("Doclava125")
- public void configureWifiChange(WifiChangeSettings settings) {
- throw new UnsupportedOperationException();
- }
-
- /** interface to receive hotlist events on; use this on {@link #setHotlist} */
- @Deprecated
- public static interface BssidListener extends ActionListener {
- /** indicates that access points were found by on going scans
- * @param results list of scan results, one for each access point visible currently
- */
- public void onFound(ScanResult[] results);
- /** indicates that access points were missed by on going scans
- * @param results list of scan results, for each access point that is not visible anymore
- */
- public void onLost(ScanResult[] results);
- }
-
- /** @hide */
- @SystemApi
- @Deprecated
- public static class HotlistSettings implements Parcelable {
- public BssidInfo[] bssidInfos;
- public int apLostThreshold;
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @NonNull Creator<HotlistSettings> CREATOR =
- new Creator<HotlistSettings>() {
- public HotlistSettings createFromParcel(Parcel in) {
- HotlistSettings settings = new HotlistSettings();
- return settings;
- }
-
- public HotlistSettings[] newArray(int size) {
- return new HotlistSettings[size];
- }
- };
- }
-
- /**
- * set interesting access points to find
- * @param bssidInfos access points of interest
- * @param apLostThreshold number of scans needed to indicate that AP is lost
- * @param listener object provided to report events on; this object must be unique and must
- * also be provided on {@link #stopTrackingBssids}
- */
- @Deprecated
- @SuppressLint("Doclava125")
- public void startTrackingBssids(BssidInfo[] bssidInfos,
- int apLostThreshold, BssidListener listener) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * remove tracking of interesting access points
- * @param listener same object provided in {@link #startTrackingBssids}
- */
- @Deprecated
- @SuppressLint("Doclava125")
- public void stopTrackingBssids(BssidListener listener) {
- throw new UnsupportedOperationException();
- }
-
-
- /* private members and methods */
-
- private static final String TAG = "WifiScanner";
- private static final boolean DBG = false;
-
- /* commands for Wifi Service */
- private static final int BASE = Protocol.BASE_WIFI_SCANNER;
-
- /** @hide */
- public static final int CMD_START_BACKGROUND_SCAN = BASE + 2;
- /** @hide */
- public static final int CMD_STOP_BACKGROUND_SCAN = BASE + 3;
- /** @hide */
- public static final int CMD_GET_SCAN_RESULTS = BASE + 4;
- /** @hide */
- public static final int CMD_SCAN_RESULT = BASE + 5;
- /** @hide */
- public static final int CMD_OP_SUCCEEDED = BASE + 17;
- /** @hide */
- public static final int CMD_OP_FAILED = BASE + 18;
- /** @hide */
- public static final int CMD_FULL_SCAN_RESULT = BASE + 20;
- /** @hide */
- public static final int CMD_START_SINGLE_SCAN = BASE + 21;
- /** @hide */
- public static final int CMD_STOP_SINGLE_SCAN = BASE + 22;
- /** @hide */
- public static final int CMD_SINGLE_SCAN_COMPLETED = BASE + 23;
- /** @hide */
- public static final int CMD_START_PNO_SCAN = BASE + 24;
- /** @hide */
- public static final int CMD_STOP_PNO_SCAN = BASE + 25;
- /** @hide */
- public static final int CMD_PNO_NETWORK_FOUND = BASE + 26;
- /** @hide */
- public static final int CMD_REGISTER_SCAN_LISTENER = BASE + 27;
- /** @hide */
- public static final int CMD_DEREGISTER_SCAN_LISTENER = BASE + 28;
- /** @hide */
- public static final int CMD_GET_SINGLE_SCAN_RESULTS = BASE + 29;
- /** @hide */
- public static final int CMD_ENABLE = BASE + 30;
- /** @hide */
- public static final int CMD_DISABLE = BASE + 31;
-
- private Context mContext;
- private IWifiScanner mService;
-
- private static final int INVALID_KEY = 0;
- private int mListenerKey = 1;
-
- private final SparseArray mListenerMap = new SparseArray();
- private final SparseArray<Executor> mExecutorMap = new SparseArray<>();
- private final Object mListenerMapLock = new Object();
-
- private AsyncChannel mAsyncChannel;
- private final Handler mInternalHandler;
-
- /**
- * Create a new WifiScanner instance.
- * Applications will almost always want to use
- * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
- * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}.
- *
- * @param context the application context
- * @param service the Binder interface for {@link Context#WIFI_SCANNING_SERVICE}
- * @param looper the Looper used to deliver callbacks
- *
- * @hide
- */
- public WifiScanner(@NonNull Context context, @NonNull IWifiScanner service,
- @NonNull Looper looper) {
- mContext = context;
- mService = service;
-
- Messenger messenger = null;
- try {
- messenger = mService.getMessenger();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- if (messenger == null) {
- throw new IllegalStateException("getMessenger() returned null! This is invalid.");
- }
-
- mAsyncChannel = new AsyncChannel();
-
- mInternalHandler = new ServiceHandler(looper);
- mAsyncChannel.connectSync(mContext, mInternalHandler, messenger);
- // We cannot use fullyConnectSync because it sends the FULL_CONNECTION message
- // synchronously, which causes WifiScanningService to receive the wrong replyTo value.
- mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
- }
-
- private void validateChannel() {
- if (mAsyncChannel == null) throw new IllegalStateException(
- "No permission to access and change wifi or a bad initialization");
- }
-
- private int addListener(ActionListener listener) {
- return addListener(listener, null);
- }
-
- // Add a listener into listener map. If the listener already exists, return INVALID_KEY and
- // send an error message to internal handler; Otherwise add the listener to the listener map and
- // return the key of the listener.
- private int addListener(ActionListener listener, Executor executor) {
- synchronized (mListenerMapLock) {
- boolean keyExists = (getListenerKey(listener) != INVALID_KEY);
- // Note we need to put the listener into listener map even if it's a duplicate as the
- // internal handler will need the key to find the listener. In case of duplicates,
- // removing duplicate key logic will be handled in internal handler.
- int key = putListener(listener);
- if (keyExists) {
- if (DBG) Log.d(TAG, "listener key already exists");
- OperationResult operationResult = new OperationResult(REASON_DUPLICATE_REQEUST,
- "Outstanding request with same key not stopped yet");
- Message message = Message.obtain(mInternalHandler, CMD_OP_FAILED, 0, key,
- operationResult);
- message.sendToTarget();
- return INVALID_KEY;
- } else {
- mExecutorMap.put(key, executor);
- return key;
- }
- }
- }
-
- private int putListener(Object listener) {
- if (listener == null) return INVALID_KEY;
- int key;
- synchronized (mListenerMapLock) {
- do {
- key = mListenerKey++;
- } while (key == INVALID_KEY);
- mListenerMap.put(key, listener);
- }
- return key;
- }
-
- private static class ListenerWithExecutor {
- @Nullable final Object mListener;
- @Nullable final Executor mExecutor;
-
- ListenerWithExecutor(@Nullable Object listener, @Nullable Executor executor) {
- mListener = listener;
- mExecutor = executor;
- }
- }
-
- private ListenerWithExecutor getListenerWithExecutor(int key) {
- if (key == INVALID_KEY) return new ListenerWithExecutor(null, null);
- synchronized (mListenerMapLock) {
- Object listener = mListenerMap.get(key);
- Executor executor = mExecutorMap.get(key);
- return new ListenerWithExecutor(listener, executor);
- }
- }
-
- private int getListenerKey(Object listener) {
- if (listener == null) return INVALID_KEY;
- synchronized (mListenerMapLock) {
- int index = mListenerMap.indexOfValue(listener);
- if (index == -1) {
- return INVALID_KEY;
- } else {
- return mListenerMap.keyAt(index);
- }
- }
- }
-
- private Object removeListener(int key) {
- if (key == INVALID_KEY) return null;
- synchronized (mListenerMapLock) {
- Object listener = mListenerMap.get(key);
- mListenerMap.remove(key);
- mExecutorMap.remove(key);
- return listener;
- }
- }
-
- private int removeListener(Object listener) {
- int key = getListenerKey(listener);
- if (key == INVALID_KEY) {
- Log.e(TAG, "listener cannot be found");
- return key;
- }
- synchronized (mListenerMapLock) {
- mListenerMap.remove(key);
- mExecutorMap.remove(key);
- return key;
- }
- }
-
- /** @hide */
- public static class OperationResult implements Parcelable {
- public int reason;
- public String description;
-
- public OperationResult(int reason, String description) {
- this.reason = reason;
- this.description = description;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(reason);
- dest.writeString(description);
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @NonNull Creator<OperationResult> CREATOR =
- new Creator<OperationResult>() {
- public OperationResult createFromParcel(Parcel in) {
- int reason = in.readInt();
- String description = in.readString();
- return new OperationResult(reason, description);
- }
-
- public OperationResult[] newArray(int size) {
- return new OperationResult[size];
- }
- };
- }
-
- private class ServiceHandler extends Handler {
- ServiceHandler(Looper looper) {
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
- return;
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- Log.e(TAG, "Channel connection lost");
- // This will cause all further async API calls on the WifiManager
- // to fail and throw an exception
- mAsyncChannel = null;
- getLooper().quit();
- return;
- }
-
- ListenerWithExecutor listenerWithExecutor = getListenerWithExecutor(msg.arg2);
- Object listener = listenerWithExecutor.mListener;
-
- if (listener == null) {
- if (DBG) Log.d(TAG, "invalid listener key = " + msg.arg2);
- return;
- } else {
- if (DBG) Log.d(TAG, "listener key = " + msg.arg2);
- }
-
- Executor executor = listenerWithExecutor.mExecutor;
- if (executor == null) {
- executor = new SynchronousExecutor();
- }
-
- switch (msg.what) {
- /* ActionListeners grouped together */
- case CMD_OP_SUCCEEDED: {
- ActionListener actionListener = (ActionListener) listener;
- Binder.clearCallingIdentity();
- executor.execute(actionListener::onSuccess);
- } break;
- case CMD_OP_FAILED: {
- OperationResult result = (OperationResult) msg.obj;
- ActionListener actionListener = (ActionListener) listener;
- removeListener(msg.arg2);
- Binder.clearCallingIdentity();
- executor.execute(() ->
- actionListener.onFailure(result.reason, result.description));
- } break;
- case CMD_SCAN_RESULT: {
- ScanListener scanListener = (ScanListener) listener;
- ParcelableScanData parcelableScanData = (ParcelableScanData) msg.obj;
- Binder.clearCallingIdentity();
- executor.execute(() -> scanListener.onResults(parcelableScanData.getResults()));
- } break;
- case CMD_FULL_SCAN_RESULT: {
- ScanResult result = (ScanResult) msg.obj;
- ScanListener scanListener = ((ScanListener) listener);
- Binder.clearCallingIdentity();
- executor.execute(() -> scanListener.onFullResult(result));
- } break;
- case CMD_SINGLE_SCAN_COMPLETED: {
- if (DBG) Log.d(TAG, "removing listener for single scan");
- removeListener(msg.arg2);
- } break;
- case CMD_PNO_NETWORK_FOUND: {
- PnoScanListener pnoScanListener = (PnoScanListener) listener;
- ParcelableScanResults parcelableScanResults = (ParcelableScanResults) msg.obj;
- Binder.clearCallingIdentity();
- executor.execute(() ->
- pnoScanListener.onPnoNetworkFound(parcelableScanResults.getResults()));
- } break;
- default: {
- if (DBG) Log.d(TAG, "Ignoring message " + msg.what);
- } break;
- }
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
deleted file mode 100644
index 704ae81..0000000
--- a/wifi/java/android/net/wifi/WifiSsid.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.io.ByteArrayOutputStream;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.util.Arrays;
-import java.util.Locale;
-
-/**
- * Stores SSID octets and handles conversion.
- *
- * For Ascii encoded string, any octet < 32 or > 127 is encoded as
- * a "\x" followed by the hex representation of the octet.
- * Exception chars are ", \, \e, \n, \r, \t which are escaped by a \
- * See src/utils/common.c for the implementation in the supplicant.
- *
- * @hide
- */
-public final class WifiSsid implements Parcelable {
- private static final String TAG = "WifiSsid";
-
- @UnsupportedAppUsage
- public final ByteArrayOutputStream octets = new ByteArrayOutputStream(32);
-
- private static final int HEX_RADIX = 16;
-
- @UnsupportedAppUsage
- public static final String NONE = WifiManager.UNKNOWN_SSID;
-
- private WifiSsid() {
- }
-
- /**
- * Create a WifiSsid from a raw byte array. If the byte array is null, return an empty WifiSsid
- * object.
- */
- @NonNull
- public static WifiSsid createFromByteArray(@Nullable byte[] ssid) {
- WifiSsid wifiSsid = new WifiSsid();
- if (ssid != null) {
- wifiSsid.octets.write(ssid, 0 /* the start offset */, ssid.length);
- }
- return wifiSsid;
- }
-
- @UnsupportedAppUsage
- public static WifiSsid createFromAsciiEncoded(String asciiEncoded) {
- WifiSsid a = new WifiSsid();
- a.convertToBytes(asciiEncoded);
- return a;
- }
-
- public static WifiSsid createFromHex(String hexStr) {
- WifiSsid a = new WifiSsid();
- if (hexStr == null) return a;
-
- if (hexStr.startsWith("0x") || hexStr.startsWith("0X")) {
- hexStr = hexStr.substring(2);
- }
-
- for (int i = 0; i < hexStr.length()-1; i += 2) {
- int val;
- try {
- val = Integer.parseInt(hexStr.substring(i, i + 2), HEX_RADIX);
- } catch(NumberFormatException e) {
- val = 0;
- }
- a.octets.write(val);
- }
- return a;
- }
-
- /* This function is equivalent to printf_decode() at src/utils/common.c in
- * the supplicant */
- private void convertToBytes(String asciiEncoded) {
- int i = 0;
- int val = 0;
- while (i< asciiEncoded.length()) {
- char c = asciiEncoded.charAt(i);
- switch (c) {
- case '\\':
- i++;
- switch(asciiEncoded.charAt(i)) {
- case '\\':
- octets.write('\\');
- i++;
- break;
- case '"':
- octets.write('"');
- i++;
- break;
- case 'n':
- octets.write('\n');
- i++;
- break;
- case 'r':
- octets.write('\r');
- i++;
- break;
- case 't':
- octets.write('\t');
- i++;
- break;
- case 'e':
- octets.write(27); //escape char
- i++;
- break;
- case 'x':
- i++;
- try {
- val = Integer.parseInt(asciiEncoded.substring(i, i + 2), HEX_RADIX);
- } catch (NumberFormatException e) {
- val = -1;
- } catch (StringIndexOutOfBoundsException e) {
- val = -1;
- }
- if (val < 0) {
- val = Character.digit(asciiEncoded.charAt(i), HEX_RADIX);
- if (val < 0) break;
- octets.write(val);
- i++;
- } else {
- octets.write(val);
- i += 2;
- }
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- val = asciiEncoded.charAt(i) - '0';
- i++;
- if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') {
- val = val * 8 + asciiEncoded.charAt(i) - '0';
- i++;
- }
- if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') {
- val = val * 8 + asciiEncoded.charAt(i) - '0';
- i++;
- }
- octets.write(val);
- break;
- default:
- break;
- }
- break;
- default:
- octets.write(c);
- i++;
- break;
- }
- }
- }
-
- /**
- * Converts this SSID to an unquoted UTF-8 String representation.
- * @return the SSID string, or {@link WifiManager#UNKNOWN_SSID} if there was an error.
- */
- @Override
- public String toString() {
- byte[] ssidBytes = octets.toByteArray();
- // Supplicant returns \x00\x00\x00\x00\x00\x00\x00\x00 hex string
- // for a hidden access point. Make sure we maintain the previous
- // behavior of returning empty string for this case.
- if (octets.size() <= 0 || isArrayAllZeroes(ssidBytes)) return "";
- // TODO: Handle conversion to other charsets upon failure
- Charset charset = Charset.forName("UTF-8");
- CharsetDecoder decoder = charset.newDecoder()
- .onMalformedInput(CodingErrorAction.REPLACE)
- .onUnmappableCharacter(CodingErrorAction.REPLACE);
- CharBuffer out = CharBuffer.allocate(32);
-
- CoderResult result = decoder.decode(ByteBuffer.wrap(ssidBytes), out, true);
- out.flip();
- if (result.isError()) {
- return WifiManager.UNKNOWN_SSID;
- }
- return out.toString();
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof WifiSsid)) {
- return false;
- }
- WifiSsid that = (WifiSsid) thatObject;
- return Arrays.equals(octets.toByteArray(), that.octets.toByteArray());
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(octets.toByteArray());
- }
-
- private boolean isArrayAllZeroes(byte[] ssidBytes) {
- for (int i = 0; i< ssidBytes.length; i++) {
- if (ssidBytes[i] != 0) return false;
- }
- return true;
- }
-
- /** @hide */
- public boolean isHidden() {
- return isArrayAllZeroes(octets.toByteArray());
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public byte[] getOctets() {
- return octets.toByteArray();
- }
-
- /** @hide */
- public String getHexString() {
- String out = "0x";
- byte[] ssidbytes = getOctets();
- for (int i = 0; i < octets.size(); i++) {
- out += String.format(Locale.US, "%02x", ssidbytes[i]);
- }
- return (octets.size() > 0) ? out : null;
- }
-
- /** Implement the Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(octets.size());
- dest.writeByteArray(octets.toByteArray());
- }
-
- /** Implement the Parcelable interface */
- @UnsupportedAppUsage
- public static final @NonNull Creator<WifiSsid> CREATOR =
- new Creator<WifiSsid>() {
- @Override
- public WifiSsid createFromParcel(Parcel in) {
- WifiSsid ssid = new WifiSsid();
- int length = in.readInt();
- byte[] b = new byte[length];
- in.readByteArray(b);
- ssid.octets.write(b, 0, length);
- return ssid;
- }
-
- @Override
- public WifiSsid[] newArray(int size) {
- return new WifiSsid[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
deleted file mode 100644
index 8f3635f..0000000
--- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
+++ /dev/null
@@ -1,351 +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.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import android.telephony.Annotation.NetworkType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class makes a subset of
- * com.android.server.wifi.nano.WifiMetricsProto.WifiUsabilityStatsEntry parcelable.
- *
- * @hide
- */
-@SystemApi
-public final class WifiUsabilityStatsEntry implements Parcelable {
- /** {@hide} */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"PROBE_STATUS_"}, value = {
- PROBE_STATUS_UNKNOWN,
- PROBE_STATUS_NO_PROBE,
- PROBE_STATUS_SUCCESS,
- PROBE_STATUS_FAILURE})
- public @interface ProbeStatus {}
-
- /** Link probe status is unknown */
- public static final int PROBE_STATUS_UNKNOWN = 0;
- /** Link probe is not triggered */
- public static final int PROBE_STATUS_NO_PROBE = 1;
- /** Link probe is triggered and the result is success */
- public static final int PROBE_STATUS_SUCCESS = 2;
- /** Link probe is triggered and the result is failure */
- public static final int PROBE_STATUS_FAILURE = 3;
-
- /** Absolute milliseconds from device boot when these stats were sampled */
- private final long mTimeStampMillis;
- /** The RSSI (in dBm) at the sample time */
- private final int mRssi;
- /** Link speed at the sample time in Mbps */
- private final int mLinkSpeedMbps;
- /** The total number of tx success counted from the last radio chip reset */
- private final long mTotalTxSuccess;
- /** The total number of MPDU data packet retries counted from the last radio chip reset */
- private final long mTotalTxRetries;
- /** The total number of tx bad counted from the last radio chip reset */
- private final long mTotalTxBad;
- /** The total number of rx success counted from the last radio chip reset */
- private final long mTotalRxSuccess;
- /** The total time the wifi radio is on in ms counted from the last radio chip reset */
- private final long mTotalRadioOnTimeMillis;
- /** The total time the wifi radio is doing tx in ms counted from the last radio chip reset */
- private final long mTotalRadioTxTimeMillis;
- /** The total time the wifi radio is doing rx in ms counted from the last radio chip reset */
- private final long mTotalRadioRxTimeMillis;
- /** The total time spent on all types of scans in ms counted from the last radio chip reset */
- private final long mTotalScanTimeMillis;
- /** The total time spent on nan scans in ms counted from the last radio chip reset */
- private final long mTotalNanScanTimeMillis;
- /** The total time spent on background scans in ms counted from the last radio chip reset */
- private final long mTotalBackgroundScanTimeMillis;
- /** The total time spent on roam scans in ms counted from the last radio chip reset */
- private final long mTotalRoamScanTimeMillis;
- /** The total time spent on pno scans in ms counted from the last radio chip reset */
- private final long mTotalPnoScanTimeMillis;
- /** The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the last radio
- * chip reset */
- private final long mTotalHotspot2ScanTimeMillis;
- /** The total time CCA is on busy status on the current frequency in ms counted from the last
- * radio chip reset */
- private final long mTotalCcaBusyFreqTimeMillis;
- /** The total radio on time on the current frequency from the last radio chip reset */
- private final long mTotalRadioOnFreqTimeMillis;
- /** The total number of beacons received from the last radio chip reset */
- private final long mTotalBeaconRx;
- /** The status of link probe since last stats update */
- @ProbeStatus private final int mProbeStatusSinceLastUpdate;
- /** The elapsed time of the most recent link probe since last stats update */
- private final int mProbeElapsedTimeSinceLastUpdateMillis;
- /** The MCS rate of the most recent link probe since last stats update */
- private final int mProbeMcsRateSinceLastUpdate;
- /** Rx link speed at the sample time in Mbps */
- private final int mRxLinkSpeedMbps;
- private final @NetworkType int mCellularDataNetworkType;
- private final int mCellularSignalStrengthDbm;
- private final int mCellularSignalStrengthDb;
- private final boolean mIsSameRegisteredCell;
-
- /** Constructor function {@hide} */
- public WifiUsabilityStatsEntry(long timeStampMillis, int rssi, int linkSpeedMbps,
- long totalTxSuccess, long totalTxRetries, long totalTxBad, long totalRxSuccess,
- long totalRadioOnTimeMillis, long totalRadioTxTimeMillis, long totalRadioRxTimeMillis,
- long totalScanTimeMillis, long totalNanScanTimeMillis,
- long totalBackgroundScanTimeMillis,
- long totalRoamScanTimeMillis, long totalPnoScanTimeMillis,
- long totalHotspot2ScanTimeMillis,
- long totalCcaBusyFreqTimeMillis, long totalRadioOnFreqTimeMillis, long totalBeaconRx,
- @ProbeStatus int probeStatusSinceLastUpdate, int probeElapsedTimeSinceLastUpdateMillis,
- int probeMcsRateSinceLastUpdate, int rxLinkSpeedMbps,
- @NetworkType int cellularDataNetworkType,
- int cellularSignalStrengthDbm, int cellularSignalStrengthDb,
- boolean isSameRegisteredCell) {
- mTimeStampMillis = timeStampMillis;
- mRssi = rssi;
- mLinkSpeedMbps = linkSpeedMbps;
- mTotalTxSuccess = totalTxSuccess;
- mTotalTxRetries = totalTxRetries;
- mTotalTxBad = totalTxBad;
- mTotalRxSuccess = totalRxSuccess;
- mTotalRadioOnTimeMillis = totalRadioOnTimeMillis;
- mTotalRadioTxTimeMillis = totalRadioTxTimeMillis;
- mTotalRadioRxTimeMillis = totalRadioRxTimeMillis;
- mTotalScanTimeMillis = totalScanTimeMillis;
- mTotalNanScanTimeMillis = totalNanScanTimeMillis;
- mTotalBackgroundScanTimeMillis = totalBackgroundScanTimeMillis;
- mTotalRoamScanTimeMillis = totalRoamScanTimeMillis;
- mTotalPnoScanTimeMillis = totalPnoScanTimeMillis;
- mTotalHotspot2ScanTimeMillis = totalHotspot2ScanTimeMillis;
- mTotalCcaBusyFreqTimeMillis = totalCcaBusyFreqTimeMillis;
- mTotalRadioOnFreqTimeMillis = totalRadioOnFreqTimeMillis;
- mTotalBeaconRx = totalBeaconRx;
- mProbeStatusSinceLastUpdate = probeStatusSinceLastUpdate;
- mProbeElapsedTimeSinceLastUpdateMillis = probeElapsedTimeSinceLastUpdateMillis;
- mProbeMcsRateSinceLastUpdate = probeMcsRateSinceLastUpdate;
- mRxLinkSpeedMbps = rxLinkSpeedMbps;
- mCellularDataNetworkType = cellularDataNetworkType;
- mCellularSignalStrengthDbm = cellularSignalStrengthDbm;
- mCellularSignalStrengthDb = cellularSignalStrengthDb;
- mIsSameRegisteredCell = isSameRegisteredCell;
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(mTimeStampMillis);
- dest.writeInt(mRssi);
- dest.writeInt(mLinkSpeedMbps);
- dest.writeLong(mTotalTxSuccess);
- dest.writeLong(mTotalTxRetries);
- dest.writeLong(mTotalTxBad);
- dest.writeLong(mTotalRxSuccess);
- dest.writeLong(mTotalRadioOnTimeMillis);
- dest.writeLong(mTotalRadioTxTimeMillis);
- dest.writeLong(mTotalRadioRxTimeMillis);
- dest.writeLong(mTotalScanTimeMillis);
- dest.writeLong(mTotalNanScanTimeMillis);
- dest.writeLong(mTotalBackgroundScanTimeMillis);
- dest.writeLong(mTotalRoamScanTimeMillis);
- dest.writeLong(mTotalPnoScanTimeMillis);
- dest.writeLong(mTotalHotspot2ScanTimeMillis);
- dest.writeLong(mTotalCcaBusyFreqTimeMillis);
- dest.writeLong(mTotalRadioOnFreqTimeMillis);
- dest.writeLong(mTotalBeaconRx);
- dest.writeInt(mProbeStatusSinceLastUpdate);
- dest.writeInt(mProbeElapsedTimeSinceLastUpdateMillis);
- dest.writeInt(mProbeMcsRateSinceLastUpdate);
- dest.writeInt(mRxLinkSpeedMbps);
- dest.writeInt(mCellularDataNetworkType);
- dest.writeInt(mCellularSignalStrengthDbm);
- dest.writeInt(mCellularSignalStrengthDb);
- dest.writeBoolean(mIsSameRegisteredCell);
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<WifiUsabilityStatsEntry> CREATOR =
- new Creator<WifiUsabilityStatsEntry>() {
- public WifiUsabilityStatsEntry createFromParcel(Parcel in) {
- return new WifiUsabilityStatsEntry(
- in.readLong(), in.readInt(),
- in.readInt(), in.readLong(), in.readLong(),
- in.readLong(), in.readLong(), in.readLong(),
- in.readLong(), in.readLong(), in.readLong(),
- in.readLong(), in.readLong(), in.readLong(),
- in.readLong(), in.readLong(), in.readLong(),
- in.readLong(), in.readLong(), in.readInt(),
- in.readInt(), in.readInt(), in.readInt(),
- in.readInt(), in.readInt(), in.readInt(),
- in.readBoolean()
- );
- }
-
- public WifiUsabilityStatsEntry[] newArray(int size) {
- return new WifiUsabilityStatsEntry[size];
- }
- };
-
- /** Absolute milliseconds from device boot when these stats were sampled */
- public long getTimeStampMillis() {
- return mTimeStampMillis;
- }
-
- /** The RSSI (in dBm) at the sample time */
- public int getRssi() {
- return mRssi;
- }
-
- /** Link speed at the sample time in Mbps */
- public int getLinkSpeedMbps() {
- return mLinkSpeedMbps;
- }
-
- /** The total number of tx success counted from the last radio chip reset */
- public long getTotalTxSuccess() {
- return mTotalTxSuccess;
- }
-
- /** The total number of MPDU data packet retries counted from the last radio chip reset */
- public long getTotalTxRetries() {
- return mTotalTxRetries;
- }
-
- /** The total number of tx bad counted from the last radio chip reset */
- public long getTotalTxBad() {
- return mTotalTxBad;
- }
-
- /** The total number of rx success counted from the last radio chip reset */
- public long getTotalRxSuccess() {
- return mTotalRxSuccess;
- }
-
- /** The total time the wifi radio is on in ms counted from the last radio chip reset */
- public long getTotalRadioOnTimeMillis() {
- return mTotalRadioOnTimeMillis;
- }
-
- /** The total time the wifi radio is doing tx in ms counted from the last radio chip reset */
- public long getTotalRadioTxTimeMillis() {
- return mTotalRadioTxTimeMillis;
- }
-
- /** The total time the wifi radio is doing rx in ms counted from the last radio chip reset */
- public long getTotalRadioRxTimeMillis() {
- return mTotalRadioRxTimeMillis;
- }
-
- /** The total time spent on all types of scans in ms counted from the last radio chip reset */
- public long getTotalScanTimeMillis() {
- return mTotalScanTimeMillis;
- }
-
- /** The total time spent on nan scans in ms counted from the last radio chip reset */
- public long getTotalNanScanTimeMillis() {
- return mTotalNanScanTimeMillis;
- }
-
- /** The total time spent on background scans in ms counted from the last radio chip reset */
- public long getTotalBackgroundScanTimeMillis() {
- return mTotalBackgroundScanTimeMillis;
- }
-
- /** The total time spent on roam scans in ms counted from the last radio chip reset */
- public long getTotalRoamScanTimeMillis() {
- return mTotalRoamScanTimeMillis;
- }
-
- /** The total time spent on pno scans in ms counted from the last radio chip reset */
- public long getTotalPnoScanTimeMillis() {
- return mTotalPnoScanTimeMillis;
- }
-
- /** The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the last radio
- * chip reset */
- public long getTotalHotspot2ScanTimeMillis() {
- return mTotalHotspot2ScanTimeMillis;
- }
-
- /** The total time CCA is on busy status on the current frequency in ms counted from the last
- * radio chip reset */
- public long getTotalCcaBusyFreqTimeMillis() {
- return mTotalCcaBusyFreqTimeMillis;
- }
-
- /** The total radio on time on the current frequency from the last radio chip reset */
- public long getTotalRadioOnFreqTimeMillis() {
- return mTotalRadioOnFreqTimeMillis;
- }
-
- /** The total number of beacons received from the last radio chip reset */
- public long getTotalBeaconRx() {
- return mTotalBeaconRx;
- }
-
- /** The status of link probe since last stats update */
- @ProbeStatus public int getProbeStatusSinceLastUpdate() {
- return mProbeStatusSinceLastUpdate;
- }
-
- /** The elapsed time of the most recent link probe since last stats update */
- public int getProbeElapsedTimeSinceLastUpdateMillis() {
- return mProbeElapsedTimeSinceLastUpdateMillis;
- }
-
- /** The MCS rate of the most recent link probe since last stats update */
- public int getProbeMcsRateSinceLastUpdate() {
- return mProbeMcsRateSinceLastUpdate;
- }
-
- /** Rx link speed at the sample time in Mbps */
- public int getRxLinkSpeedMbps() {
- return mRxLinkSpeedMbps;
- }
-
- /** Cellular data network type currently in use on the device for data transmission */
- @NetworkType public int getCellularDataNetworkType() {
- return mCellularDataNetworkType;
- }
-
- /**
- * Cellular signal strength in dBm, NR: CsiRsrp, LTE: Rsrp, WCDMA/TDSCDMA: Rscp,
- * CDMA: Rssi, EVDO: Rssi, GSM: Rssi
- */
- public int getCellularSignalStrengthDbm() {
- return mCellularSignalStrengthDbm;
- }
-
- /**
- * Cellular signal strength in dB, NR: CsiSinr, LTE: Rsrq, WCDMA: EcNo, TDSCDMA: invalid,
- * CDMA: Ecio, EVDO: SNR, GSM: invalid
- */
- public int getCellularSignalStrengthDb() {
- return mCellularSignalStrengthDb;
- }
-
- /** Whether the primary registered cell of current entry is same as that of previous entry */
- public boolean isSameRegisteredCell() {
- return mIsSameRegisteredCell;
- }
-}
diff --git a/wifi/java/android/net/wifi/WpsInfo.java b/wifi/java/android/net/wifi/WpsInfo.java
deleted file mode 100644
index 689ace5b..0000000
--- a/wifi/java/android/net/wifi/WpsInfo.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A class representing Wi-Fi Protected Setup
- *
- * {@see android.net.wifi.p2p.WifiP2pConfig}
- */
-public class WpsInfo implements Parcelable {
-
- /** Push button configuration */
- public static final int PBC = 0;
- /** Display pin method configuration - pin is generated and displayed on device */
- public static final int DISPLAY = 1;
- /** Keypad pin method configuration - pin is entered on device */
- public static final int KEYPAD = 2;
- /** Label pin method configuration - pin is labelled on device */
- public static final int LABEL = 3;
- /** Invalid configuration */
- public static final int INVALID = 4;
-
- /** Wi-Fi Protected Setup. www.wi-fi.org/wifi-protected-setup has details */
- public int setup;
-
- /** Passed with pin method KEYPAD */
- public String BSSID;
-
- /** Passed with pin method configuration */
- public String pin;
-
- public WpsInfo() {
- setup = INVALID;
- BSSID = null;
- pin = null;
- }
-
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append(" setup: ").append(setup);
- sbuf.append('\n');
- sbuf.append(" BSSID: ").append(BSSID);
- sbuf.append('\n');
- sbuf.append(" pin: ").append(pin);
- sbuf.append('\n');
- return sbuf.toString();
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /* Copy constructor */
- public WpsInfo(WpsInfo source) {
- if (source != null) {
- setup = source.setup;
- BSSID = source.BSSID;
- pin = source.pin;
- }
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(setup);
- dest.writeString(BSSID);
- dest.writeString(pin);
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<WpsInfo> CREATOR =
- new Creator<WpsInfo>() {
- public WpsInfo createFromParcel(Parcel in) {
- WpsInfo config = new WpsInfo();
- config.setup = in.readInt();
- config.BSSID = in.readString();
- config.pin = in.readString();
- return config;
- }
-
- public WpsInfo[] newArray(int size) {
- return new WpsInfo[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/aware/AttachCallback.java b/wifi/java/android/net/wifi/aware/AttachCallback.java
deleted file mode 100644
index c368b46..0000000
--- a/wifi/java/android/net/wifi/aware/AttachCallback.java
+++ /dev/null
@@ -1,45 +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.net.wifi.aware;
-
-/**
- * Base class for Aware attach callbacks. Should be extended by applications and set when calling
- * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}. These are callbacks
- * applying to the Aware connection as a whole - not to specific publish or subscribe sessions -
- * for that see {@link DiscoverySessionCallback}.
- */
-public class AttachCallback {
- /**
- * Called when Aware attach operation
- * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}
- * is completed and that we can now start discovery sessions or connections.
- *
- * @param session The Aware object on which we can execute further Aware operations - e.g.
- * discovery, connections.
- */
- public void onAttached(WifiAwareSession session) {
- /* empty */
- }
-
- /**
- * Called when Aware attach operation
- * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)} failed.
- */
- public void onAttachFailed() {
- /* empty */
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/Characteristics.java b/wifi/java/android/net/wifi/aware/Characteristics.java
deleted file mode 100644
index d5fd48e..0000000
--- a/wifi/java/android/net/wifi/aware/Characteristics.java
+++ /dev/null
@@ -1,138 +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.net.wifi.aware;
-
-import android.annotation.IntDef;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * The characteristics of the Wi-Fi Aware implementation.
- */
-public final class Characteristics implements Parcelable {
- /** @hide */
- public static final String KEY_MAX_SERVICE_NAME_LENGTH = "key_max_service_name_length";
- /** @hide */
- public static final String KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH =
- "key_max_service_specific_info_length";
- /** @hide */
- public static final String KEY_MAX_MATCH_FILTER_LENGTH = "key_max_match_filter_length";
- /** @hide */
- public static final String KEY_SUPPORTED_CIPHER_SUITES = "key_supported_cipher_suites";
-
- private Bundle mCharacteristics = new Bundle();
-
- /** @hide : should not be created by apps */
- public Characteristics(Bundle characteristics) {
- mCharacteristics = characteristics;
- }
-
- /**
- * Returns the maximum string length that can be used to specify a Aware service name. Restricts
- * the parameters of the {@link PublishConfig.Builder#setServiceName(String)} and
- * {@link SubscribeConfig.Builder#setServiceName(String)}.
- *
- * @return A positive integer, maximum string length of Aware service name.
- */
- public int getMaxServiceNameLength() {
- return mCharacteristics.getInt(KEY_MAX_SERVICE_NAME_LENGTH);
- }
-
- /**
- * Returns the maximum length of byte array that can be used to specify a Aware service specific
- * information field: the arbitrary load used in discovery or the message length of Aware
- * message exchange. Restricts the parameters of the
- * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])},
- * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[])}, and
- * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}
- * variants.
- *
- * @return A positive integer, maximum length of byte array for Aware messaging.
- */
- public int getMaxServiceSpecificInfoLength() {
- return mCharacteristics.getInt(KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH);
- }
-
- /**
- * Returns the maximum length of byte array that can be used to specify a Aware match filter.
- * Restricts the parameters of the
- * {@link PublishConfig.Builder#setMatchFilter(java.util.List)} and
- * {@link SubscribeConfig.Builder#setMatchFilter(java.util.List)}.
- *
- * @return A positive integer, maximum length of byte array for Aware discovery match filter.
- */
- public int getMaxMatchFilterLength() {
- return mCharacteristics.getInt(KEY_MAX_MATCH_FILTER_LENGTH);
- }
-
- /** @hide */
- @IntDef(flag = true, prefix = { "WIFI_AWARE_CIPHER_SUITE_" }, value = {
- WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
- WIFI_AWARE_CIPHER_SUITE_NCS_SK_256,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface WifiAwareCipherSuites {}
-
- /**
- * Wi-Fi Aware supported ciphier suite representing NCS SK 128: 128 bit shared-key.
- */
- public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_128 = 1 << 0;
-
- /**
- * Wi-Fi Aware supported ciphier suite representing NCS SK 256: 256 bit shared-key.
- */
- public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_256 = 1 << 1;
-
- /**
- * Returns the set of cipher suites supported by the device for use in Wi-Fi Aware data-paths.
- * The device automatically picks the strongest cipher suite when initiating a data-path setup.
- *
- * @return A set of flags from {@link #WIFI_AWARE_CIPHER_SUITE_NCS_SK_128}, or
- * {@link #WIFI_AWARE_CIPHER_SUITE_NCS_SK_256}.
- */
- public @WifiAwareCipherSuites int getSupportedCipherSuites() {
- return mCharacteristics.getInt(KEY_SUPPORTED_CIPHER_SUITES);
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeBundle(mCharacteristics);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final @android.annotation.NonNull Creator<Characteristics> CREATOR =
- new Creator<Characteristics>() {
- @Override
- public Characteristics createFromParcel(Parcel in) {
- Characteristics c = new Characteristics(in.readBundle());
- return c;
- }
-
- @Override
- public Characteristics[] newArray(int size) {
- return new Characteristics[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/aware/ConfigRequest.aidl b/wifi/java/android/net/wifi/aware/ConfigRequest.aidl
deleted file mode 100644
index 68a7c85..0000000
--- a/wifi/java/android/net/wifi/aware/ConfigRequest.aidl
+++ /dev/null
@@ -1,19 +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.net.wifi.aware;
-
-parcelable ConfigRequest;
diff --git a/wifi/java/android/net/wifi/aware/ConfigRequest.java b/wifi/java/android/net/wifi/aware/ConfigRequest.java
deleted file mode 100644
index 61ab92c..0000000
--- a/wifi/java/android/net/wifi/aware/ConfigRequest.java
+++ /dev/null
@@ -1,385 +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.net.wifi.aware;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-
-/**
- * Defines a request object to configure a Wi-Fi Aware network. Built using
- * {@link ConfigRequest.Builder}. Configuration is requested using
- * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}.
- * Note that the actual achieved configuration may be different from the
- * requested configuration - since different applications may request different
- * configurations.
- *
- * @hide
- */
-public final class ConfigRequest implements Parcelable {
- /**
- * Lower range of possible cluster ID.
- */
- public static final int CLUSTER_ID_MIN = 0;
-
- /**
- * Upper range of possible cluster ID.
- */
- public static final int CLUSTER_ID_MAX = 0xFFFF;
-
- /**
- * Indices for configuration variables which are specified per band.
- */
- public static final int NAN_BAND_24GHZ = 0;
- public static final int NAN_BAND_5GHZ = 1;
- public static final int NAN_BAND_6GHZ = 2;
-
- /**
- * Magic values for Discovery Window (DW) interval configuration
- */
- public static final int DW_INTERVAL_NOT_INIT = -1;
- public static final int DW_DISABLE = 0; // only valid for 5GHz
-
- /**
- * Indicates whether 5G band support is requested.
- */
- public final boolean mSupport5gBand;
-
- /**
- * Indicates whether 6G band support is requested.
- */
- public final boolean mSupport6gBand;
-
- /**
- * Specifies the desired master preference.
- */
- public final int mMasterPreference;
-
- /**
- * Specifies the desired lower range of the cluster ID. Must be lower then
- * {@link ConfigRequest#mClusterHigh}.
- */
- public final int mClusterLow;
-
- /**
- * Specifies the desired higher range of the cluster ID. Must be higher then
- * {@link ConfigRequest#mClusterLow}.
- */
- public final int mClusterHigh;
-
- /**
- * Specifies the discovery window interval for the device on NAN_BAND_*.
- */
- public final int mDiscoveryWindowInterval[];
-
- private ConfigRequest(boolean support5gBand, boolean support6gBand, int masterPreference,
- int clusterLow, int clusterHigh, int[] discoveryWindowInterval) {
- mSupport5gBand = support5gBand;
- mSupport6gBand = support6gBand;
- mMasterPreference = masterPreference;
- mClusterLow = clusterLow;
- mClusterHigh = clusterHigh;
- mDiscoveryWindowInterval = discoveryWindowInterval;
- }
-
- @Override
- public String toString() {
- return "ConfigRequest [mSupport5gBand=" + mSupport5gBand
- + ", mSupport6gBand=" + mSupport6gBand
- + ", mMasterPreference=" + mMasterPreference
- + ", mClusterLow=" + mClusterLow
- + ", mClusterHigh=" + mClusterHigh
- + ", mDiscoveryWindowInterval=" + Arrays.toString(mDiscoveryWindowInterval) + "]";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mSupport5gBand ? 1 : 0);
- dest.writeInt(mSupport6gBand ? 1 : 0);
- dest.writeInt(mMasterPreference);
- dest.writeInt(mClusterLow);
- dest.writeInt(mClusterHigh);
- dest.writeIntArray(mDiscoveryWindowInterval);
- }
-
- public static final @android.annotation.NonNull Creator<ConfigRequest> CREATOR = new Creator<ConfigRequest>() {
- @Override
- public ConfigRequest[] newArray(int size) {
- return new ConfigRequest[size];
- }
-
- @Override
- public ConfigRequest createFromParcel(Parcel in) {
- boolean support5gBand = in.readInt() != 0;
- boolean support6gBand = in.readInt() != 0;
- int masterPreference = in.readInt();
- int clusterLow = in.readInt();
- int clusterHigh = in.readInt();
- int discoveryWindowInterval[] = in.createIntArray();
-
- return new ConfigRequest(support5gBand, support6gBand, masterPreference, clusterLow,
- clusterHigh, discoveryWindowInterval);
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof ConfigRequest)) {
- return false;
- }
-
- ConfigRequest lhs = (ConfigRequest) o;
-
- return mSupport5gBand == lhs.mSupport5gBand
- && mSupport6gBand == lhs.mSupport6gBand
- && mMasterPreference == lhs.mMasterPreference
- && mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh
- && Arrays.equals(mDiscoveryWindowInterval, lhs.mDiscoveryWindowInterval);
- }
-
- @Override
- public int hashCode() {
- int result = 17;
-
- result = 31 * result + (mSupport5gBand ? 1 : 0);
- result = 31 * result + (mSupport6gBand ? 1 : 0);
- result = 31 * result + mMasterPreference;
- result = 31 * result + mClusterLow;
- result = 31 * result + mClusterHigh;
- result = 31 * result + Arrays.hashCode(mDiscoveryWindowInterval);
-
- return result;
- }
-
- /**
- * Verifies that the contents of the ConfigRequest are valid. Otherwise
- * throws an IllegalArgumentException.
- */
- public void validate() throws IllegalArgumentException {
- if (mMasterPreference < 0) {
- throw new IllegalArgumentException(
- "Master Preference specification must be non-negative");
- }
- if (mMasterPreference == 1 || mMasterPreference == 255 || mMasterPreference > 255) {
- throw new IllegalArgumentException("Master Preference specification must not "
- + "exceed 255 or use 1 or 255 (reserved values)");
- }
- if (mClusterLow < CLUSTER_ID_MIN) {
- throw new IllegalArgumentException("Cluster specification must be non-negative");
- }
- if (mClusterLow > CLUSTER_ID_MAX) {
- throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
- }
- if (mClusterHigh < CLUSTER_ID_MIN) {
- throw new IllegalArgumentException("Cluster specification must be non-negative");
- }
- if (mClusterHigh > CLUSTER_ID_MAX) {
- throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
- }
- if (mClusterLow > mClusterHigh) {
- throw new IllegalArgumentException(
- "Invalid argument combination - must have Cluster Low <= Cluster High");
- }
- if (mDiscoveryWindowInterval.length != 3) {
- throw new IllegalArgumentException(
- "Invalid discovery window interval: must have 3 elements (2.4 & 5 & 6");
- }
- if (mDiscoveryWindowInterval[NAN_BAND_24GHZ] != DW_INTERVAL_NOT_INIT &&
- (mDiscoveryWindowInterval[NAN_BAND_24GHZ] < 1 // valid for 2.4GHz: [1-5]
- || mDiscoveryWindowInterval[NAN_BAND_24GHZ] > 5)) {
- throw new IllegalArgumentException(
- "Invalid discovery window interval for 2.4GHz: valid is UNSET or [1,5]");
- }
- if (mDiscoveryWindowInterval[NAN_BAND_5GHZ] != DW_INTERVAL_NOT_INIT &&
- (mDiscoveryWindowInterval[NAN_BAND_5GHZ] < 0 // valid for 5GHz: [0-5]
- || mDiscoveryWindowInterval[NAN_BAND_5GHZ] > 5)) {
- throw new IllegalArgumentException(
- "Invalid discovery window interval for 5GHz: valid is UNSET or [0,5]");
- }
- if (mDiscoveryWindowInterval[NAN_BAND_6GHZ] != DW_INTERVAL_NOT_INIT
- && (mDiscoveryWindowInterval[NAN_BAND_6GHZ] < 0 // valid for 6GHz: [0-5]
- || mDiscoveryWindowInterval[NAN_BAND_6GHZ] > 5)) {
- throw new IllegalArgumentException(
- "Invalid discovery window interval for 6GHz: valid is UNSET or [0,5]");
- }
- }
-
- /**
- * Builder used to build {@link ConfigRequest} objects.
- */
- public static final class Builder {
- private boolean mSupport5gBand = true;
- private boolean mSupport6gBand = false;
- private int mMasterPreference = 0;
- private int mClusterLow = CLUSTER_ID_MIN;
- private int mClusterHigh = CLUSTER_ID_MAX;
- private int[] mDiscoveryWindowInterval = {DW_INTERVAL_NOT_INIT, DW_INTERVAL_NOT_INIT,
- DW_INTERVAL_NOT_INIT};
-
- /**
- * Specify whether 5G band support is required in this request. Disabled by default.
- *
- * @param support5gBand Support for 5G band is required.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setSupport5gBand(boolean support5gBand) {
- mSupport5gBand = support5gBand;
- return this;
- }
-
- /**
- * Specify whether 6G band support is required in this request. Disabled by default.
- *
- * @param support6gBand Support for 6G band is required.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setSupport6gBand(boolean support6gBand) {
- mSupport6gBand = support6gBand;
- return this;
- }
-
- /**
- * Specify the Master Preference requested. The permitted range is 0 (the default) to
- * 255 with 1 and 255 excluded (reserved).
- *
- * @param masterPreference The requested master preference
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setMasterPreference(int masterPreference) {
- if (masterPreference < 0) {
- throw new IllegalArgumentException(
- "Master Preference specification must be non-negative");
- }
- if (masterPreference == 1 || masterPreference == 255 || masterPreference > 255) {
- throw new IllegalArgumentException("Master Preference specification must not "
- + "exceed 255 or use 1 or 255 (reserved values)");
- }
-
- mMasterPreference = masterPreference;
- return this;
- }
-
- /**
- * The Cluster ID is generated randomly for new Aware networks. Specify
- * the lower range of the cluster ID. The upper range is specified using
- * the {@link ConfigRequest.Builder#setClusterHigh(int)}. The permitted
- * range is 0 (the default) to the value specified by
- * {@link ConfigRequest.Builder#setClusterHigh(int)}. Equality of Low and High is
- * permitted which restricts the Cluster ID to the specified value.
- *
- * @param clusterLow The lower range of the generated cluster ID.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setClusterLow(..).setClusterHigh(..)}.
- */
- public Builder setClusterLow(int clusterLow) {
- if (clusterLow < CLUSTER_ID_MIN) {
- throw new IllegalArgumentException("Cluster specification must be non-negative");
- }
- if (clusterLow > CLUSTER_ID_MAX) {
- throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
- }
-
- mClusterLow = clusterLow;
- return this;
- }
-
- /**
- * The Cluster ID is generated randomly for new Aware networks. Specify
- * the lower upper of the cluster ID. The lower range is specified using
- * the {@link ConfigRequest.Builder#setClusterLow(int)}. The permitted
- * range is the value specified by
- * {@link ConfigRequest.Builder#setClusterLow(int)} to 0xFFFF (the default). Equality of
- * Low and High is permitted which restricts the Cluster ID to the specified value.
- *
- * @param clusterHigh The upper range of the generated cluster ID.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setClusterLow(..).setClusterHigh(..)}.
- */
- public Builder setClusterHigh(int clusterHigh) {
- if (clusterHigh < CLUSTER_ID_MIN) {
- throw new IllegalArgumentException("Cluster specification must be non-negative");
- }
- if (clusterHigh > CLUSTER_ID_MAX) {
- throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
- }
-
- mClusterHigh = clusterHigh;
- return this;
- }
-
- /**
- * The discovery window interval specifies the discovery windows in which the device will be
- * awake. The configuration enables trading off latency vs. power (higher interval means
- * higher discovery latency but lower power).
- *
- * @param band Either {@link #NAN_BAND_24GHZ} or {@link #NAN_BAND_5GHZ} or
- * {@link #NAN_BAND_6GHZ}.
- * @param interval A value of 1, 2, 3, 4, or 5 indicating an interval of 2^(interval-1). For
- * the 5GHz band a value of 0 indicates that the device will not be awake
- * for any discovery windows.
- *
- * @return The builder itself to facilitate chaining operations
- * {@code builder.setDiscoveryWindowInterval(...).setMasterPreference(...)}.
- */
- public Builder setDiscoveryWindowInterval(int band, int interval) {
- if (band != NAN_BAND_24GHZ && band != NAN_BAND_5GHZ && band != NAN_BAND_6GHZ) {
- throw new IllegalArgumentException("Invalid band value");
- }
- if ((band == NAN_BAND_24GHZ && (interval < 1 || interval > 5))
- || (band == NAN_BAND_5GHZ && (interval < 0 || interval > 5))
- || (band == NAN_BAND_6GHZ && (interval < 0 || interval > 5))) {
- throw new IllegalArgumentException(
- "Invalid interval value: 2.4 GHz [1,5] or 5GHz/6GHz [0,5]");
- }
-
- mDiscoveryWindowInterval[band] = interval;
- return this;
- }
-
- /**
- * Build {@link ConfigRequest} given the current requests made on the
- * builder.
- */
- public ConfigRequest build() {
- if (mClusterLow > mClusterHigh) {
- throw new IllegalArgumentException(
- "Invalid argument combination - must have Cluster Low <= Cluster High");
- }
-
- return new ConfigRequest(mSupport5gBand, mSupport6gBand, mMasterPreference, mClusterLow,
- mClusterHigh, mDiscoveryWindowInterval);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
deleted file mode 100644
index 4d92ae1..0000000
--- a/wifi/java/android/net/wifi/aware/DiscoverySession.java
+++ /dev/null
@@ -1,431 +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.net.wifi.aware;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.NetworkSpecifier;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-
-/**
- * A class representing a single publish or subscribe Aware session. This object
- * will not be created directly - only its child classes are available:
- * {@link PublishDiscoverySession} and {@link SubscribeDiscoverySession}. This
- * class provides functionality common to both publish and subscribe discovery sessions:
- * <ul>
- * <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])} method.
- * <li>Creating a network-specifier when requesting a Aware connection using
- * {@link WifiAwareNetworkSpecifier.Builder}.
- * </ul>
- * <p>
- * The {@link #close()} method must be called to destroy discovery sessions once they are
- * no longer needed.
- */
-public class DiscoverySession implements AutoCloseable {
- private static final String TAG = "DiscoverySession";
- private static final boolean DBG = false;
- private static final boolean VDBG = false; // STOPSHIP if true
-
- private static final int MAX_SEND_RETRY_COUNT = 5;
-
- /** @hide */
- protected WeakReference<WifiAwareManager> mMgr;
- /** @hide */
- protected final int mClientId;
- /** @hide */
- protected final int mSessionId;
- /** @hide */
- protected boolean mTerminated = false;
-
- private final CloseGuard mCloseGuard = new CloseGuard();
-
- /**
- * Return the maximum permitted retry count when sending messages using
- * {@link #sendMessage(PeerHandle, int, byte[], int)}.
- *
- * @return Maximum retry count when sending messages.
- *
- * @hide
- */
- public static int getMaxSendRetryCount() {
- return MAX_SEND_RETRY_COUNT;
- }
-
- /** @hide */
- public DiscoverySession(WifiAwareManager manager, int clientId, int sessionId) {
- if (VDBG) {
- Log.v(TAG, "New discovery session created: manager=" + manager + ", clientId="
- + clientId + ", sessionId=" + sessionId);
- }
-
- mMgr = new WeakReference<>(manager);
- mClientId = clientId;
- mSessionId = sessionId;
-
- mCloseGuard.open("close");
- }
-
- /**
- * Destroy the publish or subscribe session - free any resources, and stop
- * transmitting packets on-air (for an active session) or listening for
- * matches (for a passive session). The session may not be used for any
- * additional operations after its destruction.
- * <p>
- * This operation must be done on a session which is no longer needed. Otherwise system
- * resources will continue to be utilized until the application exits. The only
- * exception is a session for which we received a termination callback,
- * {@link DiscoverySessionCallback#onSessionTerminated()}.
- */
- @Override
- public void close() {
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.w(TAG, "destroy: called post GC on WifiAwareManager");
- return;
- }
- mgr.terminateSession(mClientId, mSessionId);
- mTerminated = true;
- mMgr.clear();
- mCloseGuard.close();
- Reference.reachabilityFence(this);
- }
-
- /**
- * Sets the status of the session to terminated - i.e. an indication that
- * already terminated rather than executing a termination.
- *
- * @hide
- */
- public void setTerminated() {
- if (mTerminated) {
- Log.w(TAG, "terminate: already terminated.");
- return;
- }
-
- mTerminated = true;
- mMgr.clear();
- mCloseGuard.close();
- }
-
- /** @hide */
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mCloseGuard != null) {
- mCloseGuard.warnIfOpen();
- }
-
- if (!mTerminated) {
- close();
- }
- } finally {
- super.finalize();
- }
- }
-
- /**
- * Access the client ID of the Aware session.
- *
- * Note: internal visibility for testing.
- *
- * @return The internal client ID.
- *
- * @hide
- */
- @VisibleForTesting
- public int getClientId() {
- return mClientId;
- }
-
- /**
- * Access the discovery session ID of the Aware session.
- *
- * Note: internal visibility for testing.
- *
- * @return The internal discovery session ID.
- *
- * @hide
- */
- @VisibleForTesting
- public int getSessionId() {
- return mSessionId;
- }
-
- /**
- * Sends a message to the specified destination. Aware messages are transmitted in the context
- * of a discovery session - executed subsequent to a publish/subscribe
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
- * byte[], java.util.List)} event.
- * <p>
- * Aware messages are not guaranteed delivery. Callbacks on
- * {@link DiscoverySessionCallback} indicate message was transmitted successfully,
- * {@link DiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission
- * failed (possibly after several retries) -
- * {@link DiscoverySessionCallback#onMessageSendFailed(int)}.
- * <p>
- * The peer will get a callback indicating a message was received using
- * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
- * byte[])}.
- *
- * @param peerHandle The peer's handle for the message. Must be a result of an
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
- * byte[], java.util.List)} or
- * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
- * byte[])} events.
- * @param messageId An arbitrary integer used by the caller to identify the message. The same
- * integer ID will be returned in the callbacks indicating message send success or
- * failure. The {@code messageId} is not used internally by the Aware service - it
- * can be arbitrary and non-unique.
- * @param message The message to be transmitted.
- * @param retryCount An integer specifying how many additional service-level (as opposed to PHY
- * or MAC level) retries should be attempted if there is no ACK from the receiver
- * (note: no retransmissions are attempted in other failure cases). A value of 0
- * indicates no retries. Max permitted value is {@link #getMaxSendRetryCount()}.
- *
- * @hide
- */
- public void sendMessage(@NonNull PeerHandle peerHandle, int messageId,
- @Nullable byte[] message, int retryCount) {
- if (mTerminated) {
- Log.w(TAG, "sendMessage: called on terminated session");
- return;
- }
-
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.w(TAG, "sendMessage: called post GC on WifiAwareManager");
- return;
- }
-
- mgr.sendMessage(mClientId, mSessionId, peerHandle, message, messageId, retryCount);
- }
-
- /**
- * Sends a message to the specified destination. Aware messages are transmitted in the context
- * of a discovery session - executed subsequent to a publish/subscribe
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
- * byte[], java.util.List)} event.
- * <p>
- * Aware messages are not guaranteed delivery. Callbacks on
- * {@link DiscoverySessionCallback} indicate message was transmitted successfully,
- * {@link DiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission
- * failed (possibly after several retries) -
- * {@link DiscoverySessionCallback#onMessageSendFailed(int)}.
- * <p>
- * The peer will get a callback indicating a message was received using
- * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
- * byte[])}.
- *
- * @param peerHandle The peer's handle for the message. Must be a result of an
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
- * byte[], java.util.List)} or
- * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
- * byte[])} events.
- * @param messageId An arbitrary integer used by the caller to identify the message. The same
- * integer ID will be returned in the callbacks indicating message send success or
- * failure. The {@code messageId} is not used internally by the Aware service - it
- * can be arbitrary and non-unique.
- * @param message The message to be transmitted.
- */
- public void sendMessage(@NonNull PeerHandle peerHandle, int messageId,
- @Nullable byte[] message) {
- sendMessage(peerHandle, messageId, message, 0);
- }
-
- /**
- * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
- * an unencrypted WiFi Aware connection (link) to the specified peer. The
- * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
- * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
- * <p>
- * This method should be used when setting up a connection with a peer discovered through Aware
- * discovery or communication (in such scenarios the MAC address of the peer is shielded by
- * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other
- * OOB (out-of-band) mechanism then use the alternative
- * {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} method - which uses the
- * peer's MAC address.
- * <p>
- * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
- * and a Publisher is a RESPONDER.
- * <p>
- * To set up an encrypted link use the
- * {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} API.
- * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
- *
- * @param peerHandle The peer's handle obtained through
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
- * or
- * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
- * On a RESPONDER this value is used to gate the acceptance of a connection
- * request from only that peer.
- *
- * @return A {@link NetworkSpecifier} to be used to construct
- * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
- * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
- * android.net.ConnectivityManager.NetworkCallback)}
- * [or other varieties of that API].
- */
- @Deprecated
- public NetworkSpecifier createNetworkSpecifierOpen(@NonNull PeerHandle peerHandle) {
- if (mTerminated) {
- Log.w(TAG, "createNetworkSpecifierOpen: called on terminated session");
- return null;
- }
-
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.w(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager");
- return null;
- }
-
- int role = this instanceof SubscribeDiscoverySession
- ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
- : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-
- return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null, null);
- }
-
- /**
- * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
- * an encrypted WiFi Aware connection (link) to the specified peer. The
- * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
- * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
- * <p>
- * This method should be used when setting up a connection with a peer discovered through Aware
- * discovery or communication (in such scenarios the MAC address of the peer is shielded by
- * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other
- * OOB (out-of-band) mechanism then use the alternative
- * {@link WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)} method -
- * which uses the peer's MAC address.
- * <p>
- * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
- * and a Publisher is a RESPONDER.
- * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
- *
- * @param peerHandle The peer's handle obtained through
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
- * byte[], java.util.List)} or
- * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
- * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
- * from only that peer.
- * @param passphrase The passphrase to be used to encrypt the link. The PMK is generated from
- * the passphrase. Use the
- * {@link #createNetworkSpecifierOpen(PeerHandle)} API to
- * specify an open (unencrypted) link.
- *
- * @return A {@link NetworkSpecifier} to be used to construct
- * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
- * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
- * android.net.ConnectivityManager.NetworkCallback)}
- * [or other varieties of that API].
- */
- @Deprecated
- public NetworkSpecifier createNetworkSpecifierPassphrase(
- @NonNull PeerHandle peerHandle, @NonNull String passphrase) {
- if (!WifiAwareUtils.validatePassphrase(passphrase)) {
- throw new IllegalArgumentException("Passphrase must meet length requirements");
- }
-
- if (mTerminated) {
- Log.w(TAG, "createNetworkSpecifierPassphrase: called on terminated session");
- return null;
- }
-
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.w(TAG, "createNetworkSpecifierPassphrase: called post GC on WifiAwareManager");
- return null;
- }
-
- int role = this instanceof SubscribeDiscoverySession
- ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
- : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-
- return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null,
- passphrase);
- }
-
- /**
- * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
- * an encrypted WiFi Aware connection (link) to the specified peer. The
- * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
- * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
- * <p>
- * This method should be used when setting up a connection with a peer discovered through Aware
- * discovery or communication (in such scenarios the MAC address of the peer is shielded by
- * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other
- * OOB (out-of-band) mechanism then use the alternative
- * {@link WifiAwareSession#createNetworkSpecifierPmk(int, byte[], byte[])} method - which uses
- * the peer's MAC address.
- * <p>
- * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
- * and a Publisher is a RESPONDER.
- * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
- *
- * @param peerHandle The peer's handle obtained through
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
- * byte[], java.util.List)} or
- * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
- * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
- * from only that peer.
- * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
- * encrypting the data-path. Use the
- * {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} to specify a
- * Passphrase or {@link #createNetworkSpecifierOpen(PeerHandle)} to specify an
- * open (unencrypted) link.
- *
- * @return A {@link NetworkSpecifier} to be used to construct
- * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
- * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
- * android.net.ConnectivityManager.NetworkCallback)}
- * [or other varieties of that API].
- *
- * @hide
- */
- @Deprecated
- @SystemApi
- public NetworkSpecifier createNetworkSpecifierPmk(@NonNull PeerHandle peerHandle,
- @NonNull byte[] pmk) {
- if (!WifiAwareUtils.validatePmk(pmk)) {
- throw new IllegalArgumentException("PMK must 32 bytes");
- }
-
- if (mTerminated) {
- Log.w(TAG, "createNetworkSpecifierPmk: called on terminated session");
- return null;
- }
-
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.w(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager");
- return null;
- }
-
- int role = this instanceof SubscribeDiscoverySession
- ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
- : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-
- return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, pmk, null);
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
deleted file mode 100644
index bfb0462..0000000
--- a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
+++ /dev/null
@@ -1,192 +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.net.wifi.aware;
-
-import android.annotation.NonNull;
-
-import java.util.List;
-
-/**
- * Base class for Aware session events callbacks. Should be extended by
- * applications wanting notifications. The callbacks are set when a
- * publish or subscribe session is created using
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
- * android.os.Handler)} or
- * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
- * android.os.Handler)}.
- * <p>
- * A single callback is set at session creation - it cannot be replaced.
- */
-public class DiscoverySessionCallback {
- /**
- * Called when a publish operation is started successfully in response to a
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
- * android.os.Handler)} operation.
- *
- * @param session The {@link PublishDiscoverySession} used to control the
- * discovery session.
- */
- public void onPublishStarted(@NonNull PublishDiscoverySession session) {
- /* empty */
- }
-
- /**
- * Called when a subscribe operation is started successfully in response to a
- * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
- * android.os.Handler)} operation.
- *
- * @param session The {@link SubscribeDiscoverySession} used to control the
- * discovery session.
- */
- public void onSubscribeStarted(@NonNull SubscribeDiscoverySession session) {
- /* empty */
- }
-
- /**
- * Called when a publish or subscribe discovery session configuration update request
- * succeeds. Called in response to
- * {@link PublishDiscoverySession#updatePublish(PublishConfig)} or
- * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
- */
- public void onSessionConfigUpdated() {
- /* empty */
- }
-
- /**
- * Called when a publish or subscribe discovery session cannot be created:
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
- * android.os.Handler)} or
- * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
- * android.os.Handler)}, or when a configuration update fails:
- * {@link PublishDiscoverySession#updatePublish(PublishConfig)} or
- * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
- * <p>
- * For discovery session updates failure leaves the session running with its previous
- * configuration - the discovery session is not terminated.
- */
- public void onSessionConfigFailed() {
- /* empty */
- }
-
- /**
- * Called when a discovery session (publish or subscribe) terminates. Termination may be due
- * to user-request (either directly through {@link DiscoverySession#close()} or
- * application-specified expiration, e.g. {@link PublishConfig.Builder#setTtlSec(int)}
- * or {@link SubscribeConfig.Builder#setTtlSec(int)}).
- */
- public void onSessionTerminated() {
- /* empty */
- }
-
- /**
- * Called when a discovery (publish or subscribe) operation results in a
- * service discovery.
- * <p>
- * Note that this method and
- * {@link #onServiceDiscoveredWithinRange(PeerHandle, byte[], List, int)} may be called
- * multiple times per service discovery.
- *
- * @param peerHandle An opaque handle to the peer matching our discovery operation.
- * @param serviceSpecificInfo The service specific information (arbitrary
- * byte array) provided by the peer as part of its discovery
- * configuration.
- * @param matchFilter The filter which resulted in this service discovery. For
- * {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED},
- * {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE} discovery sessions this is the publisher's
- * match filter. For {@link PublishConfig#PUBLISH_TYPE_SOLICITED},
- * {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE} discovery sessions this
- * is the subscriber's match filter.
- */
- public void onServiceDiscovered(PeerHandle peerHandle,
- byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
- /* empty */
- }
-
- /**
- * Called when a discovery (publish or subscribe) operation results in a
- * service discovery. Called when a Subscribe service was configured with a range requirement
- * {@link SubscribeConfig.Builder#setMinDistanceMm(int)} and/or
- * {@link SubscribeConfig.Builder#setMaxDistanceMm(int)} and the Publish service was configured
- * with {@link PublishConfig.Builder#setRangingEnabled(boolean)}.
- * <p>
- * If either Publisher or Subscriber does not enable Ranging, or if Ranging is temporarily
- * disabled by the underlying device, service discovery proceeds without ranging and the
- * {@link #onServiceDiscovered(PeerHandle, byte[], List)} is called.
- * <p>
- * Note that this method and {@link #onServiceDiscovered(PeerHandle, byte[], List)} may be
- * called multiple times per service discovery.
- *
- * @param peerHandle An opaque handle to the peer matching our discovery operation.
- * @param serviceSpecificInfo The service specific information (arbitrary
- * byte array) provided by the peer as part of its discovery
- * configuration.
- * @param matchFilter The filter which resulted in this service discovery. For
- * {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED},
- * {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE} discovery sessions this is the publisher's
- * match filter. For {@link PublishConfig#PUBLISH_TYPE_SOLICITED},
- * {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE} discovery sessions this
- * is the subscriber's match filter.
- * @param distanceMm The measured distance to the Publisher in mm. Note: the measured distance
- * may be negative for very close devices.
- */
- public void onServiceDiscoveredWithinRange(PeerHandle peerHandle,
- byte[] serviceSpecificInfo, List<byte[]> matchFilter, int distanceMm) {
- /* empty */
- }
-
- /**
- * Called in response to
- * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}
- * when a message is transmitted successfully - i.e. when it was received successfully by the
- * peer (corresponds to an ACK being received).
- * <p>
- * Note that either this callback or
- * {@link DiscoverySessionCallback#onMessageSendFailed(int)} will be
- * received - never both.
- *
- * @param messageId The arbitrary message ID specified when sending the message.
- */
- public void onMessageSendSucceeded(@SuppressWarnings("unused") int messageId) {
- /* empty */
- }
-
- /**
- * Called when message transmission initiated with
- * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])} fails. E.g. when no ACK is
- * received from the peer.
- * <p>
- * Note that either this callback or
- * {@link DiscoverySessionCallback#onMessageSendSucceeded(int)} will be received
- * - never both.
- *
- * @param messageId The arbitrary message ID specified when sending the message.
- */
- public void onMessageSendFailed(@SuppressWarnings("unused") int messageId) {
- /* empty */
- }
-
- /**
- * Called when a message is received from a discovery session peer - in response to the
- * peer's {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}.
- *
- * @param peerHandle An opaque handle to the peer matching our discovery operation.
- * @param message A byte array containing the message.
- */
- public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
- /* empty */
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
deleted file mode 100644
index 421a8af..0000000
--- a/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
+++ /dev/null
@@ -1,38 +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.net.wifi.aware;
-
-/**
- * Callback interface that WifiAwareManager implements
- *
- * {@hide}
- */
-oneway interface IWifiAwareDiscoverySessionCallback
-{
- void onSessionStarted(int discoverySessionId);
- void onSessionConfigSuccess();
- void onSessionConfigFail(int reason);
- void onSessionTerminated(int reason);
-
- void onMatch(int peerId, in byte[] serviceSpecificInfo, in byte[] matchFilter);
- void onMatchWithDistance(int peerId, in byte[] serviceSpecificInfo, in byte[] matchFilter,
- int distanceMm);
-
- void onMessageSendSuccess(int messageId);
- void onMessageSendFail(int messageId, int reason);
- void onMessageReceived(int peerId, in byte[] message);
-}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl
deleted file mode 100644
index b646567..0000000
--- a/wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl
+++ /dev/null
@@ -1,31 +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.net.wifi.aware;
-
-import android.net.wifi.aware.ConfigRequest;
-
-/**
- * Callback interface that WifiAwareManager implements
- *
- * {@hide}
- */
-oneway interface IWifiAwareEventCallback
-{
- void onConnectSuccess(int clientId);
- void onConnectFail(int reason);
- void onIdentityChanged(in byte[] mac);
-}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl
deleted file mode 100644
index 0e7289c..0000000
--- a/wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl
+++ /dev/null
@@ -1,27 +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.net.wifi.aware;
-
-/**
- * Callback for IWifiAwareManager.getMacAddressFromPeerHandle
- *
- * @hide
- */
-oneway interface IWifiAwareMacAddressProvider
-{
- void macAddress(in Map peerIdToMacMap);
-}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
deleted file mode 100644
index 88f95ad..0000000
--- a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
+++ /dev/null
@@ -1,60 +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.net.wifi.aware;
-
-import android.app.PendingIntent;
-
-import android.net.wifi.aware.ConfigRequest;
-import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback;
-import android.net.wifi.aware.IWifiAwareEventCallback;
-import android.net.wifi.aware.IWifiAwareMacAddressProvider;
-import android.net.wifi.aware.PublishConfig;
-import android.net.wifi.aware.SubscribeConfig;
-import android.net.wifi.aware.Characteristics;
-
-/**
- * Interface that WifiAwareService implements
- *
- * {@hide}
- */
-interface IWifiAwareManager
-{
- // Aware API
- boolean isUsageEnabled();
- Characteristics getCharacteristics();
-
- // client API
- void connect(in IBinder binder, in String callingPackage, in String callingFeatureId,
- in IWifiAwareEventCallback callback, in ConfigRequest configRequest,
- boolean notifyOnIdentityChanged);
- void disconnect(int clientId, in IBinder binder);
-
- void publish(in String callingPackage, in String callingFeatureId, int clientId,
- in PublishConfig publishConfig, in IWifiAwareDiscoverySessionCallback callback);
- void subscribe(in String callingPackage, in String callingFeatureId, int clientId,
- in SubscribeConfig subscribeConfig, in IWifiAwareDiscoverySessionCallback callback);
-
- // session API
- void updatePublish(int clientId, int discoverySessionId, in PublishConfig publishConfig);
- void updateSubscribe(int clientId, int discoverySessionId, in SubscribeConfig subscribeConfig);
- void sendMessage(int clientId, int discoverySessionId, int peerId, in byte[] message,
- int messageId, int retryCount);
- void terminateSession(int clientId, int discoverySessionId);
-
- // internal APIs: intended to be used between System Services (restricted permissions)
- void requestMacAddresses(int uid, in List peerIds, in IWifiAwareMacAddressProvider callback);
-}
diff --git a/wifi/java/android/net/wifi/aware/IdentityChangedListener.java b/wifi/java/android/net/wifi/aware/IdentityChangedListener.java
deleted file mode 100644
index a8b19b3..0000000
--- a/wifi/java/android/net/wifi/aware/IdentityChangedListener.java
+++ /dev/null
@@ -1,39 +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.net.wifi.aware;
-
-/**
- * Base class for a listener which is called with the MAC address of the Aware interface whenever
- * it is changed. Change may be due to device joining a cluster, starting a cluster, or discovery
- * interface change (addresses are randomized at regular intervals). The implication is that
- * peers you've been communicating with may no longer recognize you and you need to re-establish
- * your identity - e.g. by starting a discovery session. This actual MAC address of the
- * interface may also be useful if the application uses alternative (non-Aware) discovery but needs
- * to set up a Aware connection. The provided Aware discovery interface MAC address can then be used
- * in {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} or
- * {@link WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)}.
- */
-public class IdentityChangedListener {
- /**
- * @param mac The MAC address of the Aware discovery interface. The application must have the
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} to get the actual MAC address,
- * otherwise all 0's will be provided.
- */
- public void onIdentityChanged(byte[] mac) {
- /* empty */
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/ParcelablePeerHandle.java b/wifi/java/android/net/wifi/aware/ParcelablePeerHandle.java
deleted file mode 100644
index ca473db..0000000
--- a/wifi/java/android/net/wifi/aware/ParcelablePeerHandle.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A Parcelable {@link PeerHandle}. Can be constructed from a {@code PeerHandle} and then passed
- * to any of the APIs which take a {@code PeerHandle} as inputs.
- */
-public final class ParcelablePeerHandle extends PeerHandle implements Parcelable {
- /**
- * Construct a parcelable version of {@link PeerHandle}.
- *
- * @param peerHandle The {@link PeerHandle} to be made parcelable.
- */
- public ParcelablePeerHandle(@NonNull PeerHandle peerHandle) {
- super(peerHandle.peerId);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(peerId);
- }
-
- public static final @android.annotation.NonNull Creator<ParcelablePeerHandle> CREATOR =
- new Creator<ParcelablePeerHandle>() {
- @Override
- public ParcelablePeerHandle[] newArray(int size) {
- return new ParcelablePeerHandle[size];
- }
-
- @Override
- public ParcelablePeerHandle createFromParcel(Parcel in) {
- int peerHandle = in.readInt();
- return new ParcelablePeerHandle(new PeerHandle(peerHandle));
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/aware/PeerHandle.java b/wifi/java/android/net/wifi/aware/PeerHandle.java
deleted file mode 100644
index 422e177..0000000
--- a/wifi/java/android/net/wifi/aware/PeerHandle.java
+++ /dev/null
@@ -1,63 +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.net.wifi.aware;
-
-/**
- * Opaque object used to represent a Wi-Fi Aware peer. Obtained from discovery sessions in
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)} or
- * received messages in {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}, and
- * used when sending messages e,g, {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])},
- * or when configuring a network link to a peer, e.g.
- * {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)} or
- * {@link DiscoverySession#createNetworkSpecifierPassphrase(PeerHandle, String)}.
- * <p>
- * Note that while a {@code PeerHandle} can be used to track a particular peer (i.e. you can compare
- * the values received from subsequent messages) - it is good practice not to rely on it. Instead
- * use an application level peer identifier encoded in the message,
- * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}, and/or in the Publish
- * configuration's service-specific information field,
- * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])}, or match filter,
- * {@link PublishConfig.Builder#setMatchFilter(java.util.List)}.
- * <p>A parcelable handle object is available with {@link ParcelablePeerHandle}.
- */
-public class PeerHandle {
- /** @hide */
- public PeerHandle(int peerId) {
- this.peerId = peerId;
- }
-
- /** @hide */
- public int peerId;
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof PeerHandle)) {
- return false;
- }
-
- return peerId == ((PeerHandle) o).peerId;
- }
-
- @Override
- public int hashCode() {
- return peerId;
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
deleted file mode 100644
index a8844c1..0000000
--- a/wifi/java/android/net/wifi/aware/PublishConfig.java
+++ /dev/null
@@ -1,393 +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.net.wifi.aware;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.wifi.util.HexEncoding;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Defines the configuration of a Aware publish session. Built using
- * {@link PublishConfig.Builder}. A publish session is created using
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
- * android.os.Handler)} or updated using
- * {@link PublishDiscoverySession#updatePublish(PublishConfig)}.
- */
-public final class PublishConfig implements Parcelable {
- /** @hide */
- @IntDef({
- PUBLISH_TYPE_UNSOLICITED, PUBLISH_TYPE_SOLICITED })
- @Retention(RetentionPolicy.SOURCE)
- public @interface PublishTypes {
- }
-
- /**
- * Defines an unsolicited publish session - a publish session where the publisher is
- * advertising itself by broadcasting on-the-air. An unsolicited publish session is paired
- * with an passive subscribe session {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE}.
- * Configuration is done using {@link PublishConfig.Builder#setPublishType(int)}.
- */
- public static final int PUBLISH_TYPE_UNSOLICITED = 0;
-
- /**
- * Defines a solicited publish session - a publish session which is silent, waiting for a
- * matching active subscribe session - and responding to it in unicast. A
- * solicited publish session is paired with an active subscribe session
- * {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE}. Configuration is done using
- * {@link PublishConfig.Builder#setPublishType(int)}.
- */
- public static final int PUBLISH_TYPE_SOLICITED = 1;
-
- /** @hide */
- public final byte[] mServiceName;
-
- /** @hide */
- public final byte[] mServiceSpecificInfo;
-
- /** @hide */
- public final byte[] mMatchFilter;
-
- /** @hide */
- public final int mPublishType;
-
- /** @hide */
- public final int mTtlSec;
-
- /** @hide */
- public final boolean mEnableTerminateNotification;
-
- /** @hide */
- public final boolean mEnableRanging;
-
- /** @hide */
- public PublishConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
- int publishType, int ttlSec, boolean enableTerminateNotification,
- boolean enableRanging) {
- mServiceName = serviceName;
- mServiceSpecificInfo = serviceSpecificInfo;
- mMatchFilter = matchFilter;
- mPublishType = publishType;
- mTtlSec = ttlSec;
- mEnableTerminateNotification = enableTerminateNotification;
- mEnableRanging = enableRanging;
- }
-
- @Override
- public String toString() {
- return "PublishConfig [mServiceName='" + (mServiceName == null ? "<null>" : String.valueOf(
- HexEncoding.encode(mServiceName))) + ", mServiceName.length=" + (
- mServiceName == null ? 0 : mServiceName.length) + ", mServiceSpecificInfo='" + (
- (mServiceSpecificInfo == null) ? "<null>" : String.valueOf(
- HexEncoding.encode(mServiceSpecificInfo)))
- + ", mServiceSpecificInfo.length=" + (mServiceSpecificInfo == null ? 0
- : mServiceSpecificInfo.length) + ", mMatchFilter="
- + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString()
- + ", mMatchFilter.length=" + (mMatchFilter == null ? 0 : mMatchFilter.length)
- + ", mPublishType=" + mPublishType + ", mTtlSec=" + mTtlSec
- + ", mEnableTerminateNotification=" + mEnableTerminateNotification
- + ", mEnableRanging=" + mEnableRanging + "]";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeByteArray(mServiceName);
- dest.writeByteArray(mServiceSpecificInfo);
- dest.writeByteArray(mMatchFilter);
- dest.writeInt(mPublishType);
- dest.writeInt(mTtlSec);
- dest.writeInt(mEnableTerminateNotification ? 1 : 0);
- dest.writeInt(mEnableRanging ? 1 : 0);
- }
-
- public static final @android.annotation.NonNull Creator<PublishConfig> CREATOR = new Creator<PublishConfig>() {
- @Override
- public PublishConfig[] newArray(int size) {
- return new PublishConfig[size];
- }
-
- @Override
- public PublishConfig createFromParcel(Parcel in) {
- byte[] serviceName = in.createByteArray();
- byte[] ssi = in.createByteArray();
- byte[] matchFilter = in.createByteArray();
- int publishType = in.readInt();
- int ttlSec = in.readInt();
- boolean enableTerminateNotification = in.readInt() != 0;
- boolean enableRanging = in.readInt() != 0;
-
- return new PublishConfig(serviceName, ssi, matchFilter, publishType,
- ttlSec, enableTerminateNotification, enableRanging);
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof PublishConfig)) {
- return false;
- }
-
- PublishConfig lhs = (PublishConfig) o;
-
- return Arrays.equals(mServiceName, lhs.mServiceName) && Arrays.equals(mServiceSpecificInfo,
- lhs.mServiceSpecificInfo) && Arrays.equals(mMatchFilter, lhs.mMatchFilter)
- && mPublishType == lhs.mPublishType
- && mTtlSec == lhs.mTtlSec
- && mEnableTerminateNotification == lhs.mEnableTerminateNotification
- && mEnableRanging == lhs.mEnableRanging;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(Arrays.hashCode(mServiceName), Arrays.hashCode(mServiceSpecificInfo),
- Arrays.hashCode(mMatchFilter), mPublishType, mTtlSec, mEnableTerminateNotification,
- mEnableRanging);
- }
-
- /**
- * Verifies that the contents of the PublishConfig are valid. Otherwise
- * throws an IllegalArgumentException.
- *
- * @hide
- */
- public void assertValid(Characteristics characteristics, boolean rttSupported)
- throws IllegalArgumentException {
- WifiAwareUtils.validateServiceName(mServiceName);
-
- if (!TlvBufferUtils.isValid(mMatchFilter, 0, 1)) {
- throw new IllegalArgumentException(
- "Invalid txFilter configuration - LV fields do not match up to length");
- }
- if (mPublishType < PUBLISH_TYPE_UNSOLICITED || mPublishType > PUBLISH_TYPE_SOLICITED) {
- throw new IllegalArgumentException("Invalid publishType - " + mPublishType);
- }
- if (mTtlSec < 0) {
- throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
- }
-
- if (characteristics != null) {
- int maxServiceNameLength = characteristics.getMaxServiceNameLength();
- if (maxServiceNameLength != 0 && mServiceName.length > maxServiceNameLength) {
- throw new IllegalArgumentException(
- "Service name longer than supported by device characteristics");
- }
- int maxServiceSpecificInfoLength = characteristics.getMaxServiceSpecificInfoLength();
- if (maxServiceSpecificInfoLength != 0 && mServiceSpecificInfo != null
- && mServiceSpecificInfo.length > maxServiceSpecificInfoLength) {
- throw new IllegalArgumentException(
- "Service specific info longer than supported by device characteristics");
- }
- int maxMatchFilterLength = characteristics.getMaxMatchFilterLength();
- if (maxMatchFilterLength != 0 && mMatchFilter != null
- && mMatchFilter.length > maxMatchFilterLength) {
- throw new IllegalArgumentException(
- "Match filter longer than supported by device characteristics");
- }
- }
-
- if (!rttSupported && mEnableRanging) {
- throw new IllegalArgumentException("Ranging is not supported");
- }
- }
-
- /**
- * Builder used to build {@link PublishConfig} objects.
- */
- public static final class Builder {
- private byte[] mServiceName;
- private byte[] mServiceSpecificInfo;
- private byte[] mMatchFilter;
- private int mPublishType = PUBLISH_TYPE_UNSOLICITED;
- private int mTtlSec = 0;
- private boolean mEnableTerminateNotification = true;
- private boolean mEnableRanging = false;
-
- /**
- * Specify the service name of the publish session. The actual on-air
- * value is a 6 byte hashed representation of this string.
- * <p>
- * The Service Name is a UTF-8 encoded string from 1 to 255 bytes in length.
- * The only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric
- * values (A-Z, a-z, 0-9), the hyphen ('-'), and the period ('.'). All valid multi-byte
- * UTF-8 characters are acceptable in a Service Name.
- * <p>
- * Must be called - an empty ServiceName is not valid.
- *
- * @param serviceName The service name for the publish session.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setServiceName(@NonNull String serviceName) {
- if (serviceName == null) {
- throw new IllegalArgumentException("Invalid service name - must be non-null");
- }
- mServiceName = serviceName.getBytes(StandardCharsets.UTF_8);
- return this;
- }
-
- /**
- * Specify service specific information for the publish session. This is
- * a free-form byte array available to the application to send
- * additional information as part of the discovery operation - it
- * will not be used to determine whether a publish/subscribe match
- * occurs.
- * <p>
- * Optional. Empty by default.
- *
- * @param serviceSpecificInfo A byte-array for the service-specific
- * information field.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setServiceSpecificInfo(@Nullable byte[] serviceSpecificInfo) {
- mServiceSpecificInfo = serviceSpecificInfo;
- return this;
- }
-
- /**
- * The match filter for a publish session. Used to determine whether a service
- * discovery occurred - in addition to relying on the service name.
- * <p>
- * Optional. Empty by default.
- *
- * @param matchFilter A list of match filter entries (each of which is an arbitrary byte
- * array).
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setMatchFilter(@Nullable List<byte[]> matchFilter) {
- mMatchFilter = new TlvBufferUtils.TlvConstructor(0, 1).allocateAndPut(
- matchFilter).getArray();
- return this;
- }
-
- /**
- * Specify the type of the publish session: solicited (aka active - publish
- * packets are transmitted over-the-air), or unsolicited (aka passive -
- * no publish packets are transmitted, a match is made against an active
- * subscribe session whose packets are transmitted over-the-air).
- *
- * @param publishType Publish session type:
- * {@link PublishConfig#PUBLISH_TYPE_SOLICITED} or
- * {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED} (the default).
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setPublishType(@PublishTypes int publishType) {
- if (publishType < PUBLISH_TYPE_UNSOLICITED || publishType > PUBLISH_TYPE_SOLICITED) {
- throw new IllegalArgumentException("Invalid publishType - " + publishType);
- }
- mPublishType = publishType;
- return this;
- }
-
- /**
- * Sets the time interval (in seconds) an unsolicited (
- * {@link PublishConfig.Builder#setPublishType(int)}) publish session
- * will be alive - broadcasting a packet. When the TTL is reached
- * an event will be generated for
- * {@link DiscoverySessionCallback#onSessionTerminated()} [unless
- * {@link #setTerminateNotificationEnabled(boolean)} disables the callback].
- * <p>
- * Optional. 0 by default - indicating the session doesn't terminate on its own.
- * Session will be terminated when {@link DiscoverySession#close()} is
- * called.
- *
- * @param ttlSec Lifetime of a publish session in seconds.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setTtlSec(int ttlSec) {
- if (ttlSec < 0) {
- throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
- }
- mTtlSec = ttlSec;
- return this;
- }
-
- /**
- * Configure whether a publish terminate notification
- * {@link DiscoverySessionCallback#onSessionTerminated()} is reported
- * back to the callback.
- *
- * @param enable If true the terminate callback will be called when the
- * publish is terminated. Otherwise it will not be called.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setTerminateNotificationEnabled(boolean enable) {
- mEnableTerminateNotification = enable;
- return this;
- }
-
- /**
- * Configure whether the publish discovery session supports ranging and allows peers to
- * measure distance to it. This API is used in conjunction with
- * {@link SubscribeConfig.Builder#setMinDistanceMm(int)} and
- * {@link SubscribeConfig.Builder#setMaxDistanceMm(int)} to specify a minimum and/or
- * maximum distance at which discovery will be triggered.
- * <p>
- * Optional. Disabled by default - i.e. any peer attempt to measure distance to this device
- * will be refused and discovery will proceed without ranging constraints.
- * <p>
- * The device must support Wi-Fi RTT for this feature to be used. Feature support is checked
- * as described in {@link android.net.wifi.rtt}.
- *
- * @param enable If true, ranging is supported on request of the peer.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setRangingEnabled(boolean enable) {
- mEnableRanging = enable;
- return this;
- }
-
- /**
- * Build {@link PublishConfig} given the current requests made on the
- * builder.
- */
- public PublishConfig build() {
- return new PublishConfig(mServiceName, mServiceSpecificInfo, mMatchFilter, mPublishType,
- mTtlSec, mEnableTerminateNotification, mEnableRanging);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/PublishDiscoverySession.java b/wifi/java/android/net/wifi/aware/PublishDiscoverySession.java
deleted file mode 100644
index 1c99c87..0000000
--- a/wifi/java/android/net/wifi/aware/PublishDiscoverySession.java
+++ /dev/null
@@ -1,68 +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.net.wifi.aware;
-
-import android.annotation.NonNull;
-import android.util.Log;
-
-/**
- * A class representing a Aware publish session. Created when
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
- * android.os.Handler)} is called and a discovery session is created and returned in
- * {@link DiscoverySessionCallback#onPublishStarted(PublishDiscoverySession)}. See
- * baseline functionality of all discovery sessions in {@link DiscoverySession}. This
- * object allows updating an existing/running publish discovery session using
- * {@link #updatePublish(PublishConfig)}.
- */
-public class PublishDiscoverySession extends DiscoverySession {
- private static final String TAG = "PublishDiscoverySession";
-
- /** @hide */
- public PublishDiscoverySession(WifiAwareManager manager, int clientId, int sessionId) {
- super(manager, clientId, sessionId);
- }
-
- /**
- * Re-configure the currently active publish session. The
- * {@link DiscoverySessionCallback} is not replaced - the same listener used
- * at creation is still used. The results of the configuration are returned using
- * {@link DiscoverySessionCallback}:
- * <ul>
- * <li>{@link DiscoverySessionCallback#onSessionConfigUpdated()}: configuration
- * update succeeded.
- * <li>{@link DiscoverySessionCallback#onSessionConfigFailed()}: configuration
- * update failed. The publish discovery session is still running using its previous
- * configuration (i.e. update failure does not terminate the session).
- * </ul>
- *
- * @param publishConfig The new discovery publish session configuration ({@link PublishConfig}).
- */
- public void updatePublish(@NonNull PublishConfig publishConfig) {
- if (mTerminated) {
- Log.w(TAG, "updatePublish: called on terminated session");
- return;
- } else {
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.w(TAG, "updatePublish: called post GC on WifiAwareManager");
- return;
- }
-
- mgr.updatePublish(mClientId, mSessionId, publishConfig);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
deleted file mode 100644
index 76780f4..0000000
--- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java
+++ /dev/null
@@ -1,497 +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.net.wifi.aware;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.wifi.util.HexEncoding;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Defines the configuration of a Aware subscribe session. Built using
- * {@link SubscribeConfig.Builder}. Subscribe is done using
- * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
- * android.os.Handler)} or
- * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
- */
-public final class SubscribeConfig implements Parcelable {
- /** @hide */
- @IntDef({
- SUBSCRIBE_TYPE_PASSIVE, SUBSCRIBE_TYPE_ACTIVE })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SubscribeTypes {
- }
-
- /**
- * Defines a passive subscribe session - a subscribe session where
- * subscribe packets are not transmitted over-the-air and the device listens
- * and matches to transmitted publish packets. Configuration is done using
- * {@link SubscribeConfig.Builder#setSubscribeType(int)}.
- */
- public static final int SUBSCRIBE_TYPE_PASSIVE = 0;
-
- /**
- * Defines an active subscribe session - a subscribe session where
- * subscribe packets are transmitted over-the-air. Configuration is done
- * using {@link SubscribeConfig.Builder#setSubscribeType(int)}.
- */
- public static final int SUBSCRIBE_TYPE_ACTIVE = 1;
-
- /** @hide */
- public final byte[] mServiceName;
-
- /** @hide */
- public final byte[] mServiceSpecificInfo;
-
- /** @hide */
- public final byte[] mMatchFilter;
-
- /** @hide */
- public final int mSubscribeType;
-
- /** @hide */
- public final int mTtlSec;
-
- /** @hide */
- public final boolean mEnableTerminateNotification;
-
- /** @hide */
- public final boolean mMinDistanceMmSet;
-
- /** @hide */
- public final int mMinDistanceMm;
-
- /** @hide */
- public final boolean mMaxDistanceMmSet;
-
- /** @hide */
- public final int mMaxDistanceMm;
-
- /** @hide */
- public SubscribeConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
- int subscribeType, int ttlSec, boolean enableTerminateNotification,
- boolean minDistanceMmSet, int minDistanceMm, boolean maxDistanceMmSet,
- int maxDistanceMm) {
- mServiceName = serviceName;
- mServiceSpecificInfo = serviceSpecificInfo;
- mMatchFilter = matchFilter;
- mSubscribeType = subscribeType;
- mTtlSec = ttlSec;
- mEnableTerminateNotification = enableTerminateNotification;
- mMinDistanceMm = minDistanceMm;
- mMinDistanceMmSet = minDistanceMmSet;
- mMaxDistanceMm = maxDistanceMm;
- mMaxDistanceMmSet = maxDistanceMmSet;
- }
-
- @Override
- public String toString() {
- return "SubscribeConfig [mServiceName='" + (mServiceName == null ? "<null>"
- : String.valueOf(HexEncoding.encode(mServiceName))) + ", mServiceName.length=" + (
- mServiceName == null ? 0 : mServiceName.length) + ", mServiceSpecificInfo='" + (
- (mServiceSpecificInfo == null) ? "<null>" : String.valueOf(
- HexEncoding.encode(mServiceSpecificInfo)))
- + ", mServiceSpecificInfo.length=" + (mServiceSpecificInfo == null ? 0
- : mServiceSpecificInfo.length) + ", mMatchFilter="
- + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString()
- + ", mMatchFilter.length=" + (mMatchFilter == null ? 0 : mMatchFilter.length)
- + ", mSubscribeType=" + mSubscribeType + ", mTtlSec=" + mTtlSec
- + ", mEnableTerminateNotification=" + mEnableTerminateNotification
- + ", mMinDistanceMm=" + mMinDistanceMm
- + ", mMinDistanceMmSet=" + mMinDistanceMmSet
- + ", mMaxDistanceMm=" + mMaxDistanceMm
- + ", mMaxDistanceMmSet=" + mMaxDistanceMmSet + "]";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeByteArray(mServiceName);
- dest.writeByteArray(mServiceSpecificInfo);
- dest.writeByteArray(mMatchFilter);
- dest.writeInt(mSubscribeType);
- dest.writeInt(mTtlSec);
- dest.writeInt(mEnableTerminateNotification ? 1 : 0);
- dest.writeInt(mMinDistanceMm);
- dest.writeInt(mMinDistanceMmSet ? 1 : 0);
- dest.writeInt(mMaxDistanceMm);
- dest.writeInt(mMaxDistanceMmSet ? 1 : 0);
- }
-
- public static final @android.annotation.NonNull Creator<SubscribeConfig> CREATOR = new Creator<SubscribeConfig>() {
- @Override
- public SubscribeConfig[] newArray(int size) {
- return new SubscribeConfig[size];
- }
-
- @Override
- public SubscribeConfig createFromParcel(Parcel in) {
- byte[] serviceName = in.createByteArray();
- byte[] ssi = in.createByteArray();
- byte[] matchFilter = in.createByteArray();
- int subscribeType = in.readInt();
- int ttlSec = in.readInt();
- boolean enableTerminateNotification = in.readInt() != 0;
- int minDistanceMm = in.readInt();
- boolean minDistanceMmSet = in.readInt() != 0;
- int maxDistanceMm = in.readInt();
- boolean maxDistanceMmSet = in.readInt() != 0;
-
- return new SubscribeConfig(serviceName, ssi, matchFilter, subscribeType, ttlSec,
- enableTerminateNotification, minDistanceMmSet, minDistanceMm, maxDistanceMmSet,
- maxDistanceMm);
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof SubscribeConfig)) {
- return false;
- }
-
- SubscribeConfig lhs = (SubscribeConfig) o;
-
- if (!(Arrays.equals(mServiceName, lhs.mServiceName) && Arrays.equals(
- mServiceSpecificInfo, lhs.mServiceSpecificInfo) && Arrays.equals(mMatchFilter,
- lhs.mMatchFilter) && mSubscribeType == lhs.mSubscribeType && mTtlSec == lhs.mTtlSec
- && mEnableTerminateNotification == lhs.mEnableTerminateNotification
- && mMinDistanceMmSet == lhs.mMinDistanceMmSet
- && mMaxDistanceMmSet == lhs.mMaxDistanceMmSet)) {
- return false;
- }
-
- if (mMinDistanceMmSet && mMinDistanceMm != lhs.mMinDistanceMm) {
- return false;
- }
-
- if (mMaxDistanceMmSet && mMaxDistanceMm != lhs.mMaxDistanceMm) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = Objects.hash(Arrays.hashCode(mServiceName),
- Arrays.hashCode(mServiceSpecificInfo), Arrays.hashCode(mMatchFilter),
- mSubscribeType, mTtlSec, mEnableTerminateNotification, mMinDistanceMmSet,
- mMaxDistanceMmSet);
-
- if (mMinDistanceMmSet) {
- result = Objects.hash(result, mMinDistanceMm);
- }
- if (mMaxDistanceMmSet) {
- result = Objects.hash(result, mMaxDistanceMm);
- }
-
- return result;
- }
-
- /**
- * Verifies that the contents of the SubscribeConfig are valid. Otherwise
- * throws an IllegalArgumentException.
- *
- * @hide
- */
- public void assertValid(Characteristics characteristics, boolean rttSupported)
- throws IllegalArgumentException {
- WifiAwareUtils.validateServiceName(mServiceName);
-
- if (!TlvBufferUtils.isValid(mMatchFilter, 0, 1)) {
- throw new IllegalArgumentException(
- "Invalid matchFilter configuration - LV fields do not match up to length");
- }
- if (mSubscribeType < SUBSCRIBE_TYPE_PASSIVE || mSubscribeType > SUBSCRIBE_TYPE_ACTIVE) {
- throw new IllegalArgumentException("Invalid subscribeType - " + mSubscribeType);
- }
- if (mTtlSec < 0) {
- throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
- }
-
- if (characteristics != null) {
- int maxServiceNameLength = characteristics.getMaxServiceNameLength();
- if (maxServiceNameLength != 0 && mServiceName.length > maxServiceNameLength) {
- throw new IllegalArgumentException(
- "Service name longer than supported by device characteristics");
- }
- int maxServiceSpecificInfoLength = characteristics.getMaxServiceSpecificInfoLength();
- if (maxServiceSpecificInfoLength != 0 && mServiceSpecificInfo != null
- && mServiceSpecificInfo.length > maxServiceSpecificInfoLength) {
- throw new IllegalArgumentException(
- "Service specific info longer than supported by device characteristics");
- }
- int maxMatchFilterLength = characteristics.getMaxMatchFilterLength();
- if (maxMatchFilterLength != 0 && mMatchFilter != null
- && mMatchFilter.length > maxMatchFilterLength) {
- throw new IllegalArgumentException(
- "Match filter longer than supported by device characteristics");
- }
- }
-
- if (mMinDistanceMmSet && mMinDistanceMm < 0) {
- throw new IllegalArgumentException("Minimum distance must be non-negative");
- }
- if (mMaxDistanceMmSet && mMaxDistanceMm < 0) {
- throw new IllegalArgumentException("Maximum distance must be non-negative");
- }
- if (mMinDistanceMmSet && mMaxDistanceMmSet && mMaxDistanceMm <= mMinDistanceMm) {
- throw new IllegalArgumentException(
- "Maximum distance must be greater than minimum distance");
- }
-
- if (!rttSupported && (mMinDistanceMmSet || mMaxDistanceMmSet)) {
- throw new IllegalArgumentException("Ranging is not supported");
- }
- }
-
- /**
- * Builder used to build {@link SubscribeConfig} objects.
- */
- public static final class Builder {
- private byte[] mServiceName;
- private byte[] mServiceSpecificInfo;
- private byte[] mMatchFilter;
- private int mSubscribeType = SUBSCRIBE_TYPE_PASSIVE;
- private int mTtlSec = 0;
- private boolean mEnableTerminateNotification = true;
- private boolean mMinDistanceMmSet = false;
- private int mMinDistanceMm;
- private boolean mMaxDistanceMmSet = false;
- private int mMaxDistanceMm;
-
- /**
- * Specify the service name of the subscribe session. The actual on-air
- * value is a 6 byte hashed representation of this string.
- * <p>
- * The Service Name is a UTF-8 encoded string from 1 to 255 bytes in length.
- * The only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric
- * values (A-Z, a-z, 0-9), the hyphen ('-'), and the period ('.'). All valid multi-byte
- * UTF-8 characters are acceptable in a Service Name.
- * <p>
- * Must be called - an empty ServiceName is not valid.
- *
- * @param serviceName The service name for the subscribe session.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setServiceName(@NonNull String serviceName) {
- if (serviceName == null) {
- throw new IllegalArgumentException("Invalid service name - must be non-null");
- }
- mServiceName = serviceName.getBytes(StandardCharsets.UTF_8);
- return this;
- }
-
- /**
- * Specify service specific information for the subscribe session. This is
- * a free-form byte array available to the application to send
- * additional information as part of the discovery operation - i.e. it
- * will not be used to determine whether a publish/subscribe match
- * occurs.
- * <p>
- * Optional. Empty by default.
- *
- * @param serviceSpecificInfo A byte-array for the service-specific
- * information field.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setServiceSpecificInfo(@Nullable byte[] serviceSpecificInfo) {
- mServiceSpecificInfo = serviceSpecificInfo;
- return this;
- }
-
- /**
- * The match filter for a subscribe session. Used to determine whether a service
- * discovery occurred - in addition to relying on the service name.
- * <p>
- * Optional. Empty by default.
- *
- * @param matchFilter A list of match filter entries (each of which is an arbitrary byte
- * array).
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setMatchFilter(@Nullable List<byte[]> matchFilter) {
- mMatchFilter = new TlvBufferUtils.TlvConstructor(0, 1).allocateAndPut(
- matchFilter).getArray();
- return this;
- }
-
- /**
- * Sets the type of the subscribe session: active (subscribe packets are
- * transmitted over-the-air), or passive (no subscribe packets are
- * transmitted, a match is made against a solicited/active publish
- * session whose packets are transmitted over-the-air).
- *
- * @param subscribeType Subscribe session type:
- * {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE} or
- * {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE}.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setSubscribeType(@SubscribeTypes int subscribeType) {
- if (subscribeType < SUBSCRIBE_TYPE_PASSIVE || subscribeType > SUBSCRIBE_TYPE_ACTIVE) {
- throw new IllegalArgumentException("Invalid subscribeType - " + subscribeType);
- }
- mSubscribeType = subscribeType;
- return this;
- }
-
- /**
- * Sets the time interval (in seconds) an active (
- * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe session
- * will be alive - i.e. broadcasting a packet. When the TTL is reached
- * an event will be generated for
- * {@link DiscoverySessionCallback#onSessionTerminated()}.
- * <p>
- * Optional. 0 by default - indicating the session doesn't terminate on its own.
- * Session will be terminated when {@link DiscoverySession#close()} is
- * called.
- *
- * @param ttlSec Lifetime of a subscribe session in seconds.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setTtlSec(int ttlSec) {
- if (ttlSec < 0) {
- throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
- }
- mTtlSec = ttlSec;
- return this;
- }
-
- /**
- * Configure whether a subscribe terminate notification
- * {@link DiscoverySessionCallback#onSessionTerminated()} is reported
- * back to the callback.
- *
- * @param enable If true the terminate callback will be called when the
- * subscribe is terminated. Otherwise it will not be called.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setTerminateNotificationEnabled(boolean enable) {
- mEnableTerminateNotification = enable;
- return this;
- }
-
- /**
- * Configure the minimum distance to a discovered publisher at which to trigger a discovery
- * notification. I.e. discovery will be triggered if we've found a matching publisher
- * (based on the other criteria in this configuration) <b>and</b> the distance to the
- * publisher is larger than the value specified in this API. Can be used in conjunction with
- * {@link #setMaxDistanceMm(int)} to specify a geofence, i.e. discovery with min <=
- * distance <= max.
- * <p>
- * For ranging to be used in discovery it must also be enabled on the publisher using
- * {@link PublishConfig.Builder#setRangingEnabled(boolean)}. However, ranging may
- * not be available or enabled on the publisher or may be temporarily disabled on either
- * subscriber or publisher - in such cases discovery will proceed without ranging.
- * <p>
- * When ranging is enabled and available on both publisher and subscriber and a service
- * is discovered based on geofence constraints the
- * {@link DiscoverySessionCallback#onServiceDiscoveredWithinRange(PeerHandle, byte[], List, int)}
- * is called, otherwise the
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], List)}
- * is called.
- * <p>
- * The device must support Wi-Fi RTT for this feature to be used. Feature support is checked
- * as described in {@link android.net.wifi.rtt}.
- *
- * @param minDistanceMm Minimum distance, in mm, to the publisher above which to trigger
- * discovery.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setMinDistanceMm(int minDistanceMm) {
- mMinDistanceMm = minDistanceMm;
- mMinDistanceMmSet = true;
- return this;
- }
-
- /**
- * Configure the maximum distance to a discovered publisher at which to trigger a discovery
- * notification. I.e. discovery will be triggered if we've found a matching publisher
- * (based on the other criteria in this configuration) <b>and</b> the distance to the
- * publisher is smaller than the value specified in this API. Can be used in conjunction
- * with {@link #setMinDistanceMm(int)} to specify a geofence, i.e. discovery with min <=
- * distance <= max.
- * <p>
- * For ranging to be used in discovery it must also be enabled on the publisher using
- * {@link PublishConfig.Builder#setRangingEnabled(boolean)}. However, ranging may
- * not be available or enabled on the publisher or may be temporarily disabled on either
- * subscriber or publisher - in such cases discovery will proceed without ranging.
- * <p>
- * When ranging is enabled and available on both publisher and subscriber and a service
- * is discovered based on geofence constraints the
- * {@link DiscoverySessionCallback#onServiceDiscoveredWithinRange(PeerHandle, byte[], List, int)}
- * is called, otherwise the
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], List)}
- * is called.
- * <p>
- * The device must support Wi-Fi RTT for this feature to be used. Feature support is checked
- * as described in {@link android.net.wifi.rtt}.
- *
- * @param maxDistanceMm Maximum distance, in mm, to the publisher below which to trigger
- * discovery.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setMaxDistanceMm(int maxDistanceMm) {
- mMaxDistanceMm = maxDistanceMm;
- mMaxDistanceMmSet = true;
- return this;
- }
-
- /**
- * Build {@link SubscribeConfig} given the current requests made on the
- * builder.
- */
- public SubscribeConfig build() {
- return new SubscribeConfig(mServiceName, mServiceSpecificInfo, mMatchFilter,
- mSubscribeType, mTtlSec, mEnableTerminateNotification,
- mMinDistanceMmSet, mMinDistanceMm, mMaxDistanceMmSet, mMaxDistanceMm);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/SubscribeDiscoverySession.java b/wifi/java/android/net/wifi/aware/SubscribeDiscoverySession.java
deleted file mode 100644
index ca88a90..0000000
--- a/wifi/java/android/net/wifi/aware/SubscribeDiscoverySession.java
+++ /dev/null
@@ -1,73 +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.net.wifi.aware;
-
-import android.annotation.NonNull;
-import android.util.Log;
-
-/**
- * A class representing a Aware subscribe session. Created when
- * {@link WifiAwareSession#subscribe(SubscribeConfig,
- * DiscoverySessionCallback, android.os.Handler)}
- * is called and a discovery session is created and returned in
- * {@link DiscoverySessionCallback#onSubscribeStarted(SubscribeDiscoverySession)}.
- * See baseline functionality of all discovery sessions in {@link DiscoverySession}.
- * This object allows updating an existing/running subscribe discovery session using
- * {@link #updateSubscribe(SubscribeConfig)}.
- */
-public class SubscribeDiscoverySession extends DiscoverySession {
- private static final String TAG = "SubscribeDiscSession";
-
- /**
- * {@hide}
- */
- public SubscribeDiscoverySession(WifiAwareManager manager, int clientId,
- int sessionId) {
- super(manager, clientId, sessionId);
- }
-
- /**
- * Re-configure the currently active subscribe session. The
- * {@link DiscoverySessionCallback} is not replaced - the same listener used
- * at creation is still used. The results of the configuration are returned using
- * {@link DiscoverySessionCallback}:
- * <ul>
- * <li>{@link DiscoverySessionCallback#onSessionConfigUpdated()}: configuration
- * update succeeded.
- * <li>{@link DiscoverySessionCallback#onSessionConfigFailed()}: configuration
- * update failed. The subscribe discovery session is still running using its previous
- * configuration (i.e. update failure does not terminate the session).
- * </ul>
- *
- * @param subscribeConfig The new discovery subscribe session configuration
- * ({@link SubscribeConfig}).
- */
- public void updateSubscribe(@NonNull SubscribeConfig subscribeConfig) {
- if (mTerminated) {
- Log.w(TAG, "updateSubscribe: called on terminated session");
- return;
- } else {
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.w(TAG, "updateSubscribe: called post GC on WifiAwareManager");
- return;
- }
-
- mgr.updateSubscribe(mClientId, mSessionId, subscribeConfig);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/TlvBufferUtils.java b/wifi/java/android/net/wifi/aware/TlvBufferUtils.java
deleted file mode 100644
index 2d3cc1e..0000000
--- a/wifi/java/android/net/wifi/aware/TlvBufferUtils.java
+++ /dev/null
@@ -1,714 +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.net.wifi.aware;
-
-import android.annotation.Nullable;
-
-import java.nio.BufferOverflowException;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * Utility class to construct and parse byte arrays using the TLV format -
- * Type/Length/Value format. The utilities accept a configuration of the size of
- * the Type field and the Length field. A Type field size of 0 is allowed -
- * allowing usage for LV (no T) array formats.
- *
- * @hide
- */
-public class TlvBufferUtils {
- private TlvBufferUtils() {
- // no reason to ever create this class
- }
-
- /**
- * Utility class to construct byte arrays using the TLV format -
- * Type/Length/Value.
- * <p>
- * A constructor is created specifying the size of the Type (T) and Length
- * (L) fields. A specification of zero size T field is allowed - resulting
- * in LV type format.
- * <p>
- * The byte array is either provided (using
- * {@link TlvConstructor#wrap(byte[])}) or allocated (using
- * {@link TlvConstructor#allocate(int)}).
- * <p>
- * Values are added to the structure using the {@code TlvConstructor.put*()}
- * methods.
- * <p>
- * The final byte array is obtained using {@link TlvConstructor#getArray()}.
- */
- public static class TlvConstructor {
- private int mTypeSize;
- private int mLengthSize;
- private ByteOrder mByteOrder = ByteOrder.BIG_ENDIAN;
-
- private byte[] mArray;
- private int mArrayLength;
- private int mPosition;
-
- /**
- * Define a TLV constructor with the specified size of the Type (T) and
- * Length (L) fields.
- *
- * @param typeSize Number of bytes used for the Type (T) field. Values
- * of 0, 1, or 2 bytes are allowed. A specification of 0
- * bytes implies that the field being constructed has the LV
- * format rather than the TLV format.
- * @param lengthSize Number of bytes used for the Length (L) field.
- * Values of 1 or 2 bytes are allowed.
- */
- public TlvConstructor(int typeSize, int lengthSize) {
- if (typeSize < 0 || typeSize > 2 || lengthSize <= 0 || lengthSize > 2) {
- throw new IllegalArgumentException(
- "Invalid sizes - typeSize=" + typeSize + ", lengthSize=" + lengthSize);
- }
- mTypeSize = typeSize;
- mLengthSize = lengthSize;
- mPosition = 0;
- }
-
- /**
- * Configure the TLV constructor to use a particular byte order. Should be
- * {@link ByteOrder#BIG_ENDIAN} (the default at construction) or
- * {@link ByteOrder#LITTLE_ENDIAN}.
- *
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor setByteOrder(ByteOrder byteOrder) {
- mByteOrder = byteOrder;
- return this;
- }
-
- /**
- * Set the byte array to be used to construct the TLV.
- *
- * @param array Byte array to be formatted.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor wrap(@Nullable byte[] array) {
- mArray = array;
- mArrayLength = (array == null) ? 0 : array.length;
- mPosition = 0;
- return this;
- }
-
- /**
- * Allocates a new byte array to be used ot construct a TLV.
- *
- * @param capacity The size of the byte array to be allocated.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor allocate(int capacity) {
- mArray = new byte[capacity];
- mArrayLength = capacity;
- mPosition = 0;
- return this;
- }
-
- /**
- * Creates a TLV array (of the previously specified Type and Length sizes) from the input
- * list. Allocates an array matching the contents (and required Type and Length
- * fields), copies the contents, and set the Length fields. The Type field is set to 0.
- *
- * @param list A list of fields to be added to the TLV buffer.
- * @return The constructor of the TLV.
- */
- public TlvConstructor allocateAndPut(@Nullable List<byte[]> list) {
- if (list != null) {
- int size = 0;
- for (byte[] field : list) {
- size += mTypeSize + mLengthSize;
- if (field != null) {
- size += field.length;
- }
- }
- allocate(size);
- for (byte[] field : list) {
- putByteArray(0, field);
- }
- }
- return this;
- }
-
- /**
- * Copies a byte into the TLV with the indicated type. For an LV
- * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
- * TlvConstructor(int, int)} ) the type field is ignored.
- *
- * @param type The value to be placed into the Type field.
- * @param b The byte to be inserted into the structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor putByte(int type, byte b) {
- checkLength(1);
- addHeader(type, 1);
- mArray[mPosition++] = b;
- return this;
- }
-
- /**
- * Copies a raw byte into the TLV buffer - without a type or a length.
- *
- * @param b The byte to be inserted into the structure.
- * @return The constructor to facilitate chaining {@code cts.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor putRawByte(byte b) {
- checkRawLength(1);
- mArray[mPosition++] = b;
- return this;
- }
-
- /**
- * Copies a byte array into the TLV with the indicated type. For an LV
- * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
- * TlvConstructor(int, int)} ) the type field is ignored.
- *
- * @param type The value to be placed into the Type field.
- * @param array The array to be copied into the TLV structure.
- * @param offset Start copying from the array at the specified offset.
- * @param length Copy the specified number (length) of bytes from the
- * array.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor putByteArray(int type, @Nullable byte[] array, int offset,
- int length) {
- checkLength(length);
- addHeader(type, length);
- if (length != 0) {
- System.arraycopy(array, offset, mArray, mPosition, length);
- }
- mPosition += length;
- return this;
- }
-
- /**
- * Copies a byte array into the TLV with the indicated type. For an LV
- * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
- * TlvConstructor(int, int)} ) the type field is ignored.
- *
- * @param type The value to be placed into the Type field.
- * @param array The array to be copied (in full) into the TLV structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor putByteArray(int type, @Nullable byte[] array) {
- return putByteArray(type, array, 0, (array == null) ? 0 : array.length);
- }
-
- /**
- * Copies a byte array into the TLV - without a type or a length.
- *
- * @param array The array to be copied (in full) into the TLV structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor putRawByteArray(@Nullable byte[] array) {
- if (array == null) return this;
-
- checkRawLength(array.length);
- System.arraycopy(array, 0, mArray, mPosition, array.length);
- mPosition += array.length;
- return this;
- }
-
- /**
- * Places a zero length element (i.e. Length field = 0) into the TLV.
- * For an LV formatted structure (i.e. typeLength=0 in
- * {@link TlvConstructor TlvConstructor(int, int)} ) the type field is
- * ignored.
- *
- * @param type The value to be placed into the Type field.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor putZeroLengthElement(int type) {
- checkLength(0);
- addHeader(type, 0);
- return this;
- }
-
- /**
- * Copies short into the TLV with the indicated type. For an LV
- * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
- * TlvConstructor(int, int)} ) the type field is ignored.
- *
- * @param type The value to be placed into the Type field.
- * @param data The short to be inserted into the structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor putShort(int type, short data) {
- checkLength(2);
- addHeader(type, 2);
- pokeShort(mArray, mPosition, data, mByteOrder);
- mPosition += 2;
- return this;
- }
-
- /**
- * Copies integer into the TLV with the indicated type. For an LV
- * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
- * TlvConstructor(int, int)} ) the type field is ignored.
- *
- * @param type The value to be placed into the Type field.
- * @param data The integer to be inserted into the structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor putInt(int type, int data) {
- checkLength(4);
- addHeader(type, 4);
- pokeInt(mArray, mPosition, data, mByteOrder);
- mPosition += 4;
- return this;
- }
-
- /**
- * Copies a String's byte representation into the TLV with the indicated
- * type. For an LV formatted structure (i.e. typeLength=0 in
- * {@link TlvConstructor TlvConstructor(int, int)} ) the type field is
- * ignored.
- *
- * @param type The value to be placed into the Type field.
- * @param data The string whose bytes are to be inserted into the
- * structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public TlvConstructor putString(int type, @Nullable String data) {
- byte[] bytes = null;
- int length = 0;
- if (data != null) {
- bytes = data.getBytes();
- length = bytes.length;
- }
- return putByteArray(type, bytes, 0, length);
- }
-
- /**
- * Returns the constructed TLV formatted byte-array. This array is a copy of the wrapped
- * or allocated array - truncated to just the significant bytes - i.e. those written into
- * the (T)LV.
- *
- * @return The byte array containing the TLV formatted structure.
- */
- public byte[] getArray() {
- return Arrays.copyOf(mArray, getActualLength());
- }
-
- /**
- * Returns the size of the TLV formatted portion of the wrapped or
- * allocated byte array. The array itself is returned with
- * {@link TlvConstructor#getArray()}.
- *
- * @return The size of the TLV formatted portion of the byte array.
- */
- private int getActualLength() {
- return mPosition;
- }
-
- private void checkLength(int dataLength) {
- if (mPosition + mTypeSize + mLengthSize + dataLength > mArrayLength) {
- throw new BufferOverflowException();
- }
- }
-
- private void checkRawLength(int dataLength) {
- if (mPosition + dataLength > mArrayLength) {
- throw new BufferOverflowException();
- }
- }
-
- private void addHeader(int type, int length) {
- if (mTypeSize == 1) {
- mArray[mPosition] = (byte) type;
- } else if (mTypeSize == 2) {
- pokeShort(mArray, mPosition, (short) type, mByteOrder);
- }
- mPosition += mTypeSize;
-
- if (mLengthSize == 1) {
- mArray[mPosition] = (byte) length;
- } else if (mLengthSize == 2) {
- pokeShort(mArray, mPosition, (short) length, mByteOrder);
- }
- mPosition += mLengthSize;
- }
- }
-
- /**
- * Utility class used when iterating over a TLV formatted byte-array. Use
- * {@link TlvIterable} to iterate over array. A {@link TlvElement}
- * represents each entry in a TLV formatted byte-array.
- */
- public static class TlvElement {
- /**
- * The Type (T) field of the current TLV element. Note that for LV
- * formatted byte-arrays (i.e. TLV whose Type/T size is 0) the value of
- * this field is undefined.
- */
- public int type;
-
- /**
- * The Length (L) field of the current TLV element.
- */
- public int length;
-
- /**
- * Control of the endianess of the TLV element - true for big-endian, false for little-
- * endian.
- */
- public ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
-
- /**
- * The Value (V) field - a raw byte array representing the current TLV
- * element where the entry starts at {@link TlvElement#offset}.
- */
- private byte[] mRefArray;
-
- /**
- * The offset to be used into {@link TlvElement#mRefArray} to access the
- * raw data representing the current TLV element.
- */
- public int offset;
-
- private TlvElement(int type, int length, @Nullable byte[] refArray, int offset) {
- this.type = type;
- this.length = length;
- mRefArray = refArray;
- this.offset = offset;
-
- if (offset + length > refArray.length) {
- throw new BufferOverflowException();
- }
- }
-
- /**
- * Return the raw byte array of the Value (V) field.
- *
- * @return The Value (V) field as a byte array.
- */
- public byte[] getRawData() {
- return Arrays.copyOfRange(mRefArray, offset, offset + length);
- }
-
- /**
- * Utility function to return a byte representation of a TLV element of
- * length 1. Note: an attempt to call this function on a TLV item whose
- * {@link TlvElement#length} is != 1 will result in an exception.
- *
- * @return byte representation of current TLV element.
- */
- public byte getByte() {
- if (length != 1) {
- throw new IllegalArgumentException(
- "Accesing a byte from a TLV element of length " + length);
- }
- return mRefArray[offset];
- }
-
- /**
- * Utility function to return a short representation of a TLV element of
- * length 2. Note: an attempt to call this function on a TLV item whose
- * {@link TlvElement#length} is != 2 will result in an exception.
- *
- * @return short representation of current TLV element.
- */
- public short getShort() {
- if (length != 2) {
- throw new IllegalArgumentException(
- "Accesing a short from a TLV element of length " + length);
- }
- return peekShort(mRefArray, offset, byteOrder);
- }
-
- /**
- * Utility function to return an integer representation of a TLV element
- * of length 4. Note: an attempt to call this function on a TLV item
- * whose {@link TlvElement#length} is != 4 will result in an exception.
- *
- * @return integer representation of current TLV element.
- */
- public int getInt() {
- if (length != 4) {
- throw new IllegalArgumentException(
- "Accesing an int from a TLV element of length " + length);
- }
- return peekInt(mRefArray, offset, byteOrder);
- }
-
- /**
- * Utility function to return a String representation of a TLV element.
- *
- * @return String repersentation of the current TLV element.
- */
- public String getString() {
- return new String(mRefArray, offset, length);
- }
- }
-
- /**
- * Utility class to iterate over a TLV formatted byte-array.
- */
- public static class TlvIterable implements Iterable<TlvElement> {
- private int mTypeSize;
- private int mLengthSize;
- private ByteOrder mByteOrder = ByteOrder.BIG_ENDIAN;
- private byte[] mArray;
- private int mArrayLength;
-
- /**
- * Constructs a TlvIterable object - specifying the format of the TLV
- * (the sizes of the Type and Length fields), and the byte array whose
- * data is to be parsed.
- *
- * @param typeSize Number of bytes used for the Type (T) field. Valid
- * values are 0 (i.e. indicating the format is LV rather than
- * TLV), 1, and 2 bytes.
- * @param lengthSize Number of bytes used for the Length (L) field.
- * Values values are 1 or 2 bytes.
- * @param array The TLV formatted byte-array to parse.
- */
- public TlvIterable(int typeSize, int lengthSize, @Nullable byte[] array) {
- if (typeSize < 0 || typeSize > 2 || lengthSize <= 0 || lengthSize > 2) {
- throw new IllegalArgumentException(
- "Invalid sizes - typeSize=" + typeSize + ", lengthSize=" + lengthSize);
- }
- mTypeSize = typeSize;
- mLengthSize = lengthSize;
- mArray = array;
- mArrayLength = (array == null) ? 0 : array.length;
- }
-
- /**
- * Configure the TLV iterator to use little-endian byte ordering.
- */
- public void setByteOrder(ByteOrder byteOrder) {
- mByteOrder = byteOrder;
- }
-
- /**
- * Prints out a parsed representation of the TLV-formatted byte array.
- * Whenever possible bytes, shorts, and integer are printed out (for
- * fields whose length is 1, 2, or 4 respectively).
- */
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
-
- builder.append("[");
- boolean first = true;
- for (TlvElement tlv : this) {
- if (!first) {
- builder.append(",");
- }
- first = false;
- builder.append(" (");
- if (mTypeSize != 0) {
- builder.append("T=" + tlv.type + ",");
- }
- builder.append("L=" + tlv.length + ") ");
- if (tlv.length == 0) {
- builder.append("<null>");
- } else if (tlv.length == 1) {
- builder.append(tlv.getByte());
- } else if (tlv.length == 2) {
- builder.append(tlv.getShort());
- } else if (tlv.length == 4) {
- builder.append(tlv.getInt());
- } else {
- builder.append("<bytes>");
- }
- if (tlv.length != 0) {
- builder.append(" (S='" + tlv.getString() + "')");
- }
- }
- builder.append("]");
-
- return builder.toString();
- }
-
- /**
- * Returns a List with the raw contents (no types) of the iterator.
- */
- public List<byte[]> toList() {
- List<byte[]> list = new ArrayList<>();
- for (TlvElement tlv : this) {
- list.add(Arrays.copyOfRange(tlv.mRefArray, tlv.offset, tlv.offset + tlv.length));
- }
-
- return list;
- }
-
- /**
- * Returns an iterator to step through a TLV formatted byte-array. The
- * individual elements returned by the iterator are {@link TlvElement}.
- */
- @Override
- public Iterator<TlvElement> iterator() {
- return new Iterator<TlvElement>() {
- private int mOffset = 0;
-
- @Override
- public boolean hasNext() {
- return mOffset < mArrayLength;
- }
-
- @Override
- public TlvElement next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
-
- int type = 0;
- if (mTypeSize == 1) {
- type = mArray[mOffset];
- } else if (mTypeSize == 2) {
- type = peekShort(mArray, mOffset, mByteOrder);
- }
- mOffset += mTypeSize;
-
- int length = 0;
- if (mLengthSize == 1) {
- length = mArray[mOffset];
- } else if (mLengthSize == 2) {
- length = peekShort(mArray, mOffset, mByteOrder);
- }
- mOffset += mLengthSize;
-
- TlvElement tlv = new TlvElement(type, length, mArray, mOffset);
- tlv.byteOrder = mByteOrder;
- mOffset += length;
- return tlv;
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
- }
-
- /**
- * Validates that a (T)LV array is constructed correctly. I.e. that its specified Length
- * fields correctly fill the specified length (and do not overshoot). Uses big-endian
- * byte ordering.
- *
- * @param array The (T)LV array to verify.
- * @param typeSize The size (in bytes) of the type field. Valid values are 0, 1, or 2.
- * @param lengthSize The size (in bytes) of the length field. Valid values are 1 or 2.
- * @return A boolean indicating whether the array is valid (true) or invalid (false).
- */
- public static boolean isValid(@Nullable byte[] array, int typeSize, int lengthSize) {
- return isValidEndian(array, typeSize, lengthSize, ByteOrder.BIG_ENDIAN);
- }
-
- /**
- * Validates that a (T)LV array is constructed correctly. I.e. that its specified Length
- * fields correctly fill the specified length (and do not overshoot).
- *
- * @param array The (T)LV array to verify.
- * @param typeSize The size (in bytes) of the type field. Valid values are 0, 1, or 2.
- * @param lengthSize The size (in bytes) of the length field. Valid values are 1 or 2.
- * @param byteOrder The endianness of the byte array: {@link ByteOrder#BIG_ENDIAN} or
- * {@link ByteOrder#LITTLE_ENDIAN}.
- * @return A boolean indicating whether the array is valid (true) or invalid (false).
- */
- public static boolean isValidEndian(@Nullable byte[] array, int typeSize, int lengthSize,
- ByteOrder byteOrder) {
- if (typeSize < 0 || typeSize > 2) {
- throw new IllegalArgumentException(
- "Invalid arguments - typeSize must be 0, 1, or 2: typeSize=" + typeSize);
- }
- if (lengthSize <= 0 || lengthSize > 2) {
- throw new IllegalArgumentException(
- "Invalid arguments - lengthSize must be 1 or 2: lengthSize=" + lengthSize);
- }
- if (array == null) {
- return true;
- }
-
- int nextTlvIndex = 0;
- while (nextTlvIndex + typeSize + lengthSize <= array.length) {
- nextTlvIndex += typeSize;
- if (lengthSize == 1) {
- nextTlvIndex += lengthSize + array[nextTlvIndex];
- } else {
- nextTlvIndex += lengthSize + peekShort(array, nextTlvIndex, byteOrder);
- }
- }
-
- return nextTlvIndex == array.length;
- }
-
- private static void pokeShort(byte[] dst, int offset, short value, ByteOrder order) {
- if (order == ByteOrder.BIG_ENDIAN) {
- dst[offset++] = (byte) ((value >> 8) & 0xff);
- dst[offset ] = (byte) ((value >> 0) & 0xff);
- } else {
- dst[offset++] = (byte) ((value >> 0) & 0xff);
- dst[offset ] = (byte) ((value >> 8) & 0xff);
- }
- }
-
- private static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) {
- if (order == ByteOrder.BIG_ENDIAN) {
- dst[offset++] = (byte) ((value >> 24) & 0xff);
- dst[offset++] = (byte) ((value >> 16) & 0xff);
- dst[offset++] = (byte) ((value >> 8) & 0xff);
- dst[offset ] = (byte) ((value >> 0) & 0xff);
- } else {
- dst[offset++] = (byte) ((value >> 0) & 0xff);
- dst[offset++] = (byte) ((value >> 8) & 0xff);
- dst[offset++] = (byte) ((value >> 16) & 0xff);
- dst[offset ] = (byte) ((value >> 24) & 0xff);
- }
- }
-
- private static short peekShort(byte[] src, int offset, ByteOrder order) {
- if (order == ByteOrder.BIG_ENDIAN) {
- return (short) ((src[offset] << 8) | (src[offset + 1] & 0xff));
- } else {
- return (short) ((src[offset + 1] << 8) | (src[offset] & 0xff));
- }
- }
-
- private static int peekInt(byte[] src, int offset, ByteOrder order) {
- if (order == ByteOrder.BIG_ENDIAN) {
- return ((src[offset++] & 0xff) << 24)
- | ((src[offset++] & 0xff) << 16)
- | ((src[offset++] & 0xff) << 8)
- | ((src[offset ] & 0xff) << 0);
- } else {
- return ((src[offset++] & 0xff) << 0)
- | ((src[offset++] & 0xff) << 8)
- | ((src[offset++] & 0xff) << 16)
- | ((src[offset ] & 0xff) << 24);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java
deleted file mode 100644
index 9ae3bd0..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.net.NetworkSpecifier;
-import android.net.wifi.util.HexEncoding;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.StringJoiner;
-
-/**
- * A network specifier object used to represent the capabilities of an network agent. A collection
- * of multiple WifiAwareNetworkSpecifier objects whose matching critiera (satisfiedBy) is an OR:
- * a match on any of the network specifiers in the collection is a match.
- *
- * This class is not intended for use in network requests.
- *
- * @hide
- */
-public class WifiAwareAgentNetworkSpecifier extends NetworkSpecifier implements Parcelable {
- private static final String TAG = "WifiAwareAgentNs";
-
- private static final boolean VDBG = false; // STOPSHIP if true
-
- private Set<ByteArrayWrapper> mNetworkSpecifiers = new HashSet<>();
- private MessageDigest mDigester;
-
- public WifiAwareAgentNetworkSpecifier() {
- initialize();
- }
-
- public WifiAwareAgentNetworkSpecifier(WifiAwareNetworkSpecifier ns) {
- initialize();
- mNetworkSpecifiers.add(convert(ns));
- }
-
- public WifiAwareAgentNetworkSpecifier(WifiAwareNetworkSpecifier[] nss) {
- initialize();
- for (WifiAwareNetworkSpecifier ns : nss) {
- mNetworkSpecifiers.add(convert(ns));
- }
- }
-
- public boolean isEmpty() {
- return mNetworkSpecifiers.isEmpty();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeArray(mNetworkSpecifiers.toArray());
- }
-
- public static final @android.annotation.NonNull Creator<WifiAwareAgentNetworkSpecifier> CREATOR =
- new Creator<WifiAwareAgentNetworkSpecifier>() {
- @Override
- public WifiAwareAgentNetworkSpecifier createFromParcel(Parcel in) {
- WifiAwareAgentNetworkSpecifier agentNs = new WifiAwareAgentNetworkSpecifier();
- Object[] objs = in.readArray(null);
- for (Object obj : objs) {
- agentNs.mNetworkSpecifiers.add((ByteArrayWrapper) obj);
- }
- return agentNs;
- }
-
- @Override
- public WifiAwareAgentNetworkSpecifier[] newArray(int size) {
- return new WifiAwareAgentNetworkSpecifier[size];
- }
- };
-
- @Override
- public int hashCode() {
- return mNetworkSpecifiers.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof WifiAwareAgentNetworkSpecifier)) {
- return false;
- }
- return mNetworkSpecifiers.equals(((WifiAwareAgentNetworkSpecifier) obj).mNetworkSpecifiers);
- }
-
- @Override
- public String toString() {
- StringJoiner sj = new StringJoiner(",");
- for (ByteArrayWrapper baw: mNetworkSpecifiers) {
- sj.add(baw.toString());
- }
- return sj.toString();
- }
-
- @Override
- public boolean canBeSatisfiedBy(NetworkSpecifier other) {
- if (!(other instanceof WifiAwareAgentNetworkSpecifier)) {
- return false;
- }
- WifiAwareAgentNetworkSpecifier otherNs = (WifiAwareAgentNetworkSpecifier) other;
-
- // called as old.satifiedBy(new): satisfied if old contained in new
- for (ByteArrayWrapper baw: mNetworkSpecifiers) {
- if (!otherNs.mNetworkSpecifiers.contains(baw)) {
- return false;
- }
- }
-
- return true;
- }
-
- public boolean satisfiesAwareNetworkSpecifier(WifiAwareNetworkSpecifier ns) {
- if (VDBG) Log.v(TAG, "satisfiesAwareNetworkSpecifier: ns=" + ns);
- ByteArrayWrapper nsBytes = convert(ns);
- return mNetworkSpecifiers.contains(nsBytes);
- }
-
- @Override
- public NetworkSpecifier redact() {
- return null;
- }
-
- private void initialize() {
- try {
- mDigester = MessageDigest.getInstance("SHA-256");
- } catch (NoSuchAlgorithmException e) {
- Log.e(TAG, "Can not instantiate a SHA-256 digester!? Will match nothing.");
- return;
- }
- }
-
- private ByteArrayWrapper convert(WifiAwareNetworkSpecifier ns) {
- if (mDigester == null) {
- return null;
- }
-
- Parcel parcel = Parcel.obtain();
- ns.writeToParcel(parcel, 0);
- byte[] bytes = parcel.marshall();
-
- mDigester.reset();
- mDigester.update(bytes);
- return new ByteArrayWrapper(mDigester.digest());
- }
-
- private static class ByteArrayWrapper implements Parcelable {
- private byte[] mData;
-
- ByteArrayWrapper(byte[] data) {
- mData = data;
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(mData);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof ByteArrayWrapper)) {
- return false;
- }
- return Arrays.equals(((ByteArrayWrapper) obj).mData, mData);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeByteArray(mData);
- }
-
- public static final @android.annotation.NonNull Creator<ByteArrayWrapper> CREATOR =
- new Creator<ByteArrayWrapper>() {
- @Override
- public ByteArrayWrapper createFromParcel(Parcel in) {
- return new ByteArrayWrapper(in.createByteArray());
- }
-
- @Override
- public ByteArrayWrapper[] newArray(int size) {
- return new ByteArrayWrapper[size];
- }
- };
-
- @Override
- public String toString() {
- return new String(HexEncoding.encode(mData));
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
deleted file mode 100644
index c2ae17c..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ /dev/null
@@ -1,824 +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.net.wifi.aware;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemService;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.net.wifi.util.HexEncoding;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
-import java.nio.BufferOverflowException;
-import java.util.List;
-
-/**
- * This class provides the primary API for managing Wi-Fi Aware operations:
- * discovery and peer-to-peer data connections.
- * <p>
- * The class provides access to:
- * <ul>
- * <li>Initialize a Aware cluster (peer-to-peer synchronization). Refer to
- * {@link #attach(AttachCallback, Handler)}.
- * <li>Create discovery sessions (publish or subscribe sessions). Refer to
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback, Handler)} and
- * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback, Handler)}.
- * <li>Create a Aware network specifier to be used with
- * {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)}
- * to set-up a Aware connection with a peer. Refer to {@link WifiAwareNetworkSpecifier.Builder}.
- * </ul>
- * <p>
- * Aware may not be usable when Wi-Fi is disabled (and other conditions). To validate that
- * the functionality is available use the {@link #isAvailable()} function. To track
- * changes in Aware usability register for the {@link #ACTION_WIFI_AWARE_STATE_CHANGED}
- * broadcast. Note that this broadcast is not sticky - you should register for it and then
- * check the above API to avoid a race condition.
- * <p>
- * An application must use {@link #attach(AttachCallback, Handler)} to initialize a
- * Aware cluster - before making any other Aware operation. Aware cluster membership is a
- * device-wide operation - the API guarantees that the device is in a cluster or joins a
- * Aware cluster (or starts one if none can be found). Information about attach success (or
- * failure) are returned in callbacks of {@link AttachCallback}. Proceed with Aware
- * discovery or connection setup only after receiving confirmation that Aware attach
- * succeeded - {@link AttachCallback#onAttached(WifiAwareSession)}. When an
- * application is finished using Aware it <b>must</b> use the
- * {@link WifiAwareSession#close()} API to indicate to the Aware service that the device
- * may detach from the Aware cluster. The device will actually disable Aware once the last
- * application detaches.
- * <p>
- * Once a Aware attach is confirmed use the
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback, Handler)}
- * or
- * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
- * Handler)} to create publish or subscribe Aware discovery sessions. Events are called on the
- * provided callback object {@link DiscoverySessionCallback}. Specifically, the
- * {@link DiscoverySessionCallback#onPublishStarted(PublishDiscoverySession)}
- * and
- * {@link DiscoverySessionCallback#onSubscribeStarted(
- *SubscribeDiscoverySession)}
- * return {@link PublishDiscoverySession} and
- * {@link SubscribeDiscoverySession}
- * objects respectively on which additional session operations can be performed, e.g. updating
- * the session {@link PublishDiscoverySession#updatePublish(PublishConfig)} and
- * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. Sessions can
- * also be used to send messages using the
- * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])} APIs. When an
- * application is finished with a discovery session it <b>must</b> terminate it using the
- * {@link DiscoverySession#close()} API.
- * <p>
- * Creating connections between Aware devices is managed by the standard
- * {@link ConnectivityManager#requestNetwork(NetworkRequest,
- * ConnectivityManager.NetworkCallback)}.
- * The {@link NetworkRequest} object should be constructed with:
- * <ul>
- * <li>{@link NetworkRequest.Builder#addTransportType(int)} of
- * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
- * <li>{@link NetworkRequest.Builder#setNetworkSpecifier(String)} using
- * {@link WifiAwareNetworkSpecifier.Builder}.
- * </ul>
- */
-@SystemService(Context.WIFI_AWARE_SERVICE)
-public class WifiAwareManager {
- private static final String TAG = "WifiAwareManager";
- private static final boolean DBG = false;
- private static final boolean VDBG = false; // STOPSHIP if true
-
- /**
- * Broadcast intent action to indicate that the state of Wi-Fi Aware availability has changed.
- * Use the {@link #isAvailable()} to query the current status.
- * This broadcast is <b>not</b> sticky, use the {@link #isAvailable()} API after registering
- * the broadcast to check the current state of Wi-Fi Aware.
- * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
- * components will be launched.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_WIFI_AWARE_STATE_CHANGED =
- "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED";
-
- /** @hide */
- @IntDef({
- WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, WIFI_AWARE_DATA_PATH_ROLE_RESPONDER})
- @Retention(RetentionPolicy.SOURCE)
- public @interface DataPathRole {
- }
-
- /**
- * Connection creation role is that of INITIATOR. Used to create a network specifier string
- * when requesting a Aware network.
- *
- * @see WifiAwareSession#createNetworkSpecifierOpen(int, byte[])
- * @see WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)
- */
- public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0;
-
- /**
- * Connection creation role is that of RESPONDER. Used to create a network specifier string
- * when requesting a Aware network.
- *
- * @see WifiAwareSession#createNetworkSpecifierOpen(int, byte[])
- * @see WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)
- */
- public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1;
-
- private final Context mContext;
- private final IWifiAwareManager mService;
-
- private final Object mLock = new Object(); // lock access to the following vars
-
- /** @hide */
- public WifiAwareManager(@NonNull Context context, @NonNull IWifiAwareManager service) {
- mContext = context;
- mService = service;
- }
-
- /**
- * Returns the current status of Aware API: whether or not Aware is available. To track
- * changes in the state of Aware API register for the
- * {@link #ACTION_WIFI_AWARE_STATE_CHANGED} broadcast.
- *
- * @return A boolean indicating whether the app can use the Aware API at this time (true) or
- * not (false).
- */
- public boolean isAvailable() {
- try {
- return mService.isUsageEnabled();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns the characteristics of the Wi-Fi Aware interface: a set of parameters which specify
- * limitations on configurations, e.g. the maximum service name length.
- *
- * @return An object specifying configuration limitations of Aware.
- */
- public Characteristics getCharacteristics() {
- try {
- return mService.getCharacteristics();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Attach to the Wi-Fi Aware service - enabling the application to create discovery sessions or
- * create connections to peers. The device will attach to an existing cluster if it can find
- * one or create a new cluster (if it is the first to enable Aware in its vicinity). Results
- * (e.g. successful attach to a cluster) are provided to the {@code attachCallback} object.
- * An application <b>must</b> call {@link WifiAwareSession#close()} when done with the
- * Wi-Fi Aware object.
- * <p>
- * Note: a Aware cluster is a shared resource - if the device is already attached to a cluster
- * then this function will simply indicate success immediately using the same {@code
- * attachCallback}.
- *
- * @param attachCallback A callback for attach events, extended from
- * {@link AttachCallback}.
- * @param handler The Handler on whose thread to execute the callbacks of the {@code
- * attachCallback} object. If a null is provided then the application's main thread will be
- * used.
- */
- public void attach(@NonNull AttachCallback attachCallback, @Nullable Handler handler) {
- attach(handler, null, attachCallback, null);
- }
-
- /**
- * Attach to the Wi-Fi Aware service - enabling the application to create discovery sessions or
- * create connections to peers. The device will attach to an existing cluster if it can find
- * one or create a new cluster (if it is the first to enable Aware in its vicinity). Results
- * (e.g. successful attach to a cluster) are provided to the {@code attachCallback} object.
- * An application <b>must</b> call {@link WifiAwareSession#close()} when done with the
- * Wi-Fi Aware object.
- * <p>
- * Note: a Aware cluster is a shared resource - if the device is already attached to a cluster
- * then this function will simply indicate success immediately using the same {@code
- * attachCallback}.
- * <p>
- * This version of the API attaches a listener to receive the MAC address of the Aware interface
- * on startup and whenever it is updated (it is randomized at regular intervals for privacy).
- * The application must have the {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
- * permission to execute this attach request. Otherwise, use the
- * {@link #attach(AttachCallback, Handler)} version. Note that aside from permission
- * requirements this listener will wake up the host at regular intervals causing higher power
- * consumption, do not use it unless the information is necessary (e.g. for OOB discovery).
- *
- * @param attachCallback A callback for attach events, extended from
- * {@link AttachCallback}.
- * @param identityChangedListener A listener for changed identity, extended from
- * {@link IdentityChangedListener}.
- * @param handler The Handler on whose thread to execute the callbacks of the {@code
- * attachCallback} and {@code identityChangedListener} objects. If a null is provided then the
- * application's main thread will be used.
- */
- public void attach(@NonNull AttachCallback attachCallback,
- @NonNull IdentityChangedListener identityChangedListener,
- @Nullable Handler handler) {
- attach(handler, null, attachCallback, identityChangedListener);
- }
-
- /** @hide */
- public void attach(Handler handler, ConfigRequest configRequest,
- AttachCallback attachCallback,
- IdentityChangedListener identityChangedListener) {
- if (VDBG) {
- Log.v(TAG, "attach(): handler=" + handler + ", callback=" + attachCallback
- + ", configRequest=" + configRequest + ", identityChangedListener="
- + identityChangedListener);
- }
-
- if (attachCallback == null) {
- throw new IllegalArgumentException("Null callback provided");
- }
-
- synchronized (mLock) {
- Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper();
-
- try {
- Binder binder = new Binder();
- mService.connect(binder, mContext.getOpPackageName(), mContext.getAttributionTag(),
- new WifiAwareEventCallbackProxy(this, looper, binder, attachCallback,
- identityChangedListener), configRequest,
- identityChangedListener != null);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
- /** @hide */
- public void disconnect(int clientId, Binder binder) {
- if (VDBG) Log.v(TAG, "disconnect()");
-
- try {
- mService.disconnect(clientId, binder);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- public void publish(int clientId, Looper looper, PublishConfig publishConfig,
- DiscoverySessionCallback callback) {
- if (VDBG) Log.v(TAG, "publish(): clientId=" + clientId + ", config=" + publishConfig);
-
- if (callback == null) {
- throw new IllegalArgumentException("Null callback provided");
- }
-
- try {
- mService.publish(mContext.getOpPackageName(), mContext.getAttributionTag(), clientId,
- publishConfig,
- new WifiAwareDiscoverySessionCallbackProxy(this, looper, true, callback,
- clientId));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- public void updatePublish(int clientId, int sessionId, PublishConfig publishConfig) {
- if (VDBG) {
- Log.v(TAG, "updatePublish(): clientId=" + clientId + ",sessionId=" + sessionId
- + ", config=" + publishConfig);
- }
-
- try {
- mService.updatePublish(clientId, sessionId, publishConfig);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- public void subscribe(int clientId, Looper looper, SubscribeConfig subscribeConfig,
- DiscoverySessionCallback callback) {
- if (VDBG) {
- if (VDBG) {
- Log.v(TAG,
- "subscribe(): clientId=" + clientId + ", config=" + subscribeConfig);
- }
- }
-
- if (callback == null) {
- throw new IllegalArgumentException("Null callback provided");
- }
-
- try {
- mService.subscribe(mContext.getOpPackageName(), mContext.getAttributionTag(), clientId,
- subscribeConfig,
- new WifiAwareDiscoverySessionCallbackProxy(this, looper, false, callback,
- clientId));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- public void updateSubscribe(int clientId, int sessionId, SubscribeConfig subscribeConfig) {
- if (VDBG) {
- Log.v(TAG, "updateSubscribe(): clientId=" + clientId + ",sessionId=" + sessionId
- + ", config=" + subscribeConfig);
- }
-
- try {
- mService.updateSubscribe(clientId, sessionId, subscribeConfig);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- public void terminateSession(int clientId, int sessionId) {
- if (VDBG) {
- Log.d(TAG,
- "terminateSession(): clientId=" + clientId + ", sessionId=" + sessionId);
- }
-
- try {
- mService.terminateSession(clientId, sessionId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- public void sendMessage(int clientId, int sessionId, PeerHandle peerHandle, byte[] message,
- int messageId, int retryCount) {
- if (peerHandle == null) {
- throw new IllegalArgumentException(
- "sendMessage: invalid peerHandle - must be non-null");
- }
-
- if (VDBG) {
- Log.v(TAG, "sendMessage(): clientId=" + clientId + ", sessionId=" + sessionId
- + ", peerHandle=" + peerHandle.peerId + ", messageId="
- + messageId + ", retryCount=" + retryCount);
- }
-
- try {
- mService.sendMessage(clientId, sessionId, peerHandle.peerId, message, messageId,
- retryCount);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public void requestMacAddresses(int uid, List<Integer> peerIds,
- IWifiAwareMacAddressProvider callback) {
- try {
- mService.requestMacAddresses(uid, peerIds, callback);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- public NetworkSpecifier createNetworkSpecifier(int clientId, int role, int sessionId,
- @NonNull PeerHandle peerHandle, @Nullable byte[] pmk, @Nullable String passphrase) {
- if (VDBG) {
- Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId
- + ", peerHandle=" + ((peerHandle == null) ? peerHandle : peerHandle.peerId)
- + ", pmk=" + ((pmk == null) ? "null" : "non-null")
- + ", passphrase=" + ((passphrase == null) ? "null" : "non-null"));
- }
-
- if (!WifiAwareUtils.isLegacyVersion(mContext, Build.VERSION_CODES.Q)) {
- throw new UnsupportedOperationException(
- "API deprecated - use WifiAwareNetworkSpecifier.Builder");
- }
-
- if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
- && role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
- throw new IllegalArgumentException(
- "createNetworkSpecifier: Invalid 'role' argument when creating a network "
- + "specifier");
- }
- if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR || !WifiAwareUtils.isLegacyVersion(mContext,
- Build.VERSION_CODES.P)) {
- if (peerHandle == null) {
- throw new IllegalArgumentException(
- "createNetworkSpecifier: Invalid peer handle - cannot be null");
- }
- }
-
- return new WifiAwareNetworkSpecifier(
- (peerHandle == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER
- : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB,
- role,
- clientId,
- sessionId,
- peerHandle != null ? peerHandle.peerId : 0, // 0 is an invalid peer ID
- null, // peerMac (not used in this method)
- pmk,
- passphrase,
- 0, // no port info for deprecated IB APIs
- -1); // no transport info for deprecated IB APIs
- }
-
- /** @hide */
- public NetworkSpecifier createNetworkSpecifier(int clientId, @DataPathRole int role,
- @NonNull byte[] peer, @Nullable byte[] pmk, @Nullable String passphrase) {
- if (VDBG) {
- Log.v(TAG, "createNetworkSpecifier: role=" + role
- + ", pmk=" + ((pmk == null) ? "null" : "non-null")
- + ", passphrase=" + ((passphrase == null) ? "null" : "non-null"));
- }
-
- if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
- && role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
- throw new IllegalArgumentException(
- "createNetworkSpecifier: Invalid 'role' argument when creating a network "
- + "specifier");
- }
- if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR || !WifiAwareUtils.isLegacyVersion(mContext,
- Build.VERSION_CODES.P)) {
- if (peer == null) {
- throw new IllegalArgumentException(
- "createNetworkSpecifier: Invalid peer MAC - cannot be null");
- }
- }
- if (peer != null && peer.length != 6) {
- throw new IllegalArgumentException("createNetworkSpecifier: Invalid peer MAC address");
- }
-
- return new WifiAwareNetworkSpecifier(
- (peer == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER
- : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB,
- role,
- clientId,
- 0, // 0 is an invalid session ID
- 0, // 0 is an invalid peer ID
- peer,
- pmk,
- passphrase,
- 0, // no port info for OOB APIs
- -1); // no transport protocol info for OOB APIs
- }
-
- private static class WifiAwareEventCallbackProxy extends IWifiAwareEventCallback.Stub {
- private static final int CALLBACK_CONNECT_SUCCESS = 0;
- private static final int CALLBACK_CONNECT_FAIL = 1;
- private static final int CALLBACK_IDENTITY_CHANGED = 2;
-
- private final Handler mHandler;
- private final WeakReference<WifiAwareManager> mAwareManager;
- private final Binder mBinder;
- private final Looper mLooper;
-
- /**
- * Constructs a {@link AttachCallback} using the specified looper.
- * All callbacks will delivered on the thread of the specified looper.
- *
- * @param looper The looper on which to execute the callbacks.
- */
- WifiAwareEventCallbackProxy(WifiAwareManager mgr, Looper looper, Binder binder,
- final AttachCallback attachCallback,
- final IdentityChangedListener identityChangedListener) {
- mAwareManager = new WeakReference<>(mgr);
- mLooper = looper;
- mBinder = binder;
-
- if (VDBG) Log.v(TAG, "WifiAwareEventCallbackProxy ctor: looper=" + looper);
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- if (DBG) {
- Log.d(TAG, "WifiAwareEventCallbackProxy: What=" + msg.what + ", msg="
- + msg);
- }
-
- WifiAwareManager mgr = mAwareManager.get();
- if (mgr == null) {
- Log.w(TAG, "WifiAwareEventCallbackProxy: handleMessage post GC");
- return;
- }
-
- switch (msg.what) {
- case CALLBACK_CONNECT_SUCCESS:
- attachCallback.onAttached(
- new WifiAwareSession(mgr, mBinder, msg.arg1));
- break;
- case CALLBACK_CONNECT_FAIL:
- mAwareManager.clear();
- attachCallback.onAttachFailed();
- break;
- case CALLBACK_IDENTITY_CHANGED:
- if (identityChangedListener == null) {
- Log.e(TAG, "CALLBACK_IDENTITY_CHANGED: null listener.");
- } else {
- identityChangedListener.onIdentityChanged((byte[]) msg.obj);
- }
- break;
- }
- }
- };
- }
-
- @Override
- public void onConnectSuccess(int clientId) {
- if (VDBG) Log.v(TAG, "onConnectSuccess");
-
- Message msg = mHandler.obtainMessage(CALLBACK_CONNECT_SUCCESS);
- msg.arg1 = clientId;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onConnectFail(int reason) {
- if (VDBG) Log.v(TAG, "onConnectFail: reason=" + reason);
-
- Message msg = mHandler.obtainMessage(CALLBACK_CONNECT_FAIL);
- msg.arg1 = reason;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onIdentityChanged(byte[] mac) {
- if (VDBG) Log.v(TAG, "onIdentityChanged: mac=" + new String(HexEncoding.encode(mac)));
-
- Message msg = mHandler.obtainMessage(CALLBACK_IDENTITY_CHANGED);
- msg.obj = mac;
- mHandler.sendMessage(msg);
- }
- }
-
- private static class WifiAwareDiscoverySessionCallbackProxy extends
- IWifiAwareDiscoverySessionCallback.Stub {
- private static final int CALLBACK_SESSION_STARTED = 0;
- private static final int CALLBACK_SESSION_CONFIG_SUCCESS = 1;
- private static final int CALLBACK_SESSION_CONFIG_FAIL = 2;
- private static final int CALLBACK_SESSION_TERMINATED = 3;
- private static final int CALLBACK_MATCH = 4;
- private static final int CALLBACK_MESSAGE_SEND_SUCCESS = 5;
- private static final int CALLBACK_MESSAGE_SEND_FAIL = 6;
- private static final int CALLBACK_MESSAGE_RECEIVED = 7;
- private static final int CALLBACK_MATCH_WITH_DISTANCE = 8;
-
- private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message";
- private static final String MESSAGE_BUNDLE_KEY_MESSAGE2 = "message2";
-
- private final WeakReference<WifiAwareManager> mAwareManager;
- private final boolean mIsPublish;
- private final DiscoverySessionCallback mOriginalCallback;
- private final int mClientId;
-
- private final Handler mHandler;
- private DiscoverySession mSession;
-
- WifiAwareDiscoverySessionCallbackProxy(WifiAwareManager mgr, Looper looper,
- boolean isPublish, DiscoverySessionCallback originalCallback,
- int clientId) {
- mAwareManager = new WeakReference<>(mgr);
- mIsPublish = isPublish;
- mOriginalCallback = originalCallback;
- mClientId = clientId;
-
- if (VDBG) {
- Log.v(TAG, "WifiAwareDiscoverySessionCallbackProxy ctor: isPublish=" + isPublish);
- }
-
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
-
- if (mAwareManager.get() == null) {
- Log.w(TAG, "WifiAwareDiscoverySessionCallbackProxy: handleMessage post GC");
- return;
- }
-
- switch (msg.what) {
- case CALLBACK_SESSION_STARTED:
- onProxySessionStarted(msg.arg1);
- break;
- case CALLBACK_SESSION_CONFIG_SUCCESS:
- mOriginalCallback.onSessionConfigUpdated();
- break;
- case CALLBACK_SESSION_CONFIG_FAIL:
- mOriginalCallback.onSessionConfigFailed();
- if (mSession == null) {
- /*
- * creation failed (as opposed to update
- * failing)
- */
- mAwareManager.clear();
- }
- break;
- case CALLBACK_SESSION_TERMINATED:
- onProxySessionTerminated(msg.arg1);
- break;
- case CALLBACK_MATCH:
- case CALLBACK_MATCH_WITH_DISTANCE:
- {
- List<byte[]> matchFilter = null;
- byte[] arg = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2);
- try {
- matchFilter = new TlvBufferUtils.TlvIterable(0, 1, arg).toList();
- } catch (BufferOverflowException e) {
- matchFilter = null;
- Log.e(TAG, "onServiceDiscovered: invalid match filter byte array '"
- + new String(HexEncoding.encode(arg))
- + "' - cannot be parsed: e=" + e);
- }
- if (msg.what == CALLBACK_MATCH) {
- mOriginalCallback.onServiceDiscovered(new PeerHandle(msg.arg1),
- msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE),
- matchFilter);
- } else {
- mOriginalCallback.onServiceDiscoveredWithinRange(
- new PeerHandle(msg.arg1),
- msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE),
- matchFilter, msg.arg2);
- }
- break;
- }
- case CALLBACK_MESSAGE_SEND_SUCCESS:
- mOriginalCallback.onMessageSendSucceeded(msg.arg1);
- break;
- case CALLBACK_MESSAGE_SEND_FAIL:
- mOriginalCallback.onMessageSendFailed(msg.arg1);
- break;
- case CALLBACK_MESSAGE_RECEIVED:
- mOriginalCallback.onMessageReceived(new PeerHandle(msg.arg1),
- (byte[]) msg.obj);
- break;
- }
- }
- };
- }
-
- @Override
- public void onSessionStarted(int sessionId) {
- if (VDBG) Log.v(TAG, "onSessionStarted: sessionId=" + sessionId);
-
- Message msg = mHandler.obtainMessage(CALLBACK_SESSION_STARTED);
- msg.arg1 = sessionId;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onSessionConfigSuccess() {
- if (VDBG) Log.v(TAG, "onSessionConfigSuccess");
-
- Message msg = mHandler.obtainMessage(CALLBACK_SESSION_CONFIG_SUCCESS);
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onSessionConfigFail(int reason) {
- if (VDBG) Log.v(TAG, "onSessionConfigFail: reason=" + reason);
-
- Message msg = mHandler.obtainMessage(CALLBACK_SESSION_CONFIG_FAIL);
- msg.arg1 = reason;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onSessionTerminated(int reason) {
- if (VDBG) Log.v(TAG, "onSessionTerminated: reason=" + reason);
-
- Message msg = mHandler.obtainMessage(CALLBACK_SESSION_TERMINATED);
- msg.arg1 = reason;
- mHandler.sendMessage(msg);
- }
-
- private void onMatchCommon(int messageType, int peerId, byte[] serviceSpecificInfo,
- byte[] matchFilter, int distanceMm) {
- Bundle data = new Bundle();
- data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, serviceSpecificInfo);
- data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2, matchFilter);
-
- Message msg = mHandler.obtainMessage(messageType);
- msg.arg1 = peerId;
- msg.arg2 = distanceMm;
- msg.setData(data);
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onMatch(int peerId, byte[] serviceSpecificInfo, byte[] matchFilter) {
- if (VDBG) Log.v(TAG, "onMatch: peerId=" + peerId);
-
- onMatchCommon(CALLBACK_MATCH, peerId, serviceSpecificInfo, matchFilter, 0);
- }
-
- @Override
- public void onMatchWithDistance(int peerId, byte[] serviceSpecificInfo, byte[] matchFilter,
- int distanceMm) {
- if (VDBG) {
- Log.v(TAG, "onMatchWithDistance: peerId=" + peerId + ", distanceMm=" + distanceMm);
- }
-
- onMatchCommon(CALLBACK_MATCH_WITH_DISTANCE, peerId, serviceSpecificInfo, matchFilter,
- distanceMm);
- }
-
- @Override
- public void onMessageSendSuccess(int messageId) {
- if (VDBG) Log.v(TAG, "onMessageSendSuccess");
-
- Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_SEND_SUCCESS);
- msg.arg1 = messageId;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onMessageSendFail(int messageId, int reason) {
- if (VDBG) Log.v(TAG, "onMessageSendFail: reason=" + reason);
-
- Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_SEND_FAIL);
- msg.arg1 = messageId;
- msg.arg2 = reason;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onMessageReceived(int peerId, byte[] message) {
- if (VDBG) {
- Log.v(TAG, "onMessageReceived: peerId=" + peerId);
- }
-
- Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_RECEIVED);
- msg.arg1 = peerId;
- msg.obj = message;
- mHandler.sendMessage(msg);
- }
-
- /*
- * Proxied methods
- */
- public void onProxySessionStarted(int sessionId) {
- if (VDBG) Log.v(TAG, "Proxy: onSessionStarted: sessionId=" + sessionId);
- if (mSession != null) {
- Log.e(TAG,
- "onSessionStarted: sessionId=" + sessionId + ": session already created!?");
- throw new IllegalStateException(
- "onSessionStarted: sessionId=" + sessionId + ": session already created!?");
- }
-
- WifiAwareManager mgr = mAwareManager.get();
- if (mgr == null) {
- Log.w(TAG, "onProxySessionStarted: mgr GC'd");
- return;
- }
-
- if (mIsPublish) {
- PublishDiscoverySession session = new PublishDiscoverySession(mgr,
- mClientId, sessionId);
- mSession = session;
- mOriginalCallback.onPublishStarted(session);
- } else {
- SubscribeDiscoverySession
- session = new SubscribeDiscoverySession(mgr, mClientId, sessionId);
- mSession = session;
- mOriginalCallback.onSubscribeStarted(session);
- }
- }
-
- public void onProxySessionTerminated(int reason) {
- if (VDBG) Log.v(TAG, "Proxy: onSessionTerminated: reason=" + reason);
- if (mSession != null) {
- mSession.setTerminated();
- mSession = null;
- } else {
- Log.w(TAG, "Proxy: onSessionTerminated called but mSession is null!?");
- }
- mAwareManager.clear();
- mOriginalCallback.onSessionTerminated();
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
deleted file mode 100644
index 60fe604..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
+++ /dev/null
@@ -1,182 +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.net.wifi.aware;
-
-import android.annotation.Nullable;
-import android.net.NetworkCapabilities;
-import android.net.TransportInfo;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.net.Inet6Address;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.Objects;
-
-/**
- * Wi-Fi Aware-specific network information. The information can be extracted from the
- * {@link android.net.NetworkCapabilities} of the network using
- * {@link NetworkCapabilities#getTransportInfo()}.
- * The {@link NetworkCapabilities} is provided by the connectivity service to apps, e.g. received
- * through the
- * {@link android.net.ConnectivityManager.NetworkCallback#onCapabilitiesChanged(android.net.Network,
- * android.net.NetworkCapabilities)} callback.
- * <p>
- * The Wi-Fi Aware-specific network information include the peer's scoped link-local IPv6 address
- * for the Wi-Fi Aware link, as well as (optionally) the port and transport protocol specified by
- * the peer.
- * The scoped link-local IPv6, port, and transport protocol can then be used to create a
- * {@link java.net.Socket} connection to the peer.
- * <p>
- * Note: these are the peer's IPv6 and port information - not the local device's!
- */
-public final class WifiAwareNetworkInfo implements TransportInfo, Parcelable {
- private Inet6Address mIpv6Addr;
- private int mPort = 0; // a value of 0 is considered invalid
- private int mTransportProtocol = -1; // a value of -1 is considered invalid
-
- /** @hide */
- public WifiAwareNetworkInfo(Inet6Address ipv6Addr) {
- mIpv6Addr = ipv6Addr;
- }
-
- /** @hide */
- public WifiAwareNetworkInfo(Inet6Address ipv6Addr, int port, int transportProtocol) {
- mIpv6Addr = ipv6Addr;
- mPort = port;
- mTransportProtocol = transportProtocol;
- }
-
- /**
- * Get the scoped link-local IPv6 address of the Wi-Fi Aware peer (not of the local device!).
- *
- * @return An IPv6 address.
- */
- @Nullable
- public Inet6Address getPeerIpv6Addr() {
- return mIpv6Addr;
- }
-
- /**
- * Get the port number to be used to create a network connection to the Wi-Fi Aware peer.
- * The port information is provided by the app running on the peer which requested the
- * connection, using the {@link WifiAwareNetworkSpecifier.Builder#setPort(int)}.
- *
- * @return A port number on the peer. A value of 0 indicates that no port was specified by the
- * peer.
- */
- public int getPort() {
- return mPort;
- }
-
- /**
- * Get the transport protocol to be used to communicate over a network connection to the Wi-Fi
- * Aware peer. The transport protocol is provided by the app running on the peer which requested
- * the connection, using the
- * {@link WifiAwareNetworkSpecifier.Builder#setTransportProtocol(int)}.
- * <p>
- * The transport protocol number is assigned by the Internet Assigned Numbers Authority
- * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
- *
- * @return A transport protocol id. A value of -1 indicates that no transport protocol was
- * specified by the peer.
- */
- public int getTransportProtocol() {
- return mTransportProtocol;
- }
-
- // parcelable methods
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeByteArray(mIpv6Addr.getAddress());
- NetworkInterface ni = mIpv6Addr.getScopedInterface();
- dest.writeString(ni == null ? null : ni.getName());
- dest.writeInt(mPort);
- dest.writeInt(mTransportProtocol);
- }
-
- public static final @android.annotation.NonNull Creator<WifiAwareNetworkInfo> CREATOR =
- new Creator<WifiAwareNetworkInfo>() {
- @Override
- public WifiAwareNetworkInfo createFromParcel(Parcel in) {
- byte[] addr = in.createByteArray();
- String interfaceName = in.readString();
- int port = in.readInt();
- int transportProtocol = in.readInt();
- Inet6Address ipv6Addr;
- try {
- NetworkInterface ni = null;
- if (interfaceName != null) {
- try {
- ni = NetworkInterface.getByName(interfaceName);
- } catch (SocketException e) {
- e.printStackTrace();
- }
- }
- ipv6Addr = Inet6Address.getByAddress(null, addr, ni);
- } catch (UnknownHostException e) {
- e.printStackTrace();
- return new WifiAwareNetworkInfo(null);
- }
- return new WifiAwareNetworkInfo(ipv6Addr, port, transportProtocol);
- }
-
- @Override
- public WifiAwareNetworkInfo[] newArray(int size) {
- return new WifiAwareNetworkInfo[size];
- }
- };
-
-
- // object methods
-
- @Override
- public String toString() {
- return new StringBuilder("AwareNetworkInfo: IPv6=").append(mIpv6Addr).append(
- ", port=").append(mPort).append(", transportProtocol=").append(
- mTransportProtocol).toString();
- }
-
- /** @hide */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (!(obj instanceof WifiAwareNetworkInfo)) {
- return false;
- }
-
- WifiAwareNetworkInfo lhs = (WifiAwareNetworkInfo) obj;
- return Objects.equals(mIpv6Addr, lhs.mIpv6Addr) && mPort == lhs.mPort
- && mTransportProtocol == lhs.mTransportProtocol;
- }
-
- /** @hide */
- @Override
- public int hashCode() {
- return Objects.hash(mIpv6Addr, mPort, mTransportProtocol);
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
deleted file mode 100644
index 3547750..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ /dev/null
@@ -1,446 +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.net.wifi.aware;
-
-import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * Network specifier object used to request a Wi-Fi Aware network. Apps should use the
- * {@link WifiAwareNetworkSpecifier.Builder} class to create an instance.
- */
-public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
- /**
- * TYPE: in band, specific peer: role, client_id, session_id, peer_id, pmk/passphrase optional
- * @hide
- */
- public static final int NETWORK_SPECIFIER_TYPE_IB = 0;
-
- /**
- * TYPE: in band, any peer: role, client_id, session_id, pmk/passphrase optional
- * [only permitted for RESPONDER]
- * @hide
- */
- public static final int NETWORK_SPECIFIER_TYPE_IB_ANY_PEER = 1;
-
- /**
- * TYPE: out-of-band: role, client_id, peer_mac, pmk/passphrase optional
- * @hide
- */
- public static final int NETWORK_SPECIFIER_TYPE_OOB = 2;
-
- /**
- * TYPE: out-of-band, any peer: role, client_id, pmk/passphrase optional
- * [only permitted for RESPONDER]
- * @hide
- */
- public static final int NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER = 3;
-
- /** @hide */
- public static final int NETWORK_SPECIFIER_TYPE_MAX_VALID = NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
-
- /**
- * One of the NETWORK_SPECIFIER_TYPE_* constants. The type of the network specifier object.
- * @hide
- */
- public final int type;
-
- /**
- * The role of the device: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR or
- * WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER.
- * @hide
- */
- public final int role;
-
- /**
- * The client ID of the device.
- * @hide
- */
- public final int clientId;
-
- /**
- * The session ID in which context to request a data-path. Only relevant for IB requests.
- * @hide
- */
- public final int sessionId;
-
- /**
- * The peer ID of the device which the data-path should be connected to. Only relevant for
- * IB requests (i.e. not IB_ANY_PEER or OOB*).
- * @hide
- */
- public final int peerId;
-
- /**
- * The peer MAC address of the device which the data-path should be connected to. Only relevant
- * for OB requests (i.e. not OOB_ANY_PEER or IB*).
- * @hide
- */
- public final byte[] peerMac;
-
- /**
- * The PMK of the requested data-path. Can be null. Only one or none of pmk or passphrase should
- * be specified.
- * @hide
- */
- public final byte[] pmk;
-
- /**
- * The Passphrase of the requested data-path. Can be null. Only one or none of the pmk or
- * passphrase should be specified.
- * @hide
- */
- public final String passphrase;
-
- /**
- * The port information to be used for this link. This information will be communicated to the
- * peer as part of the layer 2 link setup.
- *
- * Information only allowed on secure links since a single layer-2 link is set up for all
- * requestors. Therefore if multiple apps on a single device request links to the same peer
- * device they all get the same link. However, the link is only set up on the first request -
- * hence only the first can transmit the port information. But we don't want to expose that
- * information to other apps. Limiting to secure links would (usually) imply single app usage.
- *
- * @hide
- */
- public final int port;
-
- /**
- * The transport protocol information to be used for this link. This information will be
- * communicated to the peer as part of the layer 2 link setup.
- *
- * Information only allowed on secure links since a single layer-2 link is set up for all
- * requestors. Therefore if multiple apps on a single device request links to the same peer
- * device they all get the same link. However, the link is only set up on the first request -
- * hence only the first can transmit the port information. But we don't want to expose that
- * information to other apps. Limiting to secure links would (usually) imply single app usage.
- *
- * @hide
- */
- public final int transportProtocol;
-
- /** @hide */
- public WifiAwareNetworkSpecifier(int type, int role, int clientId, int sessionId, int peerId,
- byte[] peerMac, byte[] pmk, String passphrase, int port, int transportProtocol) {
- this.type = type;
- this.role = role;
- this.clientId = clientId;
- this.sessionId = sessionId;
- this.peerId = peerId;
- this.peerMac = peerMac;
- this.pmk = pmk;
- this.passphrase = passphrase;
- this.port = port;
- this.transportProtocol = transportProtocol;
- }
-
- public static final @android.annotation.NonNull Creator<WifiAwareNetworkSpecifier> CREATOR =
- new Creator<WifiAwareNetworkSpecifier>() {
- @Override
- public WifiAwareNetworkSpecifier createFromParcel(Parcel in) {
- return new WifiAwareNetworkSpecifier(
- in.readInt(), // type
- in.readInt(), // role
- in.readInt(), // clientId
- in.readInt(), // sessionId
- in.readInt(), // peerId
- in.createByteArray(), // peerMac
- in.createByteArray(), // pmk
- in.readString(), // passphrase
- in.readInt(), // port
- in.readInt()); // transportProtocol
- }
-
- @Override
- public WifiAwareNetworkSpecifier[] newArray(int size) {
- return new WifiAwareNetworkSpecifier[size];
- }
- };
-
- /**
- * Indicates whether the network specifier specifies an OOB (out-of-band) data-path - i.e. a
- * data-path created without a corresponding Aware discovery session.
- *
- * @hide
- */
- public boolean isOutOfBand() {
- return type == NETWORK_SPECIFIER_TYPE_OOB || type == NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(type);
- dest.writeInt(role);
- dest.writeInt(clientId);
- dest.writeInt(sessionId);
- dest.writeInt(peerId);
- dest.writeByteArray(peerMac);
- dest.writeByteArray(pmk);
- dest.writeString(passphrase);
- dest.writeInt(port);
- dest.writeInt(transportProtocol);
- }
-
- /** @hide */
- @Override
- public boolean canBeSatisfiedBy(NetworkSpecifier other) {
- // MatchAllNetworkSpecifier is taken care in NetworkCapabilities#satisfiedBySpecifier.
- if (other instanceof WifiAwareAgentNetworkSpecifier) {
- return ((WifiAwareAgentNetworkSpecifier) other).satisfiesAwareNetworkSpecifier(this);
- }
- return equals(other);
- }
-
- /** @hide */
- @Override
- public int hashCode() {
- return Objects.hash(type, role, clientId, sessionId, peerId, Arrays.hashCode(peerMac),
- Arrays.hashCode(pmk), passphrase, port, transportProtocol);
- }
-
- /** @hide */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (!(obj instanceof WifiAwareNetworkSpecifier)) {
- return false;
- }
-
- WifiAwareNetworkSpecifier lhs = (WifiAwareNetworkSpecifier) obj;
-
- return type == lhs.type
- && role == lhs.role
- && clientId == lhs.clientId
- && sessionId == lhs.sessionId
- && peerId == lhs.peerId
- && Arrays.equals(peerMac, lhs.peerMac)
- && Arrays.equals(pmk, lhs.pmk)
- && Objects.equals(passphrase, lhs.passphrase)
- && port == lhs.port
- && transportProtocol == lhs.transportProtocol;
- }
-
- /** @hide */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("WifiAwareNetworkSpecifier [");
- sb.append("type=").append(type)
- .append(", role=").append(role)
- .append(", clientId=").append(clientId)
- .append(", sessionId=").append(sessionId)
- .append(", peerId=").append(peerId)
- // masking potential PII (although low impact information)
- .append(", peerMac=").append((peerMac == null) ? "<null>" : "<non-null>")
- // masking PII
- .append(", pmk=").append((pmk == null) ? "<null>" : "<non-null>")
- // masking PII
- .append(", passphrase=").append((passphrase == null) ? "<null>" : "<non-null>")
- .append(", port=").append(port).append(", transportProtocol=")
- .append(transportProtocol)
- .append("]");
- return sb.toString();
- }
-
- /**
- * A builder class for a Wi-Fi Aware network specifier to set up an Aware connection with a
- * peer.
- */
- public static final class Builder {
- private DiscoverySession mDiscoverySession;
- private PeerHandle mPeerHandle;
- private String mPskPassphrase;
- private byte[] mPmk;
- private int mPort = 0; // invalid value
- private int mTransportProtocol = -1; // invalid value
-
- /**
- * Create a builder for {@link WifiAwareNetworkSpecifier} used in requests to set up a
- * Wi-Fi Aware connection with a peer.
- *
- * @param discoverySession A Wi-Fi Aware discovery session in whose context the connection
- * is created.
- * @param peerHandle The handle of the peer to which the Wi-Fi Aware connection is
- * requested. The peer is discovered through Wi-Fi Aware discovery. The
- * handle can be obtained through
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
- * or
- * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
- */
- public Builder(@NonNull DiscoverySession discoverySession, @NonNull PeerHandle peerHandle) {
- if (discoverySession == null) {
- throw new IllegalArgumentException("Non-null discoverySession required");
- }
- if (peerHandle == null) {
- throw new IllegalArgumentException("Non-null peerHandle required");
- }
- mDiscoverySession = discoverySession;
- mPeerHandle = peerHandle;
- }
-
- /**
- * Configure the PSK Passphrase for the Wi-Fi Aware connection being requested. This method
- * is optional - if not called, then an Open (unencrypted) connection will be created.
- *
- * @param pskPassphrase The (optional) passphrase to be used to encrypt the link. Use the
- * {@link #setPmk(byte[])} to specify a PMK.
- * @return the current {@link Builder} builder, enabling chaining of builder
- * methods.
- */
- public @NonNull Builder setPskPassphrase(@NonNull String pskPassphrase) {
- if (!WifiAwareUtils.validatePassphrase(pskPassphrase)) {
- throw new IllegalArgumentException("Passphrase must meet length requirements");
- }
- mPskPassphrase = pskPassphrase;
- return this;
- }
-
- /**
- * Configure the PMK for the Wi-Fi Aware connection being requested. This method
- * is optional - if not called, then an Open (unencrypted) connection will be created.
- *
- * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
- * encrypting the data-path. Use the {@link #setPskPassphrase(String)} to
- * specify a Passphrase.
- * @return the current {@link Builder} builder, enabling chaining of builder
- * methods.
- */
- public @NonNull Builder setPmk(@NonNull byte[] pmk) {
- if (!WifiAwareUtils.validatePmk(pmk)) {
- throw new IllegalArgumentException("PMK must 32 bytes");
- }
- mPmk = pmk;
- return this;
- }
-
- /**
- * Configure the port number which will be used to create a connection over this link. This
- * configuration should only be done on the server device, e.g. the device creating the
- * {@link java.net.ServerSocket}.
- * <p>Notes:
- * <ul>
- * <li>The server device must be the Publisher device!
- * <li>The port information can only be specified on secure links, specified using
- * {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])}.
- * </ul>
- *
- * @param port A positive integer indicating the port to be used for communication.
- * @return the current {@link Builder} builder, enabling chaining of builder
- * methods.
- */
- public @NonNull Builder setPort(@IntRange(from = 0, to = 65535) int port) {
- if (port <= 0 || port > 65535) {
- throw new IllegalArgumentException("The port must be a positive value (0, 65535]");
- }
- mPort = port;
- return this;
- }
-
- /**
- * Configure the transport protocol which will be used to create a connection over this
- * link. This configuration should only be done on the server device, e.g. the device
- * creating the {@link java.net.ServerSocket} for TCP.
- * <p>Notes:
- * <ul>
- * <li>The server device must be the Publisher device!
- * <li>The transport protocol information can only be specified on secure links,
- * specified using {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])}.
- * </ul>
- * The transport protocol number is assigned by the Internet Assigned Numbers Authority
- * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
- *
- * @param transportProtocol The transport protocol to be used for communication.
- * @return the current {@link Builder} builder, enabling chaining of builder
- * methods.
- */
- public @NonNull
- Builder setTransportProtocol(@IntRange(from = 0, to = 255) int transportProtocol) {
- if (transportProtocol < 0 || transportProtocol > 255) {
- throw new IllegalArgumentException(
- "The transport protocol must be in range [0, 255]");
- }
- mTransportProtocol = transportProtocol;
- return this;
- }
-
- /**
- * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)}
- * for a WiFi Aware connection (link) to the specified peer. The
- * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
- * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
- * <p> The default builder constructor will initialize a NetworkSpecifier which requests an
- * open (non-encrypted) link. To request an encrypted link use the
- * {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])} builder methods.
- *
- * @return A {@link NetworkSpecifier} to be used to construct
- * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass
- * to {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
- * android.net.ConnectivityManager.NetworkCallback)}
- * [or other varieties of that API].
- */
- public @NonNull WifiAwareNetworkSpecifier build() {
- if (mDiscoverySession == null) {
- throw new IllegalStateException("Null discovery session!?");
- }
- if (mPeerHandle == null) {
- throw new IllegalStateException("Null peerHandle!?");
- }
- if (mPskPassphrase != null & mPmk != null) {
- throw new IllegalStateException(
- "Can only specify a Passphrase or a PMK - not both!");
- }
-
- int role = mDiscoverySession instanceof SubscribeDiscoverySession
- ? WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
- : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-
- if (mPort != 0 || mTransportProtocol != -1) {
- if (role != WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
- throw new IllegalStateException(
- "Port and transport protocol information can only "
- + "be specified on the Publisher device (which is the server");
- }
- if (TextUtils.isEmpty(mPskPassphrase) && mPmk == null) {
- throw new IllegalStateException("Port and transport protocol information can "
- + "only be specified on a secure link");
- }
- }
-
- return new WifiAwareNetworkSpecifier(
- WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB, role,
- mDiscoverySession.mClientId, mDiscoverySession.mSessionId, mPeerHandle.peerId,
- null, mPmk, mPskPassphrase, mPort, mTransportProtocol);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
deleted file mode 100644
index fe0872c..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ /dev/null
@@ -1,343 +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.net.wifi.aware;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.NetworkSpecifier;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-
-/**
- * This class represents a Wi-Fi Aware session - an attachment to the Wi-Fi Aware service through
- * which the app can execute discovery operations.
- */
-public class WifiAwareSession implements AutoCloseable {
- private static final String TAG = "WifiAwareSession";
- private static final boolean DBG = false;
- private static final boolean VDBG = false; // STOPSHIP if true
-
- private final WeakReference<WifiAwareManager> mMgr;
- private final Binder mBinder;
- private final int mClientId;
-
- private boolean mTerminated = true;
- private final CloseGuard mCloseGuard = new CloseGuard();
-
- /** @hide */
- public WifiAwareSession(WifiAwareManager manager, Binder binder, int clientId) {
- if (VDBG) Log.v(TAG, "New session created: manager=" + manager + ", clientId=" + clientId);
-
- mMgr = new WeakReference<>(manager);
- mBinder = binder;
- mClientId = clientId;
- mTerminated = false;
-
- mCloseGuard.open("close");
- }
-
- /**
- * Destroy the Wi-Fi Aware service session and, if no other applications are attached to Aware,
- * also disable Aware. This method destroys all outstanding operations - i.e. all publish and
- * subscribes are terminated, and any outstanding data-links are shut-down. However, it is
- * good practice to destroy these discovery sessions and connections explicitly before a
- * session-wide destroy.
- * <p>
- * An application may re-attach after a destroy using
- * {@link WifiAwareManager#attach(AttachCallback, Handler)} .
- */
- @Override
- public void close() {
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.w(TAG, "destroy: called post GC on WifiAwareManager");
- return;
- }
- mgr.disconnect(mClientId, mBinder);
- mTerminated = true;
- mMgr.clear();
- mCloseGuard.close();
- Reference.reachabilityFence(this);
- }
-
- /** @hide */
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mCloseGuard != null) {
- mCloseGuard.warnIfOpen();
- }
-
- if (!mTerminated) {
- close();
- }
- } finally {
- super.finalize();
- }
- }
-
- /**
- * Access the client ID of the Aware session.
- *
- * Note: internal visibility for testing.
- *
- * @return The internal client ID.
- *
- * @hide
- */
- @VisibleForTesting
- public int getClientId() {
- return mClientId;
- }
-
- /**
- * Issue a request to the Aware service to create a new Aware publish discovery session, using
- * the specified {@code publishConfig} configuration. The results of the publish operation
- * are routed to the callbacks of {@link DiscoverySessionCallback}:
- * <ul>
- * <li>
- * {@link DiscoverySessionCallback#onPublishStarted(
- *PublishDiscoverySession)}
- * is called when the publish session is created and provides a handle to the session.
- * Further operations on the publish session can be executed on that object.
- * <li>{@link DiscoverySessionCallback#onSessionConfigFailed()} is called if the
- * publish operation failed.
- * </ul>
- * <p>
- * Other results of the publish session operations will also be routed to callbacks
- * on the {@code callback} object. The resulting publish session can be modified using
- * {@link PublishDiscoverySession#updatePublish(PublishConfig)}.
- * <p>
- * An application must use the {@link DiscoverySession#close()} to
- * terminate the publish discovery session once it isn't needed. This will free
- * resources as well terminate any on-air transmissions.
- * <p>The application must have the {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
- * permission to start a publish discovery session.
- *
- * @param publishConfig The {@link PublishConfig} specifying the
- * configuration of the requested publish session.
- * @param callback A {@link DiscoverySessionCallback} derived object to be used for
- * session event callbacks.
- * @param handler The Handler on whose thread to execute the callbacks of the {@code
- * callback} object. If a null is provided then the application's main thread will be used.
- */
- public void publish(@NonNull PublishConfig publishConfig,
- @NonNull DiscoverySessionCallback callback, @Nullable Handler handler) {
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.e(TAG, "publish: called post GC on WifiAwareManager");
- return;
- }
- if (mTerminated) {
- Log.e(TAG, "publish: called after termination");
- return;
- }
- mgr.publish(mClientId, (handler == null) ? Looper.getMainLooper() : handler.getLooper(),
- publishConfig, callback);
- }
-
- /**
- * Issue a request to the Aware service to create a new Aware subscribe discovery session, using
- * the specified {@code subscribeConfig} configuration. The results of the subscribe
- * operation are routed to the callbacks of {@link DiscoverySessionCallback}:
- * <ul>
- * <li>
- * {@link DiscoverySessionCallback#onSubscribeStarted(
- *SubscribeDiscoverySession)}
- * is called when the subscribe session is created and provides a handle to the session.
- * Further operations on the subscribe session can be executed on that object.
- * <li>{@link DiscoverySessionCallback#onSessionConfigFailed()} is called if the
- * subscribe operation failed.
- * </ul>
- * <p>
- * Other results of the subscribe session operations will also be routed to callbacks
- * on the {@code callback} object. The resulting subscribe session can be modified using
- * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
- * <p>
- * An application must use the {@link DiscoverySession#close()} to
- * terminate the subscribe discovery session once it isn't needed. This will free
- * resources as well terminate any on-air transmissions.
- * <p>The application must have the {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
- * permission to start a subscribe discovery session.
- *
- * @param subscribeConfig The {@link SubscribeConfig} specifying the
- * configuration of the requested subscribe session.
- * @param callback A {@link DiscoverySessionCallback} derived object to be used for
- * session event callbacks.
- * @param handler The Handler on whose thread to execute the callbacks of the {@code
- * callback} object. If a null is provided then the application's main thread will be used.
- */
- public void subscribe(@NonNull SubscribeConfig subscribeConfig,
- @NonNull DiscoverySessionCallback callback, @Nullable Handler handler) {
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.e(TAG, "publish: called post GC on WifiAwareManager");
- return;
- }
- if (mTerminated) {
- Log.e(TAG, "publish: called after termination");
- return;
- }
- mgr.subscribe(mClientId, (handler == null) ? Looper.getMainLooper() : handler.getLooper(),
- subscribeConfig, callback);
- }
-
- /**
- * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
- * an unencrypted WiFi Aware connection (link) to the specified peer. The
- * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
- * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
- * <p>
- * This API is targeted for applications which can obtain the peer MAC address using OOB
- * (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
- * when using Aware discovery use the alternative network specifier method -
- * {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
- * <p>
- * To set up an encrypted link use the
- * {@link #createNetworkSpecifierPassphrase(int, byte[], String)} API.
- *
- * @param role The role of this device:
- * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
- * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
- * @param peer The MAC address of the peer's Aware discovery interface. On a RESPONDER this
- * value is used to gate the acceptance of a connection request from only that
- * peer.
- *
- * @return A {@link NetworkSpecifier} to be used to construct
- * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
- * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
- * android.net.ConnectivityManager.NetworkCallback)}
- * [or other varieties of that API].
- */
- public NetworkSpecifier createNetworkSpecifierOpen(
- @WifiAwareManager.DataPathRole int role, @NonNull byte[] peer) {
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.e(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager");
- return null;
- }
- if (mTerminated) {
- Log.e(TAG, "createNetworkSpecifierOpen: called after termination");
- return null;
- }
- return mgr.createNetworkSpecifier(mClientId, role, peer, null, null);
- }
-
- /**
- * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
- * an encrypted WiFi Aware connection (link) to the specified peer. The
- * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
- * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
- * <p>
- * This API is targeted for applications which can obtain the peer MAC address using OOB
- * (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
- * when using Aware discovery use the alternative network specifier method -
- * {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
- *
- * @param role The role of this device:
- * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
- * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
- * @param peer The MAC address of the peer's Aware discovery interface. On a RESPONDER this
- * value is used to gate the acceptance of a connection request from only that
- * peer.
- * @param passphrase The passphrase to be used to encrypt the link. The PMK is generated from
- * the passphrase. Use {@link #createNetworkSpecifierOpen(int, byte[])} to
- * specify an open (unencrypted) link.
- *
- * @return A {@link NetworkSpecifier} to be used to construct
- * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
- * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
- * android.net.ConnectivityManager.NetworkCallback)}
- * [or other varieties of that API].
- */
- public NetworkSpecifier createNetworkSpecifierPassphrase(
- @WifiAwareManager.DataPathRole int role, @NonNull byte[] peer,
- @NonNull String passphrase) {
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.e(TAG, "createNetworkSpecifierPassphrase: called post GC on WifiAwareManager");
- return null;
- }
- if (mTerminated) {
- Log.e(TAG, "createNetworkSpecifierPassphrase: called after termination");
- return null;
- }
- if (!WifiAwareUtils.validatePassphrase(passphrase)) {
- throw new IllegalArgumentException("Passphrase must meet length requirements");
- }
-
- return mgr.createNetworkSpecifier(mClientId, role, peer, null, passphrase);
- }
-
- /**
- * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
- * an encrypted WiFi Aware connection (link) to the specified peer. The
- * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
- * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
- * <p>
- * This API is targeted for applications which can obtain the peer MAC address using OOB
- * (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
- * when using Aware discovery use the alternative network specifier method -
- * {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
- *
- * @param role The role of this device:
- * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
- * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
- * @param peer The MAC address of the peer's Aware discovery interface. On a RESPONDER this
- * value is used to gate the acceptance of a connection request from only that
- * peer.
- * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
- * encrypting the data-path. Use the
- * {@link #createNetworkSpecifierPassphrase(int, byte[], String)} to specify a
- * Passphrase or {@link #createNetworkSpecifierOpen(int, byte[])} to specify an
- * open (unencrypted) link.
- *
- * @return A {@link NetworkSpecifier} to be used to construct
- * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
- * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
- * android.net.ConnectivityManager.NetworkCallback)}
- * [or other varieties of that API].
- *
- * @hide
- */
- @SystemApi
- public NetworkSpecifier createNetworkSpecifierPmk(
- @WifiAwareManager.DataPathRole int role, @NonNull byte[] peer, @NonNull byte[] pmk) {
- WifiAwareManager mgr = mMgr.get();
- if (mgr == null) {
- Log.e(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager");
- return null;
- }
- if (mTerminated) {
- Log.e(TAG, "createNetworkSpecifierPmk: called after termination");
- return null;
- }
- if (!WifiAwareUtils.validatePmk(pmk)) {
- throw new IllegalArgumentException("PMK must 32 bytes");
- }
- return mgr.createNetworkSpecifier(mClientId, role, peer, pmk, null);
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareUtils.java b/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
deleted file mode 100644
index 3ece93df..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
+++ /dev/null
@@ -1,106 +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.net.wifi.aware;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.hardware.wifi.V1_0.Constants;
-
-/**
- * Provides utilities for the Wifi Aware manager/service.
- *
- * @hide
- */
-public class WifiAwareUtils {
- /**
- * Per spec: The Service Name is a UTF-8 encoded string from 1 to 255 bytes in length. The
- * only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric values (A-Z,
- * a-z, 0-9), the hyphen ('-'), and the period ('.'). All valid multi-byte UTF-8 characters
- * are acceptable in a Service Name.
- */
- public static void validateServiceName(byte[] serviceNameData) throws IllegalArgumentException {
- if (serviceNameData == null) {
- throw new IllegalArgumentException("Invalid service name - null");
- }
-
- if (serviceNameData.length < 1 || serviceNameData.length > 255) {
- throw new IllegalArgumentException("Invalid service name length - must be between "
- + "1 and 255 bytes (UTF-8 encoding)");
- }
-
- int index = 0;
- while (index < serviceNameData.length) {
- byte b = serviceNameData[index];
- if ((b & 0x80) == 0x00) {
- if (!((b >= '0' && b <= '9') || (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')
- || b == '-' || b == '.')) {
- throw new IllegalArgumentException("Invalid service name - illegal characters,"
- + " allowed = (0-9, a-z,A-Z, -, .)");
- }
- }
- ++index;
- }
- }
-
- /**
- * Validates that the passphrase is a non-null string of the right size (per the HAL min/max
- * length parameters).
- *
- * @param passphrase Passphrase to test
- * @return true if passphrase is valid, false if not
- */
- public static boolean validatePassphrase(String passphrase) {
- if (passphrase == null
- || passphrase.length() < Constants.NanParamSizeLimits.MIN_PASSPHRASE_LENGTH
- || passphrase.length() > Constants.NanParamSizeLimits.MAX_PASSPHRASE_LENGTH) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Validates that the PMK is a non-null byte array of the right size (32 bytes per spec).
- *
- * @param pmk PMK to test
- * @return true if PMK is valid, false if not
- */
- public static boolean validatePmk(byte[] pmk) {
- if (pmk == null || pmk.length != 32) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Returns true if the App version is older than minVersion.
- */
- public static boolean isLegacyVersion(Context context, int minVersion) {
- try {
- if (context.getPackageManager().getApplicationInfo(context.getOpPackageName(), 0)
- .targetSdkVersion < minVersion) {
- return true;
- }
- } catch (PackageManager.NameNotFoundException e) {
- // In case of exception, assume known app (more strict checking)
- // Note: This case will never happen since checkPackage is
- // called to verify valididity before checking App's version.
- }
- return false;
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/package.html b/wifi/java/android/net/wifi/aware/package.html
deleted file mode 100644
index c4f2e1f..0000000
--- a/wifi/java/android/net/wifi/aware/package.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes which allow applications to use Wi-Fi Aware to discover peers and create
- connections to them.</p>
-<p>Using the Wi-Fi Aware APIs, applications can advertise services, discover peers which are
- advertising services, and connect to them.
- Wi-Fi Aware is independent of Wi-Fi infrastructure (i.e. a device may or may
- not be associated with an AP concurrent to using Wi-Fi Aware). </p>
-<p>The primary entry point to Wi-Fi Aware capabilities is the
- {@link android.net.wifi.aware.WifiAwareManager} class, which is acquired by calling
- {@link android.content.Context#getSystemService(String)
- Context.getSystemService(Context.WIFI_AWARE_SERVICE)}</p>
-
-<p>Some APIs may require the following user permissions:</p>
-<ul>
- <li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
- <li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
- <li>{@link android.Manifest.permission#ACCESS_FINE_LOCATION}</li>
-</ul>
-
-<p class="note"><strong>Note:</strong> Not all Android-powered devices support Wi-Fi Aware
- functionality.
- If your application only works with Wi-Fi Aware (i.e. it should only be installed on devices which
- support Wi-Fi Aware), declare so with a <a
- href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
- {@code <uses-feature>}</a>
- element in the manifest file:</p>
-<pre>
-<manifest ...>
- <uses-feature android:name="android.hardware.wifi.aware" />
- ...
-</manifest>
-</pre>
-<p>Alternatively, if you application does not require Wi-Fi Aware but can take advantage of it if
- available, you can perform
- the check at run-time in your code using {@link
- android.content.pm.PackageManager#hasSystemFeature(String)} with {@link
- android.content.pm.PackageManager#FEATURE_WIFI_AWARE}:</p>
-<pre>
- getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)
-</pre>
-</BODY>
-</HTML>
diff --git a/wifi/java/android/net/wifi/hotspot2/ConfigParser.java b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
deleted file mode 100644
index bb01365..0000000
--- a/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
+++ /dev/null
@@ -1,486 +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.net.wifi.hotspot2;
-
-import android.net.wifi.hotspot2.omadm.PpsMoParser;
-import android.text.TextUtils;
-import android.util.Base64;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.LineNumberReader;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Utility class for building PasspointConfiguration from an installation file.
- */
-public final class ConfigParser {
- private static final String TAG = "ConfigParser";
-
- // Header names.
- private static final String CONTENT_TYPE = "Content-Type";
- private static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
-
- // MIME types.
- private static final String TYPE_MULTIPART_MIXED = "multipart/mixed";
- private static final String TYPE_WIFI_CONFIG = "application/x-wifi-config";
- private static final String TYPE_PASSPOINT_PROFILE = "application/x-passpoint-profile";
- private static final String TYPE_CA_CERT = "application/x-x509-ca-cert";
- private static final String TYPE_PKCS12 = "application/x-pkcs12";
-
- private static final String ENCODING_BASE64 = "base64";
- private static final String BOUNDARY = "boundary=";
-
- /**
- * Class represent a MIME (Multipurpose Internet Mail Extension) part.
- */
- private static class MimePart {
- /**
- * Content type of the part.
- */
- public String type = null;
-
- /**
- * Decoded data.
- */
- public byte[] data = null;
-
- /**
- * Flag indicating if this is the last part (ending with --{boundary}--).
- */
- public boolean isLast = false;
- }
-
- /**
- * Class represent the MIME (Multipurpose Internet Mail Extension) header.
- */
- private static class MimeHeader {
- /**
- * Content type.
- */
- public String contentType = null;
-
- /**
- * Boundary string (optional), only applies for the outter MIME header.
- */
- public String boundary = null;
-
- /**
- * Encoding type.
- */
- public String encodingType = null;
- }
-
- /**
- * @hide
- */
- public ConfigParser() {}
-
- /**
- * Parse the Hotspot 2.0 Release 1 configuration data into a {@link PasspointConfiguration}
- * object. The configuration data is a base64 encoded MIME multipart data. Below is
- * the format of the decoded message:
- *
- * Content-Type: multipart/mixed; boundary={boundary}
- * Content-Transfer-Encoding: base64
- * [Skip uninterested headers]
- *
- * --{boundary}
- * Content-Type: application/x-passpoint-profile
- * Content-Transfer-Encoding: base64
- *
- * [base64 encoded Passpoint profile data]
- * --{boundary}
- * Content-Type: application/x-x509-ca-cert
- * Content-Transfer-Encoding: base64
- *
- * [base64 encoded X509 CA certificate data]
- * --{boundary}
- * Content-Type: application/x-pkcs12
- * Content-Transfer-Encoding: base64
- *
- * [base64 encoded PKCS#12 ASN.1 structure containing client certificate chain]
- * --{boundary}
- *
- * @param mimeType MIME type of the encoded data.
- * @param data A base64 encoded MIME multipart message containing the Passpoint profile
- * (required), CA (Certificate Authority) certificate (optional), and client
- * certificate chain (optional).
- * @return {@link PasspointConfiguration}
- */
- public static PasspointConfiguration parsePasspointConfig(String mimeType, byte[] data) {
- // Verify MIME type.
- if (!TextUtils.equals(mimeType, TYPE_WIFI_CONFIG)) {
- Log.e(TAG, "Unexpected MIME type: " + mimeType);
- return null;
- }
-
- try {
- // Decode the data.
- byte[] decodedData = Base64.decode(new String(data, StandardCharsets.ISO_8859_1),
- Base64.DEFAULT);
- Map<String, byte[]> mimeParts = parseMimeMultipartMessage(new LineNumberReader(
- new InputStreamReader(new ByteArrayInputStream(decodedData),
- StandardCharsets.ISO_8859_1)));
- return createPasspointConfig(mimeParts);
- } catch (IOException | IllegalArgumentException e) {
- Log.e(TAG, "Failed to parse installation file: " + e.getMessage());
- return null;
- }
- }
-
- /**
- * Create a {@link PasspointConfiguration} object from list of MIME (Multipurpose Internet
- * Mail Extension) parts.
- *
- * @param mimeParts Map of content type and content data.
- * @return {@link PasspointConfiguration}
- * @throws IOException
- */
- private static PasspointConfiguration createPasspointConfig(Map<String, byte[]> mimeParts)
- throws IOException {
- byte[] profileData = mimeParts.get(TYPE_PASSPOINT_PROFILE);
- if (profileData == null) {
- throw new IOException("Missing Passpoint Profile");
- }
-
- PasspointConfiguration config = PpsMoParser.parseMoText(new String(profileData));
- if (config == null) {
- throw new IOException("Failed to parse Passpoint profile");
- }
-
- // Credential is needed for storing the certificates and private client key.
- if (config.getCredential() == null) {
- throw new IOException("Passpoint profile missing credential");
- }
-
- // Don't allow the installer to make changes to the update identifier. This is an
- // indicator of an R2 (or newer) network.
- if (config.getUpdateIdentifier() != Integer.MIN_VALUE) {
- config.setUpdateIdentifier(Integer.MIN_VALUE);
- }
-
- // Parse CA (Certificate Authority) certificate.
- byte[] caCertData = mimeParts.get(TYPE_CA_CERT);
- if (caCertData != null) {
- try {
- config.getCredential().setCaCertificate(parseCACert(caCertData));
- } catch (CertificateException e) {
- throw new IOException("Failed to parse CA Certificate");
- }
- }
-
- // Parse PKCS12 data for client private key and certificate chain.
- byte[] pkcs12Data = mimeParts.get(TYPE_PKCS12);
- if (pkcs12Data != null) {
- try {
- Pair<PrivateKey, List<X509Certificate>> clientKey = parsePkcs12(pkcs12Data);
- config.getCredential().setClientPrivateKey(clientKey.first);
- config.getCredential().setClientCertificateChain(
- clientKey.second.toArray(new X509Certificate[clientKey.second.size()]));
- } catch(GeneralSecurityException | IOException e) {
- throw new IOException("Failed to parse PCKS12 string");
- }
- }
- return config;
- }
-
- /**
- * Parse a MIME (Multipurpose Internet Mail Extension) multipart message from the given
- * input stream.
- *
- * @param in The input stream for reading the message data
- * @return A map of a content type and content data pair
- * @throws IOException
- */
- private static Map<String, byte[]> parseMimeMultipartMessage(LineNumberReader in)
- throws IOException {
- // Parse the outer MIME header.
- MimeHeader header = parseHeaders(in);
- if (!TextUtils.equals(header.contentType, TYPE_MULTIPART_MIXED)) {
- throw new IOException("Invalid content type: " + header.contentType);
- }
- if (TextUtils.isEmpty(header.boundary)) {
- throw new IOException("Missing boundary string");
- }
- if (!TextUtils.equals(header.encodingType, ENCODING_BASE64)) {
- throw new IOException("Unexpected encoding: " + header.encodingType);
- }
-
- // Read pass the first boundary string.
- for (;;) {
- String line = in.readLine();
- if (line == null) {
- throw new IOException("Unexpected EOF before first boundary @ " +
- in.getLineNumber());
- }
- if (line.equals("--" + header.boundary)) {
- break;
- }
- }
-
- // Parse each MIME part.
- Map<String, byte[]> mimeParts = new HashMap<>();
- boolean isLast = false;
- do {
- MimePart mimePart = parseMimePart(in, header.boundary);
- mimeParts.put(mimePart.type, mimePart.data);
- isLast = mimePart.isLast;
- } while(!isLast);
- return mimeParts;
- }
-
- /**
- * Parse a MIME (Multipurpose Internet Mail Extension) part. We expect the data to
- * be encoded in base64.
- *
- * @param in Input stream to read the data from
- * @param boundary Boundary string indicate the end of the part
- * @return {@link MimePart}
- * @throws IOException
- */
- private static MimePart parseMimePart(LineNumberReader in, String boundary)
- throws IOException {
- MimeHeader header = parseHeaders(in);
- // Expect encoding type to be base64.
- if (!TextUtils.equals(header.encodingType, ENCODING_BASE64)) {
- throw new IOException("Unexpected encoding type: " + header.encodingType);
- }
-
- // Check for a valid content type.
- if (!TextUtils.equals(header.contentType, TYPE_PASSPOINT_PROFILE) &&
- !TextUtils.equals(header.contentType, TYPE_CA_CERT) &&
- !TextUtils.equals(header.contentType, TYPE_PKCS12)) {
- throw new IOException("Unexpected content type: " + header.contentType);
- }
-
- StringBuilder text = new StringBuilder();
- boolean isLast = false;
- String partBoundary = "--" + boundary;
- String endBoundary = partBoundary + "--";
- for (;;) {
- String line = in.readLine();
- if (line == null) {
- throw new IOException("Unexpected EOF file in body @ " + in.getLineNumber());
- }
- // Check for boundary line.
- if (line.startsWith(partBoundary)) {
- if (line.equals(endBoundary)) {
- isLast = true;
- }
- break;
- }
- text.append(line);
- }
-
- MimePart part = new MimePart();
- part.type = header.contentType;
- part.data = Base64.decode(text.toString(), Base64.DEFAULT);
- part.isLast = isLast;
- return part;
- }
-
- /**
- * Parse a MIME (Multipurpose Internet Mail Extension) header from the input stream.
- * @param in Input stream to read from.
- * @return {@link MimeHeader}
- * @throws IOException
- */
- private static MimeHeader parseHeaders(LineNumberReader in)
- throws IOException {
- MimeHeader header = new MimeHeader();
-
- // Read the header from the input stream.
- Map<String, String> headers = readHeaders(in);
-
- // Parse each header.
- for (Map.Entry<String, String> entry : headers.entrySet()) {
- switch (entry.getKey()) {
- case CONTENT_TYPE:
- Pair<String, String> value = parseContentType(entry.getValue());
- header.contentType = value.first;
- header.boundary = value.second;
- break;
- case CONTENT_TRANSFER_ENCODING:
- header.encodingType = entry.getValue();
- break;
- default:
- Log.d(TAG, "Ignore header: " + entry.getKey());
- break;
- }
- }
- return header;
- }
-
- /**
- * Parse the Content-Type header value. The value will contain the content type string and
- * an optional boundary string separated by a ";". Below are examples of valid Content-Type
- * header value:
- * multipart/mixed; boundary={boundary}
- * application/x-passpoint-profile
- *
- * @param contentType The Content-Type value string
- * @return A pair of content type and boundary string
- * @throws IOException
- */
- private static Pair<String, String> parseContentType(String contentType) throws IOException {
- String[] attributes = contentType.split(";");
- String type = null;
- String boundary = null;
-
- if (attributes.length < 1) {
- throw new IOException("Invalid Content-Type: " + contentType);
- }
-
- // The type is always the first attribute.
- type = attributes[0].trim();
- // Look for boundary string from the rest of the attributes.
- for (int i = 1; i < attributes.length; i++) {
- String attribute = attributes[i].trim();
- if (!attribute.startsWith(BOUNDARY)) {
- Log.d(TAG, "Ignore Content-Type attribute: " + attributes[i]);
- continue;
- }
- boundary = attribute.substring(BOUNDARY.length());
- // Remove the leading and trailing quote if present.
- if (boundary.length() > 1 && boundary.startsWith("\"") && boundary.endsWith("\"")) {
- boundary = boundary.substring(1, boundary.length()-1);
- }
- }
-
- return new Pair<String, String>(type, boundary);
- }
-
- /**
- * Read the headers from the given input stream. The header section is terminated by
- * an empty line.
- *
- * @param in The input stream to read from
- * @return Map of key-value pairs.
- * @throws IOException
- */
- private static Map<String, String> readHeaders(LineNumberReader in)
- throws IOException {
- Map<String, String> headers = new HashMap<>();
- String line;
- String name = null;
- StringBuilder value = null;
- for (;;) {
- line = in.readLine();
- if (line == null) {
- throw new IOException("Missing line @ " + in.getLineNumber());
- }
-
- // End of headers section.
- if (line.length() == 0 || line.trim().length() == 0) {
- // Save the previous header line.
- if (name != null) {
- headers.put(name, value.toString());
- }
- break;
- }
-
- int nameEnd = line.indexOf(':');
- if (nameEnd < 0) {
- if (value != null) {
- // Continuation line for the header value.
- value.append(' ').append(line.trim());
- } else {
- throw new IOException("Bad header line: '" + line + "' @ " +
- in.getLineNumber());
- }
- } else {
- // New header line detected, make sure it doesn't start with a whitespace.
- if (Character.isWhitespace(line.charAt(0))) {
- throw new IOException("Illegal blank prefix in header line '" + line +
- "' @ " + in.getLineNumber());
- }
-
- if (name != null) {
- // Save the previous header line.
- headers.put(name, value.toString());
- }
-
- // Setup the current header line.
- name = line.substring(0, nameEnd).trim();
- value = new StringBuilder();
- value.append(line.substring(nameEnd+1).trim());
- }
- }
- return headers;
- }
-
- /**
- * Parse a CA (Certificate Authority) certificate data and convert it to a
- * X509Certificate object.
- *
- * @param octets Certificate data
- * @return X509Certificate
- * @throws CertificateException
- */
- private static X509Certificate parseCACert(byte[] octets) throws CertificateException {
- CertificateFactory factory = CertificateFactory.getInstance("X.509");
- return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(octets));
- }
-
- private static Pair<PrivateKey, List<X509Certificate>> parsePkcs12(byte[] octets)
- throws GeneralSecurityException, IOException {
- KeyStore ks = KeyStore.getInstance("PKCS12");
- ByteArrayInputStream in = new ByteArrayInputStream(octets);
- ks.load(in, new char[0]);
- in.close();
-
- // Only expects one set of key and certificate chain.
- if (ks.size() != 1) {
- throw new IOException("Unexpected key size: " + ks.size());
- }
-
- String alias = ks.aliases().nextElement();
- if (alias == null) {
- throw new IOException("No alias found");
- }
-
- PrivateKey clientKey = (PrivateKey) ks.getKey(alias, null);
- List<X509Certificate> clientCertificateChain = null;
- Certificate[] chain = ks.getCertificateChain(alias);
- if (chain != null) {
- clientCertificateChain = new ArrayList<>();
- for (Certificate certificate : chain) {
- if (!(certificate instanceof X509Certificate)) {
- throw new IOException("Unexpceted certificate type: " +
- certificate.getClass());
- }
- clientCertificateChain.add((X509Certificate) certificate);
- }
- }
- return new Pair<PrivateKey, List<X509Certificate>>(clientKey, clientCertificateChain);
- }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl b/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
deleted file mode 100644
index a6bdd5b6..0000000
--- a/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2;
-
-/**
- * Interface for Provisioning callback.
- *
- * @hide
- */
-oneway interface IProvisioningCallback
-{
- /**
- * Service to manager callback providing failure notification
- */
- void onProvisioningFailure(int status);
-
- /**
- * Service to manager callback providing Provisioning status
- */
- void onProvisioningStatus(int status);
-
- /**
- * Service to manager callback providing completion of Provisioning/Remediation flow
- */
- void onProvisioningComplete();
-}
-
diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
deleted file mode 100644
index f0a0607..0000000
--- a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
+++ /dev/null
@@ -1,270 +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.net.wifi.hotspot2;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.Uri;
-import android.net.wifi.WifiSsid;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Contained information for a Hotspot 2.0 OSU (Online Sign-Up provider).
- *
- * @hide
- */
-@SystemApi
-public final class OsuProvider implements Parcelable {
- /**
- * OSU (Online Sign-Up) method: OMA DM (Open Mobile Alliance Device Management).
- * For more info, refer to Section 8.3 of the Hotspot 2.0 Release 2 Technical Specification.
- * @hide
- */
- public static final int METHOD_OMA_DM = 0;
-
- /**
- * OSU (Online Sign-Up) method: SOAP XML SPP (Subscription Provisioning Protocol).
- * For more info, refer to Section 8.4 of the Hotspot 2.0 Release 2 Technical Specification.
- * @hide
- */
- public static final int METHOD_SOAP_XML_SPP = 1;
-
- /**
- * SSID of the network to connect for service sign-up.
- */
- private WifiSsid mOsuSsid;
-
- /**
- * Map of friendly names expressed as different language for the OSU provider.
- */
- private final Map<String, String> mFriendlyNames;
-
- /**
- * Description of the OSU provider.
- */
- private final String mServiceDescription;
-
- /**
- * URI to browse to for service sign-up.
- */
- private final Uri mServerUri;
-
- /**
- * Network Access Identifier used for authenticating with the OSU network when OSEN is used.
- */
- private final String mNetworkAccessIdentifier;
-
- /**
- * List of OSU (Online Sign-Up) method supported.
- */
- private final List<Integer> mMethodList;
-
- /** @hide */
- public OsuProvider(String osuSsid, Map<String, String> friendlyNames,
- String serviceDescription, Uri serverUri, String nai, List<Integer> methodList) {
- this(WifiSsid.createFromByteArray(osuSsid.getBytes(StandardCharsets.UTF_8)),
- friendlyNames, serviceDescription, serverUri, nai, methodList);
- }
-
- /** @hide */
- public OsuProvider(WifiSsid osuSsid, Map<String, String> friendlyNames,
- String serviceDescription, Uri serverUri, String nai, List<Integer> methodList) {
- mOsuSsid = osuSsid;
- mFriendlyNames = friendlyNames;
- mServiceDescription = serviceDescription;
- mServerUri = serverUri;
- mNetworkAccessIdentifier = nai;
- if (methodList == null) {
- mMethodList = new ArrayList<>();
- } else {
- mMethodList = new ArrayList<>(methodList);
- }
- }
-
- /**
- * Copy constructor.
- *
- * @param source The source to copy from
- * @hide
- */
- public OsuProvider(OsuProvider source) {
- if (source == null) {
- mOsuSsid = null;
- mFriendlyNames = null;
- mServiceDescription = null;
- mServerUri = null;
- mNetworkAccessIdentifier = null;
- mMethodList = new ArrayList<>();
- return;
- }
-
- mOsuSsid = source.mOsuSsid;
- mFriendlyNames = source.mFriendlyNames;
- mServiceDescription = source.mServiceDescription;
- mServerUri = source.mServerUri;
- mNetworkAccessIdentifier = source.mNetworkAccessIdentifier;
- if (source.mMethodList == null) {
- mMethodList = new ArrayList<>();
- } else {
- mMethodList = new ArrayList<>(source.mMethodList);
- }
- }
-
- /** @hide */
- public WifiSsid getOsuSsid() {
- return mOsuSsid;
- }
-
- /** @hide */
- public void setOsuSsid(WifiSsid osuSsid) {
- mOsuSsid = osuSsid;
- }
-
- /**
- * Return the friendly Name for current language from the list of friendly names of OSU
- * provider.
- *
- * The string matching the default locale will be returned if it is found, otherwise the string
- * in english or the first string in the list will be returned if english is not found.
- * A null will be returned if the list is empty.
- *
- * @return String matching the default locale, null otherwise
- */
- public @Nullable String getFriendlyName() {
- if (mFriendlyNames == null || mFriendlyNames.isEmpty()) return null;
- String lang = Locale.getDefault().getLanguage();
- String friendlyName = mFriendlyNames.get(lang);
- if (friendlyName != null) {
- return friendlyName;
- }
- friendlyName = mFriendlyNames.get("en");
- if (friendlyName != null) {
- return friendlyName;
- }
- return mFriendlyNames.get(mFriendlyNames.keySet().stream().findFirst().get());
- }
-
- /** @hide */
- public Map<String, String> getFriendlyNameList() {
- return mFriendlyNames;
- }
-
- /** @hide */
- public String getServiceDescription() {
- return mServiceDescription;
- }
-
- public @Nullable Uri getServerUri() {
- return mServerUri;
- }
-
- /** @hide */
- public String getNetworkAccessIdentifier() {
- return mNetworkAccessIdentifier;
- }
-
- /** @hide */
- public List<Integer> getMethodList() {
- return mMethodList;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(mOsuSsid, flags);
- dest.writeString(mServiceDescription);
- dest.writeParcelable(mServerUri, flags);
- dest.writeString(mNetworkAccessIdentifier);
- dest.writeList(mMethodList);
- Bundle bundle = new Bundle();
- bundle.putSerializable("friendlyNameMap", (HashMap<String, String>) mFriendlyNames);
- dest.writeBundle(bundle);
- }
-
- @Override
- public boolean equals(@Nullable Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof OsuProvider)) {
- return false;
- }
- OsuProvider that = (OsuProvider) thatObject;
- return Objects.equals(mOsuSsid, that.mOsuSsid)
- && Objects.equals(mFriendlyNames, that.mFriendlyNames)
- && TextUtils.equals(mServiceDescription, that.mServiceDescription)
- && Objects.equals(mServerUri, that.mServerUri)
- && TextUtils.equals(mNetworkAccessIdentifier, that.mNetworkAccessIdentifier)
- && Objects.equals(mMethodList, that.mMethodList);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mOsuSsid, mServiceDescription, mFriendlyNames,
- mServerUri, mNetworkAccessIdentifier, mMethodList);
- }
-
- @NonNull
- @Override
- public String toString() {
- return "OsuProvider{mOsuSsid=" + mOsuSsid
- + " mFriendlyNames=" + mFriendlyNames
- + " mServiceDescription=" + mServiceDescription
- + " mServerUri=" + mServerUri
- + " mNetworkAccessIdentifier=" + mNetworkAccessIdentifier
- + " mMethodList=" + mMethodList;
- }
-
- public static final @android.annotation.NonNull Creator<OsuProvider> CREATOR =
- new Creator<OsuProvider>() {
- @Override
- public OsuProvider createFromParcel(Parcel in) {
- WifiSsid osuSsid = in.readParcelable(null);
- String serviceDescription = in.readString();
- Uri serverUri = in.readParcelable(null);
- String nai = in.readString();
- List<Integer> methodList = new ArrayList<>();
- in.readList(methodList, null);
- Bundle bundle = in.readBundle();
- Map<String, String> friendlyNamesMap = (HashMap) bundle.getSerializable(
- "friendlyNameMap");
- return new OsuProvider(osuSsid, friendlyNamesMap, serviceDescription,
- serverUri, nai, methodList);
- }
-
- @Override
- public OsuProvider[] newArray(int size) {
- return new OsuProvider[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
deleted file mode 100644
index d1d1780..0000000
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ /dev/null
@@ -1,921 +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.net.wifi.hotspot2;
-
-import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
-import static android.net.wifi.WifiConfiguration.MeteredOverride;
-
-import android.annotation.CurrentTimeMillisLong;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.net.wifi.hotspot2.pps.Policy;
-import android.net.wifi.hotspot2.pps.UpdateParameter;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Class representing Passpoint configuration. This contains configurations specified in
- * PerProviderSubscription (PPS) Management Object (MO) tree.
- *
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- */
-public final class PasspointConfiguration implements Parcelable {
- private static final String TAG = "PasspointConfiguration";
-
- /**
- * Number of bytes for certificate SHA-256 fingerprint byte array.
- */
- private static final int CERTIFICATE_SHA256_BYTES = 32;
-
- /**
- * Maximum bytes for URL string.
- */
- private static final int MAX_URL_BYTES = 1023;
-
- /**
- * Integer value used for indicating null value in the Parcel.
- */
- private static final int NULL_VALUE = -1;
-
- /**
- * Configurations under HomeSp subtree.
- */
- private HomeSp mHomeSp = null;
-
- /**
- * Set the Home SP (Service Provider) information.
- *
- * @param homeSp The Home SP information to set to
- */
- public void setHomeSp(HomeSp homeSp) { mHomeSp = homeSp; }
- /**
- * Get the Home SP (Service Provider) information.
- *
- * @return Home SP information
- */
- public HomeSp getHomeSp() { return mHomeSp; }
-
- /**
- * Configurations under AAAServerTrustedNames subtree.
- */
- private String[] mAaaServerTrustedNames = null;
- /**
- * Set the AAA server trusted names information.
- *
- * @param aaaServerTrustedNames The AAA server trusted names information to set to
- * @hide
- */
- public void setAaaServerTrustedNames(@Nullable String[] aaaServerTrustedNames) {
- mAaaServerTrustedNames = aaaServerTrustedNames;
- }
- /**
- * Get the AAA server trusted names information.
- *
- * @return AAA server trusted names information
- * @hide
- */
- public @Nullable String[] getAaaServerTrustedNames() {
- return mAaaServerTrustedNames;
- }
-
- /**
- * Configurations under Credential subtree.
- */
- private Credential mCredential = null;
- /**
- * Set the credential information.
- *
- * @param credential The credential information to set to
- */
- public void setCredential(Credential credential) {
- mCredential = credential;
- }
- /**
- * Get the credential information.
- *
- * @return credential information
- */
- public Credential getCredential() {
- return mCredential;
- }
-
- /**
- * Configurations under Policy subtree.
- */
- private Policy mPolicy = null;
- /**
- * @hide
- */
- public void setPolicy(Policy policy) {
- mPolicy = policy;
- }
- /**
- * @hide
- */
- public Policy getPolicy() {
- return mPolicy;
- }
-
- /**
- * Meta data for performing subscription update.
- */
- private UpdateParameter mSubscriptionUpdate = null;
- /**
- * @hide
- */
- public void setSubscriptionUpdate(UpdateParameter subscriptionUpdate) {
- mSubscriptionUpdate = subscriptionUpdate;
- }
- /**
- * @hide
- */
- public UpdateParameter getSubscriptionUpdate() {
- return mSubscriptionUpdate;
- }
-
- /**
- * List of HTTPS URL for retrieving trust root certificate and the corresponding SHA-256
- * fingerprint of the certificate. The certificates are used for verifying AAA server's
- * identity during EAP authentication.
- */
- private Map<String, byte[]> mTrustRootCertList = null;
- /**
- * @hide
- */
- public void setTrustRootCertList(Map<String, byte[]> trustRootCertList) {
- mTrustRootCertList = trustRootCertList;
- }
- /**
- * @hide
- */
- public Map<String, byte[]> getTrustRootCertList() {
- return mTrustRootCertList;
- }
-
- /**
- * Set by the subscription server, updated every time the configuration is updated by
- * the subscription server.
- *
- * Use Integer.MIN_VALUE to indicate unset value.
- */
- private int mUpdateIdentifier = Integer.MIN_VALUE;
- /**
- * @hide
- */
- public void setUpdateIdentifier(int updateIdentifier) {
- mUpdateIdentifier = updateIdentifier;
- }
- /**
- * @hide
- */
- public int getUpdateIdentifier() {
- return mUpdateIdentifier;
- }
-
- /**
- * The priority of the credential.
- *
- * Use Integer.MIN_VALUE to indicate unset value.
- */
- private int mCredentialPriority = Integer.MIN_VALUE;
- /**
- * @hide
- */
- public void setCredentialPriority(int credentialPriority) {
- mCredentialPriority = credentialPriority;
- }
- /**
- * @hide
- */
- public int getCredentialPriority() {
- return mCredentialPriority;
- }
-
- /**
- * The time this subscription is created. It is in the format of number
- * of milliseconds since January 1, 1970, 00:00:00 GMT.
- *
- * Use Long.MIN_VALUE to indicate unset value.
- */
- private long mSubscriptionCreationTimeInMillis = Long.MIN_VALUE;
- /**
- * @hide
- */
- public void setSubscriptionCreationTimeInMillis(long subscriptionCreationTimeInMillis) {
- mSubscriptionCreationTimeInMillis = subscriptionCreationTimeInMillis;
- }
- /**
- * @hide
- */
- public long getSubscriptionCreationTimeInMillis() {
- return mSubscriptionCreationTimeInMillis;
- }
-
- /**
- * The time this subscription will expire. It is in the format of number
- * of milliseconds since January 1, 1970, 00:00:00 GMT.
- *
- * Use Long.MIN_VALUE to indicate unset value.
- */
- private long mSubscriptionExpirationTimeMillis = Long.MIN_VALUE;
- /**
- * @hide
- */
- public void setSubscriptionExpirationTimeInMillis(long subscriptionExpirationTimeInMillis) {
- mSubscriptionExpirationTimeMillis = subscriptionExpirationTimeInMillis;
- }
- /**
- * Utility method to get the time this subscription will expire. It is in the format of number
- * of milliseconds since January 1, 1970, 00:00:00 GMT.
- *
- * @return The time this subscription will expire, or Long.MIN_VALUE to indicate unset value
- */
- @CurrentTimeMillisLong
- public long getSubscriptionExpirationTimeMillis() {
- return mSubscriptionExpirationTimeMillis;
- }
-
- /**
- * The type of the subscription. This is defined by the provider and the value is provider
- * specific.
- */
- private String mSubscriptionType = null;
- /**
- * @hide
- */
- public void setSubscriptionType(String subscriptionType) {
- mSubscriptionType = subscriptionType;
- }
- /**
- * @hide
- */
- public String getSubscriptionType() {
- return mSubscriptionType;
- }
-
- /**
- * The time period for usage statistics accumulation. A value of zero means that usage
- * statistics are not accumulated on a periodic basis (e.g., a one-time limit for
- * “pay as you go” - PAYG service). A non-zero value specifies the usage interval in minutes.
- */
- private long mUsageLimitUsageTimePeriodInMinutes = Long.MIN_VALUE;
- /**
- * @hide
- */
- public void setUsageLimitUsageTimePeriodInMinutes(long usageLimitUsageTimePeriodInMinutes) {
- mUsageLimitUsageTimePeriodInMinutes = usageLimitUsageTimePeriodInMinutes;
- }
- /**
- * @hide
- */
- public long getUsageLimitUsageTimePeriodInMinutes() {
- return mUsageLimitUsageTimePeriodInMinutes;
- }
-
- /**
- * The time at which usage statistic accumulation begins. It is in the format of number
- * of milliseconds since January 1, 1970, 00:00:00 GMT.
- *
- * Use Long.MIN_VALUE to indicate unset value.
- */
- private long mUsageLimitStartTimeInMillis = Long.MIN_VALUE;
- /**
- * @hide
- */
- public void setUsageLimitStartTimeInMillis(long usageLimitStartTimeInMillis) {
- mUsageLimitStartTimeInMillis = usageLimitStartTimeInMillis;
- }
- /**
- * @hide
- */
- public long getUsageLimitStartTimeInMillis() {
- return mUsageLimitStartTimeInMillis;
- }
-
- /**
- * The cumulative data limit in megabytes for the {@link #usageLimitUsageTimePeriodInMinutes}.
- * A value of zero indicate unlimited data usage.
- *
- * Use Long.MIN_VALUE to indicate unset value.
- */
- private long mUsageLimitDataLimit = Long.MIN_VALUE;
- /**
- * @hide
- */
- public void setUsageLimitDataLimit(long usageLimitDataLimit) {
- mUsageLimitDataLimit = usageLimitDataLimit;
- }
- /**
- * @hide
- */
- public long getUsageLimitDataLimit() {
- return mUsageLimitDataLimit;
- }
-
- /**
- * The cumulative time limit in minutes for the {@link #usageLimitUsageTimePeriodInMinutes}.
- * A value of zero indicate unlimited time usage.
- */
- private long mUsageLimitTimeLimitInMinutes = Long.MIN_VALUE;
- /**
- * @hide
- */
- public void setUsageLimitTimeLimitInMinutes(long usageLimitTimeLimitInMinutes) {
- mUsageLimitTimeLimitInMinutes = usageLimitTimeLimitInMinutes;
- }
- /**
- * @hide
- */
- public long getUsageLimitTimeLimitInMinutes() {
- return mUsageLimitTimeLimitInMinutes;
- }
-
- /**
- * The map of OSU service provider names whose each element is presented in different
- * languages for the service provider, which is used for finding a matching
- * PasspointConfiguration with a given service provider name.
- */
- private Map<String, String> mServiceFriendlyNames = null;
-
- /**
- * @hide
- */
- public void setServiceFriendlyNames(Map<String, String> serviceFriendlyNames) {
- mServiceFriendlyNames = serviceFriendlyNames;
- }
-
- /**
- * @hide
- */
- public Map<String, String> getServiceFriendlyNames() {
- return mServiceFriendlyNames;
- }
-
- /**
- * Return the friendly Name for current language from the list of friendly names of OSU
- * provider.
- * The string matching the default locale will be returned if it is found, otherwise the
- * first string in the list will be returned. A null will be returned if the list is empty.
- *
- * @return String matching the default locale, null otherwise
- * @hide
- */
- public String getServiceFriendlyName() {
- if (mServiceFriendlyNames == null || mServiceFriendlyNames.isEmpty()) return null;
- String lang = Locale.getDefault().getLanguage();
- String friendlyName = mServiceFriendlyNames.get(lang);
- if (friendlyName != null) {
- return friendlyName;
- }
- friendlyName = mServiceFriendlyNames.get("en");
- if (friendlyName != null) {
- return friendlyName;
- }
- return mServiceFriendlyNames.get(mServiceFriendlyNames.keySet().stream().findFirst().get());
- }
-
- /**
- * The carrier ID identifies the operator who provides this network configuration.
- * see {@link TelephonyManager#getSimCarrierId()}
- */
- private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
-
- /**
- * Set the carrier ID associated with current configuration.
- * @param carrierId {@code mCarrierId}
- * @hide
- */
- public void setCarrierId(int carrierId) {
- this.mCarrierId = carrierId;
- }
-
- /**
- * Get the carrier ID associated with current configuration.
- * @return {@code mCarrierId}
- * @hide
- */
- public int getCarrierId() {
- return mCarrierId;
- }
-
- /**
- * The auto-join configuration specifies whether or not the Passpoint Configuration is
- * considered for auto-connection. If true then yes, if false then it isn't considered as part
- * of auto-connection - but can still be manually connected to.
- */
- private boolean mIsAutojoinEnabled = true;
-
- /**
- * The mac randomization setting specifies whether a randomized or device MAC address will
- * be used to connect to the passpoint network. If true, a randomized MAC will be used.
- * Otherwise, the device MAC address will be used.
- */
- private boolean mIsMacRandomizationEnabled = true;
-
- /**
- * Indicates if the end user has expressed an explicit opinion about the
- * meteredness of this network, such as through the Settings app.
- * This value is one of {@link #METERED_OVERRIDE_NONE}, {@link #METERED_OVERRIDE_METERED},
- * or {@link #METERED_OVERRIDE_NOT_METERED}.
- * <p>
- * This should always override any values from {@link WifiInfo#getMeteredHint()}.
- *
- * By default this field is set to {@link #METERED_OVERRIDE_NONE}.
- */
- private int mMeteredOverride = METERED_OVERRIDE_NONE;
-
- /**
- * Configures the auto-association status of this Passpoint configuration. A value of true
- * indicates that the configuration will be considered for auto-connection, a value of false
- * indicates that only manual connection will work - the framework will not auto-associate to
- * this Passpoint network.
- *
- * @param autojoinEnabled true to be considered for framework auto-connection, false otherwise.
- * @hide
- */
- public void setAutojoinEnabled(boolean autojoinEnabled) {
- mIsAutojoinEnabled = autojoinEnabled;
- }
-
- /**
- * Configures the MAC randomization setting for this Passpoint configuration.
- * If set to true, the framework will use a randomized MAC address to connect to this Passpoint
- * network. Otherwise, the framework will use the device MAC address.
- *
- * @param enabled true to use randomized MAC address, false to use device MAC address.
- * @hide
- */
- public void setMacRandomizationEnabled(boolean enabled) {
- mIsMacRandomizationEnabled = enabled;
- }
-
- /**
- * Sets the metered override setting for this Passpoint configuration.
- *
- * @param meteredOverride One of the values in {@link MeteredOverride}
- * @hide
- */
- public void setMeteredOverride(@MeteredOverride int meteredOverride) {
- mMeteredOverride = meteredOverride;
- }
-
- /**
- * Indicates whether the Passpoint configuration may be auto-connected to by the framework. A
- * value of true indicates that auto-connection can happen, a value of false indicates that it
- * cannot. However, even when auto-connection is not possible manual connection by the user is
- * possible.
- *
- * @return the auto-join configuration: true for auto-connection (or join) enabled, false
- * otherwise.
- * @hide
- */
- @SystemApi
- public boolean isAutojoinEnabled() {
- return mIsAutojoinEnabled;
- }
-
- /**
- * Indicates whether the user chose this configuration to be treated as metered or not.
- *
- * @return One of the values in {@link MeteredOverride}
- * @hide
- */
- @SystemApi
- @MeteredOverride
- public int getMeteredOverride() {
- return mMeteredOverride;
- }
-
- /**
- * Indicates whether a randomized MAC address or device MAC address will be used for
- * connections to this Passpoint network. If true, a randomized MAC address will be used.
- * Otherwise, the device MAC address will be used.
- *
- * @return true for MAC randomization enabled. False for disabled.
- * @hide
- */
- @SystemApi
- public boolean isMacRandomizationEnabled() {
- return mIsMacRandomizationEnabled;
- }
-
- /**
- * Constructor for creating PasspointConfiguration with default values.
- */
- public PasspointConfiguration() {}
-
- /**
- * Copy constructor.
- *
- * @param source The source to copy from
- */
- public PasspointConfiguration(PasspointConfiguration source) {
- if (source == null) {
- return;
- }
-
- if (source.mHomeSp != null) {
- mHomeSp = new HomeSp(source.mHomeSp);
- }
- if (source.mCredential != null) {
- mCredential = new Credential(source.mCredential);
- }
- if (source.mPolicy != null) {
- mPolicy = new Policy(source.mPolicy);
- }
- if (source.mTrustRootCertList != null) {
- mTrustRootCertList = Collections.unmodifiableMap(source.mTrustRootCertList);
- }
- if (source.mSubscriptionUpdate != null) {
- mSubscriptionUpdate = new UpdateParameter(source.mSubscriptionUpdate);
- }
- mUpdateIdentifier = source.mUpdateIdentifier;
- mCredentialPriority = source.mCredentialPriority;
- mSubscriptionCreationTimeInMillis = source.mSubscriptionCreationTimeInMillis;
- mSubscriptionExpirationTimeMillis = source.mSubscriptionExpirationTimeMillis;
- mSubscriptionType = source.mSubscriptionType;
- mUsageLimitDataLimit = source.mUsageLimitDataLimit;
- mUsageLimitStartTimeInMillis = source.mUsageLimitStartTimeInMillis;
- mUsageLimitTimeLimitInMinutes = source.mUsageLimitTimeLimitInMinutes;
- mUsageLimitUsageTimePeriodInMinutes = source.mUsageLimitUsageTimePeriodInMinutes;
- mServiceFriendlyNames = source.mServiceFriendlyNames;
- mAaaServerTrustedNames = source.mAaaServerTrustedNames;
- mCarrierId = source.mCarrierId;
- mIsAutojoinEnabled = source.mIsAutojoinEnabled;
- mIsMacRandomizationEnabled = source.mIsMacRandomizationEnabled;
- mMeteredOverride = source.mMeteredOverride;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(mHomeSp, flags);
- dest.writeParcelable(mCredential, flags);
- dest.writeParcelable(mPolicy, flags);
- dest.writeParcelable(mSubscriptionUpdate, flags);
- writeTrustRootCerts(dest, mTrustRootCertList);
- dest.writeInt(mUpdateIdentifier);
- dest.writeInt(mCredentialPriority);
- dest.writeLong(mSubscriptionCreationTimeInMillis);
- dest.writeLong(mSubscriptionExpirationTimeMillis);
- dest.writeString(mSubscriptionType);
- dest.writeLong(mUsageLimitUsageTimePeriodInMinutes);
- dest.writeLong(mUsageLimitStartTimeInMillis);
- dest.writeLong(mUsageLimitDataLimit);
- dest.writeLong(mUsageLimitTimeLimitInMinutes);
- dest.writeStringArray(mAaaServerTrustedNames);
- Bundle bundle = new Bundle();
- bundle.putSerializable("serviceFriendlyNames",
- (HashMap<String, String>) mServiceFriendlyNames);
- dest.writeBundle(bundle);
- dest.writeInt(mCarrierId);
- dest.writeBoolean(mIsAutojoinEnabled);
- dest.writeBoolean(mIsMacRandomizationEnabled);
- dest.writeInt(mMeteredOverride);
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof PasspointConfiguration)) {
- return false;
- }
- PasspointConfiguration that = (PasspointConfiguration) thatObject;
- return (mHomeSp == null ? that.mHomeSp == null : mHomeSp.equals(that.mHomeSp))
- && (mAaaServerTrustedNames == null ? that.mAaaServerTrustedNames == null
- : Arrays.equals(mAaaServerTrustedNames, that.mAaaServerTrustedNames))
- && (mCredential == null ? that.mCredential == null
- : mCredential.equals(that.mCredential))
- && (mPolicy == null ? that.mPolicy == null : mPolicy.equals(that.mPolicy))
- && (mSubscriptionUpdate == null ? that.mSubscriptionUpdate == null
- : mSubscriptionUpdate.equals(that.mSubscriptionUpdate))
- && isTrustRootCertListEquals(mTrustRootCertList, that.mTrustRootCertList)
- && mUpdateIdentifier == that.mUpdateIdentifier
- && mCredentialPriority == that.mCredentialPriority
- && mSubscriptionCreationTimeInMillis == that.mSubscriptionCreationTimeInMillis
- && mSubscriptionExpirationTimeMillis == that.mSubscriptionExpirationTimeMillis
- && TextUtils.equals(mSubscriptionType, that.mSubscriptionType)
- && mUsageLimitUsageTimePeriodInMinutes == that.mUsageLimitUsageTimePeriodInMinutes
- && mUsageLimitStartTimeInMillis == that.mUsageLimitStartTimeInMillis
- && mUsageLimitDataLimit == that.mUsageLimitDataLimit
- && mUsageLimitTimeLimitInMinutes == that.mUsageLimitTimeLimitInMinutes
- && mCarrierId == that.mCarrierId
- && mIsAutojoinEnabled == that.mIsAutojoinEnabled
- && mIsMacRandomizationEnabled == that.mIsMacRandomizationEnabled
- && mMeteredOverride == that.mMeteredOverride
- && (mServiceFriendlyNames == null ? that.mServiceFriendlyNames == null
- : mServiceFriendlyNames.equals(that.mServiceFriendlyNames));
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mHomeSp, mCredential, mPolicy, mSubscriptionUpdate, mTrustRootCertList,
- mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMillis,
- mSubscriptionExpirationTimeMillis, mUsageLimitUsageTimePeriodInMinutes,
- mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes,
- mServiceFriendlyNames, mCarrierId, mIsAutojoinEnabled, mIsMacRandomizationEnabled,
- mMeteredOverride);
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("UpdateIdentifier: ").append(mUpdateIdentifier).append("\n");
- builder.append("CredentialPriority: ").append(mCredentialPriority).append("\n");
- builder.append("SubscriptionCreationTime: ").append(
- mSubscriptionCreationTimeInMillis != Long.MIN_VALUE
- ? new Date(mSubscriptionCreationTimeInMillis) : "Not specified").append("\n");
- builder.append("SubscriptionExpirationTime: ").append(
- mSubscriptionExpirationTimeMillis != Long.MIN_VALUE
- ? new Date(mSubscriptionExpirationTimeMillis) : "Not specified").append("\n");
- builder.append("UsageLimitStartTime: ").append(mUsageLimitStartTimeInMillis != Long.MIN_VALUE
- ? new Date(mUsageLimitStartTimeInMillis) : "Not specified").append("\n");
- builder.append("UsageTimePeriod: ").append(mUsageLimitUsageTimePeriodInMinutes)
- .append("\n");
- builder.append("UsageLimitDataLimit: ").append(mUsageLimitDataLimit).append("\n");
- builder.append("UsageLimitTimeLimit: ").append(mUsageLimitTimeLimitInMinutes).append("\n");
- builder.append("Provisioned by a subscription server: ")
- .append(isOsuProvisioned() ? "Yes" : "No").append("\n");
- if (mHomeSp != null) {
- builder.append("HomeSP Begin ---\n");
- builder.append(mHomeSp);
- builder.append("HomeSP End ---\n");
- }
- if (mCredential != null) {
- builder.append("Credential Begin ---\n");
- builder.append(mCredential);
- builder.append("Credential End ---\n");
- }
- if (mPolicy != null) {
- builder.append("Policy Begin ---\n");
- builder.append(mPolicy);
- builder.append("Policy End ---\n");
- }
- if (mSubscriptionUpdate != null) {
- builder.append("SubscriptionUpdate Begin ---\n");
- builder.append(mSubscriptionUpdate);
- builder.append("SubscriptionUpdate End ---\n");
- }
- if (mTrustRootCertList != null) {
- builder.append("TrustRootCertServers: ").append(mTrustRootCertList.keySet())
- .append("\n");
- }
- if (mAaaServerTrustedNames != null) {
- builder.append("AAAServerTrustedNames: ")
- .append(String.join(";", mAaaServerTrustedNames)).append("\n");
- }
- if (mServiceFriendlyNames != null) {
- builder.append("ServiceFriendlyNames: ").append(mServiceFriendlyNames);
- }
- builder.append("CarrierId:" + mCarrierId);
- builder.append("IsAutojoinEnabled:" + mIsAutojoinEnabled);
- builder.append("mIsMacRandomizationEnabled:" + mIsMacRandomizationEnabled);
- builder.append("mMeteredOverride:" + mMeteredOverride);
- return builder.toString();
- }
-
- /**
- * Validate the R1 configuration data.
- *
- * @return true on success or false on failure
- * @hide
- */
- public boolean validate() {
- // Optional: PerProviderSubscription/<X+>/SubscriptionUpdate
- if (mSubscriptionUpdate != null && !mSubscriptionUpdate.validate()) {
- return false;
- }
- return validateForCommonR1andR2();
- }
-
- /**
- * Validate the R2 configuration data.
- *
- * @return true on success or false on failure
- * @hide
- */
- public boolean validateForR2() {
- // Required: PerProviderSubscription/UpdateIdentifier
- if (mUpdateIdentifier == Integer.MIN_VALUE) {
- return false;
- }
-
- // Required: PerProviderSubscription/<X+>/SubscriptionUpdate
- if (mSubscriptionUpdate == null || !mSubscriptionUpdate.validate()) {
- return false;
- }
- return validateForCommonR1andR2();
- }
-
- private boolean validateForCommonR1andR2() {
- // Required: PerProviderSubscription/<X+>/HomeSP
- if (mHomeSp == null || !mHomeSp.validate()) {
- return false;
- }
-
- // Required: PerProviderSubscription/<X+>/Credential
- if (mCredential == null || !mCredential.validate()) {
- return false;
- }
-
- // Optional: PerProviderSubscription/<X+>/Policy
- if (mPolicy != null && !mPolicy.validate()) {
- return false;
- }
-
- if (mTrustRootCertList != null) {
- for (Map.Entry<String, byte[]> entry : mTrustRootCertList.entrySet()) {
- String url = entry.getKey();
- byte[] certFingerprint = entry.getValue();
- if (TextUtils.isEmpty(url)) {
- Log.d(TAG, "Empty URL");
- return false;
- }
- if (url.getBytes(StandardCharsets.UTF_8).length > MAX_URL_BYTES) {
- Log.d(TAG, "URL bytes exceeded the max: "
- + url.getBytes(StandardCharsets.UTF_8).length);
- return false;
- }
-
- if (certFingerprint == null) {
- Log.d(TAG, "Fingerprint not specified");
- return false;
- }
- if (certFingerprint.length != CERTIFICATE_SHA256_BYTES) {
- Log.d(TAG, "Incorrect size of trust root certificate SHA-256 fingerprint: "
- + certFingerprint.length);
- return false;
- }
- }
- }
- return true;
- }
-
- public static final @android.annotation.NonNull Creator<PasspointConfiguration> CREATOR =
- new Creator<PasspointConfiguration>() {
- @Override
- public PasspointConfiguration createFromParcel(Parcel in) {
- PasspointConfiguration config = new PasspointConfiguration();
- config.setHomeSp(in.readParcelable(null));
- config.setCredential(in.readParcelable(null));
- config.setPolicy(in.readParcelable(null));
- config.setSubscriptionUpdate(in.readParcelable(null));
- config.setTrustRootCertList(readTrustRootCerts(in));
- config.setUpdateIdentifier(in.readInt());
- config.setCredentialPriority(in.readInt());
- config.setSubscriptionCreationTimeInMillis(in.readLong());
- config.setSubscriptionExpirationTimeInMillis(in.readLong());
- config.setSubscriptionType(in.readString());
- config.setUsageLimitUsageTimePeriodInMinutes(in.readLong());
- config.setUsageLimitStartTimeInMillis(in.readLong());
- config.setUsageLimitDataLimit(in.readLong());
- config.setUsageLimitTimeLimitInMinutes(in.readLong());
- config.setAaaServerTrustedNames(in.createStringArray());
- Bundle bundle = in.readBundle();
- Map<String, String> friendlyNamesMap = (HashMap) bundle.getSerializable(
- "serviceFriendlyNames");
- config.setServiceFriendlyNames(friendlyNamesMap);
- config.mCarrierId = in.readInt();
- config.mIsAutojoinEnabled = in.readBoolean();
- config.mIsMacRandomizationEnabled = in.readBoolean();
- config.mMeteredOverride = in.readInt();
- return config;
- }
-
- @Override
- public PasspointConfiguration[] newArray(int size) {
- return new PasspointConfiguration[size];
- }
-
- /**
- * Helper function for reading trust root certificate info list from a Parcel.
- *
- * @param in The Parcel to read from
- * @return The list of trust root certificate URL with the corresponding certificate
- * fingerprint
- */
- private Map<String, byte[]> readTrustRootCerts(Parcel in) {
- int size = in.readInt();
- if (size == NULL_VALUE) {
- return null;
- }
- Map<String, byte[]> trustRootCerts = new HashMap<>(size);
- for (int i = 0; i < size; i++) {
- String key = in.readString();
- byte[] value = in.createByteArray();
- trustRootCerts.put(key, value);
- }
- return trustRootCerts;
- }
- };
-
- /**
- * Helper function for writing trust root certificate information list.
- *
- * @param dest The Parcel to write to
- * @param trustRootCerts The list of trust root certificate URL with the corresponding
- * certificate fingerprint
- */
- private static void writeTrustRootCerts(Parcel dest, Map<String, byte[]> trustRootCerts) {
- if (trustRootCerts == null) {
- dest.writeInt(NULL_VALUE);
- return;
- }
- dest.writeInt(trustRootCerts.size());
- for (Map.Entry<String, byte[]> entry : trustRootCerts.entrySet()) {
- dest.writeString(entry.getKey());
- dest.writeByteArray(entry.getValue());
- }
- }
-
- /**
- * Helper function for comparing two trust root certificate list. Cannot use Map#equals
- * method since the value type (byte[]) doesn't override equals method.
- *
- * @param list1 The first trust root certificate list
- * @param list2 The second trust root certificate list
- * @return true if the two list are equal
- */
- private static boolean isTrustRootCertListEquals(Map<String, byte[]> list1,
- Map<String, byte[]> list2) {
- if (list1 == null || list2 == null) {
- return list1 == list2;
- }
- if (list1.size() != list2.size()) {
- return false;
- }
- for (Map.Entry<String, byte[]> entry : list1.entrySet()) {
- if (!Arrays.equals(entry.getValue(), list2.get(entry.getKey()))) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Indicates if the Passpoint Configuration was provisioned by a subscription (OSU) server,
- * which means that it's an R2 (or R3) profile.
- *
- * @return true if the Passpoint Configuration was provisioned by a subscription server.
- */
- public boolean isOsuProvisioned() {
- return getUpdateIdentifier() != Integer.MIN_VALUE;
- }
-
- /**
- * Get a unique identifier for a PasspointConfiguration object. The identifier depends on the
- * configuration that identify the service provider under the HomeSp subtree, and on the
- * credential configuration under the Credential subtree.
- * The method throws an {@link IllegalStateException} if the configuration under HomeSp subtree
- * or the configuration under Credential subtree are not initialized.
- *
- * @return A unique identifier
- */
- public @NonNull String getUniqueId() {
- if (mCredential == null || mHomeSp == null || TextUtils.isEmpty(mHomeSp.getFqdn())) {
- throw new IllegalStateException("Credential or HomeSP are not initialized");
- }
-
- StringBuilder sb = new StringBuilder();
- sb.append(String.format("%s_%x%x", mHomeSp.getFqdn(), mHomeSp.getUniqueId(),
- mCredential.getUniqueId()));
- return sb.toString();
- }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
deleted file mode 100644
index 1d499b6..0000000
--- a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2;
-
-import android.annotation.SystemApi;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-
-/**
- * Base class for provisioning callbacks. Should be extended by applications and set when calling
- * {@link WifiManager#startSubscriptionProvisioning(OsuProvider, ProvisioningCallback, Handler)}.
- *
- * @hide
- */
-@SystemApi
-public abstract class ProvisioningCallback {
-
- /**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- */
- public static final int OSU_FAILURE_AP_CONNECTION = 1;
-
- /**
- * The reason code for invalid server URL address.
- */
- public static final int OSU_FAILURE_SERVER_URL_INVALID = 2;
-
- /**
- * The reason code for provisioning failure due to connection failure to the server.
- */
- public static final int OSU_FAILURE_SERVER_CONNECTION = 3;
-
- /**
- * The reason code for provisioning failure due to invalid server certificate.
- */
- public static final int OSU_FAILURE_SERVER_VALIDATION = 4;
-
- /**
- * The reason code for provisioning failure due to invalid service provider.
- */
- public static final int OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION = 5;
-
- /**
- * The reason code for provisioning failure when a provisioning flow is aborted.
- */
- public static final int OSU_FAILURE_PROVISIONING_ABORTED = 6;
-
- /**
- * The reason code for provisioning failure when a provisioning flow is not possible.
- */
- public static final int OSU_FAILURE_PROVISIONING_NOT_AVAILABLE = 7;
-
- /**
- * The reason code for provisioning failure due to invalid web url format for an OSU web page.
- */
- public static final int OSU_FAILURE_INVALID_URL_FORMAT_FOR_OSU = 8;
-
- /**
- * The reason code for provisioning failure when a command received is not the expected command
- * type.
- */
- public static final int OSU_FAILURE_UNEXPECTED_COMMAND_TYPE = 9;
-
- /**
- * The reason code for provisioning failure when a SOAP message is not the expected message
- * type.
- */
- public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE = 10;
-
- /**
- * The reason code for provisioning failure when a SOAP message exchange fails.
- */
- public static final int OSU_FAILURE_SOAP_MESSAGE_EXCHANGE = 11;
-
- /**
- * The reason code for provisioning failure when a redirect listener fails to start.
- */
- public static final int OSU_FAILURE_START_REDIRECT_LISTENER = 12;
-
- /**
- * The reason code for provisioning failure when a redirect listener timed out to receive a HTTP
- * redirect response.
- */
- public static final int OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER = 13;
-
- /**
- * The reason code for provisioning failure when there is no OSU activity to listen to
- * {@link WifiManager#ACTION_PASSPOINT_LAUNCH_OSU_VIEW} intent.
- */
- public static final int OSU_FAILURE_NO_OSU_ACTIVITY_FOUND = 14;
-
- /**
- * The reason code for provisioning failure when the status of a SOAP message is not the
- * expected message status.
- */
- public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS = 15;
-
- /**
- * The reason code for provisioning failure when there is no PPS MO.
- * MO.
- */
- public static final int OSU_FAILURE_NO_PPS_MO = 16;
-
- /**
- * The reason code for provisioning failure when there is no AAAServerTrustRoot node in a PPS
- * MO.
- */
- public static final int OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE = 17;
-
- /**
- * The reason code for provisioning failure when there is no TrustRoot node for remediation
- * server in a PPS MO.
- */
- public static final int OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE = 18;
-
- /**
- * The reason code for provisioning failure when there is no TrustRoot node for policy server in
- * a PPS MO.
- */
- public static final int OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE = 19;
-
- /**
- * The reason code for provisioning failure when failing to retrieve trust root certificates
- * used for validating server certificate for AAA, Remediation and Policy server.
- */
- public static final int OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES = 20;
-
- /**
- * The reason code for provisioning failure when there is no trust root certificate for AAA
- * server.
- */
- public static final int OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE = 21;
-
- /**
- * The reason code for provisioning failure when a {@link PasspointConfiguration} is failed to
- * install.
- */
- public static final int OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION = 22;
-
- /**
- * The reason code for provisioning failure when an {@link OsuProvider} is not found for
- * provisioning.
- */
- public static final int OSU_FAILURE_OSU_PROVIDER_NOT_FOUND = 23;
-
- /**
- * The status code for provisioning flow to indicate connecting to OSU AP
- */
- public static final int OSU_STATUS_AP_CONNECTING = 1;
-
- /**
- * The status code for provisioning flow to indicate the OSU AP is connected.
- */
- public static final int OSU_STATUS_AP_CONNECTED = 2;
-
- /**
- * The status code for provisioning flow to indicate connecting to the server.
- */
- public static final int OSU_STATUS_SERVER_CONNECTING = 3;
-
- /**
- * The status code for provisioning flow to indicate the server certificate is validated.
- */
- public static final int OSU_STATUS_SERVER_VALIDATED = 4;
-
- /**
- * The status code for provisioning flow to indicate the server is connected
- */
- public static final int OSU_STATUS_SERVER_CONNECTED = 5;
-
- /**
- * The status code for provisioning flow to indicate starting the first SOAP exchange.
- */
- public static final int OSU_STATUS_INIT_SOAP_EXCHANGE = 6;
-
- /**
- * The status code for provisioning flow to indicate waiting for a HTTP redirect response.
- */
- public static final int OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE = 7;
-
- /**
- * The status code for provisioning flow to indicate a HTTP redirect response is received.
- */
- public static final int OSU_STATUS_REDIRECT_RESPONSE_RECEIVED = 8;
-
- /**
- * The status code for provisioning flow to indicate starting the second SOAP exchange.
- */
- public static final int OSU_STATUS_SECOND_SOAP_EXCHANGE = 9;
-
- /**
- * The status code for provisioning flow to indicate starting the third SOAP exchange.
- */
- public static final int OSU_STATUS_THIRD_SOAP_EXCHANGE = 10;
-
- /**
- * The status code for provisioning flow to indicate starting a step retrieving trust root
- * certs.
- */
- public static final int OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS = 11;
-
- /**
- * Provisioning status for OSU failure
- *
- * @param status indicates error condition
- */
- public abstract void onProvisioningFailure(int status);
-
- /**
- * Provisioning status when OSU is in progress
- *
- * @param status indicates status of OSU flow
- */
- public abstract void onProvisioningStatus(int status);
-
- /**
- * Provisioning complete when provisioning/remediation flow completes
- */
- public abstract void onProvisioningComplete();
-}
-
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
deleted file mode 100644
index ae60ed4..0000000
--- a/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
+++ /dev/null
@@ -1,1787 +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.net.wifi.hotspot2.omadm;
-
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.net.wifi.hotspot2.pps.Policy;
-import android.net.wifi.hotspot2.pps.UpdateParameter;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Utility class for converting OMA-DM (Open Mobile Alliance's Device Management)
- * PPS-MO (PerProviderSubscription Management Object) XML tree to a
- * {@link PasspointConfiguration} object.
- *
- * Currently this only supports PerProviderSubscription/HomeSP and
- * PerProviderSubscription/Credential subtree for Hotspot 2.0 Release 1 support.
- *
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- *
- * Below is a sample XML string for a Release 1 PPS MO tree:
- *
- * <MgmtTree xmlns="syncml:dmddf1.2">
- * <VerDTD>1.2</VerDTD>
- * <Node>
- * <NodeName>PerProviderSubscription</NodeName>
- * <RTProperties>
- * <Type>
- * <DDFName>urn:wfa:mo:hotspot2dot0perprovidersubscription:1.0</DDFName>
- * </Type>
- * </RTProperties>
- * <Node>
- * <NodeName>i001</NodeName>
- * <Node>
- * <NodeName>HomeSP</NodeName>
- * <Node>
- * <NodeName>FriendlyName</NodeName>
- * <Value>Century House</Value>
- * </Node>
- * <Node>
- * <NodeName>FQDN</NodeName>
- * <Value>mi6.co.uk</Value>
- * </Node>
- * <Node>
- * <NodeName>RoamingConsortiumOI</NodeName>
- * <Value>112233,445566</Value>
- * </Node>
- * </Node>
- * <Node>
- * <NodeName>Credential</NodeName>
- * <Node>
- * <NodeName>Realm</NodeName>
- * <Value>shaken.stirred.com</Value>
- * </Node>
- * <Node>
- * <NodeName>UsernamePassword</NodeName>
- * <Node>
- * <NodeName>Username</NodeName>
- * <Value>james</Value>
- * </Node>
- * <Node>
- * <NodeName>Password</NodeName>
- * <Value>Ym9uZDAwNw==</Value>
- * </Node>
- * <Node>
- * <NodeName>EAPMethod</NodeName>
- * <Node>
- * <NodeName>EAPType</NodeName>
- * <Value>21</Value>
- * </Node>
- * <Node>
- * <NodeName>InnerMethod</NodeName>
- * <Value>MS-CHAP-V2</Value>
- * </Node>
- * </Node>
- * </Node>
- * </Node>
- * </Node>
- * </Node>
- * </MgmtTree>
- */
-public final class PpsMoParser {
- private static final String TAG = "PpsMoParser";
-
- /**
- * XML tags expected in the PPS MO (PerProviderSubscription Management Object) XML tree.
- */
- private static final String TAG_MANAGEMENT_TREE = "MgmtTree";
- private static final String TAG_VER_DTD = "VerDTD";
- private static final String TAG_NODE = "Node";
- private static final String TAG_NODE_NAME = "NodeName";
- private static final String TAG_RT_PROPERTIES = "RTProperties";
- private static final String TAG_TYPE = "Type";
- private static final String TAG_DDF_NAME = "DDFName";
- private static final String TAG_VALUE = "Value";
-
- /**
- * Name for PerProviderSubscription node.
- */
- private static final String NODE_PER_PROVIDER_SUBSCRIPTION = "PerProviderSubscription";
-
- /**
- * Fields under PerProviderSubscription.
- */
- private static final String NODE_UPDATE_IDENTIFIER = "UpdateIdentifier";
- private static final String NODE_AAA_SERVER_TRUST_ROOT = "AAAServerTrustRoot";
- private static final String NODE_SUBSCRIPTION_UPDATE = "SubscriptionUpdate";
- private static final String NODE_SUBSCRIPTION_PARAMETER = "SubscriptionParameters";
- private static final String NODE_TYPE_OF_SUBSCRIPTION = "TypeOfSubscription";
- private static final String NODE_USAGE_LIMITS = "UsageLimits";
- private static final String NODE_DATA_LIMIT = "DataLimit";
- private static final String NODE_START_DATE = "StartDate";
- private static final String NODE_TIME_LIMIT = "TimeLimit";
- private static final String NODE_USAGE_TIME_PERIOD = "UsageTimePeriod";
- private static final String NODE_CREDENTIAL_PRIORITY = "CredentialPriority";
- private static final String NODE_EXTENSION = "Extension";
-
- /**
- * Fields under Extension/Android subtree.
- */
- /*
- * This node is used to put Android specific extension nodes and must be put
- * under "Extension" node. Nodes with unknown names are allowed under this subtree.
- * If there is any new node added in later release, it won't break older release parsing.
- * <p>
- * Ex:
- * <Node>
- * <NodeName>Extension</NodeName>
- * <Node>
- * <NodeName>Android</NodeName>
- * <Node>
- * <NodeName>AndroidSpecificAttribute</NodeName>
- * <Value>AndroidSpecificValue</Value>
- * </Node>
- * <Node>
- * <NodeName>AndroidSpecificAttribute2</NodeName>
- * <Value>AndroidSpecificValue2</Value>
- * </Node>
- * </Node>
- * </Node>
- */
- private static final String NODE_VENDOR_ANDROID = "Android";
- /*
- * This node describes AAA server trusted names. The trusted name must be put in
- * a leaf named "FQDN". More than one trusted names can be provided by using
- * semicolons to separate the strings (e.g., example.org;example.com).
- * <p>
- * Ex:
- * <Node>
- * <NodeName>AAAServerTrustedNames</NodeName>
- * <Node>
- * <NodeName>FQDN</NodeName>
- * <Value>trusted.com;auth.net</Value>
- * </Node>
- * <Node>
- */
- private static final String NODE_AAA_SERVER_TRUSTED_NAMES = "AAAServerTrustedNames";
-
- /**
- * Fields under HomeSP subtree.
- */
- private static final String NODE_HOMESP = "HomeSP";
- private static final String NODE_FQDN = "FQDN";
- private static final String NODE_FRIENDLY_NAME = "FriendlyName";
- private static final String NODE_ROAMING_CONSORTIUM_OI = "RoamingConsortiumOI";
- private static final String NODE_NETWORK_ID = "NetworkID";
- private static final String NODE_SSID = "SSID";
- private static final String NODE_HESSID = "HESSID";
- private static final String NODE_ICON_URL = "IconURL";
- private static final String NODE_HOME_OI_LIST = "HomeOIList";
- private static final String NODE_HOME_OI = "HomeOI";
- private static final String NODE_HOME_OI_REQUIRED = "HomeOIRequired";
- private static final String NODE_OTHER_HOME_PARTNERS = "OtherHomePartners";
-
- /**
- * Fields under Credential subtree.
- */
- private static final String NODE_CREDENTIAL = "Credential";
- private static final String NODE_CREATION_DATE = "CreationDate";
- private static final String NODE_EXPIRATION_DATE = "ExpirationDate";
- private static final String NODE_USERNAME_PASSWORD = "UsernamePassword";
- private static final String NODE_USERNAME = "Username";
- private static final String NODE_PASSWORD = "Password";
- private static final String NODE_MACHINE_MANAGED = "MachineManaged";
- private static final String NODE_SOFT_TOKEN_APP = "SoftTokenApp";
- private static final String NODE_ABLE_TO_SHARE = "AbleToShare";
- private static final String NODE_EAP_METHOD = "EAPMethod";
- private static final String NODE_EAP_TYPE = "EAPType";
- private static final String NODE_VENDOR_ID = "VendorId";
- private static final String NODE_VENDOR_TYPE = "VendorType";
- private static final String NODE_INNER_EAP_TYPE = "InnerEAPType";
- private static final String NODE_INNER_VENDOR_ID = "InnerVendorID";
- private static final String NODE_INNER_VENDOR_TYPE = "InnerVendorType";
- private static final String NODE_INNER_METHOD = "InnerMethod";
- private static final String NODE_DIGITAL_CERTIFICATE = "DigitalCertificate";
- private static final String NODE_CERTIFICATE_TYPE = "CertificateType";
- private static final String NODE_CERT_SHA256_FINGERPRINT = "CertSHA256Fingerprint";
- private static final String NODE_REALM = "Realm";
- private static final String NODE_SIM = "SIM";
- private static final String NODE_SIM_IMSI = "IMSI";
- private static final String NODE_CHECK_AAA_SERVER_CERT_STATUS = "CheckAAAServerCertStatus";
-
- /**
- * Fields under Policy subtree.
- */
- private static final String NODE_POLICY = "Policy";
- private static final String NODE_PREFERRED_ROAMING_PARTNER_LIST =
- "PreferredRoamingPartnerList";
- private static final String NODE_FQDN_MATCH = "FQDN_Match";
- private static final String NODE_PRIORITY = "Priority";
- private static final String NODE_COUNTRY = "Country";
- private static final String NODE_MIN_BACKHAUL_THRESHOLD = "MinBackhaulThreshold";
- private static final String NODE_NETWORK_TYPE = "NetworkType";
- private static final String NODE_DOWNLINK_BANDWIDTH = "DLBandwidth";
- private static final String NODE_UPLINK_BANDWIDTH = "ULBandwidth";
- private static final String NODE_POLICY_UPDATE = "PolicyUpdate";
- private static final String NODE_UPDATE_INTERVAL = "UpdateInterval";
- private static final String NODE_UPDATE_METHOD = "UpdateMethod";
- private static final String NODE_RESTRICTION = "Restriction";
- private static final String NODE_URI = "URI";
- private static final String NODE_TRUST_ROOT = "TrustRoot";
- private static final String NODE_CERT_URL = "CertURL";
- private static final String NODE_SP_EXCLUSION_LIST = "SPExclusionList";
- private static final String NODE_REQUIRED_PROTO_PORT_TUPLE = "RequiredProtoPortTuple";
- private static final String NODE_IP_PROTOCOL = "IPProtocol";
- private static final String NODE_PORT_NUMBER = "PortNumber";
- private static final String NODE_MAXIMUM_BSS_LOAD_VALUE = "MaximumBSSLoadValue";
- private static final String NODE_OTHER = "Other";
-
- /**
- * URN (Unique Resource Name) for PerProviderSubscription Management Object Tree.
- */
- private static final String PPS_MO_URN =
- "urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0";
-
- /**
- * Exception for generic parsing errors.
- */
- private static class ParsingException extends Exception {
- public ParsingException(String message) {
- super(message);
- }
- }
-
- /**
- * Class representing a node within the PerProviderSubscription tree.
- * This is used to flatten out and eliminate the extra layering in the XMLNode tree,
- * to make the data parsing easier and cleaner.
- *
- * A PPSNode can be an internal or a leaf node, but not both.
- *
- */
- private static abstract class PPSNode {
- private final String mName;
- public PPSNode(String name) {
- mName = name;
- }
-
- /**
- * @return the name of the node
- */
- public String getName() {
- return mName;
- }
-
- /**
- * Applies for internal node only.
- *
- * @return the list of children nodes.
- */
- public abstract List<PPSNode> getChildren();
-
- /**
- * Applies for leaf node only.
- *
- * @return the string value of the node
- */
- public abstract String getValue();
-
- /**
- * @return a flag indicating if this is a leaf or an internal node
- */
- public abstract boolean isLeaf();
- }
-
- /**
- * Class representing a leaf node in a PPS (PerProviderSubscription) tree.
- */
- private static class LeafNode extends PPSNode {
- private final String mValue;
- public LeafNode(String nodeName, String value) {
- super(nodeName);
- mValue = value;
- }
-
- @Override
- public String getValue() {
- return mValue;
- }
-
- @Override
- public List<PPSNode> getChildren() {
- return null;
- }
-
- @Override
- public boolean isLeaf() {
- return true;
- }
- }
-
- /**
- * Class representing an internal node in a PPS (PerProviderSubscription) tree.
- */
- private static class InternalNode extends PPSNode {
- private final List<PPSNode> mChildren;
- public InternalNode(String nodeName, List<PPSNode> children) {
- super(nodeName);
- mChildren = children;
- }
-
- @Override
- public String getValue() {
- return null;
- }
-
- @Override
- public List<PPSNode> getChildren() {
- return mChildren;
- }
-
- @Override
- public boolean isLeaf() {
- return false;
- }
- }
-
- /**
- * @hide
- */
- public PpsMoParser() {}
-
- /**
- * Convert a XML string representation of a PPS MO (PerProviderSubscription
- * Management Object) tree to a {@link PasspointConfiguration} object.
- *
- * @param xmlString XML string representation of a PPS MO tree
- * @return {@link PasspointConfiguration} or null
- */
- public static PasspointConfiguration parseMoText(String xmlString) {
- // Convert the XML string to a XML tree.
- XMLParser xmlParser = new XMLParser();
- XMLNode root = null;
- try {
- root = xmlParser.parse(xmlString);
- } catch(IOException | SAXException e) {
- return null;
- }
- if (root == null) {
- return null;
- }
-
- // Verify root node is a "MgmtTree" node.
- if (root.getTag() != TAG_MANAGEMENT_TREE) {
- Log.e(TAG, "Root is not a MgmtTree");
- return null;
- }
-
- String verDtd = null; // Used for detecting duplicate VerDTD element.
- PasspointConfiguration config = null;
- for (XMLNode child : root.getChildren()) {
- switch(child.getTag()) {
- case TAG_VER_DTD:
- if (verDtd != null) {
- Log.e(TAG, "Duplicate VerDTD element");
- return null;
- }
- verDtd = child.getText();
- break;
- case TAG_NODE:
- if (config != null) {
- Log.e(TAG, "Unexpected multiple Node element under MgmtTree");
- return null;
- }
- try {
- config = parsePpsNode(child);
- } catch (ParsingException e) {
- Log.e(TAG, e.getMessage());
- return null;
- }
- break;
- default:
- Log.e(TAG, "Unknown node: " + child.getTag());
- return null;
- }
- }
- return config;
- }
-
- /**
- * Parse a PerProviderSubscription node. Below is the format of the XML tree (with
- * each XML element represent a node in the tree):
- *
- * <Node>
- * <NodeName>PerProviderSubscription</NodeName>
- * <RTProperties>
- * ...
- * </RTPProperties>
- * <Node>
- * <NodeName>UpdateIdentifier</NodeName>
- * <Value>...</Value>
- * </Node>
- * <Node>
- * ...
- * </Node>
- * </Node>
- *
- * @param node XMLNode that contains PerProviderSubscription node.
- * @return PasspointConfiguration or null
- * @throws ParsingException
- */
- private static PasspointConfiguration parsePpsNode(XMLNode node)
- throws ParsingException {
- PasspointConfiguration config = null;
- String nodeName = null;
- int updateIdentifier = Integer.MIN_VALUE;
- for (XMLNode child : node.getChildren()) {
- switch (child.getTag()) {
- case TAG_NODE_NAME:
- if (nodeName != null) {
- throw new ParsingException("Duplicate NodeName: " + child.getText());
- }
- nodeName = child.getText();
- if (!TextUtils.equals(nodeName, NODE_PER_PROVIDER_SUBSCRIPTION)) {
- throw new ParsingException("Unexpected NodeName: " + nodeName);
- }
- break;
- case TAG_NODE:
- // A node can be either an UpdateIdentifier node or a PerProviderSubscription
- // instance node. Flatten out the XML tree first by converting it to a PPS
- // tree to reduce the complexity of the parsing code.
- PPSNode ppsNodeRoot = buildPpsNode(child);
- if (TextUtils.equals(ppsNodeRoot.getName(), NODE_UPDATE_IDENTIFIER)) {
- if (updateIdentifier != Integer.MIN_VALUE) {
- throw new ParsingException("Multiple node for UpdateIdentifier");
- }
- updateIdentifier = parseInteger(getPpsNodeValue(ppsNodeRoot));
- } else {
- // Only one PerProviderSubscription instance is expected and allowed.
- if (config != null) {
- throw new ParsingException("Multiple PPS instance");
- }
- config = parsePpsInstance(ppsNodeRoot);
- }
- break;
- case TAG_RT_PROPERTIES:
- // Parse and verify URN stored in the RT (Run Time) Properties.
- String urn = parseUrn(child);
- if (!TextUtils.equals(urn, PPS_MO_URN)) {
- throw new ParsingException("Unknown URN: " + urn);
- }
- break;
- default:
- throw new ParsingException("Unknown tag under PPS node: " + child.getTag());
- }
- }
- if (config != null && updateIdentifier != Integer.MIN_VALUE) {
- config.setUpdateIdentifier(updateIdentifier);
- }
- return config;
- }
-
- /**
- * Parse the URN stored in the RTProperties. Below is the format of the RTPProperties node:
- *
- * <RTProperties>
- * <Type>
- * <DDFName>urn:...</DDFName>
- * </Type>
- * </RTProperties>
- *
- * @param node XMLNode that contains RTProperties node.
- * @return URN String of URN.
- * @throws ParsingException
- */
- private static String parseUrn(XMLNode node) throws ParsingException {
- if (node.getChildren().size() != 1)
- throw new ParsingException("Expect RTPProperties node to only have one child");
-
- XMLNode typeNode = node.getChildren().get(0);
- if (typeNode.getChildren().size() != 1) {
- throw new ParsingException("Expect Type node to only have one child");
- }
- if (!TextUtils.equals(typeNode.getTag(), TAG_TYPE)) {
- throw new ParsingException("Unexpected tag for Type: " + typeNode.getTag());
- }
-
- XMLNode ddfNameNode = typeNode.getChildren().get(0);
- if (!ddfNameNode.getChildren().isEmpty()) {
- throw new ParsingException("Expect DDFName node to have no child");
- }
- if (!TextUtils.equals(ddfNameNode.getTag(), TAG_DDF_NAME)) {
- throw new ParsingException("Unexpected tag for DDFName: " + ddfNameNode.getTag());
- }
-
- return ddfNameNode.getText();
- }
-
- /**
- * Convert a XML tree represented by XMLNode to a PPS (PerProviderSubscription) instance tree
- * represented by PPSNode. This flattens out the XML tree to allow easier and cleaner parsing
- * of the PPS configuration data. Only three types of XML tag are expected: "NodeName",
- * "Node", and "Value".
- *
- * The original XML tree (each XML element represent a node):
- *
- * <Node>
- * <NodeName>root</NodeName>
- * <Node>
- * <NodeName>child1</NodeName>
- * <Value>value1</Value>
- * </Node>
- * <Node>
- * <NodeName>child2</NodeName>
- * <Node>
- * <NodeName>grandchild1</NodeName>
- * ...
- * </Node>
- * </Node>
- * ...
- * </Node>
- *
- * The converted PPS tree:
- *
- * [root] --- [child1, value1]
- * |
- * ---------[child2] --------[grandchild1] --- ...
- *
- * @param node XMLNode pointed to the root of a XML tree
- * @return PPSNode pointing to the root of a PPS tree
- * @throws ParsingException
- */
- private static PPSNode buildPpsNode(XMLNode node) throws ParsingException {
- String nodeName = null;
- String nodeValue = null;
- List<PPSNode> childNodes = new ArrayList<PPSNode>();
- // Names of parsed child nodes, use for detecting multiple child nodes with the same name.
- Set<String> parsedNodes = new HashSet<String>();
-
- for (XMLNode child : node.getChildren()) {
- String tag = child.getTag();
- if (TextUtils.equals(tag, TAG_NODE_NAME)) {
- if (nodeName != null) {
- throw new ParsingException("Duplicate NodeName node");
- }
- nodeName = child.getText();
- } else if (TextUtils.equals(tag, TAG_NODE)) {
- PPSNode ppsNode = buildPpsNode(child);
- if (parsedNodes.contains(ppsNode.getName())) {
- throw new ParsingException("Duplicate node: " + ppsNode.getName());
- }
- parsedNodes.add(ppsNode.getName());
- childNodes.add(ppsNode);
- } else if (TextUtils.equals(tag, TAG_VALUE)) {
- if (nodeValue != null) {
- throw new ParsingException("Duplicate Value node");
- }
- nodeValue = child.getText();
- } else {
- throw new ParsingException("Unknown tag: " + tag);
- }
- }
-
- if (nodeName == null) {
- throw new ParsingException("Invalid node: missing NodeName");
- }
- if (nodeValue == null && childNodes.size() == 0) {
- throw new ParsingException("Invalid node: " + nodeName +
- " missing both value and children");
- }
- if (nodeValue != null && childNodes.size() > 0) {
- throw new ParsingException("Invalid node: " + nodeName +
- " contained both value and children");
- }
-
- if (nodeValue != null) {
- return new LeafNode(nodeName, nodeValue);
- }
- return new InternalNode(nodeName, childNodes);
- }
-
- /**
- * Return the value of a PPSNode. An exception will be thrown if the given node
- * is not a leaf node.
- *
- * @param node PPSNode to retrieve the value from
- * @return String representing the value of the node
- * @throws ParsingException
- */
- private static String getPpsNodeValue(PPSNode node) throws ParsingException {
- if (!node.isLeaf()) {
- throw new ParsingException("Cannot get value from a non-leaf node: " + node.getName());
- }
- return node.getValue();
- }
-
- /**
- * Parse a PPS (PerProviderSubscription) configurations from a PPS tree.
- *
- * @param root PPSNode representing the root of the PPS tree
- * @return PasspointConfiguration
- * @throws ParsingException
- */
- private static PasspointConfiguration parsePpsInstance(PPSNode root)
- throws ParsingException {
- if (root.isLeaf()) {
- throw new ParsingException("Leaf node not expected for PPS instance");
- }
-
- PasspointConfiguration config = new PasspointConfiguration();
- for (PPSNode child : root.getChildren()) {
- switch(child.getName()) {
- case NODE_HOMESP:
- config.setHomeSp(parseHomeSP(child));
- break;
- case NODE_CREDENTIAL:
- config.setCredential(parseCredential(child));
- break;
- case NODE_POLICY:
- config.setPolicy(parsePolicy(child));
- break;
- case NODE_AAA_SERVER_TRUST_ROOT:
- config.setTrustRootCertList(parseAAAServerTrustRootList(child));
- break;
- case NODE_SUBSCRIPTION_UPDATE:
- config.setSubscriptionUpdate(parseUpdateParameter(child));
- break;
- case NODE_SUBSCRIPTION_PARAMETER:
- parseSubscriptionParameter(child, config);
- break;
- case NODE_CREDENTIAL_PRIORITY:
- config.setCredentialPriority(parseInteger(getPpsNodeValue(child)));
- break;
- case NODE_EXTENSION:
- // All vendor specific information will be under this node.
- parseExtension(child, config);
- break;
- default:
- throw new ParsingException("Unknown node: " + child.getName());
- }
- }
- return config;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/HomeSP subtree.
- *
- * @param node PPSNode representing the root of the PerProviderSubscription/HomeSP subtree
- * @return HomeSP
- * @throws ParsingException
- */
- private static HomeSp parseHomeSP(PPSNode node) throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for HomeSP");
- }
-
- HomeSp homeSp = new HomeSp();
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_FQDN:
- homeSp.setFqdn(getPpsNodeValue(child));
- break;
- case NODE_FRIENDLY_NAME:
- homeSp.setFriendlyName(getPpsNodeValue(child));
- break;
- case NODE_ROAMING_CONSORTIUM_OI:
- homeSp.setRoamingConsortiumOis(
- parseRoamingConsortiumOI(getPpsNodeValue(child)));
- break;
- case NODE_ICON_URL:
- homeSp.setIconUrl(getPpsNodeValue(child));
- break;
- case NODE_NETWORK_ID:
- homeSp.setHomeNetworkIds(parseNetworkIds(child));
- break;
- case NODE_HOME_OI_LIST:
- Pair<List<Long>, List<Long>> homeOIs = parseHomeOIList(child);
- homeSp.setMatchAllOis(convertFromLongList(homeOIs.first));
- homeSp.setMatchAnyOis(convertFromLongList(homeOIs.second));
- break;
- case NODE_OTHER_HOME_PARTNERS:
- homeSp.setOtherHomePartners(parseOtherHomePartners(child));
- break;
- default:
- throw new ParsingException("Unknown node under HomeSP: " + child.getName());
- }
- }
- return homeSp;
- }
-
- /**
- * Parse the roaming consortium OI string, which contains a list of OIs separated by ",".
- *
- * @param oiStr string containing list of OIs (Organization Identifiers) separated by ","
- * @return long[]
- * @throws ParsingException
- */
- private static long[] parseRoamingConsortiumOI(String oiStr)
- throws ParsingException {
- String[] oiStrArray = oiStr.split(",");
- long[] oiArray = new long[oiStrArray.length];
- for (int i = 0; i < oiStrArray.length; i++) {
- oiArray[i] = parseLong(oiStrArray[i], 16);
- }
- return oiArray;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/HomeSP/NetworkID subtree.
- *
- * @param node PPSNode representing the root of the PerProviderSubscription/HomeSP/NetworkID
- * subtree
- * @return HashMap<String, Long> representing list of <SSID, HESSID> pair.
- * @throws ParsingException
- */
- static private Map<String, Long> parseNetworkIds(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for NetworkID");
- }
-
- Map<String, Long> networkIds = new HashMap<>();
- for (PPSNode child : node.getChildren()) {
- Pair<String, Long> networkId = parseNetworkIdInstance(child);
- networkIds.put(networkId.first, networkId.second);
- }
- return networkIds;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/HomeSP/NetworkID/<X+> subtree.
- * The instance name (<X+>) is irrelevant and must be unique for each instance, which
- * is verified when the PPS tree is constructed {@link #buildPpsNode}.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/HomeSP/NetworkID/<X+> subtree
- * @return Pair<String, Long> representing <SSID, HESSID> pair.
- * @throws ParsingException
- */
- static private Pair<String, Long> parseNetworkIdInstance(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for NetworkID instance");
- }
-
- String ssid = null;
- Long hessid = null;
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_SSID:
- ssid = getPpsNodeValue(child);
- break;
- case NODE_HESSID:
- hessid = parseLong(getPpsNodeValue(child), 16);
- break;
- default:
- throw new ParsingException("Unknown node under NetworkID instance: " +
- child.getName());
- }
- }
- if (ssid == null)
- throw new ParsingException("NetworkID instance missing SSID");
-
- return new Pair<String, Long>(ssid, hessid);
- }
-
- /**
- * Parse configurations under PerProviderSubscription/HomeSP/HomeOIList subtree.
- *
- * @param node PPSNode representing the root of the PerProviderSubscription/HomeSP/HomeOIList
- * subtree
- * @return Pair<List<Long>, List<Long>> containing both MatchAllOIs and MatchAnyOIs list.
- * @throws ParsingException
- */
- private static Pair<List<Long>, List<Long>> parseHomeOIList(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for HomeOIList");
- }
-
- List<Long> matchAllOIs = new ArrayList<Long>();
- List<Long> matchAnyOIs = new ArrayList<Long>();
- for (PPSNode child : node.getChildren()) {
- Pair<Long, Boolean> homeOI = parseHomeOIInstance(child);
- if (homeOI.second.booleanValue()) {
- matchAllOIs.add(homeOI.first);
- } else {
- matchAnyOIs.add(homeOI.first);
- }
- }
- return new Pair<List<Long>, List<Long>>(matchAllOIs, matchAnyOIs);
- }
-
- /**
- * Parse configurations under PerProviderSubscription/HomeSP/HomeOIList/<X+> subtree.
- * The instance name (<X+>) is irrelevant and must be unique for each instance, which
- * is verified when the PPS tree is constructed {@link #buildPpsNode}.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/HomeSP/HomeOIList/<X+> subtree
- * @return Pair<Long, Boolean> containing a HomeOI and a HomeOIRequired flag
- * @throws ParsingException
- */
- private static Pair<Long, Boolean> parseHomeOIInstance(PPSNode node) throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for HomeOI instance");
- }
-
- Long oi = null;
- Boolean required = null;
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_HOME_OI:
- try {
- oi = Long.valueOf(getPpsNodeValue(child), 16);
- } catch (NumberFormatException e) {
- throw new ParsingException("Invalid HomeOI: " + getPpsNodeValue(child));
- }
- break;
- case NODE_HOME_OI_REQUIRED:
- required = Boolean.valueOf(getPpsNodeValue(child));
- break;
- default:
- throw new ParsingException("Unknown node under NetworkID instance: " +
- child.getName());
- }
- }
- if (oi == null) {
- throw new ParsingException("HomeOI instance missing OI field");
- }
- if (required == null) {
- throw new ParsingException("HomeOI instance missing required field");
- }
- return new Pair<Long, Boolean>(oi, required);
- }
-
- /**
- * Parse configurations under PerProviderSubscription/HomeSP/OtherHomePartners subtree.
- * This contains a list of FQDN (Fully Qualified Domain Name) that are considered
- * home partners.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/HomeSP/OtherHomePartners subtree
- * @return String[] list of partner's FQDN
- * @throws ParsingException
- */
- private static String[] parseOtherHomePartners(PPSNode node) throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for OtherHomePartners");
- }
- List<String> otherHomePartners = new ArrayList<String>();
- for (PPSNode child : node.getChildren()) {
- String fqdn = parseOtherHomePartnerInstance(child);
- otherHomePartners.add(fqdn);
- }
- return otherHomePartners.toArray(new String[otherHomePartners.size()]);
- }
-
- /**
- * Parse configurations under PerProviderSubscription/HomeSP/OtherHomePartners/<X+> subtree.
- * The instance name (<X+>) is irrelevant and must be unique for each instance, which
- * is verified when the PPS tree is constructed {@link #buildPpsNode}.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/HomeSP/OtherHomePartners/<X+> subtree
- * @return String FQDN of the partner
- * @throws ParsingException
- */
- private static String parseOtherHomePartnerInstance(PPSNode node) throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for OtherHomePartner instance");
- }
- String fqdn = null;
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_FQDN:
- fqdn = getPpsNodeValue(child);
- break;
- default:
- throw new ParsingException(
- "Unknown node under OtherHomePartner instance: " + child.getName());
- }
- }
- if (fqdn == null) {
- throw new ParsingException("OtherHomePartner instance missing FQDN field");
- }
- return fqdn;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Credential subtree.
- *
- * @param node PPSNode representing the root of the PerProviderSubscription/Credential subtree
- * @return Credential
- * @throws ParsingException
- */
- private static Credential parseCredential(PPSNode node) throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for Credential");
- }
-
- Credential credential = new Credential();
- for (PPSNode child: node.getChildren()) {
- switch (child.getName()) {
- case NODE_CREATION_DATE:
- credential.setCreationTimeInMillis(parseDate(getPpsNodeValue(child)));
- break;
- case NODE_EXPIRATION_DATE:
- credential.setExpirationTimeInMillis(parseDate(getPpsNodeValue(child)));
- break;
- case NODE_USERNAME_PASSWORD:
- credential.setUserCredential(parseUserCredential(child));
- break;
- case NODE_DIGITAL_CERTIFICATE:
- credential.setCertCredential(parseCertificateCredential(child));
- break;
- case NODE_REALM:
- credential.setRealm(getPpsNodeValue(child));
- break;
- case NODE_CHECK_AAA_SERVER_CERT_STATUS:
- credential.setCheckAaaServerCertStatus(
- Boolean.parseBoolean(getPpsNodeValue(child)));
- break;
- case NODE_SIM:
- credential.setSimCredential(parseSimCredential(child));
- break;
- default:
- throw new ParsingException("Unknown node under Credential: " +
- child.getName());
- }
- }
- return credential;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Credential/UsernamePassword subtree.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Credential/UsernamePassword subtree
- * @return Credential.UserCredential
- * @throws ParsingException
- */
- private static Credential.UserCredential parseUserCredential(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for UsernamePassword");
- }
-
- Credential.UserCredential userCred = new Credential.UserCredential();
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_USERNAME:
- userCred.setUsername(getPpsNodeValue(child));
- break;
- case NODE_PASSWORD:
- userCred.setPassword(getPpsNodeValue(child));
- break;
- case NODE_MACHINE_MANAGED:
- userCred.setMachineManaged(Boolean.parseBoolean(getPpsNodeValue(child)));
- break;
- case NODE_SOFT_TOKEN_APP:
- userCred.setSoftTokenApp(getPpsNodeValue(child));
- break;
- case NODE_ABLE_TO_SHARE:
- userCred.setAbleToShare(Boolean.parseBoolean(getPpsNodeValue(child)));
- break;
- case NODE_EAP_METHOD:
- parseEAPMethod(child, userCred);
- break;
- default:
- throw new ParsingException("Unknown node under UsernamePassword: "
- + child.getName());
- }
- }
- return userCred;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Credential/UsernamePassword/EAPMethod
- * subtree.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Credential/UsernamePassword/EAPMethod subtree
- * @param userCred UserCredential to be updated with EAP method values.
- * @throws ParsingException
- */
- private static void parseEAPMethod(PPSNode node, Credential.UserCredential userCred)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for EAPMethod");
- }
-
- for (PPSNode child : node.getChildren()) {
- switch(child.getName()) {
- case NODE_EAP_TYPE:
- userCred.setEapType(parseInteger(getPpsNodeValue(child)));
- break;
- case NODE_INNER_METHOD:
- userCred.setNonEapInnerMethod(getPpsNodeValue(child));
- break;
- case NODE_VENDOR_ID:
- case NODE_VENDOR_TYPE:
- case NODE_INNER_EAP_TYPE:
- case NODE_INNER_VENDOR_ID:
- case NODE_INNER_VENDOR_TYPE:
- // Only EAP-TTLS is currently supported for user credential, which doesn't
- // use any of these parameters.
- Log.d(TAG, "Ignore unsupported EAP method parameter: " + child.getName());
- break;
- default:
- throw new ParsingException("Unknown node under EAPMethod: " + child.getName());
- }
- }
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Credential/DigitalCertificate subtree.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Credential/DigitalCertificate subtree
- * @return Credential.CertificateCredential
- * @throws ParsingException
- */
- private static Credential.CertificateCredential parseCertificateCredential(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for CertificateCredential");
- }
-
- Credential.CertificateCredential certCred = new Credential.CertificateCredential();
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_CERTIFICATE_TYPE:
- certCred.setCertType(getPpsNodeValue(child));
- break;
- case NODE_CERT_SHA256_FINGERPRINT:
- certCred.setCertSha256Fingerprint(parseHexString(getPpsNodeValue(child)));
- break;
- default:
- throw new ParsingException("Unknown node under CertificateCredential: "
- + child.getName());
- }
- }
- return certCred;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Credential/SIM subtree.
- *
- * @param node PPSNode representing the root of the PerProviderSubscription/Credential/SIM
- * subtree
- * @return Credential.SimCredential
- * @throws ParsingException
- */
- private static Credential.SimCredential parseSimCredential(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for SimCredential");
- }
-
- Credential.SimCredential simCred = new Credential.SimCredential();
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_SIM_IMSI:
- simCred.setImsi(getPpsNodeValue(child));
- break;
- case NODE_EAP_TYPE:
- simCred.setEapType(parseInteger(getPpsNodeValue(child)));
- break;
- default:
- throw new ParsingException("Unknown node under SimCredential: "
- + child.getName());
- }
- }
- return simCred;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Policy subtree.
- *
- * @param node PPSNode representing the root of the PerProviderSubscription/Policy subtree
- * @return {@link Policy}
- * @throws ParsingException
- */
- private static Policy parsePolicy(PPSNode node) throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for Policy");
- }
-
- Policy policy = new Policy();
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_PREFERRED_ROAMING_PARTNER_LIST:
- policy.setPreferredRoamingPartnerList(parsePreferredRoamingPartnerList(child));
- break;
- case NODE_MIN_BACKHAUL_THRESHOLD:
- parseMinBackhaulThreshold(child, policy);
- break;
- case NODE_POLICY_UPDATE:
- policy.setPolicyUpdate(parseUpdateParameter(child));
- break;
- case NODE_SP_EXCLUSION_LIST:
- policy.setExcludedSsidList(parseSpExclusionList(child));
- break;
- case NODE_REQUIRED_PROTO_PORT_TUPLE:
- policy.setRequiredProtoPortMap(parseRequiredProtoPortTuple(child));
- break;
- case NODE_MAXIMUM_BSS_LOAD_VALUE:
- policy.setMaximumBssLoadValue(parseInteger(getPpsNodeValue(child)));
- break;
- default:
- throw new ParsingException("Unknown node under Policy: " + child.getName());
- }
- }
- return policy;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Policy/PreferredRoamingPartnerList
- * subtree.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Policy/PreferredRoamingPartnerList subtree
- * @return List of {@link Policy#RoamingPartner}
- * @throws ParsingException
- */
- private static List<Policy.RoamingPartner> parsePreferredRoamingPartnerList(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for PreferredRoamingPartnerList");
- }
- List<Policy.RoamingPartner> partnerList = new ArrayList<>();
- for (PPSNode child : node.getChildren()) {
- partnerList.add(parsePreferredRoamingPartner(child));
- }
- return partnerList;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Policy/PreferredRoamingPartnerList/<X+>
- * subtree.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Policy/PreferredRoamingPartnerList/<X+> subtree
- * @return {@link Policy#RoamingPartner}
- * @throws ParsingException
- */
- private static Policy.RoamingPartner parsePreferredRoamingPartner(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for PreferredRoamingPartner "
- + "instance");
- }
-
- Policy.RoamingPartner roamingPartner = new Policy.RoamingPartner();
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_FQDN_MATCH:
- // FQDN_Match field is in the format of "[FQDN],[MatchInfo]", where [MatchInfo]
- // is either "exactMatch" for exact match of FQDN or "includeSubdomains" for
- // matching all FQDNs with the same sub-domain.
- String fqdnMatch = getPpsNodeValue(child);
- String[] fqdnMatchArray = fqdnMatch.split(",");
- if (fqdnMatchArray.length != 2) {
- throw new ParsingException("Invalid FQDN_Match: " + fqdnMatch);
- }
- roamingPartner.setFqdn(fqdnMatchArray[0]);
- if (TextUtils.equals(fqdnMatchArray[1], "exactMatch")) {
- roamingPartner.setFqdnExactMatch(true);
- } else if (TextUtils.equals(fqdnMatchArray[1], "includeSubdomains")) {
- roamingPartner.setFqdnExactMatch(false);
- } else {
- throw new ParsingException("Invalid FQDN_Match: " + fqdnMatch);
- }
- break;
- case NODE_PRIORITY:
- roamingPartner.setPriority(parseInteger(getPpsNodeValue(child)));
- break;
- case NODE_COUNTRY:
- roamingPartner.setCountries(getPpsNodeValue(child));
- break;
- default:
- throw new ParsingException("Unknown node under PreferredRoamingPartnerList "
- + "instance " + child.getName());
- }
- }
- return roamingPartner;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Policy/MinBackhaulThreshold subtree
- * into the given policy.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Policy/MinBackhaulThreshold subtree
- * @param policy The policy to store the MinBackhualThreshold configuration
- * @throws ParsingException
- */
- private static void parseMinBackhaulThreshold(PPSNode node, Policy policy)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for MinBackhaulThreshold");
- }
- for (PPSNode child : node.getChildren()) {
- parseMinBackhaulThresholdInstance(child, policy);
- }
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Policy/MinBackhaulThreshold/<X+> subtree
- * into the given policy.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Policy/MinBackhaulThreshold/<X+> subtree
- * @param policy The policy to store the MinBackhaulThreshold configuration
- * @throws ParsingException
- */
- private static void parseMinBackhaulThresholdInstance(PPSNode node, Policy policy)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for MinBackhaulThreshold instance");
- }
- String networkType = null;
- long downlinkBandwidth = Long.MIN_VALUE;
- long uplinkBandwidth = Long.MIN_VALUE;
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_NETWORK_TYPE:
- networkType = getPpsNodeValue(child);
- break;
- case NODE_DOWNLINK_BANDWIDTH:
- downlinkBandwidth = parseLong(getPpsNodeValue(child), 10);
- break;
- case NODE_UPLINK_BANDWIDTH:
- uplinkBandwidth = parseLong(getPpsNodeValue(child), 10);
- break;
- default:
- throw new ParsingException("Unknown node under MinBackhaulThreshold instance "
- + child.getName());
- }
- }
- if (networkType == null) {
- throw new ParsingException("Missing NetworkType field");
- }
-
- if (TextUtils.equals(networkType, "home")) {
- policy.setMinHomeDownlinkBandwidth(downlinkBandwidth);
- policy.setMinHomeUplinkBandwidth(uplinkBandwidth);
- } else if (TextUtils.equals(networkType, "roaming")) {
- policy.setMinRoamingDownlinkBandwidth(downlinkBandwidth);
- policy.setMinRoamingUplinkBandwidth(uplinkBandwidth);
- } else {
- throw new ParsingException("Invalid network type: " + networkType);
- }
- }
-
- /**
- * Parse update parameters. This contained configurations from either
- * PerProviderSubscription/Policy/PolicyUpdate or PerProviderSubscription/SubscriptionUpdate
- * subtree.
- *
- * @param node PPSNode representing the root of the PerProviderSubscription/Policy/PolicyUpdate
- * or PerProviderSubscription/SubscriptionUpdate subtree
- * @return {@link UpdateParameter}
- * @throws ParsingException
- */
- private static UpdateParameter parseUpdateParameter(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for Update Parameters");
- }
-
- UpdateParameter updateParam = new UpdateParameter();
- for (PPSNode child : node.getChildren()) {
- switch(child.getName()) {
- case NODE_UPDATE_INTERVAL:
- updateParam.setUpdateIntervalInMinutes(parseLong(getPpsNodeValue(child), 10));
- break;
- case NODE_UPDATE_METHOD:
- updateParam.setUpdateMethod(getPpsNodeValue(child));
- break;
- case NODE_RESTRICTION:
- updateParam.setRestriction(getPpsNodeValue(child));
- break;
- case NODE_URI:
- updateParam.setServerUri(getPpsNodeValue(child));
- break;
- case NODE_USERNAME_PASSWORD:
- Pair<String, String> usernamePassword = parseUpdateUserCredential(child);
- updateParam.setUsername(usernamePassword.first);
- updateParam.setBase64EncodedPassword(usernamePassword.second);
- break;
- case NODE_TRUST_ROOT:
- Pair<String, byte[]> trustRoot = parseTrustRoot(child);
- updateParam.setTrustRootCertUrl(trustRoot.first);
- updateParam.setTrustRootCertSha256Fingerprint(trustRoot.second);
- break;
- case NODE_OTHER:
- Log.d(TAG, "Ignore unsupported paramter: " + child.getName());
- break;
- default:
- throw new ParsingException("Unknown node under Update Parameters: "
- + child.getName());
- }
- }
- return updateParam;
- }
-
- /**
- * Parse username and password parameters associated with policy or subscription update.
- * This contained configurations under either
- * PerProviderSubscription/Policy/PolicyUpdate/UsernamePassword or
- * PerProviderSubscription/SubscriptionUpdate/UsernamePassword subtree.
- *
- * @param node PPSNode representing the root of the UsernamePassword subtree
- * @return Pair of username and password
- * @throws ParsingException
- */
- private static Pair<String, String> parseUpdateUserCredential(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for UsernamePassword");
- }
-
- String username = null;
- String password = null;
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_USERNAME:
- username = getPpsNodeValue(child);
- break;
- case NODE_PASSWORD:
- password = getPpsNodeValue(child);
- break;
- default:
- throw new ParsingException("Unknown node under UsernamePassword: "
- + child.getName());
- }
- }
- return Pair.create(username, password);
- }
-
- /**
- * Parse the trust root parameters associated with policy update, subscription update, or AAA
- * server trust root.
- *
- * This contained configurations under either
- * PerProviderSubscription/Policy/PolicyUpdate/TrustRoot or
- * PerProviderSubscription/SubscriptionUpdate/TrustRoot or
- * PerProviderSubscription/AAAServerTrustRoot/<X+> subtree.
- *
- * @param node PPSNode representing the root of the TrustRoot subtree
- * @return Pair of Certificate URL and fingerprint
- * @throws ParsingException
- */
- private static Pair<String, byte[]> parseTrustRoot(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for TrustRoot");
- }
-
- String certUrl = null;
- byte[] certFingerprint = null;
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_CERT_URL:
- certUrl = getPpsNodeValue(child);
- break;
- case NODE_CERT_SHA256_FINGERPRINT:
- certFingerprint = parseHexString(getPpsNodeValue(child));
- break;
- default:
- throw new ParsingException("Unknown node under TrustRoot: "
- + child.getName());
- }
- }
- return Pair.create(certUrl, certFingerprint);
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Policy/SPExclusionList subtree.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Policy/SPExclusionList subtree
- * @return Array of excluded SSIDs
- * @throws ParsingException
- */
- private static String[] parseSpExclusionList(PPSNode node) throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for SPExclusionList");
- }
- List<String> ssidList = new ArrayList<>();
- for (PPSNode child : node.getChildren()) {
- ssidList.add(parseSpExclusionInstance(child));
- }
- return ssidList.toArray(new String[ssidList.size()]);
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Policy/SPExclusionList/<X+> subtree.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Policy/SPExclusionList/<X+> subtree
- * @return String
- * @throws ParsingException
- */
- private static String parseSpExclusionInstance(PPSNode node) throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for SPExclusion instance");
- }
- String ssid = null;
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_SSID:
- ssid = getPpsNodeValue(child);
- break;
- default:
- throw new ParsingException("Unknown node under SPExclusion instance");
- }
- }
- return ssid;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Policy/RequiredProtoPortTuple subtree.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Policy/RequiredProtoPortTuple subtree
- * @return Map of IP Protocol to Port Number tuples
- * @throws ParsingException
- */
- private static Map<Integer, String> parseRequiredProtoPortTuple(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for RequiredProtoPortTuple");
- }
- Map<Integer, String> protoPortTupleMap = new HashMap<>();
- for (PPSNode child : node.getChildren()) {
- Pair<Integer, String> protoPortTuple = parseProtoPortTuple(child);
- protoPortTupleMap.put(protoPortTuple.first, protoPortTuple.second);
- }
- return protoPortTupleMap;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Policy/RequiredProtoPortTuple/<X+>
- * subtree.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Policy/RequiredProtoPortTuple/<X+> subtree
- * @return Pair of IP Protocol to Port Number tuple
- * @throws ParsingException
- */
- private static Pair<Integer, String> parseProtoPortTuple(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for RequiredProtoPortTuple "
- + "instance");
- }
- int proto = Integer.MIN_VALUE;
- String ports = null;
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_IP_PROTOCOL:
- proto = parseInteger(getPpsNodeValue(child));
- break;
- case NODE_PORT_NUMBER:
- ports = getPpsNodeValue(child);
- break;
- default:
- throw new ParsingException("Unknown node under RequiredProtoPortTuple instance"
- + child.getName());
- }
- }
- if (proto == Integer.MIN_VALUE) {
- throw new ParsingException("Missing IPProtocol field");
- }
- if (ports == null) {
- throw new ParsingException("Missing PortNumber field");
- }
- return Pair.create(proto, ports);
- }
-
- /**
- * Parse configurations under PerProviderSubscription/AAAServerTrustRoot subtree.
- *
- * @param node PPSNode representing the root of PerProviderSubscription/AAAServerTrustRoot
- * subtree
- * @return Map of certificate URL with the corresponding certificate fingerprint
- * @throws ParsingException
- */
- private static Map<String, byte[]> parseAAAServerTrustRootList(PPSNode node)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for AAAServerTrustRoot");
- }
- Map<String, byte[]> certList = new HashMap<>();
- for (PPSNode child : node.getChildren()) {
- Pair<String, byte[]> certTuple = parseTrustRoot(child);
- certList.put(certTuple.first, certTuple.second);
- }
- return certList;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/SubscriptionParameter subtree.
- *
- * @param node PPSNode representing the root of PerProviderSubscription/SubscriptionParameter
- * subtree
- * @param config Instance of {@link PasspointConfiguration}
- * @throws ParsingException
- */
- private static void parseSubscriptionParameter(PPSNode node, PasspointConfiguration config)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for SubscriptionParameter");
- }
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_CREATION_DATE:
- config.setSubscriptionCreationTimeInMillis(parseDate(getPpsNodeValue(child)));
- break;
- case NODE_EXPIRATION_DATE:
- config.setSubscriptionExpirationTimeInMillis(parseDate(getPpsNodeValue(child)));
- break;
- case NODE_TYPE_OF_SUBSCRIPTION:
- config.setSubscriptionType(getPpsNodeValue(child));
- break;
- case NODE_USAGE_LIMITS:
- parseUsageLimits(child, config);
- break;
- default:
- throw new ParsingException("Unknown node under SubscriptionParameter"
- + child.getName());
- }
- }
- }
-
- /**
- * Parse configurations under PerProviderSubscription/SubscriptionParameter/UsageLimits
- * subtree.
- *
- * @param node PPSNode representing the root of
- * PerProviderSubscription/SubscriptionParameter/UsageLimits subtree
- * @param config Instance of {@link PasspointConfiguration}
- * @throws ParsingException
- */
- private static void parseUsageLimits(PPSNode node, PasspointConfiguration config)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for UsageLimits");
- }
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_DATA_LIMIT:
- config.setUsageLimitDataLimit(parseLong(getPpsNodeValue(child), 10));
- break;
- case NODE_START_DATE:
- config.setUsageLimitStartTimeInMillis(parseDate(getPpsNodeValue(child)));
- break;
- case NODE_TIME_LIMIT:
- config.setUsageLimitTimeLimitInMinutes(parseLong(getPpsNodeValue(child), 10));
- break;
- case NODE_USAGE_TIME_PERIOD:
- config.setUsageLimitUsageTimePeriodInMinutes(
- parseLong(getPpsNodeValue(child), 10));
- break;
- default:
- throw new ParsingException("Unknown node under UsageLimits"
- + child.getName());
- }
- }
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Extension/Android/AAAServerTrustedNames
- * subtree.
- *
- * @param node PPSNode representing the root of the
- * PerProviderSubscription/Extension/Android/AAAServerTrustedNames subtree
- * @return String[] list of trusted name
- * @throws ParsingException
- */
- private static String[] parseAaaServerTrustedNames(PPSNode node) throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for AAAServerTrustedNames instance");
- }
- String fqdnListStr = null;
- String[] fqdnListArray = null;
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_FQDN:
- fqdnListStr = getPpsNodeValue(child);
- fqdnListArray = fqdnListStr.split(";");
- break;
- default:
- throw new ParsingException(
- "Unknown node under AAAServerTrustedNames instance: "
- + child.getName());
- }
- }
- if (fqdnListArray == null) {
- throw new ParsingException("AAAServerTrustedNames instance missing FQDN field");
- }
-
- return fqdnListArray;
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Extension/Android subtree.
- *
- * @param node PPSNode representing the root of PerProviderSubscription/Extension
- * subtree
- * @param config Instance of {@link PasspointConfiguration}
- * @throws ParsingException
- */
- private static void parseVendorAndroidExtension(PPSNode node, PasspointConfiguration config)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for AndroidExtension");
- }
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_AAA_SERVER_TRUSTED_NAMES:
- config.setAaaServerTrustedNames(parseAaaServerTrustedNames(child));
- break;
- default:
- // Don't raise an exception for unknown nodes to avoid breaking old release
- Log.w(TAG, "Unknown node under Android Extension: " + child.getName());
- }
- }
- }
-
- /**
- * Parse configurations under PerProviderSubscription/Extension subtree.
- *
- * @param node PPSNode representing the root of PerProviderSubscription/Extension
- * subtree
- * @param config Instance of {@link PasspointConfiguration}
- * @throws ParsingException
- */
- private static void parseExtension(PPSNode node, PasspointConfiguration config)
- throws ParsingException {
- if (node.isLeaf()) {
- throw new ParsingException("Leaf node not expected for Extension");
- }
- for (PPSNode child : node.getChildren()) {
- switch (child.getName()) {
- case NODE_VENDOR_ANDROID:
- parseVendorAndroidExtension(child, config);
- break;
- default:
- // Unknown nodes under Extension won't raise exception.
- // This allows adding new nodes in the future and
- // won't break older release.
- Log.w(TAG, "Unknown node under Extension: " + child.getName());
- }
- }
- }
-
- /**
- * Convert a hex string to a byte array.
- *
- * @param str String containing hex values
- * @return byte[]
- * @throws ParsingException
- */
- private static byte[] parseHexString(String str) throws ParsingException {
- if ((str.length() & 1) == 1) {
- throw new ParsingException("Odd length hex string: " + str + ", length: "
- + str.length());
- }
-
- byte[] result = new byte[str.length() / 2];
- for (int i = 0; i < result.length; i++) {
- int index = i * 2;
- try {
- result[i] = (byte) Integer.parseInt(str.substring(index, index + 2), 16);
- } catch (NumberFormatException e) {
- throw new ParsingException("Invalid hex string: " + str);
- }
- }
- return result;
- }
-
- /**
- * Convert a date string to the number of milliseconds since January 1, 1970, 00:00:00 GMT.
- *
- * @param dateStr String in the format of yyyy-MM-dd'T'HH:mm:ss'Z'
- * @return number of milliseconds
- * @throws ParsingException
- */
- private static long parseDate(String dateStr) throws ParsingException {
- try {
- DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
- return format.parse(dateStr).getTime();
- } catch (ParseException pe) {
- throw new ParsingException("Badly formatted time: " + dateStr);
- }
- }
-
- /**
- * Parse an integer string.
- *
- * @param value String of integer value
- * @return int
- * @throws ParsingException
- */
- private static int parseInteger(String value) throws ParsingException {
- try {
- return Integer.parseInt(value);
- } catch (NumberFormatException e) {
- throw new ParsingException("Invalid integer value: " + value);
- }
- }
-
- /**
- * Parse a string representing a long integer.
- *
- * @param value String of long integer value
- * @return long
- * @throws ParsingException
- */
- private static long parseLong(String value, int radix) throws ParsingException {
- try {
- return Long.parseLong(value, radix);
- } catch (NumberFormatException e) {
- throw new ParsingException("Invalid long integer value: " + value);
- }
- }
-
- /**
- * Convert a List<Long> to a primitive long array long[].
- *
- * @param list List to be converted
- * @return long[]
- */
- private static long[] convertFromLongList(List<Long> list) {
- Long[] objectArray = list.toArray(new Long[list.size()]);
- long[] primitiveArray = new long[objectArray.length];
- for (int i = 0; i < objectArray.length; i++) {
- primitiveArray[i] = objectArray[i].longValue();
- }
- return primitiveArray;
- }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java b/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java
deleted file mode 100644
index 959d505..0000000
--- a/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java
+++ /dev/null
@@ -1,109 +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.net.wifi.hotspot2.omadm;
-
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * A class represent a node in an XML tree. Each node is an XML element.
- * Used by {@link XMLParser} for parsing/converting each XML element to XMLNode.
- *
- * @hide
- */
-public class XMLNode {
- private final String mTag;
- private final List<XMLNode> mChildren;
- private final XMLNode mParent;
- private StringBuilder mTextBuilder;
- private String mText;
-
- public XMLNode(XMLNode parent, String tag) {
- mTag = tag;
- mParent = parent;
- mChildren = new ArrayList<>();
- mTextBuilder = new StringBuilder();
- mText = null;
- }
-
- /**
- * Adding a text to this node. Invoked by {@link XMLParser#characters}.
- *
- * @param text String to be added
- */
- public void addText(String text) {
- mTextBuilder.append(text);
- }
-
- /**
- * Adding a child node to this node. Invoked by {@link XMLParser#startElement}.
- *
- * @param child XMLNode to be added
- */
- public void addChild(XMLNode child) {
- mChildren.add(child);
- }
-
- /**
- * Invoked when the end of the XML element is detected. Used for further processing
- * of the text enclosed within this XML element. Invoked by {@link XMLParser#endElement}.
- */
- public void close() {
- // Remove the leading and the trailing whitespaces.
- mText = mTextBuilder.toString().trim();
- mTextBuilder = null;
- }
-
- public String getTag() {
- return mTag;
- }
-
- public XMLNode getParent() {
- return mParent;
- }
-
- public String getText() {
- return mText;
- }
-
- public List<XMLNode> getChildren() {
- return mChildren;
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof XMLNode)) {
- return false;
- }
- XMLNode that = (XMLNode) thatObject;
-
- return TextUtils.equals(mTag, that.mTag) &&
- TextUtils.equals(mText, that.mText) &&
- mChildren.equals(that.mChildren);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mTag, mText, mChildren);
- }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java
deleted file mode 100644
index 948052c..0000000
--- a/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java
+++ /dev/null
@@ -1,108 +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.net.wifi.hotspot2.omadm;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import android.text.TextUtils;
-
-import java.io.IOException;
-import java.io.StringReader;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Class for parsing an XML string to an XML tree represented by {@link XMLNode}.
- *
- * The original XML string:
- * <root>
- * <tag1>text1</tag1>
- * <tag2>
- * <tag3>text3</tag3>
- * </tag2>
- * </root>
- *
- * The XML tree representation:
- * [root]
- * |
- * |
- * [tag1, text1]-----|-----[tag2]
- * |
- * |
- * [tag3, text3]
- *
- * @hide
- */
-public class XMLParser extends DefaultHandler {
- private XMLNode mRoot = null;
- private XMLNode mCurrent = null;
-
- public XMLNode parse(String text) throws IOException, SAXException {
- if (TextUtils.isEmpty(text)) {
- throw new IOException("XML string not provided");
- }
-
- // Reset pointers.
- mRoot = null;
- mCurrent = null;
-
- try {
- SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
- parser.parse(new InputSource(new StringReader(text)), this);
- return mRoot;
- } catch (ParserConfigurationException pce) {
- throw new SAXException(pce);
- }
- }
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attributes)
- throws SAXException {
- XMLNode parent = mCurrent;
-
- mCurrent = new XMLNode(parent, qName);
-
- if (mRoot == null) {
- mRoot = mCurrent;
- } else if (parent == null) {
- throw new SAXException("More than one root nodes");
- } else {
- parent.addChild(mCurrent);
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- if (!qName.equals(mCurrent.getTag())) {
- throw new SAXException("End tag '" + qName + "' doesn't match current node: " +
- mCurrent);
- }
-
- mCurrent.close();
- mCurrent = mCurrent.getParent();
- }
-
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- mCurrent.addText(new String(ch, start, length));
- }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
deleted file mode 100644
index fa806e7..0000000
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ /dev/null
@@ -1,1302 +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.net.wifi.hotspot2.pps;
-
-import android.net.wifi.EAPConstants;
-import android.net.wifi.ParcelUtil;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Class representing Credential subtree in the PerProviderSubscription (PPS)
- * Management Object (MO) tree.
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- *
- * In addition to the fields in the Credential subtree, this will also maintain necessary
- * information for the private key and certificates associated with this credential.
- */
-public final class Credential implements Parcelable {
- private static final String TAG = "Credential";
-
- /**
- * Max string length for realm. Refer to Credential/Realm node in Hotspot 2.0 Release 2
- * Technical Specification Section 9.1 for more info.
- */
- private static final int MAX_REALM_BYTES = 253;
-
- /**
- * The time this credential is created. It is in the format of number
- * of milliseconds since January 1, 1970, 00:00:00 GMT.
- * Using Long.MIN_VALUE to indicate unset value.
- */
- private long mCreationTimeInMillis = Long.MIN_VALUE;
- /**
- * @hide
- */
- public void setCreationTimeInMillis(long creationTimeInMillis) {
- mCreationTimeInMillis = creationTimeInMillis;
- }
- /**
- * @hide
- */
- public long getCreationTimeInMillis() {
- return mCreationTimeInMillis;
- }
-
- /**
- * The time this credential will expire. It is in the format of number
- * of milliseconds since January 1, 1970, 00:00:00 GMT.
- * Using Long.MIN_VALUE to indicate unset value.
- */
- private long mExpirationTimeInMillis = Long.MIN_VALUE;
- /**
- * @hide
- */
- public void setExpirationTimeInMillis(long expirationTimeInMillis) {
- mExpirationTimeInMillis = expirationTimeInMillis;
- }
- /**
- * @hide
- */
- public long getExpirationTimeInMillis() {
- return mExpirationTimeInMillis;
- }
-
- /**
- * The realm associated with this credential. It will be used to determine
- * if this credential can be used to authenticate with a given hotspot by
- * comparing the realm specified in that hotspot's ANQP element.
- */
- private String mRealm = null;
- /**
- * Set the realm associated with this credential.
- *
- * @param realm The realm to set to
- */
- public void setRealm(String realm) {
- mRealm = realm;
- }
- /**
- * Get the realm associated with this credential.
- *
- * @return the realm associated with this credential
- */
- public String getRealm() {
- return mRealm;
- }
-
- /**
- * When set to true, the device should check AAA (Authentication, Authorization,
- * and Accounting) server's certificate during EAP (Extensible Authentication
- * Protocol) authentication.
- */
- private boolean mCheckAaaServerCertStatus = false;
- /**
- * @hide
- */
- public void setCheckAaaServerCertStatus(boolean checkAaaServerCertStatus) {
- mCheckAaaServerCertStatus = checkAaaServerCertStatus;
- }
- /**
- * @hide
- */
- public boolean getCheckAaaServerCertStatus() {
- return mCheckAaaServerCertStatus;
- }
-
- /**
- * Username-password based credential.
- * Contains the fields under PerProviderSubscription/Credential/UsernamePassword subtree.
- */
- public static final class UserCredential implements Parcelable {
- /**
- * Maximum string length for username. Refer to Credential/UsernamePassword/Username
- * node in Hotspot 2.0 Release 2 Technical Specification Section 9.1 for more info.
- */
- private static final int MAX_USERNAME_BYTES = 63;
-
- /**
- * Maximum string length for password. Refer to Credential/UsernamePassword/Password
- * in Hotspot 2.0 Release 2 Technical Specification Section 9.1 for more info.
- */
- private static final int MAX_PASSWORD_BYTES = 255;
-
- /**
- * Supported authentication methods.
- * @hide
- */
- public static final String AUTH_METHOD_PAP = "PAP";
- /** @hide */
- public static final String AUTH_METHOD_MSCHAP = "MS-CHAP";
- /** @hide */
- public static final String AUTH_METHOD_MSCHAPV2 = "MS-CHAP-V2";
-
- /**
- * Supported Non-EAP inner methods. Refer to
- * Credential/UsernamePassword/EAPMethod/InnerEAPType in Hotspot 2.0 Release 2 Technical
- * Specification Section 9.1 for more info.
- */
- private static final Set<String> SUPPORTED_AUTH = new HashSet<String>(
- Arrays.asList(AUTH_METHOD_PAP, AUTH_METHOD_MSCHAP, AUTH_METHOD_MSCHAPV2));
-
- /**
- * Username of the credential.
- */
- private String mUsername = null;
- /**
- * Set the username associated with this user credential.
- *
- * @param username The username to set to
- */
- public void setUsername(String username) {
- mUsername = username;
- }
- /**
- * Get the username associated with this user credential.
- *
- * @return the username associated with this user credential
- */
- public String getUsername() {
- return mUsername;
- }
-
- /**
- * Base64-encoded password.
- */
- private String mPassword = null;
- /**
- * Set the Base64-encoded password associated with this user credential.
- *
- * @param password The password to set to
- */
- public void setPassword(String password) {
- mPassword = password;
- }
- /**
- * Get the Base64-encoded password associated with this user credential.
- *
- * @return the Base64-encoded password associated with this user credential
- */
- public String getPassword() {
- return mPassword;
- }
-
- /**
- * Flag indicating if the password is machine managed.
- */
- private boolean mMachineManaged = false;
- /**
- * @hide
- */
- public void setMachineManaged(boolean machineManaged) {
- mMachineManaged = machineManaged;
- }
- /**
- * @hide
- */
- public boolean getMachineManaged() {
- return mMachineManaged;
- }
-
- /**
- * The name of the application used to generate the password.
- */
- private String mSoftTokenApp = null;
- /**
- * @hide
- */
- public void setSoftTokenApp(String softTokenApp) {
- mSoftTokenApp = softTokenApp;
- }
- /**
- * @hide
- */
- public String getSoftTokenApp() {
- return mSoftTokenApp;
- }
-
- /**
- * Flag indicating if this credential is usable on other mobile devices as well.
- */
- private boolean mAbleToShare = false;
- /**
- * @hide
- */
- public void setAbleToShare(boolean ableToShare) {
- mAbleToShare = ableToShare;
- }
- /**
- * @hide
- */
- public boolean getAbleToShare() {
- return mAbleToShare;
- }
-
- /**
- * EAP (Extensible Authentication Protocol) method type.
- * Refer to
- * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4">
- * EAP Numbers</a> for valid values.
- * Using Integer.MIN_VALUE to indicate unset value.
- */
- private int mEapType = Integer.MIN_VALUE;
- /**
- * Set the EAP (Extensible Authentication Protocol) method type associated with this
- * user credential.
- * Refer to
- * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4">
- * EAP Numbers</a> for valid values.
- *
- * @param eapType The EAP method type associated with this user credential
- */
- public void setEapType(int eapType) {
- mEapType = eapType;
- }
- /**
- * Get the EAP (Extensible Authentication Protocol) method type associated with this
- * user credential.
- *
- * @return EAP method type
- */
- public int getEapType() {
- return mEapType;
- }
-
- /**
- * Non-EAP inner authentication method.
- */
- private String mNonEapInnerMethod = null;
- /**
- * Set the inner non-EAP method associated with this user credential.
- *
- * @param nonEapInnerMethod The non-EAP inner method to set to
- */
- public void setNonEapInnerMethod(String nonEapInnerMethod) {
- mNonEapInnerMethod = nonEapInnerMethod;
- }
- /**
- * Get the inner non-EAP method associated with this user credential.
- *
- * @return Non-EAP inner method associated with this user credential
- */
- public String getNonEapInnerMethod() {
- return mNonEapInnerMethod;
- }
-
- /**
- * Constructor for creating UserCredential with default values.
- */
- public UserCredential() {}
-
- /**
- * Copy constructor.
- *
- * @param source The source to copy from
- */
- public UserCredential(UserCredential source) {
- if (source != null) {
- mUsername = source.mUsername;
- mPassword = source.mPassword;
- mMachineManaged = source.mMachineManaged;
- mSoftTokenApp = source.mSoftTokenApp;
- mAbleToShare = source.mAbleToShare;
- mEapType = source.mEapType;
- mNonEapInnerMethod = source.mNonEapInnerMethod;
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mUsername);
- dest.writeString(mPassword);
- dest.writeInt(mMachineManaged ? 1 : 0);
- dest.writeString(mSoftTokenApp);
- dest.writeInt(mAbleToShare ? 1 : 0);
- dest.writeInt(mEapType);
- dest.writeString(mNonEapInnerMethod);
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof UserCredential)) {
- return false;
- }
-
- UserCredential that = (UserCredential) thatObject;
- return TextUtils.equals(mUsername, that.mUsername)
- && TextUtils.equals(mPassword, that.mPassword)
- && mMachineManaged == that.mMachineManaged
- && TextUtils.equals(mSoftTokenApp, that.mSoftTokenApp)
- && mAbleToShare == that.mAbleToShare
- && mEapType == that.mEapType
- && TextUtils.equals(mNonEapInnerMethod, that.mNonEapInnerMethod);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mUsername, mPassword, mMachineManaged, mSoftTokenApp,
- mAbleToShare, mEapType, mNonEapInnerMethod);
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("Username: ").append(mUsername).append("\n");
- builder.append("MachineManaged: ").append(mMachineManaged).append("\n");
- builder.append("SoftTokenApp: ").append(mSoftTokenApp).append("\n");
- builder.append("AbleToShare: ").append(mAbleToShare).append("\n");
- builder.append("EAPType: ").append(mEapType).append("\n");
- builder.append("AuthMethod: ").append(mNonEapInnerMethod).append("\n");
- return builder.toString();
- }
-
- /**
- * Validate the configuration data.
- *
- * @return true on success or false on failure
- * @hide
- */
- public boolean validate() {
- if (TextUtils.isEmpty(mUsername)) {
- Log.d(TAG, "Missing username");
- return false;
- }
- if (mUsername.getBytes(StandardCharsets.UTF_8).length > MAX_USERNAME_BYTES) {
- Log.d(TAG, "username exceeding maximum length: "
- + mUsername.getBytes(StandardCharsets.UTF_8).length);
- return false;
- }
-
- if (TextUtils.isEmpty(mPassword)) {
- Log.d(TAG, "Missing password");
- return false;
- }
- if (mPassword.getBytes(StandardCharsets.UTF_8).length > MAX_PASSWORD_BYTES) {
- Log.d(TAG, "password exceeding maximum length: "
- + mPassword.getBytes(StandardCharsets.UTF_8).length);
- return false;
- }
-
- // Only supports EAP-TTLS for user credential.
- if (mEapType != EAPConstants.EAP_TTLS) {
- Log.d(TAG, "Invalid EAP Type for user credential: " + mEapType);
- return false;
- }
-
- // Verify Non-EAP inner method for EAP-TTLS.
- if (!SUPPORTED_AUTH.contains(mNonEapInnerMethod)) {
- Log.d(TAG, "Invalid non-EAP inner method for EAP-TTLS: " + mNonEapInnerMethod);
- return false;
- }
- return true;
- }
-
- public static final @android.annotation.NonNull Creator<UserCredential> CREATOR =
- new Creator<UserCredential>() {
- @Override
- public UserCredential createFromParcel(Parcel in) {
- UserCredential userCredential = new UserCredential();
- userCredential.setUsername(in.readString());
- userCredential.setPassword(in.readString());
- userCredential.setMachineManaged(in.readInt() != 0);
- userCredential.setSoftTokenApp(in.readString());
- userCredential.setAbleToShare(in.readInt() != 0);
- userCredential.setEapType(in.readInt());
- userCredential.setNonEapInnerMethod(in.readString());
- return userCredential;
- }
-
- @Override
- public UserCredential[] newArray(int size) {
- return new UserCredential[size];
- }
- };
- }
- private UserCredential mUserCredential = null;
- /**
- * Set the user credential information.
- *
- * @param userCredential The user credential to set to
- */
- public void setUserCredential(UserCredential userCredential) {
- mUserCredential = userCredential;
- }
- /**
- * Get the user credential information.
- *
- * @return user credential information
- */
- public UserCredential getUserCredential() {
- return mUserCredential;
- }
-
- /**
- * Certificate based credential. This is used for EAP-TLS.
- * Contains fields under PerProviderSubscription/Credential/DigitalCertificate subtree.
- */
- public static final class CertificateCredential implements Parcelable {
- /**
- * Supported certificate types.
- * @hide
- */
- public static final String CERT_TYPE_X509V3 = "x509v3";
-
- /**
- * Certificate SHA-256 fingerprint length.
- */
- private static final int CERT_SHA256_FINGER_PRINT_LENGTH = 32;
-
- /**
- * Certificate type.
- */
- private String mCertType = null;
- /**
- * Set the certificate type associated with this certificate credential.
- *
- * @param certType The certificate type to set to
- */
- public void setCertType(String certType) {
- mCertType = certType;
- }
- /**
- * Get the certificate type associated with this certificate credential.
- *
- * @return certificate type
- */
- public String getCertType() {
- return mCertType;
- }
-
- /**
- * The SHA-256 fingerprint of the certificate.
- */
- private byte[] mCertSha256Fingerprint = null;
- /**
- * Set the certificate SHA-256 fingerprint associated with this certificate credential.
- *
- * @param certSha256Fingerprint The certificate fingerprint to set to
- */
- public void setCertSha256Fingerprint(byte[] certSha256Fingerprint) {
- mCertSha256Fingerprint = certSha256Fingerprint;
- }
- /**
- * Get the certificate SHA-256 fingerprint associated with this certificate credential.
- *
- * @return certificate SHA-256 fingerprint
- */
- public byte[] getCertSha256Fingerprint() {
- return mCertSha256Fingerprint;
- }
-
- /**
- * Constructor for creating CertificateCredential with default values.
- */
- public CertificateCredential() {}
-
- /**
- * Copy constructor.
- *
- * @param source The source to copy from
- */
- public CertificateCredential(CertificateCredential source) {
- if (source != null) {
- mCertType = source.mCertType;
- if (source.mCertSha256Fingerprint != null) {
- mCertSha256Fingerprint = Arrays.copyOf(source.mCertSha256Fingerprint,
- source.mCertSha256Fingerprint.length);
- }
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mCertType);
- dest.writeByteArray(mCertSha256Fingerprint);
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof CertificateCredential)) {
- return false;
- }
-
- CertificateCredential that = (CertificateCredential) thatObject;
- return TextUtils.equals(mCertType, that.mCertType)
- && Arrays.equals(mCertSha256Fingerprint, that.mCertSha256Fingerprint);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mCertType, Arrays.hashCode(mCertSha256Fingerprint));
- }
-
- @Override
- public String toString() {
- return "CertificateType: " + mCertType + "\n";
- }
-
- /**
- * Validate the configuration data.
- *
- * @return true on success or false on failure
- * @hide
- */
- public boolean validate() {
- if (!TextUtils.equals(CERT_TYPE_X509V3, mCertType)) {
- Log.d(TAG, "Unsupported certificate type: " + mCertType);
- return false;
- }
- if (mCertSha256Fingerprint == null
- || mCertSha256Fingerprint.length != CERT_SHA256_FINGER_PRINT_LENGTH) {
- Log.d(TAG, "Invalid SHA-256 fingerprint");
- return false;
- }
- return true;
- }
-
- public static final @android.annotation.NonNull Creator<CertificateCredential> CREATOR =
- new Creator<CertificateCredential>() {
- @Override
- public CertificateCredential createFromParcel(Parcel in) {
- CertificateCredential certCredential = new CertificateCredential();
- certCredential.setCertType(in.readString());
- certCredential.setCertSha256Fingerprint(in.createByteArray());
- return certCredential;
- }
-
- @Override
- public CertificateCredential[] newArray(int size) {
- return new CertificateCredential[size];
- }
- };
- }
- private CertificateCredential mCertCredential = null;
- /**
- * Set the certificate credential information.
- *
- * @param certCredential The certificate credential to set to
- */
- public void setCertCredential(CertificateCredential certCredential) {
- mCertCredential = certCredential;
- }
- /**
- * Get the certificate credential information.
- *
- * @return certificate credential information
- */
- public CertificateCredential getCertCredential() {
- return mCertCredential;
- }
-
- /**
- * SIM (Subscriber Identify Module) based credential.
- * Contains fields under PerProviderSubscription/Credential/SIM subtree.
- */
- public static final class SimCredential implements Parcelable {
- /**
- * Maximum string length for IMSI.
- */
- private static final int MAX_IMSI_LENGTH = 15;
-
- /**
- * International Mobile Subscriber Identity, is used to identify the user
- * of a cellular network and is a unique identification associated with all
- * cellular networks
- */
- private String mImsi = null;
- /**
- * Set the IMSI (International Mobile Subscriber Identity) associated with this SIM
- * credential.
- *
- * @param imsi The IMSI to set to
- */
- public void setImsi(String imsi) {
- mImsi = imsi;
- }
- /**
- * Get the IMSI (International Mobile Subscriber Identity) associated with this SIM
- * credential.
- *
- * @return IMSI associated with this SIM credential
- */
- public String getImsi() {
- return mImsi;
- }
-
- /**
- * EAP (Extensible Authentication Protocol) method type for using SIM credential.
- * Refer to http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4
- * for valid values.
- * Using Integer.MIN_VALUE to indicate unset value.
- */
- private int mEapType = Integer.MIN_VALUE;
- /**
- * Set the EAP (Extensible Authentication Protocol) method type associated with this
- * SIM credential.
- *
- * @param eapType The EAP method type to set to
- */
- public void setEapType(int eapType) {
- mEapType = eapType;
- }
- /**
- * Get the EAP (Extensible Authentication Protocol) method type associated with this
- * SIM credential.
- *
- * @return EAP method type associated with this SIM credential
- */
- public int getEapType() {
- return mEapType;
- }
-
- /**
- * Constructor for creating SimCredential with default values.
- */
- public SimCredential() {}
-
- /**
- * Copy constructor
- *
- * @param source The source to copy from
- */
- public SimCredential(SimCredential source) {
- if (source != null) {
- mImsi = source.mImsi;
- mEapType = source.mEapType;
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof SimCredential)) {
- return false;
- }
-
- SimCredential that = (SimCredential) thatObject;
- return TextUtils.equals(mImsi, that.mImsi)
- && mEapType == that.mEapType;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mImsi, mEapType);
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- String imsi;
- if (mImsi != null) {
- if (mImsi.length() > 6 && mImsi.charAt(6) != '*') {
- // Truncate the full IMSI from the log
- imsi = mImsi.substring(0, 6) + "****";
- } else {
- imsi = mImsi;
- }
- builder.append("IMSI: ").append(imsi).append("\n");
- }
- builder.append("EAPType: ").append(mEapType).append("\n");
- return builder.toString();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mImsi);
- dest.writeInt(mEapType);
- }
-
- /**
- * Validate the configuration data.
- *
- * @return true on success or false on failure
- * @hide
- */
- public boolean validate() {
- // Note: this only validate the format of IMSI string itself. Additional verification
- // will be done by WifiService at the time of provisioning to verify against the IMSI
- // of the SIM card installed in the device.
- if (!verifyImsi()) {
- return false;
- }
- if (mEapType != EAPConstants.EAP_SIM && mEapType != EAPConstants.EAP_AKA
- && mEapType != EAPConstants.EAP_AKA_PRIME) {
- Log.d(TAG, "Invalid EAP Type for SIM credential: " + mEapType);
- return false;
- }
- return true;
- }
-
- public static final @android.annotation.NonNull Creator<SimCredential> CREATOR =
- new Creator<SimCredential>() {
- @Override
- public SimCredential createFromParcel(Parcel in) {
- SimCredential simCredential = new SimCredential();
- simCredential.setImsi(in.readString());
- simCredential.setEapType(in.readInt());
- return simCredential;
- }
-
- @Override
- public SimCredential[] newArray(int size) {
- return new SimCredential[size];
- }
- };
-
- /**
- * Verify the IMSI (International Mobile Subscriber Identity) string. The string
- * should contain zero or more numeric digits, and might ends with a "*" for prefix
- * matching.
- *
- * @return true if IMSI is valid, false otherwise.
- */
- private boolean verifyImsi() {
- if (TextUtils.isEmpty(mImsi)) {
- Log.d(TAG, "Missing IMSI");
- return false;
- }
- if (mImsi.length() > MAX_IMSI_LENGTH) {
- Log.d(TAG, "IMSI exceeding maximum length: " + mImsi.length());
- return false;
- }
-
- // Locate the first non-digit character.
- int nonDigit;
- char stopChar = '\0';
- for (nonDigit = 0; nonDigit < mImsi.length(); nonDigit++) {
- stopChar = mImsi.charAt(nonDigit);
- if (stopChar < '0' || stopChar > '9') {
- break;
- }
- }
-
- if (nonDigit == mImsi.length()) {
- return true;
- }
- else if (nonDigit == mImsi.length()-1 && stopChar == '*') {
- // Prefix matching.
- return true;
- }
- return false;
- }
- }
- private SimCredential mSimCredential = null;
- /**
- * Set the SIM credential information.
- *
- * @param simCredential The SIM credential to set to
- */
- public void setSimCredential(SimCredential simCredential) {
- mSimCredential = simCredential;
- }
- /**
- * Get the SIM credential information.
- *
- * @return SIM credential information
- */
- public SimCredential getSimCredential() {
- return mSimCredential;
- }
-
- /**
- * CA (Certificate Authority) X509 certificates.
- */
- private X509Certificate[] mCaCertificates = null;
-
- /**
- * Set the CA (Certification Authority) certificate associated with this credential.
- *
- * @param caCertificate The CA certificate to set to
- */
- public void setCaCertificate(X509Certificate caCertificate) {
- mCaCertificates = null;
- if (caCertificate != null) {
- mCaCertificates = new X509Certificate[] {caCertificate};
- }
- }
-
- /**
- * Set the CA (Certification Authority) certificates associated with this credential.
- *
- * @param caCertificates The list of CA certificates to set to
- * @hide
- */
- public void setCaCertificates(X509Certificate[] caCertificates) {
- mCaCertificates = caCertificates;
- }
-
- /**
- * Get the CA (Certification Authority) certificate associated with this credential.
- *
- * @return CA certificate associated with this credential, {@code null} if certificate is not
- * set or certificate is more than one.
- */
- public X509Certificate getCaCertificate() {
- return mCaCertificates == null || mCaCertificates.length > 1 ? null : mCaCertificates[0];
- }
-
- /**
- * Get the CA (Certification Authority) certificates associated with this credential.
- *
- * @return The list of CA certificates associated with this credential
- * @hide
- */
- public X509Certificate[] getCaCertificates() {
- return mCaCertificates;
- }
-
- /**
- * Client side X509 certificate chain.
- */
- private X509Certificate[] mClientCertificateChain = null;
- /**
- * Set the client certificate chain associated with this credential.
- *
- * @param certificateChain The client certificate chain to set to
- */
- public void setClientCertificateChain(X509Certificate[] certificateChain) {
- mClientCertificateChain = certificateChain;
- }
- /**
- * Get the client certificate chain associated with this credential.
- *
- * @return client certificate chain associated with this credential
- */
- public X509Certificate[] getClientCertificateChain() {
- return mClientCertificateChain;
- }
-
- /**
- * Client side private key.
- */
- private PrivateKey mClientPrivateKey = null;
- /**
- * Set the client private key associated with this credential.
- *
- * @param clientPrivateKey the client private key to set to
- */
- public void setClientPrivateKey(PrivateKey clientPrivateKey) {
- mClientPrivateKey = clientPrivateKey;
- }
- /**
- * Get the client private key associated with this credential.
- *
- * @return client private key associated with this credential.
- */
- public PrivateKey getClientPrivateKey() {
- return mClientPrivateKey;
- }
-
- /**
- * Constructor for creating Credential with default values.
- */
- public Credential() {}
-
- /**
- * Copy constructor.
- *
- * @param source The source to copy from
- */
- public Credential(Credential source) {
- if (source != null) {
- mCreationTimeInMillis = source.mCreationTimeInMillis;
- mExpirationTimeInMillis = source.mExpirationTimeInMillis;
- mRealm = source.mRealm;
- mCheckAaaServerCertStatus = source.mCheckAaaServerCertStatus;
- if (source.mUserCredential != null) {
- mUserCredential = new UserCredential(source.mUserCredential);
- }
- if (source.mCertCredential != null) {
- mCertCredential = new CertificateCredential(source.mCertCredential);
- }
- if (source.mSimCredential != null) {
- mSimCredential = new SimCredential(source.mSimCredential);
- }
- if (source.mClientCertificateChain != null) {
- mClientCertificateChain = Arrays.copyOf(source.mClientCertificateChain,
- source.mClientCertificateChain.length);
- }
- if (source.mCaCertificates != null) {
- mCaCertificates = Arrays.copyOf(source.mCaCertificates,
- source.mCaCertificates.length);
- }
-
- mClientPrivateKey = source.mClientPrivateKey;
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(mCreationTimeInMillis);
- dest.writeLong(mExpirationTimeInMillis);
- dest.writeString(mRealm);
- dest.writeInt(mCheckAaaServerCertStatus ? 1 : 0);
- dest.writeParcelable(mUserCredential, flags);
- dest.writeParcelable(mCertCredential, flags);
- dest.writeParcelable(mSimCredential, flags);
- ParcelUtil.writeCertificates(dest, mCaCertificates);
- ParcelUtil.writeCertificates(dest, mClientCertificateChain);
- ParcelUtil.writePrivateKey(dest, mClientPrivateKey);
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof Credential)) {
- return false;
- }
-
- Credential that = (Credential) thatObject;
- return TextUtils.equals(mRealm, that.mRealm)
- && mCreationTimeInMillis == that.mCreationTimeInMillis
- && mExpirationTimeInMillis == that.mExpirationTimeInMillis
- && mCheckAaaServerCertStatus == that.mCheckAaaServerCertStatus
- && (mUserCredential == null ? that.mUserCredential == null
- : mUserCredential.equals(that.mUserCredential))
- && (mCertCredential == null ? that.mCertCredential == null
- : mCertCredential.equals(that.mCertCredential))
- && (mSimCredential == null ? that.mSimCredential == null
- : mSimCredential.equals(that.mSimCredential))
- && isX509CertificatesEquals(mCaCertificates, that.mCaCertificates)
- && isX509CertificatesEquals(mClientCertificateChain, that.mClientCertificateChain)
- && isPrivateKeyEquals(mClientPrivateKey, that.mClientPrivateKey);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mCreationTimeInMillis, mExpirationTimeInMillis, mRealm,
- mCheckAaaServerCertStatus, mUserCredential, mCertCredential, mSimCredential,
- mClientPrivateKey, Arrays.hashCode(mCaCertificates),
- Arrays.hashCode(mClientCertificateChain));
- }
-
- /**
- * Get a unique identifier for Credential. This identifier depends only on items that remain
- * constant throughout the lifetime of a subscription's credentials.
- *
- * @hide
- * @return a Unique identifier for a Credential object
- */
- public int getUniqueId() {
- return Objects.hash(mUserCredential, mCertCredential, mSimCredential, mRealm);
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("Realm: ").append(mRealm).append("\n");
- builder.append("CreationTime: ").append(mCreationTimeInMillis != Long.MIN_VALUE
- ? new Date(mCreationTimeInMillis) : "Not specified").append("\n");
- builder.append("ExpirationTime: ").append(mExpirationTimeInMillis != Long.MIN_VALUE
- ? new Date(mExpirationTimeInMillis) : "Not specified").append("\n");
- builder.append("CheckAAAServerStatus: ").append(mCheckAaaServerCertStatus).append("\n");
- if (mUserCredential != null) {
- builder.append("UserCredential Begin ---\n");
- builder.append(mUserCredential);
- builder.append("UserCredential End ---\n");
- }
- if (mCertCredential != null) {
- builder.append("CertificateCredential Begin ---\n");
- builder.append(mCertCredential);
- builder.append("CertificateCredential End ---\n");
- }
- if (mSimCredential != null) {
- builder.append("SIMCredential Begin ---\n");
- builder.append(mSimCredential);
- builder.append("SIMCredential End ---\n");
- }
- return builder.toString();
- }
-
- /**
- * Validate the configuration data.
- *
- * @return true on success or false on failure
- * @hide
- */
- public boolean validate() {
- if (TextUtils.isEmpty(mRealm)) {
- Log.d(TAG, "Missing realm");
- return false;
- }
- if (mRealm.getBytes(StandardCharsets.UTF_8).length > MAX_REALM_BYTES) {
- Log.d(TAG, "realm exceeding maximum length: "
- + mRealm.getBytes(StandardCharsets.UTF_8).length);
- return false;
- }
-
- // Verify the credential.
- if (mUserCredential != null) {
- if (!verifyUserCredential()) {
- return false;
- }
- } else if (mCertCredential != null) {
- if (!verifyCertCredential()) {
- return false;
- }
- } else if (mSimCredential != null) {
- if (!verifySimCredential()) {
- return false;
- }
- } else {
- Log.d(TAG, "Missing required credential");
- return false;
- }
-
- return true;
- }
-
- public static final @android.annotation.NonNull Creator<Credential> CREATOR =
- new Creator<Credential>() {
- @Override
- public Credential createFromParcel(Parcel in) {
- Credential credential = new Credential();
- credential.setCreationTimeInMillis(in.readLong());
- credential.setExpirationTimeInMillis(in.readLong());
- credential.setRealm(in.readString());
- credential.setCheckAaaServerCertStatus(in.readInt() != 0);
- credential.setUserCredential(in.readParcelable(null));
- credential.setCertCredential(in.readParcelable(null));
- credential.setSimCredential(in.readParcelable(null));
- credential.setCaCertificates(ParcelUtil.readCertificates(in));
- credential.setClientCertificateChain(ParcelUtil.readCertificates(in));
- credential.setClientPrivateKey(ParcelUtil.readPrivateKey(in));
- return credential;
- }
-
- @Override
- public Credential[] newArray(int size) {
- return new Credential[size];
- }
- };
-
- /**
- * Verify user credential.
- * If no CA certificate is provided, then the system uses the CAs in the trust store.
- *
- * @return true if user credential is valid, false otherwise.
- */
- private boolean verifyUserCredential() {
- if (mUserCredential == null) {
- Log.d(TAG, "Missing user credential");
- return false;
- }
- if (mCertCredential != null || mSimCredential != null) {
- Log.d(TAG, "Contained more than one type of credential");
- return false;
- }
- if (!mUserCredential.validate()) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Verify certificate credential, which is used for EAP-TLS. This will verify
- * that the necessary client key and certificates are provided.
- * If no CA certificate is provided, then the system uses the CAs in the trust store.
- *
- * @return true if certificate credential is valid, false otherwise.
- */
- private boolean verifyCertCredential() {
- if (mCertCredential == null) {
- Log.d(TAG, "Missing certificate credential");
- return false;
- }
- if (mUserCredential != null || mSimCredential != null) {
- Log.d(TAG, "Contained more than one type of credential");
- return false;
- }
-
- if (!mCertCredential.validate()) {
- return false;
- }
-
- if (mClientPrivateKey == null) {
- Log.d(TAG, "Missing client private key for certificate credential");
- return false;
- }
- try {
- // Verify SHA-256 fingerprint for client certificate.
- if (!verifySha256Fingerprint(mClientCertificateChain,
- mCertCredential.getCertSha256Fingerprint())) {
- Log.d(TAG, "SHA-256 fingerprint mismatch");
- return false;
- }
- } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
- Log.d(TAG, "Failed to verify SHA-256 fingerprint: " + e.getMessage());
- return false;
- }
-
- return true;
- }
-
- /**
- * Verify SIM credential.
- *
- * @return true if SIM credential is valid, false otherwise.
- */
- private boolean verifySimCredential() {
- if (mSimCredential == null) {
- Log.d(TAG, "Missing SIM credential");
- return false;
- }
- if (mUserCredential != null || mCertCredential != null) {
- Log.d(TAG, "Contained more than one type of credential");
- return false;
- }
- return mSimCredential.validate();
- }
-
- private static boolean isPrivateKeyEquals(PrivateKey key1, PrivateKey key2) {
- if (key1 == null && key2 == null) {
- return true;
- }
-
- /* Return false if only one of them is null */
- if (key1 == null || key2 == null) {
- return false;
- }
-
- return TextUtils.equals(key1.getAlgorithm(), key2.getAlgorithm()) &&
- Arrays.equals(key1.getEncoded(), key2.getEncoded());
- }
-
- /**
- * Verify two X.509 certificates are identical.
- *
- * @param cert1 a certificate to compare
- * @param cert2 a certificate to compare
- * @return {@code true} if given certificates are the same each other, {@code false} otherwise.
- * @hide
- */
- public static boolean isX509CertificateEquals(X509Certificate cert1, X509Certificate cert2) {
- if (cert1 == null && cert2 == null) {
- return true;
- }
-
- /* Return false if only one of them is null */
- if (cert1 == null || cert2 == null) {
- return false;
- }
-
- boolean result = false;
- try {
- result = Arrays.equals(cert1.getEncoded(), cert2.getEncoded());
- } catch (CertificateEncodingException e) {
- /* empty, return false. */
- }
- return result;
- }
-
- private static boolean isX509CertificatesEquals(X509Certificate[] certs1,
- X509Certificate[] certs2) {
- if (certs1 == null && certs2 == null) {
- return true;
- }
-
- /* Return false if only one of them is null */
- if (certs1 == null || certs2 == null) {
- return false;
- }
-
- if (certs1.length != certs2.length) {
- return false;
- }
-
- for (int i = 0; i < certs1.length; i++) {
- if (!isX509CertificateEquals(certs1[i], certs2[i])) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Verify that the digest for a certificate in the certificate chain matches expected
- * fingerprint. The certificate that matches the fingerprint is the client certificate.
- *
- * @param certChain Chain of certificates
- * @param expectedFingerprint The expected SHA-256 digest of the client certificate
- * @return true if the certificate chain contains a matching certificate, false otherwise
- * @throws NoSuchAlgorithmException
- * @throws CertificateEncodingException
- */
- private static boolean verifySha256Fingerprint(X509Certificate[] certChain,
- byte[] expectedFingerprint)
- throws NoSuchAlgorithmException, CertificateEncodingException {
- if (certChain == null) {
- return false;
- }
- MessageDigest digester = MessageDigest.getInstance("SHA-256");
- for (X509Certificate certificate : certChain) {
- digester.reset();
- byte[] fingerprint = digester.digest(certificate.getEncoded());
- if (Arrays.equals(expectedFingerprint, fingerprint)) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
deleted file mode 100644
index 224c4be..0000000
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
+++ /dev/null
@@ -1,431 +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.net.wifi.hotspot2.pps;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Class representing HomeSP subtree in PerProviderSubscription (PPS)
- * Management Object (MO) tree.
- *
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- */
-public final class HomeSp implements Parcelable {
- private static final String TAG = "HomeSp";
-
- /**
- * Maximum number of bytes allowed for a SSID.
- */
- private static final int MAX_SSID_BYTES = 32;
-
- /**
- * Integer value used for indicating null value in the Parcel.
- */
- private static final int NULL_VALUE = -1;
-
- /**
- * FQDN (Fully Qualified Domain Name) of this home service provider.
- */
- private String mFqdn = null;
- /**
- * Set the FQDN (Fully Qualified Domain Name) associated with this home service provider.
- *
- * @param fqdn The FQDN to set to
- */
- public void setFqdn(String fqdn) {
- mFqdn = fqdn;
- }
- /**
- * Get the FQDN (Fully Qualified Domain Name) associated with this home service provider.
- *
- * @return the FQDN associated with this home service provider
- */
- public String getFqdn() {
- return mFqdn;
- }
-
- /**
- * Friendly name of this home service provider.
- */
- private String mFriendlyName = null;
- /**
- * Set the friendly name associated with this home service provider.
- *
- * @param friendlyName The friendly name to set to
- */
- public void setFriendlyName(String friendlyName) {
- mFriendlyName = friendlyName;
- }
- /**
- * Get the friendly name associated with this home service provider.
- *
- * @return the friendly name associated with this home service provider
- */
- public String getFriendlyName() {
- return mFriendlyName;
- }
-
- /**
- * Icon URL of this home service provider.
- */
- private String mIconUrl = null;
- /**
- * @hide
- */
- public void setIconUrl(String iconUrl) {
- mIconUrl = iconUrl;
- }
- /**
- * @hide
- */
- public String getIconUrl() {
- return mIconUrl;
- }
-
- /**
- * <SSID, HESSID> duple of the networks that are consider home networks.
- *
- * According to the Section 9.1.2 of the Hotspot 2.0 Release 2 Technical Specification,
- * all nodes in the PSS MO are encoded using UTF-8 unless stated otherwise. Thus, the SSID
- * string is assumed to be encoded using UTF-8.
- */
- private Map<String, Long> mHomeNetworkIds = null;
- /**
- * @hide
- */
- public void setHomeNetworkIds(Map<String, Long> homeNetworkIds) {
- mHomeNetworkIds = homeNetworkIds;
- }
- /**
- * @hide
- */
- public Map<String, Long> getHomeNetworkIds() {
- return mHomeNetworkIds;
- }
-
- /**
- * Used for determining if this provider is a member of a given Hotspot provider.
- * Every Organization Identifiers (OIs) in this list are required to match an OI in the
- * the Roaming Consortium advertised by a Hotspot, in order to consider this provider
- * as a member of that Hotspot provider (e.g. successful authentication with such Hotspot
- * is possible).
- *
- * Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
- * (MO) tree for more detail.
- */
- private long[] mMatchAllOis = null;
- /**
- * @hide
- */
- public void setMatchAllOis(long[] matchAllOis) {
- mMatchAllOis = matchAllOis;
- }
- /**
- * @hide
- */
- public long[] getMatchAllOis() {
- return mMatchAllOis;
- }
-
- /**
- * Used for determining if this provider is a member of a given Hotspot provider.
- * Matching of any Organization Identifiers (OIs) in this list with an OI in the
- * Roaming Consortium advertised by a Hotspot, will consider this provider as a member
- * of that Hotspot provider (e.g. successful authentication with such Hotspot
- * is possible).
- *
- * {@link #mMatchAllOIs} will have precedence over this one, meaning this list will
- * only be used for matching if {@link #mMatchAllOIs} is null or empty.
- *
- * Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
- * (MO) tree for more detail.
- */
- private long[] mMatchAnyOis = null;
- /**
- * @hide
- */
- public void setMatchAnyOis(long[] matchAnyOis) {
- mMatchAnyOis = matchAnyOis;
- }
- /**
- * @hide
- */
- public long[] getMatchAnyOis() {
- return mMatchAnyOis;
- }
-
- /**
- * List of FQDN (Fully Qualified Domain Name) of partner providers.
- * These providers should also be regarded as home Hotspot operators.
- * This relationship is most likely achieved via a commercial agreement or
- * operator merges between the providers.
- */
- private String[] mOtherHomePartners = null;
- /**
- * @hide
- */
- public void setOtherHomePartners(String[] otherHomePartners) {
- mOtherHomePartners = otherHomePartners;
- }
- /**
- * @hide
- */
- public String[] getOtherHomePartners() {
- return mOtherHomePartners;
- }
-
- /**
- * List of Organization Identifiers (OIs) identifying a roaming consortium of
- * which this provider is a member.
- */
- private long[] mRoamingConsortiumOis = null;
- /**
- * Set the Organization Identifiers (OIs) identifying a roaming consortium of which this
- * provider is a member.
- *
- * @param roamingConsortiumOis Array of roaming consortium OIs
- */
- public void setRoamingConsortiumOis(long[] roamingConsortiumOis) {
- mRoamingConsortiumOis = roamingConsortiumOis;
- }
- /**
- * Get the Organization Identifiers (OIs) identifying a roaming consortium of which this
- * provider is a member.
- *
- * @return array of roaming consortium OIs
- */
- public long[] getRoamingConsortiumOis() {
- return mRoamingConsortiumOis;
- }
-
- /**
- * Constructor for creating HomeSp with default values.
- */
- public HomeSp() {}
-
- /**
- * Copy constructor.
- *
- * @param source The source to copy from
- */
- public HomeSp(HomeSp source) {
- if (source == null) {
- return;
- }
- mFqdn = source.mFqdn;
- mFriendlyName = source.mFriendlyName;
- mIconUrl = source.mIconUrl;
- if (source.mHomeNetworkIds != null) {
- mHomeNetworkIds = Collections.unmodifiableMap(source.mHomeNetworkIds);
- }
- if (source.mMatchAllOis != null) {
- mMatchAllOis = Arrays.copyOf(source.mMatchAllOis, source.mMatchAllOis.length);
- }
- if (source.mMatchAnyOis != null) {
- mMatchAnyOis = Arrays.copyOf(source.mMatchAnyOis, source.mMatchAnyOis.length);
- }
- if (source.mOtherHomePartners != null) {
- mOtherHomePartners = Arrays.copyOf(source.mOtherHomePartners,
- source.mOtherHomePartners.length);
- }
- if (source.mRoamingConsortiumOis != null) {
- mRoamingConsortiumOis = Arrays.copyOf(source.mRoamingConsortiumOis,
- source.mRoamingConsortiumOis.length);
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mFqdn);
- dest.writeString(mFriendlyName);
- dest.writeString(mIconUrl);
- writeHomeNetworkIds(dest, mHomeNetworkIds);
- dest.writeLongArray(mMatchAllOis);
- dest.writeLongArray(mMatchAnyOis);
- dest.writeStringArray(mOtherHomePartners);
- dest.writeLongArray(mRoamingConsortiumOis);
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof HomeSp)) {
- return false;
- }
- HomeSp that = (HomeSp) thatObject;
-
- return TextUtils.equals(mFqdn, that.mFqdn)
- && TextUtils.equals(mFriendlyName, that.mFriendlyName)
- && TextUtils.equals(mIconUrl, that.mIconUrl)
- && (mHomeNetworkIds == null ? that.mHomeNetworkIds == null
- : mHomeNetworkIds.equals(that.mHomeNetworkIds))
- && Arrays.equals(mMatchAllOis, that.mMatchAllOis)
- && Arrays.equals(mMatchAnyOis, that.mMatchAnyOis)
- && Arrays.equals(mOtherHomePartners, that.mOtherHomePartners)
- && Arrays.equals(mRoamingConsortiumOis, that.mRoamingConsortiumOis);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mFqdn, mFriendlyName, mIconUrl,
- mHomeNetworkIds, Arrays.hashCode(mMatchAllOis),
- Arrays.hashCode(mMatchAnyOis), Arrays.hashCode(mOtherHomePartners),
- Arrays.hashCode(mRoamingConsortiumOis));
- }
-
- /**
- * Get a unique identifier for HomeSp. This identifier depends only on items that remain
- * constant throughout the lifetime of a subscription.
- *
- * @hide
- * @return a Unique identifier for a HomeSp object
- */
- public int getUniqueId() {
- return Objects.hash(mFqdn, mFriendlyName, mHomeNetworkIds, Arrays.hashCode(mMatchAllOis),
- Arrays.hashCode(mMatchAnyOis), Arrays.hashCode(mOtherHomePartners),
- Arrays.hashCode(mRoamingConsortiumOis));
- }
-
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("FQDN: ").append(mFqdn).append("\n");
- builder.append("FriendlyName: ").append(mFriendlyName).append("\n");
- builder.append("IconURL: ").append(mIconUrl).append("\n");
- builder.append("HomeNetworkIDs: ").append(mHomeNetworkIds).append("\n");
- builder.append("MatchAllOIs: ").append(mMatchAllOis).append("\n");
- builder.append("MatchAnyOIs: ").append(mMatchAnyOis).append("\n");
- builder.append("OtherHomePartners: ").append(mOtherHomePartners).append("\n");
- builder.append("RoamingConsortiumOIs: ").append(mRoamingConsortiumOis).append("\n");
- return builder.toString();
- }
-
- /**
- * Validate HomeSp data.
- *
- * @return true on success or false on failure
- * @hide
- */
- public boolean validate() {
- if (TextUtils.isEmpty(mFqdn)) {
- Log.d(TAG, "Missing FQDN");
- return false;
- }
- if (TextUtils.isEmpty(mFriendlyName)) {
- Log.d(TAG, "Missing friendly name");
- return false;
- }
- // Verify SSIDs specified in the NetworkID
- if (mHomeNetworkIds != null) {
- for (Map.Entry<String, Long> entry : mHomeNetworkIds.entrySet()) {
- if (entry.getKey() == null ||
- entry.getKey().getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) {
- Log.d(TAG, "Invalid SSID in HomeNetworkIDs");
- return false;
- }
- }
- }
- return true;
- }
-
- public static final @android.annotation.NonNull Creator<HomeSp> CREATOR =
- new Creator<HomeSp>() {
- @Override
- public HomeSp createFromParcel(Parcel in) {
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(in.readString());
- homeSp.setFriendlyName(in.readString());
- homeSp.setIconUrl(in.readString());
- homeSp.setHomeNetworkIds(readHomeNetworkIds(in));
- homeSp.setMatchAllOis(in.createLongArray());
- homeSp.setMatchAnyOis(in.createLongArray());
- homeSp.setOtherHomePartners(in.createStringArray());
- homeSp.setRoamingConsortiumOis(in.createLongArray());
- return homeSp;
- }
-
- @Override
- public HomeSp[] newArray(int size) {
- return new HomeSp[size];
- }
-
- /**
- * Helper function for reading a Home Network IDs map from a Parcel.
- *
- * @param in The Parcel to read from
- * @return Map of home network IDs
- */
- private Map<String, Long> readHomeNetworkIds(Parcel in) {
- int size = in.readInt();
- if (size == NULL_VALUE) {
- return null;
- }
- Map<String, Long> networkIds = new HashMap<>(size);
- for (int i = 0; i < size; i++) {
- String key = in.readString();
- Long value = null;
- long readValue = in.readLong();
- if (readValue != NULL_VALUE) {
- value = Long.valueOf(readValue);
- }
- networkIds.put(key, value);
- }
- return networkIds;
- }
- };
-
- /**
- * Helper function for writing Home Network IDs map to a Parcel.
- *
- * @param dest The Parcel to write to
- * @param networkIds The map of home network IDs
- */
- private static void writeHomeNetworkIds(Parcel dest, Map<String, Long> networkIds) {
- if (networkIds == null) {
- dest.writeInt(NULL_VALUE);
- return;
- }
- dest.writeInt(networkIds.size());
- for (Map.Entry<String, Long> entry : networkIds.entrySet()) {
- dest.writeString(entry.getKey());
- if (entry.getValue() == null) {
- dest.writeLong(NULL_VALUE);
- } else {
- dest.writeLong(entry.getValue());
- }
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
deleted file mode 100644
index b0a2cc3..0000000
--- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/**
- * Copyright (c) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.pps;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Class representing Policy subtree in PerProviderSubscription (PPS)
- * Management Object (MO) tree.
- *
- * The Policy specifies additional criteria for Passpoint network selections, such as preferred
- * roaming partner, minimum backhaul bandwidth, and etc. It also provides the meta data for
- * updating the policy.
- *
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- *
- * @hide
- */
-public final class Policy implements Parcelable {
- private static final String TAG = "Policy";
-
- /**
- * Maximum number of SSIDs in the exclusion list.
- */
- private static final int MAX_EXCLUSION_SSIDS = 128;
-
- /**
- * Maximum byte for SSID.
- */
- private static final int MAX_SSID_BYTES = 32;
-
- /**
- * Maximum bytes for port string in {@link #requiredProtoPortMap}.
- */
- private static final int MAX_PORT_STRING_BYTES = 64;
-
- /**
- * Integer value used for indicating null value in the Parcel.
- */
- private static final int NULL_VALUE = -1;
-
- /**
- * Minimum available downlink/uplink bandwidth (in kilobits per second) required when
- * selecting a network from home providers.
- *
- * The bandwidth is calculated as the LinkSpeed * (1 – LinkLoad/255), where LinkSpeed
- * and LinkLoad parameters are drawn from the WAN Metrics ANQP element at that hotspot.
- *
- * Using Long.MIN_VALUE to indicate unset value.
- */
- private long mMinHomeDownlinkBandwidth = Long.MIN_VALUE;
- public void setMinHomeDownlinkBandwidth(long minHomeDownlinkBandwidth) {
- mMinHomeDownlinkBandwidth = minHomeDownlinkBandwidth;
- }
- public long getMinHomeDownlinkBandwidth() {
- return mMinHomeDownlinkBandwidth;
- }
- private long mMinHomeUplinkBandwidth = Long.MIN_VALUE;
- public void setMinHomeUplinkBandwidth(long minHomeUplinkBandwidth) {
- mMinHomeUplinkBandwidth = minHomeUplinkBandwidth;
- }
- public long getMinHomeUplinkBandwidth() {
- return mMinHomeUplinkBandwidth;
- }
-
- /**
- * Minimum available downlink/uplink bandwidth (in kilobits per second) required when
- * selecting a network from roaming providers.
- *
- * The bandwidth is calculated as the LinkSpeed * (1 – LinkLoad/255), where LinkSpeed
- * and LinkLoad parameters are drawn from the WAN Metrics ANQP element at that hotspot.
- *
- * Using Long.MIN_VALUE to indicate unset value.
- */
- private long mMinRoamingDownlinkBandwidth = Long.MIN_VALUE;
- public void setMinRoamingDownlinkBandwidth(long minRoamingDownlinkBandwidth) {
- mMinRoamingDownlinkBandwidth = minRoamingDownlinkBandwidth;
- }
- public long getMinRoamingDownlinkBandwidth() {
- return mMinRoamingDownlinkBandwidth;
- }
- private long mMinRoamingUplinkBandwidth = Long.MIN_VALUE;
- public void setMinRoamingUplinkBandwidth(long minRoamingUplinkBandwidth) {
- mMinRoamingUplinkBandwidth = minRoamingUplinkBandwidth;
- }
- public long getMinRoamingUplinkBandwidth() {
- return mMinRoamingUplinkBandwidth;
- }
-
- /**
- * List of SSIDs that are not preferred by the Home SP.
- */
- private String[] mExcludedSsidList = null;
- public void setExcludedSsidList(String[] excludedSsidList) {
- mExcludedSsidList = excludedSsidList;
- }
- public String[] getExcludedSsidList() {
- return mExcludedSsidList;
- }
-
- /**
- * List of IP protocol and port number required by one or more operator supported application.
- * The port string contained one or more port numbers delimited by ",".
- */
- private Map<Integer, String> mRequiredProtoPortMap = null;
- public void setRequiredProtoPortMap(Map<Integer, String> requiredProtoPortMap) {
- mRequiredProtoPortMap = requiredProtoPortMap;
- }
- public Map<Integer, String> getRequiredProtoPortMap() {
- return mRequiredProtoPortMap;
- }
-
- /**
- * This specifies the maximum acceptable BSS load policy. This is used to prevent device
- * from joining an AP whose channel is overly congested with traffic.
- * Using Integer.MIN_VALUE to indicate unset value.
- */
- private int mMaximumBssLoadValue = Integer.MIN_VALUE;
- public void setMaximumBssLoadValue(int maximumBssLoadValue) {
- mMaximumBssLoadValue = maximumBssLoadValue;
- }
- public int getMaximumBssLoadValue() {
- return mMaximumBssLoadValue;
- }
-
- /**
- * Policy associated with a roaming provider. This specifies a priority associated
- * with a roaming provider for given list of countries.
- *
- * Contains field under PerProviderSubscription/Policy/PreferredRoamingPartnerList.
- */
- public static final class RoamingPartner implements Parcelable {
- /**
- * FQDN of the roaming partner.
- */
- private String mFqdn = null;
- public void setFqdn(String fqdn) {
- mFqdn = fqdn;
- }
- public String getFqdn() {
- return mFqdn;
- }
-
- /**
- * Flag indicating the exact match of FQDN is required for FQDN matching.
- *
- * When this flag is set to false, sub-domain matching is used. For example, when
- * {@link #fqdn} s set to "example.com", "host.example.com" would be a match.
- */
- private boolean mFqdnExactMatch = false;
- public void setFqdnExactMatch(boolean fqdnExactMatch) {
- mFqdnExactMatch = fqdnExactMatch;
- }
- public boolean getFqdnExactMatch() {
- return mFqdnExactMatch;
- }
-
- /**
- * Priority associated with this roaming partner policy.
- * Using Integer.MIN_VALUE to indicate unset value.
- */
- private int mPriority = Integer.MIN_VALUE;
- public void setPriority(int priority) {
- mPriority = priority;
- }
- public int getPriority() {
- return mPriority;
- }
-
- /**
- * A string contained One or more, comma delimited (i.e., ",") ISO/IEC 3166-1 two
- * character country strings or the country-independent value, "*".
- */
- private String mCountries = null;
- public void setCountries(String countries) {
- mCountries = countries;
- }
- public String getCountries() {
- return mCountries;
- }
-
- public RoamingPartner() {}
-
- public RoamingPartner(RoamingPartner source) {
- if (source != null) {
- mFqdn = source.mFqdn;
- mFqdnExactMatch = source.mFqdnExactMatch;
- mPriority = source.mPriority;
- mCountries = source.mCountries;
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mFqdn);
- dest.writeInt(mFqdnExactMatch ? 1 : 0);
- dest.writeInt(mPriority);
- dest.writeString(mCountries);
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof RoamingPartner)) {
- return false;
- }
-
- RoamingPartner that = (RoamingPartner) thatObject;
- return TextUtils.equals(mFqdn, that.mFqdn)
- && mFqdnExactMatch == that.mFqdnExactMatch
- && mPriority == that.mPriority
- && TextUtils.equals(mCountries, that.mCountries);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mFqdn, mFqdnExactMatch, mPriority, mCountries);
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("FQDN: ").append(mFqdn).append("\n");
- builder.append("ExactMatch: ").append("mFqdnExactMatch").append("\n");
- builder.append("Priority: ").append(mPriority).append("\n");
- builder.append("Countries: ").append(mCountries).append("\n");
- return builder.toString();
- }
-
- /**
- * Validate RoamingParnter data.
- *
- * @return true on success
- * @hide
- */
- public boolean validate() {
- if (TextUtils.isEmpty(mFqdn)) {
- Log.d(TAG, "Missing FQDN");
- return false;
- }
- if (TextUtils.isEmpty(mCountries)) {
- Log.d(TAG, "Missing countries");
- return false;
- }
- return true;
- }
-
- public static final @android.annotation.NonNull Creator<RoamingPartner> CREATOR =
- new Creator<RoamingPartner>() {
- @Override
- public RoamingPartner createFromParcel(Parcel in) {
- RoamingPartner roamingPartner = new RoamingPartner();
- roamingPartner.setFqdn(in.readString());
- roamingPartner.setFqdnExactMatch(in.readInt() != 0);
- roamingPartner.setPriority(in.readInt());
- roamingPartner.setCountries(in.readString());
- return roamingPartner;
- }
-
- @Override
- public RoamingPartner[] newArray(int size) {
- return new RoamingPartner[size];
- }
- };
- }
- private List<RoamingPartner> mPreferredRoamingPartnerList = null;
- public void setPreferredRoamingPartnerList(List<RoamingPartner> partnerList) {
- mPreferredRoamingPartnerList = partnerList;
- }
- public List<RoamingPartner> getPreferredRoamingPartnerList() {
- return mPreferredRoamingPartnerList;
- }
-
- /**
- * Meta data used for policy update.
- */
- private UpdateParameter mPolicyUpdate = null;
- public void setPolicyUpdate(UpdateParameter policyUpdate) {
- mPolicyUpdate = policyUpdate;
- }
- public UpdateParameter getPolicyUpdate() {
- return mPolicyUpdate;
- }
-
- /**
- * Constructor for creating Policy with default values.
- */
- public Policy() {}
-
- /**
- * Copy constructor.
- *
- * @param source The source to copy from
- */
- public Policy(Policy source) {
- if (source == null) {
- return;
- }
- mMinHomeDownlinkBandwidth = source.mMinHomeDownlinkBandwidth;
- mMinHomeUplinkBandwidth = source.mMinHomeUplinkBandwidth;
- mMinRoamingDownlinkBandwidth = source.mMinRoamingDownlinkBandwidth;
- mMinRoamingUplinkBandwidth = source.mMinRoamingUplinkBandwidth;
- mMaximumBssLoadValue = source.mMaximumBssLoadValue;
- if (source.mExcludedSsidList != null) {
- mExcludedSsidList = Arrays.copyOf(source.mExcludedSsidList,
- source.mExcludedSsidList.length);
- }
- if (source.mRequiredProtoPortMap != null) {
- mRequiredProtoPortMap = Collections.unmodifiableMap(source.mRequiredProtoPortMap);
- }
- if (source.mPreferredRoamingPartnerList != null) {
- mPreferredRoamingPartnerList = Collections.unmodifiableList(
- source.mPreferredRoamingPartnerList);
- }
- if (source.mPolicyUpdate != null) {
- mPolicyUpdate = new UpdateParameter(source.mPolicyUpdate);
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(mMinHomeDownlinkBandwidth);
- dest.writeLong(mMinHomeUplinkBandwidth);
- dest.writeLong(mMinRoamingDownlinkBandwidth);
- dest.writeLong(mMinRoamingUplinkBandwidth);
- dest.writeStringArray(mExcludedSsidList);
- writeProtoPortMap(dest, mRequiredProtoPortMap);
- dest.writeInt(mMaximumBssLoadValue);
- writeRoamingPartnerList(dest, flags, mPreferredRoamingPartnerList);
- dest.writeParcelable(mPolicyUpdate, flags);
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof Policy)) {
- return false;
- }
- Policy that = (Policy) thatObject;
-
- return mMinHomeDownlinkBandwidth == that.mMinHomeDownlinkBandwidth
- && mMinHomeUplinkBandwidth == that.mMinHomeUplinkBandwidth
- && mMinRoamingDownlinkBandwidth == that.mMinRoamingDownlinkBandwidth
- && mMinRoamingUplinkBandwidth == that.mMinRoamingUplinkBandwidth
- && Arrays.equals(mExcludedSsidList, that.mExcludedSsidList)
- && (mRequiredProtoPortMap == null ? that.mRequiredProtoPortMap == null
- : mRequiredProtoPortMap.equals(that.mRequiredProtoPortMap))
- && mMaximumBssLoadValue == that.mMaximumBssLoadValue
- && (mPreferredRoamingPartnerList == null
- ? that.mPreferredRoamingPartnerList == null
- : mPreferredRoamingPartnerList.equals(that.mPreferredRoamingPartnerList))
- && (mPolicyUpdate == null ? that.mPolicyUpdate == null
- : mPolicyUpdate.equals(that.mPolicyUpdate));
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mMinHomeDownlinkBandwidth, mMinHomeUplinkBandwidth,
- mMinRoamingDownlinkBandwidth, mMinRoamingUplinkBandwidth, mExcludedSsidList,
- mRequiredProtoPortMap, mMaximumBssLoadValue, mPreferredRoamingPartnerList,
- mPolicyUpdate);
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("MinHomeDownlinkBandwidth: ").append(mMinHomeDownlinkBandwidth)
- .append("\n");
- builder.append("MinHomeUplinkBandwidth: ").append(mMinHomeUplinkBandwidth).append("\n");
- builder.append("MinRoamingDownlinkBandwidth: ").append(mMinRoamingDownlinkBandwidth)
- .append("\n");
- builder.append("MinRoamingUplinkBandwidth: ").append(mMinRoamingUplinkBandwidth)
- .append("\n");
- builder.append("ExcludedSSIDList: ").append(mExcludedSsidList).append("\n");
- builder.append("RequiredProtoPortMap: ").append(mRequiredProtoPortMap).append("\n");
- builder.append("MaximumBSSLoadValue: ").append(mMaximumBssLoadValue).append("\n");
- builder.append("PreferredRoamingPartnerList: ").append(mPreferredRoamingPartnerList)
- .append("\n");
- if (mPolicyUpdate != null) {
- builder.append("PolicyUpdate Begin ---\n");
- builder.append(mPolicyUpdate);
- builder.append("PolicyUpdate End ---\n");
- }
- return builder.toString();
- }
-
- /**
- * Validate Policy data.
- *
- * @return true on success
- * @hide
- */
- public boolean validate() {
- if (mPolicyUpdate == null) {
- Log.d(TAG, "PolicyUpdate not specified");
- return false;
- }
- if (!mPolicyUpdate.validate()) {
- return false;
- }
-
- // Validate SSID exclusion list.
- if (mExcludedSsidList != null) {
- if (mExcludedSsidList.length > MAX_EXCLUSION_SSIDS) {
- Log.d(TAG, "SSID exclusion list size exceeded the max: "
- + mExcludedSsidList.length);
- return false;
- }
- for (String ssid : mExcludedSsidList) {
- if (ssid.getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) {
- Log.d(TAG, "Invalid SSID: " + ssid);
- return false;
- }
- }
- }
- // Validate required protocol to port map.
- if (mRequiredProtoPortMap != null) {
- for (Map.Entry<Integer, String> entry : mRequiredProtoPortMap.entrySet()) {
- String portNumber = entry.getValue();
- if (portNumber.getBytes(StandardCharsets.UTF_8).length > MAX_PORT_STRING_BYTES) {
- Log.d(TAG, "PortNumber string bytes exceeded the max: " + portNumber);
- return false;
- }
- }
- }
- // Validate preferred roaming partner list.
- if (mPreferredRoamingPartnerList != null) {
- for (RoamingPartner partner : mPreferredRoamingPartnerList) {
- if (!partner.validate()) {
- return false;
- }
- }
- }
- return true;
- }
-
- public static final @android.annotation.NonNull Creator<Policy> CREATOR =
- new Creator<Policy>() {
- @Override
- public Policy createFromParcel(Parcel in) {
- Policy policy = new Policy();
- policy.setMinHomeDownlinkBandwidth(in.readLong());
- policy.setMinHomeUplinkBandwidth(in.readLong());
- policy.setMinRoamingDownlinkBandwidth(in.readLong());
- policy.setMinRoamingUplinkBandwidth(in.readLong());
- policy.setExcludedSsidList(in.createStringArray());
- policy.setRequiredProtoPortMap(readProtoPortMap(in));
- policy.setMaximumBssLoadValue(in.readInt());
- policy.setPreferredRoamingPartnerList(readRoamingPartnerList(in));
- policy.setPolicyUpdate(in.readParcelable(null));
- return policy;
- }
-
- @Override
- public Policy[] newArray(int size) {
- return new Policy[size];
- }
-
- /**
- * Helper function for reading IP Protocol to Port Number map from a Parcel.
- *
- * @param in The Parcel to read from
- * @return Map of IP protocol to port number
- */
- private Map<Integer, String> readProtoPortMap(Parcel in) {
- int size = in.readInt();
- if (size == NULL_VALUE) {
- return null;
- }
- Map<Integer, String> protoPortMap = new HashMap<>(size);
- for (int i = 0; i < size; i++) {
- int key = in.readInt();
- String value = in.readString();
- protoPortMap.put(key, value);
- }
- return protoPortMap;
- }
-
- /**
- * Helper function for reading roaming partner list from a Parcel.
- *
- * @param in The Parcel to read from
- * @return List of roaming partners
- */
- private List<RoamingPartner> readRoamingPartnerList(Parcel in) {
- int size = in.readInt();
- if (size == NULL_VALUE) {
- return null;
- }
- List<RoamingPartner> partnerList = new ArrayList<>();
- for (int i = 0; i < size; i++) {
- partnerList.add(in.readParcelable(null));
- }
- return partnerList;
- }
-
- };
-
- /**
- * Helper function for writing IP Protocol to Port Number map to a Parcel.
- *
- * @param dest The Parcel to write to
- * @param protoPortMap The map to write
- */
- private static void writeProtoPortMap(Parcel dest, Map<Integer, String> protoPortMap) {
- if (protoPortMap == null) {
- dest.writeInt(NULL_VALUE);
- return;
- }
- dest.writeInt(protoPortMap.size());
- for (Map.Entry<Integer, String> entry : protoPortMap.entrySet()) {
- dest.writeInt(entry.getKey());
- dest.writeString(entry.getValue());
- }
- }
-
- /**
- * Helper function for writing roaming partner list to a Parcel.
- *
- * @param dest The Parcel to write to
- * @param flags The flag about how the object should be written
- * @param partnerList The partner list to write
- */
- private static void writeRoamingPartnerList(Parcel dest, int flags,
- List<RoamingPartner> partnerList) {
- if (partnerList == null) {
- dest.writeInt(NULL_VALUE);
- return;
- }
- dest.writeInt(partnerList.size());
- for (RoamingPartner partner : partnerList) {
- dest.writeParcelable(partner, flags);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
deleted file mode 100644
index 4a8aa36..0000000
--- a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
+++ /dev/null
@@ -1,403 +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.net.wifi.hotspot2.pps;
-
-import android.net.wifi.ParcelUtil;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Base64;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * Class representing configuration parameters for subscription or policy update in
- * PerProviderSubscription (PPS) Management Object (MO) tree. This is used by both
- * PerProviderSubscription/Policy/PolicyUpdate and PerProviderSubscription/SubscriptionUpdate
- * subtree.
- *
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- *
- * @hide
- */
-public final class UpdateParameter implements Parcelable {
- private static final String TAG = "UpdateParameter";
-
- /**
- * Value indicating policy update is not applicable. Thus, never check with policy server
- * for updates.
- */
- public static final long UPDATE_CHECK_INTERVAL_NEVER = 0xFFFFFFFFL;
-
- /**
- * Valid string for UpdateMethod.
- */
- public static final String UPDATE_METHOD_OMADM = "OMA-DM-ClientInitiated";
- public static final String UPDATE_METHOD_SSP = "SSP-ClientInitiated";
-
- /**
- * Valid string for Restriction.
- */
- public static final String UPDATE_RESTRICTION_HOMESP = "HomeSP";
- public static final String UPDATE_RESTRICTION_ROAMING_PARTNER = "RoamingPartner";
- public static final String UPDATE_RESTRICTION_UNRESTRICTED = "Unrestricted";
-
- /**
- * Maximum bytes for URI string.
- */
- private static final int MAX_URI_BYTES = 1023;
-
- /**
- * Maximum bytes for URI string.
- */
- private static final int MAX_URL_BYTES = 1023;
-
- /**
- * Maximum bytes for username.
- */
- private static final int MAX_USERNAME_BYTES = 63;
-
- /**
- * Maximum bytes for password.
- */
- private static final int MAX_PASSWORD_BYTES = 255;
-
- /**
- * Number of bytes for certificate SHA-256 fingerprint byte array.
- */
- private static final int CERTIFICATE_SHA256_BYTES = 32;
-
- /**
- * This specifies how often the mobile device shall check with policy server for updates.
- *
- * Using Long.MIN_VALUE to indicate unset value.
- */
- private long mUpdateIntervalInMinutes = Long.MIN_VALUE;
- public void setUpdateIntervalInMinutes(long updateIntervalInMinutes) {
- mUpdateIntervalInMinutes = updateIntervalInMinutes;
- }
- public long getUpdateIntervalInMinutes() {
- return mUpdateIntervalInMinutes;
- }
-
- /**
- * The method used to update the policy. Permitted values are "OMA-DM-ClientInitiated"
- * and "SPP-ClientInitiated".
- */
- private String mUpdateMethod = null;
- public void setUpdateMethod(String updateMethod) {
- mUpdateMethod = updateMethod;
- }
- public String getUpdateMethod() {
- return mUpdateMethod;
- }
-
- /**
- * This specifies the hotspots at which the subscription update is permitted. Permitted
- * values are "HomeSP", "RoamingPartner", or "Unrestricted";
- */
- private String mRestriction = null;
- public void setRestriction(String restriction) {
- mRestriction = restriction;
- }
- public String getRestriction() {
- return mRestriction;
- }
-
- /**
- * The URI of the update server.
- */
- private String mServerUri = null;
- public void setServerUri(String serverUri) {
- mServerUri = serverUri;
- }
- public String getServerUri() {
- return mServerUri;
- }
-
- /**
- * Username used to authenticate with the policy server.
- */
- private String mUsername = null;
- public void setUsername(String username) {
- mUsername = username;
- }
- public String getUsername() {
- return mUsername;
- }
-
- /**
- * Base64 encoded password used to authenticate with the policy server.
- */
- private String mBase64EncodedPassword = null;
- public void setBase64EncodedPassword(String password) {
- mBase64EncodedPassword = password;
- }
- public String getBase64EncodedPassword() {
- return mBase64EncodedPassword;
- }
-
- /**
- * HTTPS URL for retrieving certificate for trust root. The trust root is used to validate
- * policy server's identity.
- */
- private String mTrustRootCertUrl = null;
- public void setTrustRootCertUrl(String trustRootCertUrl) {
- mTrustRootCertUrl = trustRootCertUrl;
- }
- public String getTrustRootCertUrl() {
- return mTrustRootCertUrl;
- }
-
- /**
- * SHA-256 fingerprint of the certificate located at {@code mTrustRootCertUrl}
- */
- private byte[] mTrustRootCertSha256Fingerprint = null;
- public void setTrustRootCertSha256Fingerprint(byte[] fingerprint) {
- mTrustRootCertSha256Fingerprint = fingerprint;
- }
- public byte[] getTrustRootCertSha256Fingerprint() {
- return mTrustRootCertSha256Fingerprint;
- }
-
- /**
- * CA (Certificate Authority) X509 certificates.
- */
- private X509Certificate mCaCertificate;
-
- /**
- * Set the CA (Certification Authority) certificate associated with Policy/Subscription update.
- *
- * @param caCertificate The CA certificate to set
- * @hide
- */
- public void setCaCertificate(X509Certificate caCertificate) {
- mCaCertificate = caCertificate;
- }
-
- /**
- * Get the CA (Certification Authority) certificate associated with Policy/Subscription update.
- *
- * @return CA certificate associated and {@code null} if certificate is not set.
- * @hide
- */
- public X509Certificate getCaCertificate() {
- return mCaCertificate;
- }
-
- /**
- * Constructor for creating Policy with default values.
- */
- public UpdateParameter() {}
-
- /**
- * Copy constructor.
- *
- * @param source The source to copy from
- */
- public UpdateParameter(UpdateParameter source) {
- if (source == null) {
- return;
- }
- mUpdateIntervalInMinutes = source.mUpdateIntervalInMinutes;
- mUpdateMethod = source.mUpdateMethod;
- mRestriction = source.mRestriction;
- mServerUri = source.mServerUri;
- mUsername = source.mUsername;
- mBase64EncodedPassword = source.mBase64EncodedPassword;
- mTrustRootCertUrl = source.mTrustRootCertUrl;
- if (source.mTrustRootCertSha256Fingerprint != null) {
- mTrustRootCertSha256Fingerprint = Arrays.copyOf(source.mTrustRootCertSha256Fingerprint,
- source.mTrustRootCertSha256Fingerprint.length);
- }
- mCaCertificate = source.mCaCertificate;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(mUpdateIntervalInMinutes);
- dest.writeString(mUpdateMethod);
- dest.writeString(mRestriction);
- dest.writeString(mServerUri);
- dest.writeString(mUsername);
- dest.writeString(mBase64EncodedPassword);
- dest.writeString(mTrustRootCertUrl);
- dest.writeByteArray(mTrustRootCertSha256Fingerprint);
- ParcelUtil.writeCertificate(dest, mCaCertificate);
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (!(thatObject instanceof UpdateParameter)) {
- return false;
- }
- UpdateParameter that = (UpdateParameter) thatObject;
-
- return mUpdateIntervalInMinutes == that.mUpdateIntervalInMinutes
- && TextUtils.equals(mUpdateMethod, that.mUpdateMethod)
- && TextUtils.equals(mRestriction, that.mRestriction)
- && TextUtils.equals(mServerUri, that.mServerUri)
- && TextUtils.equals(mUsername, that.mUsername)
- && TextUtils.equals(mBase64EncodedPassword, that.mBase64EncodedPassword)
- && TextUtils.equals(mTrustRootCertUrl, that.mTrustRootCertUrl)
- && Arrays.equals(mTrustRootCertSha256Fingerprint,
- that.mTrustRootCertSha256Fingerprint)
- && Credential.isX509CertificateEquals(mCaCertificate, that.mCaCertificate);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mUpdateIntervalInMinutes, mUpdateMethod, mRestriction, mServerUri,
- mUsername, mBase64EncodedPassword, mTrustRootCertUrl,
- Arrays.hashCode(mTrustRootCertSha256Fingerprint), mCaCertificate);
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("UpdateInterval: ").append(mUpdateIntervalInMinutes).append("\n");
- builder.append("UpdateMethod: ").append(mUpdateMethod).append("\n");
- builder.append("Restriction: ").append(mRestriction).append("\n");
- builder.append("ServerURI: ").append(mServerUri).append("\n");
- builder.append("Username: ").append(mUsername).append("\n");
- builder.append("TrustRootCertURL: ").append(mTrustRootCertUrl).append("\n");
- return builder.toString();
- }
-
- /**
- * Validate UpdateParameter data.
- *
- * @return true on success
- * @hide
- */
- public boolean validate() {
- if (mUpdateIntervalInMinutes == Long.MIN_VALUE) {
- Log.d(TAG, "Update interval not specified");
- return false;
- }
- // Update not applicable.
- if (mUpdateIntervalInMinutes == UPDATE_CHECK_INTERVAL_NEVER) {
- return true;
- }
-
- if (!TextUtils.equals(mUpdateMethod, UPDATE_METHOD_OMADM)
- && !TextUtils.equals(mUpdateMethod, UPDATE_METHOD_SSP)) {
- Log.d(TAG, "Unknown update method: " + mUpdateMethod);
- return false;
- }
-
- if (!TextUtils.equals(mRestriction, UPDATE_RESTRICTION_HOMESP)
- && !TextUtils.equals(mRestriction, UPDATE_RESTRICTION_ROAMING_PARTNER)
- && !TextUtils.equals(mRestriction, UPDATE_RESTRICTION_UNRESTRICTED)) {
- Log.d(TAG, "Unknown restriction: " + mRestriction);
- return false;
- }
-
- if (TextUtils.isEmpty(mServerUri)) {
- Log.d(TAG, "Missing update server URI");
- return false;
- }
- if (mServerUri.getBytes(StandardCharsets.UTF_8).length > MAX_URI_BYTES) {
- Log.d(TAG, "URI bytes exceeded the max: "
- + mServerUri.getBytes(StandardCharsets.UTF_8).length);
- return false;
- }
-
- if (TextUtils.isEmpty(mUsername)) {
- Log.d(TAG, "Missing username");
- return false;
- }
- if (mUsername.getBytes(StandardCharsets.UTF_8).length > MAX_USERNAME_BYTES) {
- Log.d(TAG, "Username bytes exceeded the max: "
- + mUsername.getBytes(StandardCharsets.UTF_8).length);
- return false;
- }
-
- if (TextUtils.isEmpty(mBase64EncodedPassword)) {
- Log.d(TAG, "Missing username");
- return false;
- }
- if (mBase64EncodedPassword.getBytes(StandardCharsets.UTF_8).length > MAX_PASSWORD_BYTES) {
- Log.d(TAG, "Password bytes exceeded the max: "
- + mBase64EncodedPassword.getBytes(StandardCharsets.UTF_8).length);
- return false;
- }
- try {
- Base64.decode(mBase64EncodedPassword, Base64.DEFAULT);
- } catch (IllegalArgumentException e) {
- Log.d(TAG, "Invalid encoding for password: " + mBase64EncodedPassword);
- return false;
- }
-
- if (TextUtils.isEmpty(mTrustRootCertUrl)) {
- Log.d(TAG, "Missing trust root certificate URL");
- return false;
- }
- if (mTrustRootCertUrl.getBytes(StandardCharsets.UTF_8).length > MAX_URL_BYTES) {
- Log.d(TAG, "Trust root cert URL bytes exceeded the max: "
- + mTrustRootCertUrl.getBytes(StandardCharsets.UTF_8).length);
- return false;
- }
-
- if (mTrustRootCertSha256Fingerprint == null) {
- Log.d(TAG, "Missing trust root certificate SHA-256 fingerprint");
- return false;
- }
- if (mTrustRootCertSha256Fingerprint.length != CERTIFICATE_SHA256_BYTES) {
- Log.d(TAG, "Incorrect size of trust root certificate SHA-256 fingerprint: "
- + mTrustRootCertSha256Fingerprint.length);
- return false;
- }
- return true;
- }
-
- public static final @android.annotation.NonNull Creator<UpdateParameter> CREATOR =
- new Creator<UpdateParameter>() {
- @Override
- public UpdateParameter createFromParcel(Parcel in) {
- UpdateParameter updateParam = new UpdateParameter();
- updateParam.setUpdateIntervalInMinutes(in.readLong());
- updateParam.setUpdateMethod(in.readString());
- updateParam.setRestriction(in.readString());
- updateParam.setServerUri(in.readString());
- updateParam.setUsername(in.readString());
- updateParam.setBase64EncodedPassword(in.readString());
- updateParam.setTrustRootCertUrl(in.readString());
- updateParam.setTrustRootCertSha256Fingerprint(in.createByteArray());
- updateParam.setCaCertificate(ParcelUtil.readCertificate(in));
- return updateParam;
- }
-
- @Override
- public UpdateParameter[] newArray(int size) {
- return new UpdateParameter[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
deleted file mode 100644
index bfdd45d..0000000
--- a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-import android.os.Messenger;
-
-/**
- * Interface that WifiP2pService implements
- *
- * {@hide}
- */
-interface IWifiP2pManager
-{
- Messenger getMessenger(in IBinder binder);
- Messenger getP2pStateMachineMessenger();
- oneway void close(in IBinder binder);
- void setMiracastMode(int mode);
- void checkConfigureWifiDisplayPermission();
-}
-
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
deleted file mode 100644
index d479892..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.MacAddress;
-import android.net.wifi.WpsInfo;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * A class representing a Wi-Fi P2p configuration for setting up a connection
- *
- * {@see WifiP2pManager}
- */
-public class WifiP2pConfig implements Parcelable {
-
- /**
- * The device MAC address uniquely identifies a Wi-Fi p2p device
- */
- public String deviceAddress = "";
-
- /**
- * Wi-Fi Protected Setup information
- */
- public WpsInfo wps;
-
- /** Get the network name of this P2P configuration, or null if unset. */
- @Nullable
- public String getNetworkName() {
- return networkName;
- }
-
- /** @hide */
- public String networkName = "";
-
- /** Get the passphrase of this P2P configuration, or null if unset. */
- @Nullable
- public String getPassphrase() {
- return passphrase;
- }
-
- /** @hide */
- public String passphrase = "";
-
- /**
- * Get the required band for the group owner.
- * The result will be one of the following:
- * {@link #GROUP_OWNER_BAND_AUTO},
- * {@link #GROUP_OWNER_BAND_2GHZ},
- * {@link #GROUP_OWNER_BAND_5GHZ}
- */
- @GroupOperatingBandType
- public int getGroupOwnerBand() {
- return groupOwnerBand;
- }
-
- /** @hide */
- @GroupOperatingBandType
- public int groupOwnerBand = GROUP_OWNER_BAND_AUTO;
-
- /** @hide */
- @IntDef(flag = false, prefix = { "GROUP_OWNER_BAND_" }, value = {
- GROUP_OWNER_BAND_AUTO,
- GROUP_OWNER_BAND_2GHZ,
- GROUP_OWNER_BAND_5GHZ
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface GroupOperatingBandType {}
-
- /**
- * Allow the system to pick the operating frequency from all supported bands.
- */
- public static final int GROUP_OWNER_BAND_AUTO = 0;
- /**
- * Allow the system to pick the operating frequency from the 2.4 GHz band.
- */
- public static final int GROUP_OWNER_BAND_2GHZ = 1;
- /**
- * Allow the system to pick the operating frequency from the 5 GHz band.
- */
- public static final int GROUP_OWNER_BAND_5GHZ = 2;
-
- /**
- * The least inclination to be a group owner, to be filled in the field
- * {@link #groupOwnerIntent}.
- */
- public static final int GROUP_OWNER_INTENT_MIN = 0;
-
- /**
- * The most inclination to be a group owner, to be filled in the field
- * {@link #groupOwnerIntent}.
- */
- public static final int GROUP_OWNER_INTENT_MAX = 15;
-
- /**
- * The system can choose an appropriate owner intent value, to be filled in the field
- * {@link #groupOwnerIntent}.
- */
- public static final int GROUP_OWNER_INTENT_AUTO = -1;
-
- /**
- * This is an integer value between {@link #GROUP_OWNER_INTENT_MIN} and
- * {@link #GROUP_OWNER_INTENT_MAX} where
- * {@link #GROUP_OWNER_INTENT_MIN} indicates the least inclination to be a group owner and
- * {@link #GROUP_OWNER_INTENT_MAX} indicates the highest inclination to be a group owner.
- *
- * A value of {@link #GROUP_OWNER_INTENT_AUTO} indicates the system can choose an appropriate
- * value.
- *
- * By default this field is set to {@link #GROUP_OWNER_INTENT_AUTO}.
- */
- @IntRange(from = 0, to = 15)
- public int groupOwnerIntent = GROUP_OWNER_INTENT_AUTO;
-
- /** @hide */
- @UnsupportedAppUsage
- public int netId = WifiP2pGroup.NETWORK_ID_PERSISTENT;
-
- /**
- * Get the network ID of this P2P configuration.
- * @return either a non-negative network ID, or one of
- * {@link WifiP2pGroup#NETWORK_ID_PERSISTENT} or {@link WifiP2pGroup#NETWORK_ID_TEMPORARY}.
- */
- public int getNetworkId() {
- return netId;
- }
-
- public WifiP2pConfig() {
- //set defaults
- wps = new WpsInfo();
- wps.setup = WpsInfo.PBC;
- }
-
- /** @hide */
- public void invalidate() {
- deviceAddress = "";
- }
-
- /** P2P-GO-NEG-REQUEST 42:fc:89:a8:96:09 dev_passwd_id=4 {@hide}*/
- @UnsupportedAppUsage
- public WifiP2pConfig(String supplicantEvent) throws IllegalArgumentException {
- String[] tokens = supplicantEvent.split(" ");
-
- if (tokens.length < 2 || !tokens[0].equals("P2P-GO-NEG-REQUEST")) {
- throw new IllegalArgumentException("Malformed supplicant event");
- }
-
- deviceAddress = tokens[1];
- wps = new WpsInfo();
-
- if (tokens.length > 2) {
- String[] nameVal = tokens[2].split("=");
- int devPasswdId;
- try {
- devPasswdId = Integer.parseInt(nameVal[1]);
- } catch (NumberFormatException e) {
- devPasswdId = 0;
- }
- //Based on definitions in wps/wps_defs.h
- switch (devPasswdId) {
- //DEV_PW_USER_SPECIFIED = 0x0001,
- case 0x01:
- wps.setup = WpsInfo.DISPLAY;
- break;
- //DEV_PW_PUSHBUTTON = 0x0004,
- case 0x04:
- wps.setup = WpsInfo.PBC;
- break;
- //DEV_PW_REGISTRAR_SPECIFIED = 0x0005
- case 0x05:
- wps.setup = WpsInfo.KEYPAD;
- break;
- default:
- wps.setup = WpsInfo.PBC;
- break;
- }
- }
- }
-
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("\n address: ").append(deviceAddress);
- sbuf.append("\n wps: ").append(wps);
- sbuf.append("\n groupOwnerIntent: ").append(groupOwnerIntent);
- sbuf.append("\n persist: ").append(netId);
- sbuf.append("\n networkName: ").append(networkName);
- sbuf.append("\n passphrase: ").append(
- TextUtils.isEmpty(passphrase) ? "<empty>" : "<non-empty>");
- sbuf.append("\n groupOwnerBand: ").append(groupOwnerBand);
- return sbuf.toString();
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** copy constructor */
- public WifiP2pConfig(WifiP2pConfig source) {
- if (source != null) {
- deviceAddress = source.deviceAddress;
- wps = new WpsInfo(source.wps);
- groupOwnerIntent = source.groupOwnerIntent;
- netId = source.netId;
- networkName = source.networkName;
- passphrase = source.passphrase;
- groupOwnerBand = source.groupOwnerBand;
- }
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(deviceAddress);
- dest.writeParcelable(wps, flags);
- dest.writeInt(groupOwnerIntent);
- dest.writeInt(netId);
- dest.writeString(networkName);
- dest.writeString(passphrase);
- dest.writeInt(groupOwnerBand);
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<WifiP2pConfig> CREATOR =
- new Creator<WifiP2pConfig>() {
- public WifiP2pConfig createFromParcel(Parcel in) {
- WifiP2pConfig config = new WifiP2pConfig();
- config.deviceAddress = in.readString();
- config.wps = (WpsInfo) in.readParcelable(null);
- config.groupOwnerIntent = in.readInt();
- config.netId = in.readInt();
- config.networkName = in.readString();
- config.passphrase = in.readString();
- config.groupOwnerBand = in.readInt();
- return config;
- }
-
- public WifiP2pConfig[] newArray(int size) {
- return new WifiP2pConfig[size];
- }
- };
-
- /**
- * Builder used to build {@link WifiP2pConfig} objects for
- * creating or joining a group.
- */
- public static final class Builder {
-
- private static final MacAddress MAC_ANY_ADDRESS =
- MacAddress.fromString("02:00:00:00:00:00");
- /**
- * Maximum number of bytes allowed for a SSID.
- */
- private static final int MAX_SSID_BYTES = 32;
-
- private MacAddress mDeviceAddress = MAC_ANY_ADDRESS;
- private String mNetworkName = "";
- private String mPassphrase = "";
- private int mGroupOperatingBand = GROUP_OWNER_BAND_AUTO;
- private int mGroupOperatingFrequency = GROUP_OWNER_BAND_AUTO;
- private int mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY;
-
- /**
- * Specify the peer's MAC address. If not set, the device will
- * try to find a peer whose SSID matches the network name as
- * specified by {@link #setNetworkName(String)}. Specifying null will
- * reset the peer's MAC address to "02:00:00:00:00:00".
- * <p>
- * Optional. "02:00:00:00:00:00" by default.
- *
- * @param deviceAddress the peer's MAC address.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public @NonNull Builder setDeviceAddress(@Nullable MacAddress deviceAddress) {
- if (deviceAddress == null) {
- mDeviceAddress = MAC_ANY_ADDRESS;
- } else {
- mDeviceAddress = deviceAddress;
- }
- return this;
- }
-
- /**
- * Specify the network name, a.k.a. group name,
- * for creating or joining a group.
- * <p>
- * A network name shall begin with "DIRECT-xy". x and y are selected
- * from the following character set: upper case letters, lower case
- * letters and numbers. Any byte values allowed for an SSID according to
- * IEEE802.11-2012 [1] may be included after the string "DIRECT-xy"
- * (including none).
- * <p>
- * Must be called - an empty network name or an network name
- * not conforming to the P2P Group ID naming rule is not valid.
- *
- * @param networkName network name of a group.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public @NonNull Builder setNetworkName(@NonNull String networkName) {
- if (TextUtils.isEmpty(networkName)) {
- throw new IllegalArgumentException(
- "network name must be non-empty.");
- }
- if (networkName.getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) {
- throw new IllegalArgumentException(
- "network name exceeds " + MAX_SSID_BYTES + " bytes.");
- }
- try {
- if (!networkName.matches("^DIRECT-[a-zA-Z0-9]{2}.*")) {
- throw new IllegalArgumentException(
- "network name must starts with the prefix DIRECT-xy.");
- }
- } catch (PatternSyntaxException e) {
- // can never happen (fixed pattern)
- }
- mNetworkName = networkName;
- return this;
- }
-
- /**
- * Specify the passphrase for creating or joining a group.
- * <p>
- * The passphrase must be an ASCII string whose length is between 8
- * and 63.
- * <p>
- * Must be called - an empty passphrase is not valid.
- *
- * @param passphrase the passphrase of a group.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public @NonNull Builder setPassphrase(@NonNull String passphrase) {
- if (TextUtils.isEmpty(passphrase)) {
- throw new IllegalArgumentException(
- "passphrase must be non-empty.");
- }
- if (passphrase.length() < 8 || passphrase.length() > 63) {
- throw new IllegalArgumentException(
- "The length of a passphrase must be between 8 and 63.");
- }
- mPassphrase = passphrase;
- return this;
- }
-
- /**
- * Specify the band to use for creating the group or joining the group. The band should
- * be {@link #GROUP_OWNER_BAND_2GHZ}, {@link #GROUP_OWNER_BAND_5GHZ} or
- * {@link #GROUP_OWNER_BAND_AUTO}.
- * <p>
- * When creating a group as Group Owner using {@link
- * WifiP2pManager#createGroup(WifiP2pManager.Channel,
- * WifiP2pConfig, WifiP2pManager.ActionListener)},
- * specifying {@link #GROUP_OWNER_BAND_AUTO} allows the system to pick the operating
- * frequency from all supported bands.
- * Specifying {@link #GROUP_OWNER_BAND_2GHZ} or {@link #GROUP_OWNER_BAND_5GHZ}
- * only allows the system to pick the operating frequency in the specified band.
- * If the Group Owner cannot create a group in the specified band, the operation will fail.
- * <p>
- * When joining a group as Group Client using {@link
- * WifiP2pManager#connect(WifiP2pManager.Channel, WifiP2pConfig,
- * WifiP2pManager.ActionListener)},
- * specifying {@link #GROUP_OWNER_BAND_AUTO} allows the system to scan all supported
- * frequencies to find the desired group. Specifying {@link #GROUP_OWNER_BAND_2GHZ} or
- * {@link #GROUP_OWNER_BAND_5GHZ} only allows the system to scan the specified band.
- * <p>
- * {@link #setGroupOperatingBand(int)} and {@link #setGroupOperatingFrequency(int)} are
- * mutually exclusive. Setting operating band and frequency both is invalid.
- * <p>
- * Optional. {@link #GROUP_OWNER_BAND_AUTO} by default.
- *
- * @param band the operating band of the group.
- * This should be one of {@link #GROUP_OWNER_BAND_AUTO},
- * {@link #GROUP_OWNER_BAND_2GHZ}, {@link #GROUP_OWNER_BAND_5GHZ}.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public @NonNull Builder setGroupOperatingBand(@GroupOperatingBandType int band) {
- switch (band) {
- case GROUP_OWNER_BAND_AUTO:
- case GROUP_OWNER_BAND_2GHZ:
- case GROUP_OWNER_BAND_5GHZ:
- mGroupOperatingBand = band;
- break;
- default:
- throw new IllegalArgumentException(
- "Invalid constant for the group operating band!");
- }
- return this;
- }
-
- /**
- * Specify the frequency, in MHz, to use for creating the group or joining the group.
- * <p>
- * When creating a group as Group Owner using {@link WifiP2pManager#createGroup(
- * WifiP2pManager.Channel, WifiP2pConfig, WifiP2pManager.ActionListener)},
- * specifying a frequency only allows the system to pick the specified frequency.
- * If the Group Owner cannot create a group at the specified frequency,
- * the operation will fail.
- * When not specifying a frequency, it allows the system to pick operating frequency
- * from all supported bands.
- * <p>
- * When joining a group as Group Client using {@link WifiP2pManager#connect(
- * WifiP2pManager.Channel, WifiP2pConfig, WifiP2pManager.ActionListener)},
- * specifying a frequency only allows the system to scan the specified frequency.
- * If the frequency is not supported or invalid, the operation will fail.
- * When not specifying a frequency, it allows the system to scan all supported
- * frequencies to find the desired group.
- * <p>
- * {@link #setGroupOperatingBand(int)} and {@link #setGroupOperatingFrequency(int)} are
- * mutually exclusive. Setting operating band and frequency both is invalid.
- * <p>
- * Optional. 0 by default.
- *
- * @param frequency the operating frequency of the group.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public @NonNull Builder setGroupOperatingFrequency(int frequency) {
- if (frequency < 0) {
- throw new IllegalArgumentException(
- "Invalid group operating frequency!");
- }
- mGroupOperatingFrequency = frequency;
- return this;
- }
-
- /**
- * Specify that the group configuration be persisted (i.e. saved).
- * By default the group configuration will not be saved.
- * <p>
- * Optional. false by default.
- *
- * @param persistent is this group persistent group.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public @NonNull Builder enablePersistentMode(boolean persistent) {
- if (persistent) {
- mNetId = WifiP2pGroup.NETWORK_ID_PERSISTENT;
- } else {
- mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY;
- }
- return this;
- }
-
- /**
- * Build {@link WifiP2pConfig} given the current requests made on the builder.
- * @return {@link WifiP2pConfig} constructed based on builder method calls.
- */
- public @NonNull WifiP2pConfig build() {
- if (TextUtils.isEmpty(mNetworkName)) {
- throw new IllegalStateException(
- "network name must be non-empty.");
- }
- if (TextUtils.isEmpty(mPassphrase)) {
- throw new IllegalStateException(
- "passphrase must be non-empty.");
- }
-
- if (mGroupOperatingFrequency > 0 && mGroupOperatingBand > 0) {
- throw new IllegalStateException(
- "Preferred frequency and band are mutually exclusive.");
- }
-
- WifiP2pConfig config = new WifiP2pConfig();
- config.deviceAddress = mDeviceAddress.toString();
- config.networkName = mNetworkName;
- config.passphrase = mPassphrase;
- config.groupOwnerBand = GROUP_OWNER_BAND_AUTO;
- if (mGroupOperatingFrequency > 0) {
- config.groupOwnerBand = mGroupOperatingFrequency;
- } else if (mGroupOperatingBand > 0) {
- config.groupOwnerBand = mGroupOperatingBand;
- }
- config.netId = mNetId;
- return config;
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
deleted file mode 100644
index 710175f..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.util.Objects;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A class representing a Wi-Fi p2p device
- *
- * Note that the operations are not thread safe
- * {@see WifiP2pManager}
- */
-public class WifiP2pDevice implements Parcelable {
-
- private static final String TAG = "WifiP2pDevice";
-
- /**
- * The device name is a user friendly string to identify a Wi-Fi p2p device
- */
- public String deviceName = "";
-
- /**
- * The device MAC address uniquely identifies a Wi-Fi p2p device
- */
- public String deviceAddress = "";
-
- /**
- * Primary device type identifies the type of device. For example, an application
- * could filter the devices discovered to only display printers if the purpose is to
- * enable a printing action from the user. See the Wi-Fi Direct technical specification
- * for the full list of standard device types supported.
- */
- public String primaryDeviceType;
-
- /**
- * Secondary device type is an optional attribute that can be provided by a device in
- * addition to the primary device type.
- */
- public String secondaryDeviceType;
-
-
- // These definitions match the ones in wpa_supplicant
- /* WPS config methods supported */
- private static final int WPS_CONFIG_DISPLAY = 0x0008;
- private static final int WPS_CONFIG_PUSHBUTTON = 0x0080;
- private static final int WPS_CONFIG_KEYPAD = 0x0100;
-
- /* Device Capability bitmap */
- private static final int DEVICE_CAPAB_SERVICE_DISCOVERY = 1;
- @SuppressWarnings("unused")
- private static final int DEVICE_CAPAB_CLIENT_DISCOVERABILITY = 1<<1;
- @SuppressWarnings("unused")
- private static final int DEVICE_CAPAB_CONCURRENT_OPER = 1<<2;
- @SuppressWarnings("unused")
- private static final int DEVICE_CAPAB_INFRA_MANAGED = 1<<3;
- @SuppressWarnings("unused")
- private static final int DEVICE_CAPAB_DEVICE_LIMIT = 1<<4;
- private static final int DEVICE_CAPAB_INVITATION_PROCEDURE = 1<<5;
-
- /* Group Capability bitmap */
- private static final int GROUP_CAPAB_GROUP_OWNER = 1;
- @SuppressWarnings("unused")
- private static final int GROUP_CAPAB_PERSISTENT_GROUP = 1<<1;
- private static final int GROUP_CAPAB_GROUP_LIMIT = 1<<2;
- @SuppressWarnings("unused")
- private static final int GROUP_CAPAB_INTRA_BSS_DIST = 1<<3;
- @SuppressWarnings("unused")
- private static final int GROUP_CAPAB_CROSS_CONN = 1<<4;
- @SuppressWarnings("unused")
- private static final int GROUP_CAPAB_PERSISTENT_RECONN = 1<<5;
- @SuppressWarnings("unused")
- private static final int GROUP_CAPAB_GROUP_FORMATION = 1<<6;
-
- /**
- * WPS config methods supported
- * @hide
- */
- @UnsupportedAppUsage
- public int wpsConfigMethodsSupported;
-
- /**
- * Device capability
- * @hide
- */
- @UnsupportedAppUsage
- public int deviceCapability;
-
- /**
- * Group capability
- * @hide
- */
- @UnsupportedAppUsage
- public int groupCapability;
-
- public static final int CONNECTED = 0;
- public static final int INVITED = 1;
- public static final int FAILED = 2;
- public static final int AVAILABLE = 3;
- public static final int UNAVAILABLE = 4;
-
- /** Device connection status */
- public int status = UNAVAILABLE;
-
- /** @hide */
- @UnsupportedAppUsage
- public WifiP2pWfdInfo wfdInfo;
-
- /** Detailed device string pattern with WFD info
- * Example:
- * P2P-DEVICE-FOUND 00:18:6b:de:a3:6e p2p_dev_addr=00:18:6b:de:a3:6e
- * pri_dev_type=1-0050F204-1 name='DWD-300-DEA36E' config_methods=0x188
- * dev_capab=0x21 group_capab=0x9
- */
- private static final Pattern detailedDevicePattern = Pattern.compile(
- "((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) " +
- "(\\d+ )?" +
- "p2p_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) " +
- "pri_dev_type=(\\d+-[0-9a-fA-F]+-\\d+) " +
- "name='(.*)' " +
- "config_methods=(0x[0-9a-fA-F]+) " +
- "dev_capab=(0x[0-9a-fA-F]+) " +
- "group_capab=(0x[0-9a-fA-F]+)" +
- "( wfd_dev_info=0x([0-9a-fA-F]{12}))?"
- );
-
- /** 2 token device address pattern
- * Example:
- * P2P-DEVICE-LOST p2p_dev_addr=fa:7b:7a:42:02:13
- * AP-STA-DISCONNECTED 42:fc:89:a8:96:09
- */
- private static final Pattern twoTokenPattern = Pattern.compile(
- "(p2p_dev_addr=)?((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
- );
-
- /** 3 token device address pattern
- * Example:
- * AP-STA-CONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=fa:7b:7a:42:02:13
- * AP-STA-DISCONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=fa:7b:7a:42:02:13
- */
- private static final Pattern threeTokenPattern = Pattern.compile(
- "(?:[0-9a-f]{2}:){5}[0-9a-f]{2} p2p_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
- );
-
-
- public WifiP2pDevice() {
- }
-
- /**
- * @param string formats supported include
- * P2P-DEVICE-FOUND fa:7b:7a:42:02:13 p2p_dev_addr=fa:7b:7a:42:02:13
- * pri_dev_type=1-0050F204-1 name='p2p-TEST1' config_methods=0x188 dev_capab=0x27
- * group_capab=0x0 wfd_dev_info=000006015d022a0032
- *
- * P2P-DEVICE-LOST p2p_dev_addr=fa:7b:7a:42:02:13
- *
- * AP-STA-CONNECTED 42:fc:89:a8:96:09 [p2p_dev_addr=02:90:4c:a0:92:54]
- *
- * AP-STA-DISCONNECTED 42:fc:89:a8:96:09 [p2p_dev_addr=02:90:4c:a0:92:54]
- *
- * fa:7b:7a:42:02:13
- *
- * Note: The events formats can be looked up in the wpa_supplicant code
- * @hide
- */
- @UnsupportedAppUsage
- public WifiP2pDevice(String string) throws IllegalArgumentException {
- String[] tokens = string.split("[ \n]");
- Matcher match;
-
- if (tokens.length < 1) {
- throw new IllegalArgumentException("Malformed supplicant event");
- }
-
- switch (tokens.length) {
- case 1:
- /* Just a device address */
- deviceAddress = string;
- return;
- case 2:
- match = twoTokenPattern.matcher(string);
- if (!match.find()) {
- throw new IllegalArgumentException("Malformed supplicant event");
- }
- deviceAddress = match.group(2);
- return;
- case 3:
- match = threeTokenPattern.matcher(string);
- if (!match.find()) {
- throw new IllegalArgumentException("Malformed supplicant event");
- }
- deviceAddress = match.group(1);
- return;
- default:
- match = detailedDevicePattern.matcher(string);
- if (!match.find()) {
- throw new IllegalArgumentException("Malformed supplicant event");
- }
-
- deviceAddress = match.group(3);
- primaryDeviceType = match.group(4);
- deviceName = match.group(5);
- wpsConfigMethodsSupported = parseHex(match.group(6));
- deviceCapability = parseHex(match.group(7));
- groupCapability = parseHex(match.group(8));
- if (match.group(9) != null) {
- String str = match.group(10);
- wfdInfo = new WifiP2pWfdInfo(parseHex(str.substring(0,4)),
- parseHex(str.substring(4,8)),
- parseHex(str.substring(8,12)));
- }
- break;
- }
-
- if (tokens[0].startsWith("P2P-DEVICE-FOUND")) {
- status = AVAILABLE;
- }
- }
-
- /** The Wifi Display information for this device, or null if unavailable. */
- @Nullable
- public WifiP2pWfdInfo getWfdInfo() {
- return wfdInfo;
- }
-
- /** Returns true if WPS push button configuration is supported */
- public boolean wpsPbcSupported() {
- return (wpsConfigMethodsSupported & WPS_CONFIG_PUSHBUTTON) != 0;
- }
-
- /** Returns true if WPS keypad configuration is supported */
- public boolean wpsKeypadSupported() {
- return (wpsConfigMethodsSupported & WPS_CONFIG_KEYPAD) != 0;
- }
-
- /** Returns true if WPS display configuration is supported */
- public boolean wpsDisplaySupported() {
- return (wpsConfigMethodsSupported & WPS_CONFIG_DISPLAY) != 0;
- }
-
- /** Returns true if the device is capable of service discovery */
- public boolean isServiceDiscoveryCapable() {
- return (deviceCapability & DEVICE_CAPAB_SERVICE_DISCOVERY) != 0;
- }
-
- /** Returns true if the device is capable of invitation {@hide}*/
- public boolean isInvitationCapable() {
- return (deviceCapability & DEVICE_CAPAB_INVITATION_PROCEDURE) != 0;
- }
-
- /** Returns true if the device reaches the limit. {@hide}*/
- public boolean isDeviceLimit() {
- return (deviceCapability & DEVICE_CAPAB_DEVICE_LIMIT) != 0;
- }
-
- /** Returns true if the device is a group owner */
- public boolean isGroupOwner() {
- return (groupCapability & GROUP_CAPAB_GROUP_OWNER) != 0;
- }
-
- /** Returns true if the group reaches the limit. {@hide}*/
- public boolean isGroupLimit() {
- return (groupCapability & GROUP_CAPAB_GROUP_LIMIT) != 0;
- }
-
- /**
- * Update this device's details using another {@link WifiP2pDevice} instance.
- * This will throw an exception if the device address does not match.
- *
- * @param device another instance of {@link WifiP2pDevice} used to update this instance.
- * @throws IllegalArgumentException if the device is null or the device address does not match
- */
- public void update(@NonNull WifiP2pDevice device) {
- updateSupplicantDetails(device);
- status = device.status;
- }
-
- /** Updates details obtained from supplicant @hide */
- public void updateSupplicantDetails(WifiP2pDevice device) {
- if (device == null) {
- throw new IllegalArgumentException("device is null");
- }
- if (device.deviceAddress == null) {
- throw new IllegalArgumentException("deviceAddress is null");
- }
- if (!deviceAddress.equals(device.deviceAddress)) {
- throw new IllegalArgumentException("deviceAddress does not match");
- }
- deviceName = device.deviceName;
- primaryDeviceType = device.primaryDeviceType;
- secondaryDeviceType = device.secondaryDeviceType;
- wpsConfigMethodsSupported = device.wpsConfigMethodsSupported;
- deviceCapability = device.deviceCapability;
- groupCapability = device.groupCapability;
- wfdInfo = device.wfdInfo;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (!(obj instanceof WifiP2pDevice)) return false;
-
- WifiP2pDevice other = (WifiP2pDevice) obj;
- if (other == null || other.deviceAddress == null) {
- return (deviceAddress == null);
- }
- return other.deviceAddress.equals(deviceAddress);
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(deviceAddress);
- }
-
- @Override
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("Device: ").append(deviceName);
- sbuf.append("\n deviceAddress: ").append(deviceAddress);
- sbuf.append("\n primary type: ").append(primaryDeviceType);
- sbuf.append("\n secondary type: ").append(secondaryDeviceType);
- sbuf.append("\n wps: ").append(wpsConfigMethodsSupported);
- sbuf.append("\n grpcapab: ").append(groupCapability);
- sbuf.append("\n devcapab: ").append(deviceCapability);
- sbuf.append("\n status: ").append(status);
- sbuf.append("\n wfdInfo: ").append(wfdInfo);
- return sbuf.toString();
- }
-
- /** Implement the Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** copy constructor */
- public WifiP2pDevice(WifiP2pDevice source) {
- if (source != null) {
- deviceName = source.deviceName;
- deviceAddress = source.deviceAddress;
- primaryDeviceType = source.primaryDeviceType;
- secondaryDeviceType = source.secondaryDeviceType;
- wpsConfigMethodsSupported = source.wpsConfigMethodsSupported;
- deviceCapability = source.deviceCapability;
- groupCapability = source.groupCapability;
- status = source.status;
- if (source.wfdInfo != null) {
- wfdInfo = new WifiP2pWfdInfo(source.wfdInfo);
- }
- }
- }
-
- /** Implement the Parcelable interface */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(deviceName);
- dest.writeString(deviceAddress);
- dest.writeString(primaryDeviceType);
- dest.writeString(secondaryDeviceType);
- dest.writeInt(wpsConfigMethodsSupported);
- dest.writeInt(deviceCapability);
- dest.writeInt(groupCapability);
- dest.writeInt(status);
- if (wfdInfo != null) {
- dest.writeInt(1);
- wfdInfo.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<WifiP2pDevice> CREATOR =
- new Creator<WifiP2pDevice>() {
- @Override
- public WifiP2pDevice createFromParcel(Parcel in) {
- WifiP2pDevice device = new WifiP2pDevice();
- device.deviceName = in.readString();
- device.deviceAddress = in.readString();
- device.primaryDeviceType = in.readString();
- device.secondaryDeviceType = in.readString();
- device.wpsConfigMethodsSupported = in.readInt();
- device.deviceCapability = in.readInt();
- device.groupCapability = in.readInt();
- device.status = in.readInt();
- if (in.readInt() == 1) {
- device.wfdInfo = WifiP2pWfdInfo.CREATOR.createFromParcel(in);
- }
- return device;
- }
-
- @Override
- public WifiP2pDevice[] newArray(int size) {
- return new WifiP2pDevice[size];
- }
- };
-
- //supported formats: 0x1abc, 0X1abc, 1abc
- private int parseHex(String hexString) {
- int num = 0;
- if (hexString.startsWith("0x") || hexString.startsWith("0X")) {
- hexString = hexString.substring(2);
- }
-
- try {
- num = Integer.parseInt(hexString, 16);
- } catch(NumberFormatException e) {
- Log.e(TAG, "Failed to parse hex string " + hexString);
- }
- return num;
- }
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
deleted file mode 100644
index ededf67..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-
-/**
- * A class representing a Wi-Fi P2p device list.
- *
- * Note that the operations are not thread safe.
- * {@see WifiP2pManager}
- */
-public class WifiP2pDeviceList implements Parcelable {
-
- private final HashMap<String, WifiP2pDevice> mDevices = new HashMap<String, WifiP2pDevice>();
-
- public WifiP2pDeviceList() {
- }
-
- /** copy constructor */
- public WifiP2pDeviceList(WifiP2pDeviceList source) {
- if (source != null) {
- for (WifiP2pDevice d : source.getDeviceList()) {
- mDevices.put(d.deviceAddress, new WifiP2pDevice(d));
- }
- }
- }
-
- /** @hide */
- public WifiP2pDeviceList(ArrayList<WifiP2pDevice> devices) {
- for (WifiP2pDevice device : devices) {
- if (device.deviceAddress != null) {
- mDevices.put(device.deviceAddress, new WifiP2pDevice(device));
- }
- }
- }
-
- private void validateDevice(WifiP2pDevice device) {
- if (device == null) throw new IllegalArgumentException("Null device");
- if (TextUtils.isEmpty(device.deviceAddress)) {
- throw new IllegalArgumentException("Empty deviceAddress");
- }
- }
-
- private void validateDeviceAddress(String deviceAddress) {
- if (TextUtils.isEmpty(deviceAddress)) {
- throw new IllegalArgumentException("Empty deviceAddress");
- }
- }
-
- /** Clear the list @hide */
- public boolean clear() {
- if (mDevices.isEmpty()) return false;
- mDevices.clear();
- return true;
- }
-
- /**
- * Add/update a device to the list. If the device is not found, a new device entry
- * is created. If the device is already found, the device details are updated
- * @param device to be updated
- * @hide
- */
- @UnsupportedAppUsage
- public void update(WifiP2pDevice device) {
- updateSupplicantDetails(device);
- mDevices.get(device.deviceAddress).status = device.status;
- }
-
- /** Only updates details fetched from the supplicant @hide */
- public void updateSupplicantDetails(WifiP2pDevice device) {
- validateDevice(device);
- WifiP2pDevice d = mDevices.get(device.deviceAddress);
- if (d != null) {
- d.deviceName = device.deviceName;
- d.primaryDeviceType = device.primaryDeviceType;
- d.secondaryDeviceType = device.secondaryDeviceType;
- d.wpsConfigMethodsSupported = device.wpsConfigMethodsSupported;
- d.deviceCapability = device.deviceCapability;
- d.groupCapability = device.groupCapability;
- d.wfdInfo = device.wfdInfo;
- return;
- }
- //Not found, add a new one
- mDevices.put(device.deviceAddress, device);
- }
-
- /** @hide */
- public void updateGroupCapability(String deviceAddress, int groupCapab) {
- validateDeviceAddress(deviceAddress);
- WifiP2pDevice d = mDevices.get(deviceAddress);
- if (d != null) {
- d.groupCapability = groupCapab;
- }
- }
-
- /** @hide */
- public void updateStatus(String deviceAddress, int status) {
- validateDeviceAddress(deviceAddress);
- WifiP2pDevice d = mDevices.get(deviceAddress);
- if (d != null) {
- d.status = status;
- }
- }
-
- /**
- * Fetch a device from the list
- * @param deviceAddress is the address of the device
- * @return WifiP2pDevice device found, or null if none found
- */
- public WifiP2pDevice get(String deviceAddress) {
- validateDeviceAddress(deviceAddress);
- return mDevices.get(deviceAddress);
- }
-
- /** @hide */
- public boolean remove(WifiP2pDevice device) {
- validateDevice(device);
- return mDevices.remove(device.deviceAddress) != null;
- }
-
- /**
- * Remove a device from the list
- * @param deviceAddress is the address of the device
- * @return WifiP2pDevice device removed, or null if none removed
- * @hide
- */
- @UnsupportedAppUsage
- public WifiP2pDevice remove(String deviceAddress) {
- validateDeviceAddress(deviceAddress);
- return mDevices.remove(deviceAddress);
- }
-
- /** Returns true if any device the list was removed @hide */
- public boolean remove(WifiP2pDeviceList list) {
- boolean ret = false;
- for (WifiP2pDevice d : list.mDevices.values()) {
- if (remove(d)) ret = true;
- }
- return ret;
- }
-
- /** Get the list of devices */
- public Collection<WifiP2pDevice> getDeviceList() {
- return Collections.unmodifiableCollection(mDevices.values());
- }
-
- /** @hide */
- public boolean isGroupOwner(String deviceAddress) {
- validateDeviceAddress(deviceAddress);
- WifiP2pDevice device = mDevices.get(deviceAddress);
- if (device == null) {
- throw new IllegalArgumentException("Device not found " + deviceAddress);
- }
- return device.isGroupOwner();
- }
-
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- for (WifiP2pDevice device : mDevices.values()) {
- sbuf.append("\n").append(device);
- }
- return sbuf.toString();
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mDevices.size());
- for(WifiP2pDevice device : mDevices.values()) {
- dest.writeParcelable(device, flags);
- }
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<WifiP2pDeviceList> CREATOR =
- new Creator<WifiP2pDeviceList>() {
- public WifiP2pDeviceList createFromParcel(Parcel in) {
- WifiP2pDeviceList deviceList = new WifiP2pDeviceList();
-
- int deviceCount = in.readInt();
- for (int i = 0; i < deviceCount; i++) {
- deviceList.update((WifiP2pDevice)in.readParcelable(null));
- }
- return deviceList;
- }
-
- public WifiP2pDeviceList[] newArray(int size) {
- return new WifiP2pDeviceList[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
deleted file mode 100644
index e497b22..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A class representing a Wi-Fi P2p group. A p2p group consists of a single group
- * owner and one or more clients. In the case of a group with only two devices, one
- * will be the group owner and the other will be a group client.
- *
- * {@see WifiP2pManager}
- */
-public class WifiP2pGroup implements Parcelable {
-
- /**
- * The temporary network id.
- * @see #getNetworkId()
- */
- public static final int NETWORK_ID_TEMPORARY = -1;
-
- /**
- * The temporary network id.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static final int TEMPORARY_NET_ID = NETWORK_ID_TEMPORARY;
-
- /**
- * The persistent network id.
- * If a matching persistent profile is found, use it.
- * Otherwise, create a new persistent profile.
- * @see #getNetworkId()
- */
- public static final int NETWORK_ID_PERSISTENT = -2;
-
- /** The network name */
- private String mNetworkName;
-
- /** Group owner */
- private WifiP2pDevice mOwner;
-
- /** Device is group owner */
- private boolean mIsGroupOwner;
-
- /** Group clients */
- private List<WifiP2pDevice> mClients = new ArrayList<WifiP2pDevice>();
-
- /** The passphrase used for WPA2-PSK */
- private String mPassphrase;
-
- private String mInterface;
-
- /** The network ID in wpa_supplicant */
- private int mNetId;
-
- /** The frequency (in MHz) used by this group */
- private int mFrequency;
-
- /** P2P group started string pattern */
- private static final Pattern groupStartedPattern = Pattern.compile(
- "ssid=\"(.+)\" " +
- "freq=(\\d+) " +
- "(?:psk=)?([0-9a-fA-F]{64})?" +
- "(?:passphrase=)?(?:\"(.{0,63})\")? " +
- "go_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})" +
- " ?(\\[PERSISTENT\\])?"
- );
-
- public WifiP2pGroup() {
- }
-
- /**
- * @param supplicantEvent formats supported include
- *
- * P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
- * [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|
- * passphrase="fKG4jMe3"] go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT]
- *
- * P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED
- *
- * P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13
- * bssid=fa:7b:7a:42:82:13 unknown-network
- *
- * P2P-INVITATION-RECEIVED sa=b8:f9:34:2a:c7:9d persistent=0
- *
- * Note: The events formats can be looked up in the wpa_supplicant code
- * @hide
- */
- @UnsupportedAppUsage
- public WifiP2pGroup(String supplicantEvent) throws IllegalArgumentException {
-
- String[] tokens = supplicantEvent.split(" ");
-
- if (tokens.length < 3) {
- throw new IllegalArgumentException("Malformed supplicant event");
- }
-
- if (tokens[0].startsWith("P2P-GROUP")) {
- mInterface = tokens[1];
- mIsGroupOwner = tokens[2].equals("GO");
-
- Matcher match = groupStartedPattern.matcher(supplicantEvent);
- if (!match.find()) {
- return;
- }
-
- mNetworkName = match.group(1);
- // It throws NumberFormatException if the string cannot be parsed as an integer.
- mFrequency = Integer.parseInt(match.group(2));
- // psk is unused right now
- //String psk = match.group(3);
- mPassphrase = match.group(4);
- mOwner = new WifiP2pDevice(match.group(5));
- if (match.group(6) != null) {
- mNetId = NETWORK_ID_PERSISTENT;
- } else {
- mNetId = NETWORK_ID_TEMPORARY;
- }
- } else if (tokens[0].equals("P2P-INVITATION-RECEIVED")) {
- String sa = null;
- mNetId = NETWORK_ID_PERSISTENT;
- for (String token : tokens) {
- String[] nameValue = token.split("=");
- if (nameValue.length != 2) continue;
-
- if (nameValue[0].equals("sa")) {
- sa = nameValue[1];
-
- // set source address into the client list.
- WifiP2pDevice dev = new WifiP2pDevice();
- dev.deviceAddress = nameValue[1];
- mClients.add(dev);
- continue;
- }
-
- if (nameValue[0].equals("go_dev_addr")) {
- mOwner = new WifiP2pDevice(nameValue[1]);
- continue;
- }
-
- if (nameValue[0].equals("persistent")) {
- mNetId = Integer.parseInt(nameValue[1]);
- continue;
- }
- }
- } else {
- throw new IllegalArgumentException("Malformed supplicant event");
- }
- }
-
- /** @hide */
- public void setNetworkName(String networkName) {
- mNetworkName = networkName;
- }
-
- /**
- * Get the network name (SSID) of the group. Legacy Wi-Fi clients will discover
- * the p2p group using the network name.
- */
- public String getNetworkName() {
- return mNetworkName;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setIsGroupOwner(boolean isGo) {
- mIsGroupOwner = isGo;
- }
-
- /** Check whether this device is the group owner of the created p2p group */
- public boolean isGroupOwner() {
- return mIsGroupOwner;
- }
-
- /** @hide */
- public void setOwner(WifiP2pDevice device) {
- mOwner = device;
- }
-
- /** Get the details of the group owner as a {@link WifiP2pDevice} object */
- public WifiP2pDevice getOwner() {
- return mOwner;
- }
-
- /** @hide */
- public void addClient(String address) {
- addClient(new WifiP2pDevice(address));
- }
-
- /** @hide */
- public void addClient(WifiP2pDevice device) {
- for (WifiP2pDevice client : mClients) {
- if (client.equals(device)) return;
- }
- mClients.add(device);
- }
-
- /** @hide */
- public boolean removeClient(String address) {
- return mClients.remove(new WifiP2pDevice(address));
- }
-
- /** @hide */
- public boolean removeClient(WifiP2pDevice device) {
- return mClients.remove(device);
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public boolean isClientListEmpty() {
- return mClients.size() == 0;
- }
-
- /**
- * Returns {@code true} if the device is part of the group, {@code false} otherwise.
- *
- * @hide
- */
- public boolean contains(@Nullable WifiP2pDevice device) {
- return mOwner.equals(device) || mClients.contains(device);
- }
-
- /** Get the list of clients currently part of the p2p group */
- public Collection<WifiP2pDevice> getClientList() {
- return Collections.unmodifiableCollection(mClients);
- }
-
- /** @hide */
- public void setPassphrase(String passphrase) {
- mPassphrase = passphrase;
- }
-
- /**
- * Get the passphrase of the group. This function will return a valid passphrase only
- * at the group owner. Legacy Wi-Fi clients will need this passphrase alongside
- * network name obtained from {@link #getNetworkName()} to join the group
- */
- public String getPassphrase() {
- return mPassphrase;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setInterface(String intf) {
- mInterface = intf;
- }
-
- /** Get the interface name on which the group is created */
- public String getInterface() {
- return mInterface;
- }
-
- /** The network ID of the P2P group in wpa_supplicant. */
- public int getNetworkId() {
- return mNetId;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setNetworkId(int netId) {
- this.mNetId = netId;
- }
-
- /** Get the operating frequency (in MHz) of the p2p group */
- public int getFrequency() {
- return mFrequency;
- }
-
- /** @hide */
- public void setFrequency(int freq) {
- this.mFrequency = freq;
- }
-
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("network: ").append(mNetworkName);
- sbuf.append("\n isGO: ").append(mIsGroupOwner);
- sbuf.append("\n GO: ").append(mOwner);
- for (WifiP2pDevice client : mClients) {
- sbuf.append("\n Client: ").append(client);
- }
- sbuf.append("\n interface: ").append(mInterface);
- sbuf.append("\n networkId: ").append(mNetId);
- sbuf.append("\n frequency: ").append(mFrequency);
- return sbuf.toString();
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** copy constructor */
- public WifiP2pGroup(WifiP2pGroup source) {
- if (source != null) {
- mNetworkName = source.getNetworkName();
- mOwner = new WifiP2pDevice(source.getOwner());
- mIsGroupOwner = source.mIsGroupOwner;
- for (WifiP2pDevice d : source.getClientList()) mClients.add(d);
- mPassphrase = source.getPassphrase();
- mInterface = source.getInterface();
- mNetId = source.getNetworkId();
- mFrequency = source.getFrequency();
- }
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mNetworkName);
- dest.writeParcelable(mOwner, flags);
- dest.writeByte(mIsGroupOwner ? (byte) 1: (byte) 0);
- dest.writeInt(mClients.size());
- for (WifiP2pDevice client : mClients) {
- dest.writeParcelable(client, flags);
- }
- dest.writeString(mPassphrase);
- dest.writeString(mInterface);
- dest.writeInt(mNetId);
- dest.writeInt(mFrequency);
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<WifiP2pGroup> CREATOR =
- new Creator<WifiP2pGroup>() {
- public WifiP2pGroup createFromParcel(Parcel in) {
- WifiP2pGroup group = new WifiP2pGroup();
- group.setNetworkName(in.readString());
- group.setOwner((WifiP2pDevice)in.readParcelable(null));
- group.setIsGroupOwner(in.readByte() == (byte)1);
- int clientCount = in.readInt();
- for (int i=0; i<clientCount; i++) {
- group.addClient((WifiP2pDevice) in.readParcelable(null));
- }
- group.setPassphrase(in.readString());
- group.setInterface(in.readString());
- group.setNetworkId(in.readInt());
- group.setFrequency(in.readInt());
- return group;
- }
-
- public WifiP2pGroup[] newArray(int size) {
- return new WifiP2pGroup[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
deleted file mode 100644
index 8a86311..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.LruCache;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * A class representing a Wi-Fi P2p group list
- *
- * {@see WifiP2pManager}
- * @hide
- */
-@SystemApi
-public final class WifiP2pGroupList implements Parcelable {
-
- private static final int CREDENTIAL_MAX_NUM = 32;
-
- @UnsupportedAppUsage
- private final LruCache<Integer, WifiP2pGroup> mGroups;
- private final GroupDeleteListener mListener;
-
- private boolean isClearCalled = false;
-
- /** @hide */
- public interface GroupDeleteListener {
- public void onDeleteGroup(int netId);
- }
-
- /** @hide */
- public WifiP2pGroupList() {
- this(null, null);
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public WifiP2pGroupList(WifiP2pGroupList source, GroupDeleteListener listener) {
- mListener = listener;
- mGroups = new LruCache<Integer, WifiP2pGroup>(CREDENTIAL_MAX_NUM) {
- @Override
- protected void entryRemoved(boolean evicted, Integer netId,
- WifiP2pGroup oldValue, WifiP2pGroup newValue) {
- if (mListener != null && !isClearCalled) {
- mListener.onDeleteGroup(oldValue.getNetworkId());
- }
- }
- };
-
- if (source != null) {
- for (Map.Entry<Integer, WifiP2pGroup> item : source.mGroups.snapshot().entrySet()) {
- mGroups.put(item.getKey(), item.getValue());
- }
- }
- }
-
- /**
- * Get the list of P2P groups.
- */
- @NonNull
- public List<WifiP2pGroup> getGroupList() {
- return new ArrayList<>(mGroups.snapshot().values());
- }
-
- /**
- * Add the specified group to this group list.
- *
- * @param group
- * @hide
- */
- public void add(WifiP2pGroup group) {
- mGroups.put(group.getNetworkId(), group);
- }
-
- /**
- * Remove the group with the specified network id from this group list.
- *
- * @param netId
- * @hide
- */
- public void remove(int netId) {
- mGroups.remove(netId);
- }
-
- /**
- * Remove the group with the specified device address from this group list.
- *
- * @param deviceAddress
- */
- void remove(String deviceAddress) {
- remove(getNetworkId(deviceAddress));
- }
-
- /**
- * Clear the group.
- * @hide
- */
- public boolean clear() {
- if (mGroups.size() == 0) return false;
- isClearCalled = true;
- mGroups.evictAll();
- isClearCalled = false;
- return true;
- }
-
- /**
- * Return the network id of the group owner profile with the specified p2p device
- * address.
- * If more than one persistent group of the same address is present in the list,
- * return the first one.
- *
- * @param deviceAddress p2p device address.
- * @return the network id. if not found, return -1.
- * @hide
- */
- public int getNetworkId(String deviceAddress) {
- if (deviceAddress == null) return -1;
-
- final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
- for (WifiP2pGroup grp: groups) {
- if (deviceAddress.equalsIgnoreCase(grp.getOwner().deviceAddress)) {
- // update cache ordered.
- mGroups.get(grp.getNetworkId());
- return grp.getNetworkId();
- }
- }
- return -1;
- }
-
- /**
- * Return the network id of the group with the specified p2p device address
- * and the ssid.
- *
- * @param deviceAddress p2p device address.
- * @param ssid ssid.
- * @return the network id. if not found, return -1.
- * @hide
- */
- public int getNetworkId(String deviceAddress, String ssid) {
- if (deviceAddress == null || ssid == null) {
- return -1;
- }
-
- final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
- for (WifiP2pGroup grp: groups) {
- if (deviceAddress.equalsIgnoreCase(grp.getOwner().deviceAddress) &&
- ssid.equals(grp.getNetworkName())) {
- // update cache ordered.
- mGroups.get(grp.getNetworkId());
- return grp.getNetworkId();
- }
- }
-
- return -1;
- }
-
- /**
- * Return the group owner address of the group with the specified network id
- *
- * @param netId network id.
- * @return the address. if not found, return null.
- * @hide
- */
- public String getOwnerAddr(int netId) {
- WifiP2pGroup grp = mGroups.get(netId);
- if (grp != null) {
- return grp.getOwner().deviceAddress;
- }
- return null;
- }
-
- /**
- * Return true if this group list contains the specified network id.
- * This function does NOT update LRU information.
- * It means the internal queue is NOT reordered.
- *
- * @param netId network id.
- * @return true if the specified network id is present in this group list.
- * @hide
- */
- public boolean contains(int netId) {
- final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
- for (WifiP2pGroup grp: groups) {
- if (netId == grp.getNetworkId()) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
-
- final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
- for (WifiP2pGroup grp: groups) {
- sbuf.append(grp).append("\n");
- }
- return sbuf.toString();
- }
-
- /** Implement the Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
- dest.writeInt(groups.size());
- for(WifiP2pGroup group : groups) {
- dest.writeParcelable(group, flags);
- }
- }
-
- /** Implement the Parcelable interface */
- public static final @NonNull Creator<WifiP2pGroupList> CREATOR =
- new Creator<WifiP2pGroupList>() {
- public WifiP2pGroupList createFromParcel(Parcel in) {
- WifiP2pGroupList grpList = new WifiP2pGroupList();
-
- int deviceCount = in.readInt();
- for (int i = 0; i < deviceCount; i++) {
- grpList.add((WifiP2pGroup)in.readParcelable(null));
- }
- return grpList;
- }
-
- public WifiP2pGroupList[] newArray(int size) {
- return new WifiP2pGroupList[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java
deleted file mode 100644
index 33bc37e..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * A class representing connection information about a Wi-Fi p2p group
- *
- * {@see WifiP2pManager}
- */
-public class WifiP2pInfo implements Parcelable {
-
- /** Indicates if a p2p group has been successfully formed */
- public boolean groupFormed;
-
- /** Indicates if the current device is the group owner */
- public boolean isGroupOwner;
-
- /** Group owner address */
- public InetAddress groupOwnerAddress;
-
- public WifiP2pInfo() {
- }
-
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("groupFormed: ").append(groupFormed)
- .append(" isGroupOwner: ").append(isGroupOwner)
- .append(" groupOwnerAddress: ").append(groupOwnerAddress);
- return sbuf.toString();
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** copy constructor */
- public WifiP2pInfo(WifiP2pInfo source) {
- if (source != null) {
- groupFormed = source.groupFormed;
- isGroupOwner = source.isGroupOwner;
- groupOwnerAddress = source.groupOwnerAddress;
- }
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeByte(groupFormed ? (byte)1 : (byte)0);
- dest.writeByte(isGroupOwner ? (byte)1 : (byte)0);
-
- if (groupOwnerAddress != null) {
- dest.writeByte((byte)1);
- dest.writeByteArray(groupOwnerAddress.getAddress());
- } else {
- dest.writeByte((byte)0);
- }
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<WifiP2pInfo> CREATOR =
- new Creator<WifiP2pInfo>() {
- public WifiP2pInfo createFromParcel(Parcel in) {
- WifiP2pInfo info = new WifiP2pInfo();
- info.groupFormed = (in.readByte() == 1);
- info.isGroupOwner = (in.readByte() == 1);
- if (in.readByte() == 1) {
- try {
- info.groupOwnerAddress = InetAddress.getByAddress(in.createByteArray());
- } catch (UnknownHostException e) {}
- }
- return info;
- }
-
- public WifiP2pInfo[] newArray(int size) {
- return new WifiP2pInfo[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
deleted file mode 100644
index 724ccf0..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ /dev/null
@@ -1,2034 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.net.NetworkInfo;
-import android.net.wifi.WpsInfo;
-import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo;
-import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceResponse;
-import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
-import android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
-import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
-import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
-import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceResponse;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.Reference;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class provides the API for managing Wi-Fi peer-to-peer connectivity. This lets an
- * application discover available peers, setup connection to peers and query for the list of peers.
- * When a p2p connection is formed over wifi, the device continues to maintain the uplink
- * connection over mobile or any other available network for internet connectivity on the device.
- *
- * <p> The API is asynchronous and responses to requests from an application are on listener
- * callbacks provided by the application. The application needs to do an initialization with
- * {@link #initialize} before doing any p2p operation.
- *
- * <p> Most application calls need a {@link ActionListener} instance for receiving callbacks
- * {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}. Action callbacks
- * indicate whether the initiation of the action was a success or a failure.
- * Upon failure, the reason of failure can be one of {@link #ERROR}, {@link #P2P_UNSUPPORTED}
- * or {@link #BUSY}.
- *
- * <p> An application can initiate discovery of peers with {@link #discoverPeers}. An initiated
- * discovery request from an application stays active until the device starts connecting to a peer
- * ,forms a p2p group or there is an explicit {@link #stopPeerDiscovery}.
- * Applications can listen to {@link #WIFI_P2P_DISCOVERY_CHANGED_ACTION} to know if a peer-to-peer
- * discovery is running or stopped. Additionally, {@link #WIFI_P2P_PEERS_CHANGED_ACTION} indicates
- * if the peer list has changed.
- *
- * <p> When an application needs to fetch the current list of peers, it can request the list
- * of peers with {@link #requestPeers}. When the peer list is available
- * {@link PeerListListener#onPeersAvailable} is called with the device list.
- *
- * <p> An application can initiate a connection request to a peer through {@link #connect}. See
- * {@link WifiP2pConfig} for details on setting up the configuration. For communication with legacy
- * Wi-Fi devices that do not support p2p, an app can create a group using {@link #createGroup}
- * which creates an access point whose details can be fetched with {@link #requestGroupInfo}.
- *
- * <p> After a successful group formation through {@link #createGroup} or through {@link #connect},
- * use {@link #requestConnectionInfo} to fetch the connection details. The connection info
- * {@link WifiP2pInfo} contains the address of the group owner
- * {@link WifiP2pInfo#groupOwnerAddress} and a flag {@link WifiP2pInfo#isGroupOwner} to indicate
- * if the current device is a p2p group owner. A p2p client can thus communicate with
- * the p2p group owner through a socket connection. If the current device is the p2p group owner,
- * {@link WifiP2pInfo#groupOwnerAddress} is anonymized unless the caller holds the
- * {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} permission.
- *
- * <p> With peer discovery using {@link #discoverPeers}, an application discovers the neighboring
- * peers, but has no good way to figure out which peer to establish a connection with. For example,
- * if a game application is interested in finding all the neighboring peers that are also running
- * the same game, it has no way to find out until after the connection is setup. Pre-association
- * service discovery is meant to address this issue of filtering the peers based on the running
- * services.
- *
- * <p>With pre-association service discovery, an application can advertise a service for a
- * application on a peer device prior to a connection setup between the devices.
- * Currently, DNS based service discovery (Bonjour) and Upnp are the higher layer protocols
- * supported. Get Bonjour resources at dns-sd.org and Upnp resources at upnp.org
- * As an example, a video application can discover a Upnp capable media renderer
- * prior to setting up a Wi-fi p2p connection with the device.
- *
- * <p> An application can advertise a Upnp or a Bonjour service with a call to
- * {@link #addLocalService}. After a local service is added,
- * the framework automatically responds to a peer application discovering the service prior
- * to establishing a p2p connection. A call to {@link #removeLocalService} removes a local
- * service and {@link #clearLocalServices} can be used to clear all local services.
- *
- * <p> An application that is looking for peer devices that support certain services
- * can do so with a call to {@link #discoverServices}. Prior to initiating the discovery,
- * application can add service discovery request with a call to {@link #addServiceRequest},
- * remove a service discovery request with a call to {@link #removeServiceRequest} or clear
- * all requests with a call to {@link #clearServiceRequests}. When no service requests remain,
- * a previously running service discovery will stop.
- *
- * The application is notified of a result of service discovery request through listener callbacks
- * set through {@link #setDnsSdResponseListeners} for Bonjour or
- * {@link #setUpnpServiceResponseListener} for Upnp.
- *
- * <p class="note"><strong>Note:</strong>
- * Registering an application handler with {@link #initialize} requires the permissions
- * {@link android.Manifest.permission#ACCESS_WIFI_STATE} and
- * {@link android.Manifest.permission#CHANGE_WIFI_STATE} to perform any further peer-to-peer
- * operations.
- *
- * {@see WifiP2pConfig}
- * {@see WifiP2pInfo}
- * {@see WifiP2pGroup}
- * {@see WifiP2pDevice}
- * {@see WifiP2pDeviceList}
- * {@see android.net.wifi.WpsInfo}
- */
-@SystemService(Context.WIFI_P2P_SERVICE)
-public class WifiP2pManager {
- private static final String TAG = "WifiP2pManager";
- /**
- * Broadcast intent action to indicate whether Wi-Fi p2p is enabled or disabled. An
- * extra {@link #EXTRA_WIFI_STATE} provides the state information as int.
- *
- * @see #EXTRA_WIFI_STATE
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String WIFI_P2P_STATE_CHANGED_ACTION =
- "android.net.wifi.p2p.STATE_CHANGED";
-
- /**
- * The lookup key for an int that indicates whether Wi-Fi p2p is enabled or disabled.
- * Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
- *
- * @see #WIFI_P2P_STATE_DISABLED
- * @see #WIFI_P2P_STATE_ENABLED
- */
- public static final String EXTRA_WIFI_STATE = "wifi_p2p_state";
-
- /** @hide */
- @IntDef({
- WIFI_P2P_STATE_DISABLED,
- WIFI_P2P_STATE_ENABLED})
- @Retention(RetentionPolicy.SOURCE)
- public @interface WifiP2pState {
- }
-
- /**
- * Wi-Fi p2p is disabled.
- *
- * @see #WIFI_P2P_STATE_CHANGED_ACTION
- */
- public static final int WIFI_P2P_STATE_DISABLED = 1;
-
- /**
- * Wi-Fi p2p is enabled.
- *
- * @see #WIFI_P2P_STATE_CHANGED_ACTION
- */
- public static final int WIFI_P2P_STATE_ENABLED = 2;
-
- /**
- * Broadcast intent action indicating that the state of Wi-Fi p2p connectivity
- * has changed. One extra {@link #EXTRA_WIFI_P2P_INFO} provides the p2p connection info in
- * the form of a {@link WifiP2pInfo} object. Another extra {@link #EXTRA_NETWORK_INFO} provides
- * the network info in the form of a {@link android.net.NetworkInfo}. A third extra provides
- * the details of the group and may contain a {@code null}.
- *
- * All of these permissions are required to receive this broadcast:
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
- * {@link android.Manifest.permission#ACCESS_WIFI_STATE}
- *
- * @see #EXTRA_WIFI_P2P_INFO
- * @see #EXTRA_NETWORK_INFO
- * @see #EXTRA_WIFI_P2P_GROUP
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION =
- "android.net.wifi.p2p.CONNECTION_STATE_CHANGE";
-
- /**
- * The lookup key for a {@link android.net.wifi.p2p.WifiP2pInfo} object
- * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo";
-
- /**
- * The lookup key for a {@link android.net.NetworkInfo} object associated with the
- * p2p network. Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_NETWORK_INFO = "networkInfo";
-
- /**
- * The lookup key for a {@link android.net.wifi.p2p.WifiP2pGroup} object
- * associated with the p2p network. Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo";
-
- /**
- * Broadcast intent action indicating that the available peer list has changed. This
- * can be sent as a result of peers being found, lost or updated.
- *
- * All of these permissions are required to receive this broadcast:
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
- * {@link android.Manifest.permission#ACCESS_WIFI_STATE}
- *
- * <p> An extra {@link #EXTRA_P2P_DEVICE_LIST} provides the full list of
- * current peers. The full list of peers can also be obtained any time with
- * {@link #requestPeers}.
- *
- * @see #EXTRA_P2P_DEVICE_LIST
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String WIFI_P2P_PEERS_CHANGED_ACTION =
- "android.net.wifi.p2p.PEERS_CHANGED";
-
- /**
- * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDeviceList} object representing
- * the new peer list when {@link #WIFI_P2P_PEERS_CHANGED_ACTION} broadcast is sent.
- *
- * <p>Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_P2P_DEVICE_LIST = "wifiP2pDeviceList";
-
- /**
- * Broadcast intent action indicating that peer discovery has either started or stopped.
- * One extra {@link #EXTRA_DISCOVERY_STATE} indicates whether discovery has started
- * or stopped.
- *
- * <p>Note that discovery will be stopped during a connection setup. If the application tries
- * to re-initiate discovery during this time, it can fail.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String WIFI_P2P_DISCOVERY_CHANGED_ACTION =
- "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE";
-
- /**
- * The lookup key for an int that indicates whether p2p discovery has started or stopped.
- * Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
- *
- * @see #WIFI_P2P_DISCOVERY_STARTED
- * @see #WIFI_P2P_DISCOVERY_STOPPED
- */
- public static final String EXTRA_DISCOVERY_STATE = "discoveryState";
-
- /** @hide */
- @IntDef({
- WIFI_P2P_DISCOVERY_STOPPED,
- WIFI_P2P_DISCOVERY_STARTED})
- @Retention(RetentionPolicy.SOURCE)
- public @interface WifiP2pDiscoveryState {
- }
-
- /**
- * p2p discovery has stopped
- *
- * @see #WIFI_P2P_DISCOVERY_CHANGED_ACTION
- */
- public static final int WIFI_P2P_DISCOVERY_STOPPED = 1;
-
- /**
- * p2p discovery has started
- *
- * @see #WIFI_P2P_DISCOVERY_CHANGED_ACTION
- */
- public static final int WIFI_P2P_DISCOVERY_STARTED = 2;
-
- /**
- * Broadcast intent action indicating that this device details have changed.
- *
- * <p> An extra {@link #EXTRA_WIFI_P2P_DEVICE} provides this device details.
- * The valid device details can also be obtained with
- * {@link #requestDeviceInfo(Channel, DeviceInfoListener)} when p2p is enabled.
- * To get information notifications on P2P getting enabled refers
- * {@link #WIFI_P2P_STATE_ENABLED}.
- *
- * <p> The {@link #EXTRA_WIFI_P2P_DEVICE} extra contains an anonymized version of the device's
- * MAC address. Callers holding the {@code android.Manifest.permission#LOCAL_MAC_ADDRESS}
- * permission can use {@link #requestDeviceInfo} to obtain the actual MAC address of this
- * device.
- *
- * All of these permissions are required to receive this broadcast:
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
- * {@link android.Manifest.permission#ACCESS_WIFI_STATE}
- *
- * @see #EXTRA_WIFI_P2P_DEVICE
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String WIFI_P2P_THIS_DEVICE_CHANGED_ACTION =
- "android.net.wifi.p2p.THIS_DEVICE_CHANGED";
-
- /**
- * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDevice} object
- * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice";
-
- /**
- * Broadcast intent action indicating that remembered persistent groups have changed.
- *
- * You can <em>not</em> receive this through components declared
- * in manifests, only by explicitly registering for it with
- * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver,
- * android.content.IntentFilter) Context.registerReceiver()}.
- *
- * @hide
- */
- @SystemApi
- public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED =
- "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED";
-
- /**
- * The lookup key for a handover message returned by the WifiP2pService.
- * @hide
- */
- public static final String EXTRA_HANDOVER_MESSAGE =
- "android.net.wifi.p2p.EXTRA_HANDOVER_MESSAGE";
-
- /**
- * The lookup key for a calling package name from WifiP2pManager
- * @hide
- */
- public static final String CALLING_PACKAGE =
- "android.net.wifi.p2p.CALLING_PACKAGE";
-
- /**
- * The lookup key for a calling feature id from WifiP2pManager
- * @hide
- */
- public static final String CALLING_FEATURE_ID =
- "android.net.wifi.p2p.CALLING_FEATURE_ID";
-
- /**
- * The lookup key for a calling package binder from WifiP2pManager
- * @hide
- */
- public static final String CALLING_BINDER =
- "android.net.wifi.p2p.CALLING_BINDER";
-
- IWifiP2pManager mService;
-
- private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER;
-
- /** @hide */
- public static final int DISCOVER_PEERS = BASE + 1;
- /** @hide */
- public static final int DISCOVER_PEERS_FAILED = BASE + 2;
- /** @hide */
- public static final int DISCOVER_PEERS_SUCCEEDED = BASE + 3;
-
- /** @hide */
- public static final int STOP_DISCOVERY = BASE + 4;
- /** @hide */
- public static final int STOP_DISCOVERY_FAILED = BASE + 5;
- /** @hide */
- public static final int STOP_DISCOVERY_SUCCEEDED = BASE + 6;
-
- /** @hide */
- public static final int CONNECT = BASE + 7;
- /** @hide */
- public static final int CONNECT_FAILED = BASE + 8;
- /** @hide */
- public static final int CONNECT_SUCCEEDED = BASE + 9;
-
- /** @hide */
- public static final int CANCEL_CONNECT = BASE + 10;
- /** @hide */
- public static final int CANCEL_CONNECT_FAILED = BASE + 11;
- /** @hide */
- public static final int CANCEL_CONNECT_SUCCEEDED = BASE + 12;
-
- /** @hide */
- @UnsupportedAppUsage
- public static final int CREATE_GROUP = BASE + 13;
- /** @hide */
- public static final int CREATE_GROUP_FAILED = BASE + 14;
- /** @hide */
- public static final int CREATE_GROUP_SUCCEEDED = BASE + 15;
-
- /** @hide */
- public static final int REMOVE_GROUP = BASE + 16;
- /** @hide */
- public static final int REMOVE_GROUP_FAILED = BASE + 17;
- /** @hide */
- public static final int REMOVE_GROUP_SUCCEEDED = BASE + 18;
-
- /** @hide */
- public static final int REQUEST_PEERS = BASE + 19;
- /** @hide */
- public static final int RESPONSE_PEERS = BASE + 20;
-
- /** @hide */
- public static final int REQUEST_CONNECTION_INFO = BASE + 21;
- /** @hide */
- public static final int RESPONSE_CONNECTION_INFO = BASE + 22;
-
- /** @hide */
- public static final int REQUEST_GROUP_INFO = BASE + 23;
- /** @hide */
- public static final int RESPONSE_GROUP_INFO = BASE + 24;
-
- /** @hide */
- public static final int ADD_LOCAL_SERVICE = BASE + 28;
- /** @hide */
- public static final int ADD_LOCAL_SERVICE_FAILED = BASE + 29;
- /** @hide */
- public static final int ADD_LOCAL_SERVICE_SUCCEEDED = BASE + 30;
-
- /** @hide */
- public static final int REMOVE_LOCAL_SERVICE = BASE + 31;
- /** @hide */
- public static final int REMOVE_LOCAL_SERVICE_FAILED = BASE + 32;
- /** @hide */
- public static final int REMOVE_LOCAL_SERVICE_SUCCEEDED = BASE + 33;
-
- /** @hide */
- public static final int CLEAR_LOCAL_SERVICES = BASE + 34;
- /** @hide */
- public static final int CLEAR_LOCAL_SERVICES_FAILED = BASE + 35;
- /** @hide */
- public static final int CLEAR_LOCAL_SERVICES_SUCCEEDED = BASE + 36;
-
- /** @hide */
- public static final int ADD_SERVICE_REQUEST = BASE + 37;
- /** @hide */
- public static final int ADD_SERVICE_REQUEST_FAILED = BASE + 38;
- /** @hide */
- public static final int ADD_SERVICE_REQUEST_SUCCEEDED = BASE + 39;
-
- /** @hide */
- public static final int REMOVE_SERVICE_REQUEST = BASE + 40;
- /** @hide */
- public static final int REMOVE_SERVICE_REQUEST_FAILED = BASE + 41;
- /** @hide */
- public static final int REMOVE_SERVICE_REQUEST_SUCCEEDED = BASE + 42;
-
- /** @hide */
- public static final int CLEAR_SERVICE_REQUESTS = BASE + 43;
- /** @hide */
- public static final int CLEAR_SERVICE_REQUESTS_FAILED = BASE + 44;
- /** @hide */
- public static final int CLEAR_SERVICE_REQUESTS_SUCCEEDED = BASE + 45;
-
- /** @hide */
- public static final int DISCOVER_SERVICES = BASE + 46;
- /** @hide */
- public static final int DISCOVER_SERVICES_FAILED = BASE + 47;
- /** @hide */
- public static final int DISCOVER_SERVICES_SUCCEEDED = BASE + 48;
-
- /** @hide */
- public static final int PING = BASE + 49;
-
- /** @hide */
- public static final int RESPONSE_SERVICE = BASE + 50;
-
- /** @hide */
- public static final int SET_DEVICE_NAME = BASE + 51;
- /** @hide */
- public static final int SET_DEVICE_NAME_FAILED = BASE + 52;
- /** @hide */
- public static final int SET_DEVICE_NAME_SUCCEEDED = BASE + 53;
-
- /** @hide */
- public static final int DELETE_PERSISTENT_GROUP = BASE + 54;
- /** @hide */
- public static final int DELETE_PERSISTENT_GROUP_FAILED = BASE + 55;
- /** @hide */
- public static final int DELETE_PERSISTENT_GROUP_SUCCEEDED = BASE + 56;
-
- /** @hide */
- public static final int REQUEST_PERSISTENT_GROUP_INFO = BASE + 57;
- /** @hide */
- public static final int RESPONSE_PERSISTENT_GROUP_INFO = BASE + 58;
-
- /** @hide */
- public static final int SET_WFD_INFO = BASE + 59;
- /** @hide */
- public static final int SET_WFD_INFO_FAILED = BASE + 60;
- /** @hide */
- public static final int SET_WFD_INFO_SUCCEEDED = BASE + 61;
-
- /** @hide */
- public static final int START_WPS = BASE + 62;
- /** @hide */
- public static final int START_WPS_FAILED = BASE + 63;
- /** @hide */
- public static final int START_WPS_SUCCEEDED = BASE + 64;
-
- /** @hide */
- public static final int START_LISTEN = BASE + 65;
- /** @hide */
- public static final int START_LISTEN_FAILED = BASE + 66;
- /** @hide */
- public static final int START_LISTEN_SUCCEEDED = BASE + 67;
-
- /** @hide */
- public static final int STOP_LISTEN = BASE + 68;
- /** @hide */
- public static final int STOP_LISTEN_FAILED = BASE + 69;
- /** @hide */
- public static final int STOP_LISTEN_SUCCEEDED = BASE + 70;
-
- /** @hide */
- public static final int SET_CHANNEL = BASE + 71;
- /** @hide */
- public static final int SET_CHANNEL_FAILED = BASE + 72;
- /** @hide */
- public static final int SET_CHANNEL_SUCCEEDED = BASE + 73;
-
- /** @hide */
- public static final int GET_HANDOVER_REQUEST = BASE + 75;
- /** @hide */
- public static final int GET_HANDOVER_SELECT = BASE + 76;
- /** @hide */
- public static final int RESPONSE_GET_HANDOVER_MESSAGE = BASE + 77;
- /** @hide */
- public static final int INITIATOR_REPORT_NFC_HANDOVER = BASE + 78;
- /** @hide */
- public static final int RESPONDER_REPORT_NFC_HANDOVER = BASE + 79;
- /** @hide */
- public static final int REPORT_NFC_HANDOVER_SUCCEEDED = BASE + 80;
- /** @hide */
- public static final int REPORT_NFC_HANDOVER_FAILED = BASE + 81;
-
- /** @hide */
- public static final int FACTORY_RESET = BASE + 82;
- /** @hide */
- public static final int FACTORY_RESET_FAILED = BASE + 83;
- /** @hide */
- public static final int FACTORY_RESET_SUCCEEDED = BASE + 84;
-
- /** @hide */
- public static final int REQUEST_ONGOING_PEER_CONFIG = BASE + 85;
- /** @hide */
- public static final int RESPONSE_ONGOING_PEER_CONFIG = BASE + 86;
- /** @hide */
- public static final int SET_ONGOING_PEER_CONFIG = BASE + 87;
- /** @hide */
- public static final int SET_ONGOING_PEER_CONFIG_FAILED = BASE + 88;
- /** @hide */
- public static final int SET_ONGOING_PEER_CONFIG_SUCCEEDED = BASE + 89;
-
- /** @hide */
- public static final int REQUEST_P2P_STATE = BASE + 90;
- /** @hide */
- public static final int RESPONSE_P2P_STATE = BASE + 91;
-
- /** @hide */
- public static final int REQUEST_DISCOVERY_STATE = BASE + 92;
- /** @hide */
- public static final int RESPONSE_DISCOVERY_STATE = BASE + 93;
-
- /** @hide */
- public static final int REQUEST_NETWORK_INFO = BASE + 94;
- /** @hide */
- public static final int RESPONSE_NETWORK_INFO = BASE + 95;
-
- /** @hide */
- public static final int UPDATE_CHANNEL_INFO = BASE + 96;
-
- /** @hide */
- public static final int REQUEST_DEVICE_INFO = BASE + 97;
- /** @hide */
- public static final int RESPONSE_DEVICE_INFO = BASE + 98;
-
- /**
- * Create a new WifiP2pManager instance. Applications use
- * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
- * the standard {@link android.content.Context#WIFI_P2P_SERVICE Context.WIFI_P2P_SERVICE}.
- * @param service the Binder interface
- * @hide - hide this because it takes in a parameter of type IWifiP2pManager, which
- * is a system private class.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public WifiP2pManager(IWifiP2pManager service) {
- mService = service;
- }
-
- /**
- * Passed with {@link ActionListener#onFailure}.
- * Indicates that the operation failed due to an internal error.
- */
- public static final int ERROR = 0;
-
- /**
- * Passed with {@link ActionListener#onFailure}.
- * Indicates that the operation failed because p2p is unsupported on the device.
- */
- public static final int P2P_UNSUPPORTED = 1;
-
- /**
- * Passed with {@link ActionListener#onFailure}.
- * Indicates that the operation failed because the framework is busy and
- * unable to service the request
- */
- public static final int BUSY = 2;
-
- /**
- * Passed with {@link ActionListener#onFailure}.
- * Indicates that the {@link #discoverServices} failed because no service
- * requests are added. Use {@link #addServiceRequest} to add a service
- * request.
- */
- public static final int NO_SERVICE_REQUESTS = 3;
-
- /** Interface for callback invocation when framework channel is lost */
- public interface ChannelListener {
- /**
- * The channel to the framework has been disconnected.
- * Application could try re-initializing using {@link #initialize}
- */
- public void onChannelDisconnected();
- }
-
- /** Interface for callback invocation on an application action */
- public interface ActionListener {
- /** The operation succeeded */
- public void onSuccess();
- /**
- * The operation failed
- * @param reason The reason for failure could be one of {@link #P2P_UNSUPPORTED},
- * {@link #ERROR} or {@link #BUSY}
- */
- public void onFailure(int reason);
- }
-
- /** Interface for callback invocation when peer list is available */
- public interface PeerListListener {
- /**
- * The requested peer list is available
- * @param peers List of available peers
- */
- public void onPeersAvailable(WifiP2pDeviceList peers);
- }
-
- /** Interface for callback invocation when connection info is available */
- public interface ConnectionInfoListener {
- /**
- * The requested connection info is available
- * @param info Wi-Fi p2p connection info
- */
- public void onConnectionInfoAvailable(WifiP2pInfo info);
- }
-
- /** Interface for callback invocation when group info is available */
- public interface GroupInfoListener {
- /**
- * The requested p2p group info is available
- * @param group Wi-Fi p2p group info
- */
- public void onGroupInfoAvailable(WifiP2pGroup group);
- }
-
- /**
- * Interface for callback invocation when service discovery response other than
- * Upnp or Bonjour is received
- */
- public interface ServiceResponseListener {
-
- /**
- * The requested service response is available.
- *
- * @param protocolType protocol type. currently only
- * {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}.
- * @param responseData service discovery response data based on the requested
- * service protocol type. The format depends on the service type.
- * @param srcDevice source device.
- */
- public void onServiceAvailable(int protocolType,
- byte[] responseData, WifiP2pDevice srcDevice);
- }
-
- /**
- * Interface for callback invocation when Bonjour service discovery response
- * is received
- */
- public interface DnsSdServiceResponseListener {
-
- /**
- * The requested Bonjour service response is available.
- *
- * <p>This function is invoked when the device with the specified Bonjour
- * registration type returned the instance name.
- * @param instanceName instance name.<br>
- * e.g) "MyPrinter".
- * @param registrationType <br>
- * e.g) "_ipp._tcp.local."
- * @param srcDevice source device.
- */
- public void onDnsSdServiceAvailable(String instanceName,
- String registrationType, WifiP2pDevice srcDevice);
-
- }
-
- /**
- * Interface for callback invocation when Bonjour TXT record is available
- * for a service
- */
- public interface DnsSdTxtRecordListener {
- /**
- * The requested Bonjour service response is available.
- *
- * <p>This function is invoked when the device with the specified full
- * service domain service returned TXT record.
- *
- * @param fullDomainName full domain name. <br>
- * e.g) "MyPrinter._ipp._tcp.local.".
- * @param txtRecordMap TXT record data as a map of key/value pairs
- * @param srcDevice source device.
- */
- public void onDnsSdTxtRecordAvailable(String fullDomainName,
- Map<String, String> txtRecordMap,
- WifiP2pDevice srcDevice);
- }
-
- /**
- * Interface for callback invocation when upnp service discovery response
- * is received
- * */
- public interface UpnpServiceResponseListener {
-
- /**
- * The requested upnp service response is available.
- *
- * <p>This function is invoked when the specified device or service is found.
- *
- * @param uniqueServiceNames The list of unique service names.<br>
- * e.g) uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:
- * MediaServer:1
- * @param srcDevice source device.
- */
- public void onUpnpServiceAvailable(List<String> uniqueServiceNames,
- WifiP2pDevice srcDevice);
- }
-
-
- /**
- * Interface for callback invocation when stored group info list is available
- *
- * @hide
- */
- @SystemApi
- public interface PersistentGroupInfoListener {
- /**
- * The requested stored p2p group info list is available
- * @param groups Wi-Fi p2p group info list
- */
- void onPersistentGroupInfoAvailable(@NonNull WifiP2pGroupList groups);
- }
-
- /**
- * Interface for callback invocation when Handover Request or Select Message is available
- * @hide
- */
- public interface HandoverMessageListener {
- public void onHandoverMessageAvailable(String handoverMessage);
- }
-
- /** Interface for callback invocation when p2p state is available
- * in response to {@link #requestP2pState}.
- */
- public interface P2pStateListener {
- /**
- * The requested p2p state is available.
- * @param state Wi-Fi p2p state
- * @see #WIFI_P2P_STATE_DISABLED
- * @see #WIFI_P2P_STATE_ENABLED
- */
- void onP2pStateAvailable(@WifiP2pState int state);
- }
-
- /** Interface for callback invocation when p2p state is available
- * in response to {@link #requestDiscoveryState}.
- */
- public interface DiscoveryStateListener {
- /**
- * The requested p2p discovery state is available.
- * @param state Wi-Fi p2p discovery state
- * @see #WIFI_P2P_DISCOVERY_STARTED
- * @see #WIFI_P2P_DISCOVERY_STOPPED
- */
- void onDiscoveryStateAvailable(@WifiP2pDiscoveryState int state);
- }
-
- /** Interface for callback invocation when {@link android.net.NetworkInfo} is available
- * in response to {@link #requestNetworkInfo}.
- */
- public interface NetworkInfoListener {
- /**
- * The requested {@link android.net.NetworkInfo} is available
- * @param networkInfo Wi-Fi p2p {@link android.net.NetworkInfo}
- */
- void onNetworkInfoAvailable(@NonNull NetworkInfo networkInfo);
- }
-
- /**
- * Interface for callback invocation when ongoing peer info is available
- * @hide
- */
- public interface OngoingPeerInfoListener {
- /**
- * The requested ongoing WifiP2pConfig is available
- * @param peerConfig WifiP2pConfig for current connecting session
- */
- void onOngoingPeerAvailable(WifiP2pConfig peerConfig);
- }
-
- /** Interface for callback invocation when {@link android.net.wifi.p2p.WifiP2pDevice}
- * is available in response to {@link #requestDeviceInfo(Channel, DeviceInfoListener)}.
- */
- public interface DeviceInfoListener {
- /**
- * The requested {@link android.net.wifi.p2p.WifiP2pDevice} is available.
- * @param wifiP2pDevice Wi-Fi p2p {@link android.net.wifi.p2p.WifiP2pDevice}
- */
- void onDeviceInfoAvailable(@Nullable WifiP2pDevice wifiP2pDevice);
- }
-
- /**
- * A channel that connects the application to the Wifi p2p framework.
- * Most p2p operations require a Channel as an argument. An instance of Channel is obtained
- * by doing a call on {@link #initialize}
- */
- public static class Channel implements AutoCloseable {
- /** @hide */
- public Channel(Context context, Looper looper, ChannelListener l, Binder binder,
- WifiP2pManager p2pManager) {
- mAsyncChannel = new AsyncChannel();
- mHandler = new P2pHandler(looper);
- mChannelListener = l;
- mContext = context;
- mBinder = binder;
- mP2pManager = p2pManager;
-
- mCloseGuard.open("close");
- }
- private final static int INVALID_LISTENER_KEY = 0;
- private final WifiP2pManager mP2pManager;
- private ChannelListener mChannelListener;
- private ServiceResponseListener mServRspListener;
- private DnsSdServiceResponseListener mDnsSdServRspListener;
- private DnsSdTxtRecordListener mDnsSdTxtListener;
- private UpnpServiceResponseListener mUpnpServRspListener;
- private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>();
- private final Object mListenerMapLock = new Object();
- private int mListenerKey = 0;
-
- private final CloseGuard mCloseGuard = new CloseGuard();
-
- /**
- * Close the current P2P connection and indicate to the P2P service that connections
- * created by the app can be removed.
- */
- public void close() {
- if (mP2pManager == null) {
- Log.w(TAG, "Channel.close(): Null mP2pManager!?");
- } else {
- try {
- mP2pManager.mService.close(mBinder);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- mAsyncChannel.disconnect();
- mCloseGuard.close();
- Reference.reachabilityFence(this);
- }
-
- /** @hide */
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mCloseGuard != null) {
- mCloseGuard.warnIfOpen();
- }
-
- close();
- } finally {
- super.finalize();
- }
- }
-
- /* package */ final Binder mBinder;
-
- @UnsupportedAppUsage
- private AsyncChannel mAsyncChannel;
- private P2pHandler mHandler;
- Context mContext;
- class P2pHandler extends Handler {
- P2pHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message message) {
- Object listener = getListener(message.arg2);
- switch (message.what) {
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- if (mChannelListener != null) {
- mChannelListener.onChannelDisconnected();
- mChannelListener = null;
- }
- break;
- /* ActionListeners grouped together */
- case DISCOVER_PEERS_FAILED:
- case STOP_DISCOVERY_FAILED:
- case DISCOVER_SERVICES_FAILED:
- case CONNECT_FAILED:
- case CANCEL_CONNECT_FAILED:
- case CREATE_GROUP_FAILED:
- case REMOVE_GROUP_FAILED:
- case ADD_LOCAL_SERVICE_FAILED:
- case REMOVE_LOCAL_SERVICE_FAILED:
- case CLEAR_LOCAL_SERVICES_FAILED:
- case ADD_SERVICE_REQUEST_FAILED:
- case REMOVE_SERVICE_REQUEST_FAILED:
- case CLEAR_SERVICE_REQUESTS_FAILED:
- case SET_DEVICE_NAME_FAILED:
- case DELETE_PERSISTENT_GROUP_FAILED:
- case SET_WFD_INFO_FAILED:
- case START_WPS_FAILED:
- case START_LISTEN_FAILED:
- case STOP_LISTEN_FAILED:
- case SET_CHANNEL_FAILED:
- case REPORT_NFC_HANDOVER_FAILED:
- case FACTORY_RESET_FAILED:
- case SET_ONGOING_PEER_CONFIG_FAILED:
- if (listener != null) {
- ((ActionListener) listener).onFailure(message.arg1);
- }
- break;
- /* ActionListeners grouped together */
- case DISCOVER_PEERS_SUCCEEDED:
- case STOP_DISCOVERY_SUCCEEDED:
- case DISCOVER_SERVICES_SUCCEEDED:
- case CONNECT_SUCCEEDED:
- case CANCEL_CONNECT_SUCCEEDED:
- case CREATE_GROUP_SUCCEEDED:
- case REMOVE_GROUP_SUCCEEDED:
- case ADD_LOCAL_SERVICE_SUCCEEDED:
- case REMOVE_LOCAL_SERVICE_SUCCEEDED:
- case CLEAR_LOCAL_SERVICES_SUCCEEDED:
- case ADD_SERVICE_REQUEST_SUCCEEDED:
- case REMOVE_SERVICE_REQUEST_SUCCEEDED:
- case CLEAR_SERVICE_REQUESTS_SUCCEEDED:
- case SET_DEVICE_NAME_SUCCEEDED:
- case DELETE_PERSISTENT_GROUP_SUCCEEDED:
- case SET_WFD_INFO_SUCCEEDED:
- case START_WPS_SUCCEEDED:
- case START_LISTEN_SUCCEEDED:
- case STOP_LISTEN_SUCCEEDED:
- case SET_CHANNEL_SUCCEEDED:
- case REPORT_NFC_HANDOVER_SUCCEEDED:
- case FACTORY_RESET_SUCCEEDED:
- case SET_ONGOING_PEER_CONFIG_SUCCEEDED:
- if (listener != null) {
- ((ActionListener) listener).onSuccess();
- }
- break;
- case RESPONSE_PEERS:
- WifiP2pDeviceList peers = (WifiP2pDeviceList) message.obj;
- if (listener != null) {
- ((PeerListListener) listener).onPeersAvailable(peers);
- }
- break;
- case RESPONSE_CONNECTION_INFO:
- WifiP2pInfo wifiP2pInfo = (WifiP2pInfo) message.obj;
- if (listener != null) {
- ((ConnectionInfoListener) listener).onConnectionInfoAvailable(wifiP2pInfo);
- }
- break;
- case RESPONSE_GROUP_INFO:
- WifiP2pGroup group = (WifiP2pGroup) message.obj;
- if (listener != null) {
- ((GroupInfoListener) listener).onGroupInfoAvailable(group);
- }
- break;
- case RESPONSE_SERVICE:
- WifiP2pServiceResponse resp = (WifiP2pServiceResponse) message.obj;
- handleServiceResponse(resp);
- break;
- case RESPONSE_PERSISTENT_GROUP_INFO:
- WifiP2pGroupList groups = (WifiP2pGroupList) message.obj;
- if (listener != null) {
- ((PersistentGroupInfoListener) listener).
- onPersistentGroupInfoAvailable(groups);
- }
- break;
- case RESPONSE_GET_HANDOVER_MESSAGE:
- Bundle handoverBundle = (Bundle) message.obj;
- if (listener != null) {
- String handoverMessage = handoverBundle != null
- ? handoverBundle.getString(EXTRA_HANDOVER_MESSAGE)
- : null;
- ((HandoverMessageListener) listener)
- .onHandoverMessageAvailable(handoverMessage);
- }
- break;
- case RESPONSE_ONGOING_PEER_CONFIG:
- WifiP2pConfig peerConfig = (WifiP2pConfig) message.obj;
- if (listener != null) {
- ((OngoingPeerInfoListener) listener)
- .onOngoingPeerAvailable(peerConfig);
- }
- break;
- case RESPONSE_P2P_STATE:
- if (listener != null) {
- ((P2pStateListener) listener)
- .onP2pStateAvailable(message.arg1);
- }
- break;
- case RESPONSE_DISCOVERY_STATE:
- if (listener != null) {
- ((DiscoveryStateListener) listener)
- .onDiscoveryStateAvailable(message.arg1);
- }
- break;
- case RESPONSE_NETWORK_INFO:
- if (listener != null) {
- ((NetworkInfoListener) listener)
- .onNetworkInfoAvailable((NetworkInfo) message.obj);
- }
- break;
- case RESPONSE_DEVICE_INFO:
- if (listener != null) {
- ((DeviceInfoListener) listener)
- .onDeviceInfoAvailable((WifiP2pDevice) message.obj);
- }
- break;
- default:
- Log.d(TAG, "Ignored " + message);
- break;
- }
- }
- }
-
- private void handleServiceResponse(WifiP2pServiceResponse resp) {
- if (resp instanceof WifiP2pDnsSdServiceResponse) {
- handleDnsSdServiceResponse((WifiP2pDnsSdServiceResponse)resp);
- } else if (resp instanceof WifiP2pUpnpServiceResponse) {
- if (mUpnpServRspListener != null) {
- handleUpnpServiceResponse((WifiP2pUpnpServiceResponse)resp);
- }
- } else {
- if (mServRspListener != null) {
- mServRspListener.onServiceAvailable(resp.getServiceType(),
- resp.getRawData(), resp.getSrcDevice());
- }
- }
- }
-
- private void handleUpnpServiceResponse(WifiP2pUpnpServiceResponse resp) {
- mUpnpServRspListener.onUpnpServiceAvailable(resp.getUniqueServiceNames(),
- resp.getSrcDevice());
- }
-
- private void handleDnsSdServiceResponse(WifiP2pDnsSdServiceResponse resp) {
- if (resp.getDnsType() == WifiP2pDnsSdServiceInfo.DNS_TYPE_PTR) {
- if (mDnsSdServRspListener != null) {
- mDnsSdServRspListener.onDnsSdServiceAvailable(
- resp.getInstanceName(),
- resp.getDnsQueryName(),
- resp.getSrcDevice());
- }
- } else if (resp.getDnsType() == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
- if (mDnsSdTxtListener != null) {
- mDnsSdTxtListener.onDnsSdTxtRecordAvailable(
- resp.getDnsQueryName(),
- resp.getTxtRecord(),
- resp.getSrcDevice());
- }
- } else {
- Log.e(TAG, "Unhandled resp " + resp);
- }
- }
-
- @UnsupportedAppUsage
- private int putListener(Object listener) {
- if (listener == null) return INVALID_LISTENER_KEY;
- int key;
- synchronized (mListenerMapLock) {
- do {
- key = mListenerKey++;
- } while (key == INVALID_LISTENER_KEY);
- mListenerMap.put(key, listener);
- }
- return key;
- }
-
- private Object getListener(int key) {
- if (key == INVALID_LISTENER_KEY) return null;
- synchronized (mListenerMapLock) {
- return mListenerMap.remove(key);
- }
- }
- }
-
- private static void checkChannel(Channel c) {
- if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
- }
-
- private static void checkServiceInfo(WifiP2pServiceInfo info) {
- if (info == null) throw new IllegalArgumentException("service info is null");
- }
-
- private static void checkServiceRequest(WifiP2pServiceRequest req) {
- if (req == null) throw new IllegalArgumentException("service request is null");
- }
-
- private static void checkP2pConfig(WifiP2pConfig c) {
- if (c == null) throw new IllegalArgumentException("config cannot be null");
- if (TextUtils.isEmpty(c.deviceAddress)) {
- throw new IllegalArgumentException("deviceAddress cannot be empty");
- }
- }
-
- /**
- * Registers the application with the Wi-Fi framework. This function
- * must be the first to be called before any p2p operations are performed.
- *
- * @param srcContext is the context of the source
- * @param srcLooper is the Looper on which the callbacks are receivied
- * @param listener for callback at loss of framework communication. Can be null.
- * @return Channel instance that is necessary for performing any further p2p operations
- */
- public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
- Binder binder = new Binder();
- Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder),
- binder);
- return channel;
- }
-
- /**
- * Registers the application with the Wi-Fi framework. Enables system-only functionality.
- * @hide
- */
- public Channel initializeInternal(Context srcContext, Looper srcLooper,
- ChannelListener listener) {
- return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger(),
- null);
- }
-
- private Channel initalizeChannel(Context srcContext, Looper srcLooper, ChannelListener listener,
- Messenger messenger, Binder binder) {
- if (messenger == null) return null;
-
- Channel c = new Channel(srcContext, srcLooper, listener, binder, this);
- if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
- == AsyncChannel.STATUS_SUCCESSFUL) {
- Bundle bundle = new Bundle();
- bundle.putString(CALLING_PACKAGE, c.mContext.getOpPackageName());
- bundle.putString(CALLING_FEATURE_ID, c.mContext.getAttributionTag());
- bundle.putBinder(CALLING_BINDER, binder);
- c.mAsyncChannel.sendMessage(UPDATE_CHANNEL_INFO, 0,
- c.putListener(null), bundle);
- return c;
- } else {
- c.close();
- return null;
- }
- }
-
- /**
- * Initiate peer discovery. A discovery process involves scanning for available Wi-Fi peers
- * for the purpose of establishing a connection.
- *
- * <p> The function call immediately returns after sending a discovery request
- * to the framework. The application is notified of a success or failure to initiate
- * discovery through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * <p> The discovery remains active until a connection is initiated or
- * a p2p group is formed. Register for {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent to
- * determine when the framework notifies of a change as peers are discovered.
- *
- * <p> Upon receiving a {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent, an application
- * can request for the list of peers using {@link #requestPeers}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callbacks on success or failure. Can be null.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
- public void discoverPeers(Channel c, ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener));
- }
-
- /**
- * Stop an ongoing peer discovery
- *
- * <p> The function call immediately returns after sending a stop request
- * to the framework. The application is notified of a success or failure to initiate
- * stop through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callbacks on success or failure. Can be null.
- */
- public void stopPeerDiscovery(Channel c, ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, c.putListener(listener));
- }
-
- /**
- * Start a p2p connection to a device with the specified configuration.
- *
- * <p> The function call immediately returns after sending a connection request
- * to the framework. The application is notified of a success or failure to initiate
- * connect through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * <p> Register for {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION} intent to
- * determine when the framework notifies of a change in connectivity.
- *
- * <p> If the current device is not part of a p2p group, a connect request initiates
- * a group negotiation with the peer.
- *
- * <p> If the current device is part of an existing p2p group or has created
- * a p2p group with {@link #createGroup}, an invitation to join the group is sent to
- * the peer device.
- *
- * @param c is the channel created at {@link #initialize}
- * @param config options as described in {@link WifiP2pConfig} class
- * @param listener for callbacks on success or failure. Can be null.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
- public void connect(Channel c, WifiP2pConfig config, ActionListener listener) {
- checkChannel(c);
- checkP2pConfig(config);
- c.mAsyncChannel.sendMessage(CONNECT, 0, c.putListener(listener), config);
- }
-
- /**
- * Cancel any ongoing p2p group negotiation
- *
- * <p> The function call immediately returns after sending a connection cancellation request
- * to the framework. The application is notified of a success or failure to initiate
- * cancellation through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callbacks on success or failure. Can be null.
- */
- public void cancelConnect(Channel c, ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(CANCEL_CONNECT, 0, c.putListener(listener));
- }
-
- /**
- * Create a p2p group with the current device as the group owner. This essentially creates
- * an access point that can accept connections from legacy clients as well as other p2p
- * devices.
- *
- * <p class="note"><strong>Note:</strong>
- * This function would normally not be used unless the current device needs
- * to form a p2p connection with a legacy client
- *
- * <p> The function call immediately returns after sending a group creation request
- * to the framework. The application is notified of a success or failure to initiate
- * group creation through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * <p> Application can request for the group details with {@link #requestGroupInfo}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callbacks on success or failure. Can be null.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
- public void createGroup(Channel c, ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.NETWORK_ID_PERSISTENT,
- c.putListener(listener));
- }
-
- /**
- * Create a p2p group with the current device as the group owner. This essentially creates
- * an access point that can accept connections from legacy clients as well as other p2p
- * devices.
- *
- * <p> An app should use {@link WifiP2pConfig.Builder} to build the configuration
- * for a group.
- *
- * <p class="note"><strong>Note:</strong>
- * This function would normally not be used unless the current device needs
- * to form a p2p group as a Group Owner and allow peers to join it as either
- * Group Clients or legacy Wi-Fi STAs.
- *
- * <p> The function call immediately returns after sending a group creation request
- * to the framework. The application is notified of a success or failure to initiate
- * group creation through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * <p> Application can request for the group details with {@link #requestGroupInfo}.
- *
- * @param c is the channel created at {@link #initialize}.
- * @param config the configuration of a p2p group.
- * @param listener for callbacks on success or failure. Can be null.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
- public void createGroup(@NonNull Channel c,
- @Nullable WifiP2pConfig config,
- @Nullable ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(CREATE_GROUP, 0,
- c.putListener(listener), config);
- }
-
- /**
- * Remove the current p2p group.
- *
- * <p> The function call immediately returns after sending a group removal request
- * to the framework. The application is notified of a success or failure to initiate
- * group removal through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callbacks on success or failure. Can be null.
- */
- public void removeGroup(Channel c, ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(REMOVE_GROUP, 0, c.putListener(listener));
- }
-
- /**
- * Force p2p to enter listen state
- *
- * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)}
- * @param listener for callbacks on success or failure. Can be null.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void startListening(@NonNull Channel c, @Nullable ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(START_LISTEN, 0, c.putListener(listener));
- }
-
- /**
- * Force p2p to exit listen state
- *
- * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)}
- * @param listener for callbacks on success or failure. Can be null.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void stopListening(@NonNull Channel c, @Nullable ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(STOP_LISTEN, 0, c.putListener(listener));
- }
-
- /**
- * Set P2P listening and operating channel.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listeningChannel the listening channel's Wifi channel number. e.g. 1, 6, 11.
- * @param operatingChannel the operating channel's Wifi channel number. e.g. 1, 6, 11.
- * @param listener for callbacks on success or failure. Can be null.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.OVERRIDE_WIFI_CONFIG
- })
- public void setWifiP2pChannels(@NonNull Channel c, int listeningChannel, int operatingChannel,
- @Nullable ActionListener listener) {
- checkChannel(c);
- Bundle p2pChannels = new Bundle();
- p2pChannels.putInt("lc", listeningChannel);
- p2pChannels.putInt("oc", operatingChannel);
- c.mAsyncChannel.sendMessage(SET_CHANNEL, 0, c.putListener(listener), p2pChannels);
- }
-
- /**
- * Start a Wi-Fi Protected Setup (WPS) session.
- *
- * <p> The function call immediately returns after sending a request to start a
- * WPS session. Currently, this is only valid if the current device is running
- * as a group owner to allow any new clients to join the group. The application
- * is notified of a success or failure to initiate WPS through listener callbacks
- * {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}.
- * @hide
- */
- @UnsupportedAppUsage
- public void startWps(Channel c, WpsInfo wps, ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(START_WPS, 0, c.putListener(listener), wps);
- }
-
- /**
- * Register a local service for service discovery. If a local service is registered,
- * the framework automatically responds to a service discovery request from a peer.
- *
- * <p> The function call immediately returns after sending a request to add a local
- * service to the framework. The application is notified of a success or failure to
- * add service through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * <p>The service information is set through {@link WifiP2pServiceInfo}.<br>
- * or its subclass calls {@link WifiP2pUpnpServiceInfo#newInstance} or
- * {@link WifiP2pDnsSdServiceInfo#newInstance} for a Upnp or Bonjour service
- * respectively
- *
- * <p>The service information can be cleared with calls to
- * {@link #removeLocalService} or {@link #clearLocalServices}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param servInfo is a local service information.
- * @param listener for callbacks on success or failure. Can be null.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
- public void addLocalService(Channel c, WifiP2pServiceInfo servInfo, ActionListener listener) {
- checkChannel(c);
- checkServiceInfo(servInfo);
- c.mAsyncChannel.sendMessage(ADD_LOCAL_SERVICE, 0, c.putListener(listener), servInfo);
- }
-
- /**
- * Remove a registered local service added with {@link #addLocalService}
- *
- * <p> The function call immediately returns after sending a request to remove a
- * local service to the framework. The application is notified of a success or failure to
- * add service through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param servInfo is the local service information.
- * @param listener for callbacks on success or failure. Can be null.
- */
- public void removeLocalService(Channel c, WifiP2pServiceInfo servInfo,
- ActionListener listener) {
- checkChannel(c);
- checkServiceInfo(servInfo);
- c.mAsyncChannel.sendMessage(REMOVE_LOCAL_SERVICE, 0, c.putListener(listener), servInfo);
- }
-
- /**
- * Clear all registered local services of service discovery.
- *
- * <p> The function call immediately returns after sending a request to clear all
- * local services to the framework. The application is notified of a success or failure to
- * add service through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callbacks on success or failure. Can be null.
- */
- public void clearLocalServices(Channel c, ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(CLEAR_LOCAL_SERVICES, 0, c.putListener(listener));
- }
-
- /**
- * Register a callback to be invoked on receiving service discovery response.
- * Used only for vendor specific protocol right now. For Bonjour or Upnp, use
- * {@link #setDnsSdResponseListeners} or {@link #setUpnpServiceResponseListener}
- * respectively.
- *
- * <p> see {@link #discoverServices} for the detail.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callbacks on receiving service discovery response.
- */
- public void setServiceResponseListener(Channel c,
- ServiceResponseListener listener) {
- checkChannel(c);
- c.mServRspListener = listener;
- }
-
- /**
- * Register a callback to be invoked on receiving Bonjour service discovery
- * response.
- *
- * <p> see {@link #discoverServices} for the detail.
- *
- * @param c
- * @param servListener is for listening to a Bonjour service response
- * @param txtListener is for listening to a Bonjour TXT record response
- */
- public void setDnsSdResponseListeners(Channel c,
- DnsSdServiceResponseListener servListener, DnsSdTxtRecordListener txtListener) {
- checkChannel(c);
- c.mDnsSdServRspListener = servListener;
- c.mDnsSdTxtListener = txtListener;
- }
-
- /**
- * Register a callback to be invoked on receiving upnp service discovery
- * response.
- *
- * <p> see {@link #discoverServices} for the detail.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callbacks on receiving service discovery response.
- */
- public void setUpnpServiceResponseListener(Channel c,
- UpnpServiceResponseListener listener) {
- checkChannel(c);
- c.mUpnpServRspListener = listener;
- }
-
- /**
- * Initiate service discovery. A discovery process involves scanning for
- * requested services for the purpose of establishing a connection to a peer
- * that supports an available service.
- *
- * <p> The function call immediately returns after sending a request to start service
- * discovery to the framework. The application is notified of a success or failure to initiate
- * discovery through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * <p> The services to be discovered are specified with calls to {@link #addServiceRequest}.
- *
- * <p>The application is notified of the response against the service discovery request
- * through listener callbacks registered by {@link #setServiceResponseListener} or
- * {@link #setDnsSdResponseListeners}, or {@link #setUpnpServiceResponseListener}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callbacks on success or failure. Can be null.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
- public void discoverServices(Channel c, ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, c.putListener(listener));
- }
-
- /**
- * Add a service discovery request.
- *
- * <p> The function call immediately returns after sending a request to add service
- * discovery request to the framework. The application is notified of a success or failure to
- * add service through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * <p>After service discovery request is added, you can initiate service discovery by
- * {@link #discoverServices}.
- *
- * <p>The added service requests can be cleared with calls to
- * {@link #removeServiceRequest(Channel, WifiP2pServiceRequest, ActionListener)} or
- * {@link #clearServiceRequests(Channel, ActionListener)}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param req is the service discovery request.
- * @param listener for callbacks on success or failure. Can be null.
- */
- public void addServiceRequest(Channel c,
- WifiP2pServiceRequest req, ActionListener listener) {
- checkChannel(c);
- checkServiceRequest(req);
- c.mAsyncChannel.sendMessage(ADD_SERVICE_REQUEST, 0,
- c.putListener(listener), req);
- }
-
- /**
- * Remove a specified service discovery request added with {@link #addServiceRequest}
- *
- * <p> The function call immediately returns after sending a request to remove service
- * discovery request to the framework. The application is notified of a success or failure to
- * add service through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param req is the service discovery request.
- * @param listener for callbacks on success or failure. Can be null.
- */
- public void removeServiceRequest(Channel c, WifiP2pServiceRequest req,
- ActionListener listener) {
- checkChannel(c);
- checkServiceRequest(req);
- c.mAsyncChannel.sendMessage(REMOVE_SERVICE_REQUEST, 0,
- c.putListener(listener), req);
- }
-
- /**
- * Clear all registered service discovery requests.
- *
- * <p> The function call immediately returns after sending a request to clear all
- * service discovery requests to the framework. The application is notified of a success
- * or failure to add service through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callbacks on success or failure. Can be null.
- */
- public void clearServiceRequests(Channel c, ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(CLEAR_SERVICE_REQUESTS,
- 0, c.putListener(listener));
- }
-
- /**
- * Request the current list of peers.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callback when peer list is available. Can be null.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
- public void requestPeers(Channel c, PeerListListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(REQUEST_PEERS, 0, c.putListener(listener));
- }
-
- /**
- * Request device connection info.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callback when connection info is available. Can be null.
- */
- public void requestConnectionInfo(Channel c, ConnectionInfoListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(REQUEST_CONNECTION_INFO, 0, c.putListener(listener));
- }
-
- /**
- * Request p2p group info.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callback when group info is available. Can be null.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
- public void requestGroupInfo(Channel c, GroupInfoListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(REQUEST_GROUP_INFO, 0, c.putListener(listener));
- }
-
- /**
- * Set p2p device name.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callback when group info is available. Can be null.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.OVERRIDE_WIFI_CONFIG
- })
- public void setDeviceName(@NonNull Channel c, @NonNull String devName,
- @Nullable ActionListener listener) {
- checkChannel(c);
- WifiP2pDevice d = new WifiP2pDevice();
- d.deviceName = devName;
- c.mAsyncChannel.sendMessage(SET_DEVICE_NAME, 0, c.putListener(listener), d);
- }
-
- /**
- * Set Wifi Display information.
- *
- * @param c is the channel created at {@link #initialize}
- * @param wfdInfo the Wifi Display information to set
- * @param listener for callbacks on success or failure. Can be null.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
- public void setWfdInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo,
- @Nullable ActionListener listener) {
- setWFDInfo(c, wfdInfo, listener);
- }
-
- /** @hide */
- @UnsupportedAppUsage
- @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
- public void setWFDInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo,
- @Nullable ActionListener listener) {
- checkChannel(c);
- try {
- mService.checkConfigureWifiDisplayPermission();
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- c.mAsyncChannel.sendMessage(SET_WFD_INFO, 0, c.putListener(listener), wfdInfo);
- }
-
-
- /**
- * Delete a stored persistent group from the system settings.
- *
- * <p> The function call immediately returns after sending a persistent group removal request
- * to the framework. The application is notified of a success or failure to initiate
- * group removal through listener callbacks {@link ActionListener#onSuccess} or
- * {@link ActionListener#onFailure}.
- *
- * <p>The persistent p2p group list stored in the system can be obtained by
- * {@link #requestPersistentGroupInfo(Channel, PersistentGroupInfoListener)} and
- * a network id can be obtained by {@link WifiP2pGroup#getNetworkId()}.
- *
- * @param c is the channel created at {@link #initialize}
- * @param netId the network id of the p2p group.
- * @param listener for callbacks on success or failure. Can be null.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.OVERRIDE_WIFI_CONFIG
- })
- public void deletePersistentGroup(@NonNull Channel c, int netId,
- @Nullable ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(DELETE_PERSISTENT_GROUP, netId, c.putListener(listener));
- }
-
- /**
- * Request a list of all the persistent p2p groups stored in system.
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callback when persistent group info list is available. Can be null.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.READ_WIFI_CREDENTIAL
- })
- public void requestPersistentGroupInfo(@NonNull Channel c,
- @Nullable PersistentGroupInfoListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(REQUEST_PERSISTENT_GROUP_INFO, 0, c.putListener(listener));
- }
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"MIRACAST_"}, value = {
- MIRACAST_DISABLED,
- MIRACAST_SOURCE,
- MIRACAST_SINK})
- public @interface MiracastMode {}
-
- /**
- * Miracast is disabled.
- * @hide
- */
- @SystemApi
- public static final int MIRACAST_DISABLED = 0;
- /**
- * Device acts as a Miracast source.
- * @hide
- */
- @SystemApi
- public static final int MIRACAST_SOURCE = 1;
- /**
- * Device acts as a Miracast sink.
- * @hide
- */
- @SystemApi
- public static final int MIRACAST_SINK = 2;
-
- /**
- * This is used to provide information to drivers to optimize performance depending
- * on the current mode of operation.
- * {@link #MIRACAST_DISABLED} - disabled
- * {@link #MIRACAST_SOURCE} - source operation
- * {@link #MIRACAST_SINK} - sink operation
- *
- * As an example, the driver could reduce the channel dwell time during scanning
- * when acting as a source or sink to minimize impact on Miracast.
- *
- * @param mode mode of operation. One of {@link #MIRACAST_DISABLED}, {@link #MIRACAST_SOURCE},
- * or {@link #MIRACAST_SINK}
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
- public void setMiracastMode(@MiracastMode int mode) {
- try {
- mService.setMiracastMode(mode);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get a reference to WifiP2pService handler. This is used to establish
- * an AsyncChannel communication with WifiService
- *
- * @param binder A binder for the service to associate with this client.
- *
- * @return Messenger pointing to the WifiP2pService handler
- * @hide
- */
- public Messenger getMessenger(Binder binder) {
- try {
- return mService.getMessenger(binder);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get a reference to P2pStateMachine handler. This is used to establish
- * a priveleged AsyncChannel communication with WifiP2pService.
- *
- * @return Messenger pointing to the WifiP2pService handler
- * @hide
- */
- public Messenger getP2pStateMachineMessenger() {
- try {
- return mService.getP2pStateMachineMessenger();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get a handover request message for use in WFA NFC Handover transfer.
- * @hide
- */
- public void getNfcHandoverRequest(Channel c, HandoverMessageListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(GET_HANDOVER_REQUEST, 0, c.putListener(listener));
- }
-
-
- /**
- * Get a handover select message for use in WFA NFC Handover transfer.
- * @hide
- */
- public void getNfcHandoverSelect(Channel c, HandoverMessageListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(GET_HANDOVER_SELECT, 0, c.putListener(listener));
- }
-
- /**
- * @hide
- */
- public void initiatorReportNfcHandover(Channel c, String handoverSelect,
- ActionListener listener) {
- checkChannel(c);
- Bundle bundle = new Bundle();
- bundle.putString(EXTRA_HANDOVER_MESSAGE, handoverSelect);
- c.mAsyncChannel.sendMessage(INITIATOR_REPORT_NFC_HANDOVER, 0,
- c.putListener(listener), bundle);
- }
-
-
- /**
- * @hide
- */
- public void responderReportNfcHandover(Channel c, String handoverRequest,
- ActionListener listener) {
- checkChannel(c);
- Bundle bundle = new Bundle();
- bundle.putString(EXTRA_HANDOVER_MESSAGE, handoverRequest);
- c.mAsyncChannel.sendMessage(RESPONDER_REPORT_NFC_HANDOVER, 0,
- c.putListener(listener), bundle);
- }
-
- /**
- * Removes all saved p2p groups.
- *
- * @param c is the channel created at {@link #initialize}.
- * @param listener for callback on success or failure. Can be null.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void factoryReset(@NonNull Channel c, @Nullable ActionListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(FACTORY_RESET, 0, c.putListener(listener));
- }
-
- /**
- * Request saved WifiP2pConfig which used for an ongoing peer connection
- *
- * @param c is the channel created at {@link #initialize}
- * @param listener for callback when ongoing peer config updated. Can't be null.
- *
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public void requestOngoingPeerConfig(@NonNull Channel c,
- @NonNull OngoingPeerInfoListener listener) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(REQUEST_ONGOING_PEER_CONFIG,
- Binder.getCallingUid(), c.putListener(listener));
- }
-
- /**
- * Set saved WifiP2pConfig which used for an ongoing peer connection
- *
- * @param c is the channel created at {@link #initialize}
- * @param config used for change an ongoing peer connection
- * @param listener for callback when ongoing peer config updated. Can be null.
- *
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public void setOngoingPeerConfig(@NonNull Channel c, @NonNull WifiP2pConfig config,
- @Nullable ActionListener listener) {
- checkChannel(c);
- checkP2pConfig(config);
- c.mAsyncChannel.sendMessage(SET_ONGOING_PEER_CONFIG, 0,
- c.putListener(listener), config);
- }
-
- /**
- * Request p2p enabled state.
- *
- * <p> This state indicates whether Wi-Fi p2p is enabled or disabled.
- * The valid value is one of {@link #WIFI_P2P_STATE_DISABLED} or
- * {@link #WIFI_P2P_STATE_ENABLED}. The state is returned using the
- * {@link P2pStateListener} listener.
- *
- * <p> This state is also included in the {@link #WIFI_P2P_STATE_CHANGED_ACTION}
- * broadcast event with extra {@link #EXTRA_WIFI_STATE}.
- *
- * @param c is the channel created at {@link #initialize}.
- * @param listener for callback when p2p state is available..
- */
- public void requestP2pState(@NonNull Channel c,
- @NonNull P2pStateListener listener) {
- checkChannel(c);
- if (listener == null) throw new IllegalArgumentException("This listener cannot be null.");
- c.mAsyncChannel.sendMessage(REQUEST_P2P_STATE, 0, c.putListener(listener));
- }
-
- /**
- * Request p2p discovery state.
- *
- * <p> This state indicates whether p2p discovery has started or stopped.
- * The valid value is one of {@link #WIFI_P2P_DISCOVERY_STARTED} or
- * {@link #WIFI_P2P_DISCOVERY_STOPPED}. The state is returned using the
- * {@link DiscoveryStateListener} listener.
- *
- * <p> This state is also included in the {@link #WIFI_P2P_DISCOVERY_CHANGED_ACTION}
- * broadcast event with extra {@link #EXTRA_DISCOVERY_STATE}.
- *
- * @param c is the channel created at {@link #initialize}.
- * @param listener for callback when discovery state is available..
- */
- public void requestDiscoveryState(@NonNull Channel c,
- @NonNull DiscoveryStateListener listener) {
- checkChannel(c);
- if (listener == null) throw new IllegalArgumentException("This listener cannot be null.");
- c.mAsyncChannel.sendMessage(REQUEST_DISCOVERY_STATE, 0, c.putListener(listener));
- }
-
- /**
- * Request network info.
- *
- * <p> This method provides the network info in the form of a {@link android.net.NetworkInfo}.
- * {@link android.net.NetworkInfo#isAvailable()} indicates the p2p availability and
- * {@link android.net.NetworkInfo#getDetailedState()} reports the current fine-grained state
- * of the network. This {@link android.net.NetworkInfo} is returned using the
- * {@link NetworkInfoListener} listener.
- *
- * <p> This information is also included in the {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION}
- * broadcast event with extra {@link #EXTRA_NETWORK_INFO}.
- *
- * @param c is the channel created at {@link #initialize}.
- * @param listener for callback when network info is available..
- */
- public void requestNetworkInfo(@NonNull Channel c,
- @NonNull NetworkInfoListener listener) {
- checkChannel(c);
- if (listener == null) throw new IllegalArgumentException("This listener cannot be null.");
- c.mAsyncChannel.sendMessage(REQUEST_NETWORK_INFO, 0, c.putListener(listener));
- }
-
- /**
- * Request Device Info
- *
- * <p> This method provides the device info
- * in the form of a {@link android.net.wifi.p2p.WifiP2pDevice}.
- * Valid {@link android.net.wifi.p2p.WifiP2pDevice} is returned when p2p is enabled.
- * To get information notifications on P2P getting enabled refers
- * {@link #WIFI_P2P_STATE_ENABLED}.
- *
- * <p> This {@link android.net.wifi.p2p.WifiP2pDevice} is returned using the
- * {@link DeviceInfoListener} listener.
- *
- * <p> {@link android.net.wifi.p2p.WifiP2pDevice#deviceAddress} is only available if the caller
- * holds the {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} permission, and holds the
- * anonymized MAC address (02:00:00:00:00:00) otherwise.
- *
- * <p> This information is also included in the {@link #WIFI_P2P_THIS_DEVICE_CHANGED_ACTION}
- * broadcast event with extra {@link #EXTRA_WIFI_P2P_DEVICE}.
- *
- * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)}.
- * @param listener for callback when network info is available.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
- public void requestDeviceInfo(@NonNull Channel c, @NonNull DeviceInfoListener listener) {
- checkChannel(c);
- if (listener == null) throw new IllegalArgumentException("This listener cannot be null.");
- c.mAsyncChannel.sendMessage(REQUEST_DEVICE_INFO, 0, c.putListener(listener));
- }
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
deleted file mode 100644
index d0fe92d..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-import android.compat.annotation.UnsupportedAppUsage;
-
-/**
- * A class representing a Wi-Fi p2p provisional discovery request/response
- * See {@link #WifiP2pProvDiscEvent} for supported types
- *
- * @hide
- */
-public class WifiP2pProvDiscEvent {
-
- private static final String TAG = "WifiP2pProvDiscEvent";
-
- public static final int PBC_REQ = 1;
- public static final int PBC_RSP = 2;
- public static final int ENTER_PIN = 3;
- public static final int SHOW_PIN = 4;
-
- /* One of PBC_REQ, PBC_RSP, ENTER_PIN or SHOW_PIN */
- @UnsupportedAppUsage
- public int event;
-
- @UnsupportedAppUsage
- public WifiP2pDevice device;
-
- /* Valid when event = SHOW_PIN */
- @UnsupportedAppUsage
- public String pin;
-
- @UnsupportedAppUsage
- public WifiP2pProvDiscEvent() {
- device = new WifiP2pDevice();
- }
-
- /**
- * @param string formats supported include
- *
- * P2P-PROV-DISC-PBC-REQ 42:fc:89:e1:e2:27
- * P2P-PROV-DISC-PBC-RESP 02:12:47:f2:5a:36
- * P2P-PROV-DISC-ENTER-PIN 42:fc:89:e1:e2:27
- * P2P-PROV-DISC-SHOW-PIN 42:fc:89:e1:e2:27 44490607
- *
- * Note: The events formats can be looked up in the wpa_supplicant code
- * @hide
- */
- public WifiP2pProvDiscEvent(String string) throws IllegalArgumentException {
- String[] tokens = string.split(" ");
-
- if (tokens.length < 2) {
- throw new IllegalArgumentException("Malformed event " + string);
- }
-
- if (tokens[0].endsWith("PBC-REQ")) event = PBC_REQ;
- else if (tokens[0].endsWith("PBC-RESP")) event = PBC_RSP;
- else if (tokens[0].endsWith("ENTER-PIN")) event = ENTER_PIN;
- else if (tokens[0].endsWith("SHOW-PIN")) event = SHOW_PIN;
- else throw new IllegalArgumentException("Malformed event " + string);
-
-
- device = new WifiP2pDevice();
- device.deviceAddress = tokens[1];
-
- if (event == SHOW_PIN) {
- pin = tokens[2];
- }
- }
-
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append(device);
- sbuf.append("\n event: ").append(event);
- sbuf.append("\n pin: ").append(pin);
- return sbuf.toString();
- }
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
deleted file mode 100644
index e399b5b..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p;
-
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Locale;
-
-/**
- * A class representing Wifi Display information for a device.
- *
- * See Wifi Display technical specification v1.0.0, section 5.1.2.
- */
-public final class WifiP2pWfdInfo implements Parcelable {
-
- private boolean mEnabled;
-
- /** Device information bitmap */
- private int mDeviceInfo;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "DEVICE_TYPE_" }, value = {
- DEVICE_TYPE_WFD_SOURCE,
- DEVICE_TYPE_PRIMARY_SINK,
- DEVICE_TYPE_SECONDARY_SINK,
- DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK})
- public @interface DeviceType {}
-
- /** The device is a Wifi Display Source. */
- public static final int DEVICE_TYPE_WFD_SOURCE = 0;
- /** The device is a primary sink. */
- public static final int DEVICE_TYPE_PRIMARY_SINK = 1;
- /** The device is a secondary sink. */
- public static final int DEVICE_TYPE_SECONDARY_SINK = 2;
- /** The device is dual-role capable i.e. either a WFD source or a primary sink. */
- public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3;
-
- /**
- * {@link #mDeviceInfo} & {@link #DEVICE_TYPE} is one of {@link #DEVICE_TYPE_WFD_SOURCE},
- * {@link #DEVICE_TYPE_PRIMARY_SINK}, {@link #DEVICE_TYPE_SECONDARY_SINK} or
- * {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}.
- *
- * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
- * Wi-Fi Display Technical Specification.
- */
- private static final int DEVICE_TYPE = 1 << 1 | 1 << 0;
- private static final int COUPLED_SINK_SUPPORT_AT_SOURCE = 1 << 2;
- private static final int COUPLED_SINK_SUPPORT_AT_SINK = 1 << 3;
- private static final int SESSION_AVAILABLE_BIT1 = 1 << 4;
- private static final int SESSION_AVAILABLE_BIT2 = 1 << 5;
- private static final int SESSION_AVAILABLE =
- SESSION_AVAILABLE_BIT2 | SESSION_AVAILABLE_BIT1;
- /* The support of Content Protection using the HDCP system 2.0/2.1. */
- private static final int CONTENT_PROTECTION_SUPPORT = 1 << 8;
-
- private int mCtrlPort;
-
- private int mMaxThroughput;
-
- /** Default constructor. */
- public WifiP2pWfdInfo() {}
-
- /** @hide */
- @UnsupportedAppUsage
- public WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput) {
- mEnabled = true;
- mDeviceInfo = devInfo;
- mCtrlPort = ctrlPort;
- mMaxThroughput = maxTput;
- }
-
- /** Returns true is Wifi Display is enabled, false otherwise. */
- public boolean isEnabled() {
- return mEnabled;
- }
-
- /**
- * Sets whether Wifi Display should be enabled.
- *
- * @param enabled true to enable Wifi Display, false to disable
- */
- public void setEnabled(boolean enabled) {
- mEnabled = enabled;
- }
-
- /**
- * Get the type of the device.
- * One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
- * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
- */
- @DeviceType
- public int getDeviceType() {
- return mDeviceInfo & DEVICE_TYPE;
- }
-
- /**
- * Sets the type of the device.
- *
- * @param deviceType One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
- * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
- * @return true if the device type was successfully set, false otherwise
- */
- public boolean setDeviceType(@DeviceType int deviceType) {
- if (DEVICE_TYPE_WFD_SOURCE <= deviceType
- && deviceType <= DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK) {
- mDeviceInfo &= ~DEVICE_TYPE;
- mDeviceInfo |= deviceType;
- return true;
- }
- return false;
- }
-
- /** Returns true if a session is available, false otherwise. */
- public boolean isSessionAvailable() {
- return (mDeviceInfo & SESSION_AVAILABLE) != 0;
- }
-
- /**
- * Sets whether a session is available.
- *
- * @param enabled true to indicate that a session is available, false otherwise.
- */
- public void setSessionAvailable(boolean enabled) {
- if (enabled) {
- mDeviceInfo |= SESSION_AVAILABLE_BIT1;
- mDeviceInfo &= ~SESSION_AVAILABLE_BIT2;
- } else {
- mDeviceInfo &= ~SESSION_AVAILABLE;
- }
- }
-
- /**
- * @return true if Content Protection using the HDCP system 2.0/2.1 is supported.
- */
- public boolean isContentProtectionSupported() {
- return (mDeviceInfo & CONTENT_PROTECTION_SUPPORT) != 0;
- }
-
- /**
- * Sets whether Content Protection using the HDCP system 2.0/2.1 is supported.
- *
- * @param enabled true to indicate that Content Protection is supported, false otherwise.
- */
- public void setContentProtectionSupported(boolean enabled) {
- if (enabled) {
- mDeviceInfo |= CONTENT_PROTECTION_SUPPORT;
- } else {
- mDeviceInfo &= ~CONTENT_PROTECTION_SUPPORT;
- }
- }
-
- /** Returns the TCP port at which the WFD Device listens for RTSP messages. */
- public int getControlPort() {
- return mCtrlPort;
- }
-
- /** Sets the TCP port at which the WFD Device listens for RTSP messages. */
- public void setControlPort(@IntRange(from = 0) int port) {
- mCtrlPort = port;
- }
-
- /** Sets the maximum average throughput capability of the WFD Device, in megabits/second. */
- public void setMaxThroughput(@IntRange(from = 0) int maxThroughput) {
- mMaxThroughput = maxThroughput;
- }
-
- /** Returns the maximum average throughput capability of the WFD Device, in megabits/second. */
- public int getMaxThroughput() {
- return mMaxThroughput;
- }
-
- /** @hide */
- public String getDeviceInfoHex() {
- return String.format(
- Locale.US, "%04x%04x%04x", mDeviceInfo, mCtrlPort, mMaxThroughput);
- }
-
- @Override
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("WFD enabled: ").append(mEnabled);
- sbuf.append("WFD DeviceInfo: ").append(mDeviceInfo);
- sbuf.append("\n WFD CtrlPort: ").append(mCtrlPort);
- sbuf.append("\n WFD MaxThroughput: ").append(mMaxThroughput);
- return sbuf.toString();
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** Copy constructor. */
- public WifiP2pWfdInfo(@Nullable WifiP2pWfdInfo source) {
- if (source != null) {
- mEnabled = source.mEnabled;
- mDeviceInfo = source.mDeviceInfo;
- mCtrlPort = source.mCtrlPort;
- mMaxThroughput = source.mMaxThroughput;
- }
- }
-
- /** Implement the Parcelable interface */
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mEnabled ? 1 : 0);
- dest.writeInt(mDeviceInfo);
- dest.writeInt(mCtrlPort);
- dest.writeInt(mMaxThroughput);
- }
-
- private void readFromParcel(Parcel in) {
- mEnabled = (in.readInt() == 1);
- mDeviceInfo = in.readInt();
- mCtrlPort = in.readInt();
- mMaxThroughput = in.readInt();
- }
-
- /** Implement the Parcelable interface */
- public static final @NonNull Creator<WifiP2pWfdInfo> CREATOR =
- new Creator<WifiP2pWfdInfo>() {
- public WifiP2pWfdInfo createFromParcel(Parcel in) {
- WifiP2pWfdInfo device = new WifiP2pWfdInfo();
- device.readFromParcel(in);
- return device;
- }
-
- public WifiP2pWfdInfo[] newArray(int size) {
- return new WifiP2pWfdInfo[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
deleted file mode 100644
index dad431c1..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.nsd;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.nsd.DnsSdTxtRecord;
-import android.os.Build;
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * A class for storing Bonjour service information that is advertised
- * over a Wi-Fi peer-to-peer setup.
- *
- * {@see android.net.wifi.p2p.WifiP2pManager#addLocalService}
- * {@see android.net.wifi.p2p.WifiP2pManager#removeLocalService}
- * {@see WifiP2pServiceInfo}
- * {@see WifiP2pUpnpServiceInfo}
- */
-public class WifiP2pDnsSdServiceInfo extends WifiP2pServiceInfo {
-
- /**
- * Bonjour version 1.
- * @hide
- */
- public static final int VERSION_1 = 0x01;
-
- /**
- * Pointer record.
- * @hide
- */
- public static final int DNS_TYPE_PTR = 12;
-
- /**
- * Text record.
- * @hide
- */
- public static final int DNS_TYPE_TXT = 16;
-
- /**
- * virtual memory packet.
- * see E.3 of the Wi-Fi Direct technical specification for the detail.<br>
- * Key: domain name Value: pointer address.<br>
- */
- private final static Map<String, String> sVmPacket;
-
- static {
- sVmPacket = new HashMap<String, String>();
- sVmPacket.put("_tcp.local.", "c00c");
- sVmPacket.put("local.", "c011");
- sVmPacket.put("_udp.local.", "c01c");
- }
-
- /**
- * This constructor is only used in newInstance().
- *
- * @param queryList
- */
- private WifiP2pDnsSdServiceInfo(List<String> queryList) {
- super(queryList);
- }
-
- /**
- * Create a Bonjour service information object.
- *
- * @param instanceName instance name.<br>
- * e.g) "MyPrinter"
- * @param serviceType service type.<br>
- * e.g) "_ipp._tcp"
- * @param txtMap TXT record with key/value pair in a map confirming to format defined at
- * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
- * @return Bonjour service information object
- */
- public static WifiP2pDnsSdServiceInfo newInstance(String instanceName,
- String serviceType, Map<String, String> txtMap) {
- if (TextUtils.isEmpty(instanceName) || TextUtils.isEmpty(serviceType)) {
- throw new IllegalArgumentException(
- "instance name or service type cannot be empty");
- }
-
- DnsSdTxtRecord txtRecord = new DnsSdTxtRecord();
- if (txtMap != null) {
- for (String key : txtMap.keySet()) {
- txtRecord.set(key, txtMap.get(key));
- }
- }
-
- ArrayList<String> queries = new ArrayList<String>();
- queries.add(createPtrServiceQuery(instanceName, serviceType));
- queries.add(createTxtServiceQuery(instanceName, serviceType, txtRecord));
-
- return new WifiP2pDnsSdServiceInfo(queries);
- }
-
- /**
- * Create wpa_supplicant service query for PTR record.
- *
- * @param instanceName instance name.<br>
- * e.g) "MyPrinter"
- * @param serviceType service type.<br>
- * e.g) "_ipp._tcp"
- * @return wpa_supplicant service query.
- */
- private static String createPtrServiceQuery(String instanceName,
- String serviceType) {
-
- StringBuffer sb = new StringBuffer();
- sb.append("bonjour ");
- sb.append(createRequest(serviceType + ".local.", DNS_TYPE_PTR, VERSION_1));
- sb.append(" ");
-
- byte[] data = instanceName.getBytes();
- sb.append(String.format(Locale.US, "%02x", data.length));
- sb.append(WifiP2pServiceInfo.bin2HexStr(data));
- // This is the start point of this response.
- // Therefore, it indicates the request domain name.
- sb.append("c027");
- return sb.toString();
- }
-
- /**
- * Create wpa_supplicant service query for TXT record.
- *
- * @param instanceName instance name.<br>
- * e.g) "MyPrinter"
- * @param serviceType service type.<br>
- * e.g) "_ipp._tcp"
- * @param txtRecord TXT record.<br>
- * @return wpa_supplicant service query.
- */
- private static String createTxtServiceQuery(String instanceName,
- String serviceType,
- DnsSdTxtRecord txtRecord) {
-
-
- StringBuffer sb = new StringBuffer();
- sb.append("bonjour ");
-
- sb.append(createRequest((instanceName + "." + serviceType + ".local."),
- DNS_TYPE_TXT, VERSION_1));
- sb.append(" ");
- byte[] rawData = txtRecord.getRawData();
- if (rawData.length == 0) {
- sb.append("00");
- } else {
- sb.append(bin2HexStr(rawData));
- }
- return sb.toString();
- }
-
- /**
- * Create bonjour service discovery request.
- *
- * @param dnsName dns name
- * @param dnsType dns type
- * @param version version number
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- static String createRequest(String dnsName, int dnsType, int version) {
- StringBuffer sb = new StringBuffer();
-
- /*
- * The request format is as follows.
- * ________________________________________________
- * | Encoded and Compressed dns name (variable) |
- * ________________________________________________
- * | Type (2) | Version (1) |
- */
- if (dnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
- dnsName = dnsName.toLowerCase(Locale.ROOT); // TODO: is this right?
- }
- sb.append(compressDnsName(dnsName));
- sb.append(String.format(Locale.US, "%04x", dnsType));
- sb.append(String.format(Locale.US, "%02x", version));
-
- return sb.toString();
- }
-
- /**
- * Compress DNS data.
- *
- * see E.3 of the Wi-Fi Direct technical specification for the detail.
- *
- * @param dnsName dns name
- * @return compressed dns name
- */
- private static String compressDnsName(String dnsName) {
- StringBuffer sb = new StringBuffer();
-
- // The domain name is replaced with a pointer to a prior
- // occurrence of the same name in virtual memory packet.
- while (true) {
- String data = sVmPacket.get(dnsName);
- if (data != null) {
- sb.append(data);
- break;
- }
- int i = dnsName.indexOf('.');
- if (i == -1) {
- if (dnsName.length() > 0) {
- sb.append(String.format(Locale.US, "%02x", dnsName.length()));
- sb.append(WifiP2pServiceInfo.bin2HexStr(dnsName.getBytes()));
- }
- // for a sequence of labels ending in a zero octet
- sb.append("00");
- break;
- }
-
- String name = dnsName.substring(0, i);
- dnsName = dnsName.substring(i + 1);
- sb.append(String.format(Locale.US, "%02x", name.length()));
- sb.append(WifiP2pServiceInfo.bin2HexStr(name.getBytes()));
- }
- return sb.toString();
- }
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequest.java
deleted file mode 100644
index d5415e0..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.nsd;
-
-import android.net.wifi.p2p.WifiP2pManager;
-
-/**
- * A class for creating a Bonjour service discovery request for use with
- * {@link WifiP2pManager#addServiceRequest} and {@link WifiP2pManager#removeServiceRequest}
- *
- * {@see WifiP2pManager}
- * {@see WifiP2pServiceRequest}
- * {@see WifiP2pUpnpServiceRequest}
- */
-public class WifiP2pDnsSdServiceRequest extends WifiP2pServiceRequest {
-
- /**
- * This constructor is only used in newInstance().
- *
- * @param query The part of service specific query.
- * @hide
- */
- private WifiP2pDnsSdServiceRequest(String query) {
- super(WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR, query);
- }
-
- /**
- * This constructor is only used in newInstance().
- * @hide
- */
- private WifiP2pDnsSdServiceRequest() {
- super(WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR, null);
- }
-
- private WifiP2pDnsSdServiceRequest(String dnsQuery, int dnsType, int version) {
- super(WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR, WifiP2pDnsSdServiceInfo.createRequest(
- dnsQuery,
- dnsType,
- version));
- }
-
- /**
- * Create a service discovery request to search all Bonjour services.
- *
- * @return service request for Bonjour.
- */
- public static WifiP2pDnsSdServiceRequest newInstance() {
- return new WifiP2pDnsSdServiceRequest();
- }
-
- /**
- * Create a service discovery to search for Bonjour services with the specified
- * service type.
- *
- * @param serviceType service type. Cannot be null <br>
- * "_afpovertcp._tcp."(Apple File Sharing over TCP)<br>
- * "_ipp._tcp" (IP Printing over TCP)<br>
- * "_http._tcp" (http service)
- * @return service request for DnsSd.
- */
- public static WifiP2pDnsSdServiceRequest newInstance(String serviceType) {
- if (serviceType == null) {
- throw new IllegalArgumentException("service type cannot be null");
- }
- return new WifiP2pDnsSdServiceRequest(serviceType + ".local.",
- WifiP2pDnsSdServiceInfo.DNS_TYPE_PTR,
- WifiP2pDnsSdServiceInfo.VERSION_1);
- }
-
- /**
- * Create a service discovery request to get the TXT data from the specified
- * Bonjour service.
- *
- * @param instanceName instance name. Cannot be null. <br>
- * "MyPrinter"
- * @param serviceType service type. Cannot be null. <br>
- * e.g) <br>
- * "_afpovertcp._tcp"(Apple File Sharing over TCP)<br>
- * "_ipp._tcp" (IP Printing over TCP)<br>
- * @return service request for Bonjour.
- */
- public static WifiP2pDnsSdServiceRequest newInstance(String instanceName,
- String serviceType) {
- if (instanceName == null || serviceType == null) {
- throw new IllegalArgumentException(
- "instance name or service type cannot be null");
- }
- String fullDomainName = instanceName + "." + serviceType + ".local.";
- return new WifiP2pDnsSdServiceRequest(fullDomainName,
- WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT,
- WifiP2pDnsSdServiceInfo.VERSION_1);
- }
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse.java
deleted file mode 100644
index ed84a1a..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.nsd;
-
-import android.net.wifi.p2p.WifiP2pDevice;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A class for a response of bonjour service discovery.
- *
- * @hide
- */
-public class WifiP2pDnsSdServiceResponse extends WifiP2pServiceResponse {
-
- /**
- * DNS query name.
- * e.g)
- * for PTR
- * "_ipp._tcp.local."
- * for TXT
- * "MyPrinter._ipp._tcp.local."
- */
- private String mDnsQueryName;
-
- /**
- * Service instance name.
- * e.g) "MyPrinter"
- * This field is only used when the dns type equals to
- * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_PTR}.
- */
- private String mInstanceName;
-
- /**
- * DNS Type.
- * Should be {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_PTR} or
- * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_TXT}.
- */
- private int mDnsType;
-
- /**
- * DnsSd version number.
- * Should be {@link WifiP2pDnsSdServiceInfo#VERSION_1}.
- */
- private int mVersion;
-
- /**
- * Txt record.
- * This field is only used when the dns type equals to
- * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_TXT}.
- */
- private final HashMap<String, String> mTxtRecord = new HashMap<String, String>();
-
- /**
- * Virtual memory packet.
- * see E.3 of the Wi-Fi Direct technical specification for the detail.<br>
- * The spec can be obtained from wi-fi.org
- * Key: pointer Value: domain name.<br>
- */
- private final static Map<Integer, String> sVmpack;
-
- static {
- sVmpack = new HashMap<Integer, String>();
- sVmpack.put(0x0c, "_tcp.local.");
- sVmpack.put(0x11, "local.");
- sVmpack.put(0x1c, "_udp.local.");
- }
-
- /**
- * Returns query DNS name.
- * @return DNS name.
- */
- public String getDnsQueryName() {
- return mDnsQueryName;
- }
-
- /**
- * Return query DNS type.
- * @return DNS type.
- */
- public int getDnsType() {
- return mDnsType;
- }
-
- /**
- * Return bonjour version number.
- * @return version number.
- */
- public int getVersion() {
- return mVersion;
- }
-
- /**
- * Return instance name.
- * @return
- */
- public String getInstanceName() {
- return mInstanceName;
- }
-
- /**
- * Return TXT record data.
- * @return TXT record data.
- */
- public Map<String, String> getTxtRecord() {
- return mTxtRecord;
- }
-
- @Override
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("serviceType:DnsSd(").append(mServiceType).append(")");
- sbuf.append(" status:").append(Status.toString(mStatus));
- sbuf.append(" srcAddr:").append(mDevice.deviceAddress);
- sbuf.append(" version:").append(String.format("%02x", mVersion));
- sbuf.append(" dnsName:").append(mDnsQueryName);
- sbuf.append(" TxtRecord:");
- for (String key : mTxtRecord.keySet()) {
- sbuf.append(" key:").append(key).append(" value:").append(mTxtRecord.get(key));
- }
- if (mInstanceName != null) {
- sbuf.append(" InsName:").append(mInstanceName);
- }
- return sbuf.toString();
- }
-
- /**
- * This is only used in framework.
- * @param status status code.
- * @param dev source device.
- * @param data RDATA.
- * @hide
- */
- protected WifiP2pDnsSdServiceResponse(int status,
- int tranId, WifiP2pDevice dev, byte[] data) {
- super(WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR,
- status, tranId, dev, data);
- if (!parse()) {
- throw new IllegalArgumentException("Malformed bonjour service response");
- }
- }
-
- /**
- * Parse DnsSd service discovery response.
- *
- * @return {@code true} if the operation succeeded
- */
- private boolean parse() {
- /*
- * The data format from Wi-Fi Direct spec is as follows.
- * ________________________________________________
- * | encoded and compressed dns name (variable) |
- * ________________________________________________
- * | dnstype(2byte) | version(1byte) |
- * ________________________________________________
- * | RDATA (variable) |
- */
- if (mData == null) {
- // the empty is OK.
- return true;
- }
-
- DataInputStream dis = new DataInputStream(new ByteArrayInputStream(mData));
-
- mDnsQueryName = readDnsName(dis);
- if (mDnsQueryName == null) {
- return false;
- }
-
- try {
- mDnsType = dis.readUnsignedShort();
- mVersion = dis.readUnsignedByte();
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- }
-
- if (mDnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_PTR) {
- String rData = readDnsName(dis);
- if (rData == null) {
- return false;
- }
- if (rData.length() <= mDnsQueryName.length()) {
- return false;
- }
-
- mInstanceName = rData.substring(0,
- rData.length() - mDnsQueryName.length() -1);
- } else if (mDnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
- return readTxtData(dis);
- } else {
- return false;
- }
-
- return true;
- }
-
- /**
- * Read dns name.
- *
- * @param dis data input stream.
- * @return dns name
- */
- private String readDnsName(DataInputStream dis) {
- StringBuffer sb = new StringBuffer();
-
- // copy virtual memory packet.
- HashMap<Integer, String> vmpack = new HashMap<Integer, String>(sVmpack);
- if (mDnsQueryName != null) {
- vmpack.put(0x27, mDnsQueryName);
- }
- try {
- while (true) {
- int i = dis.readUnsignedByte();
- if (i == 0x00) {
- return sb.toString();
- } else if (i == 0xc0) {
- // refer to pointer.
- String ref = vmpack.get(dis.readUnsignedByte());
- if (ref == null) {
- //invalid.
- return null;
- }
- sb.append(ref);
- return sb.toString();
- } else {
- byte[] data = new byte[i];
- dis.readFully(data);
- sb.append(new String(data));
- sb.append(".");
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- /**
- * Read TXT record data.
- *
- * @param dis
- * @return true if TXT data is valid
- */
- private boolean readTxtData(DataInputStream dis) {
- try {
- while (dis.available() > 0) {
- int len = dis.readUnsignedByte();
- if (len == 0) {
- break;
- }
- byte[] data = new byte[len];
- dis.readFully(data);
- String[] keyVal = new String(data).split("=");
- if (keyVal.length != 2) {
- return false;
- }
- mTxtRecord.put(keyVal[0], keyVal[1]);
- }
- return true;
- } catch (IOException e) {
- e.printStackTrace();
- }
- return false;
- }
-
- /**
- * Creates DnsSd service response.
- * This is only called from WifiP2pServiceResponse
- *
- * @param status status code.
- * @param dev source device.
- * @param data DnsSd response data.
- * @return DnsSd service response data.
- * @hide
- */
- static WifiP2pDnsSdServiceResponse newInstance(int status,
- int transId, WifiP2pDevice dev, byte[] data) {
- if (status != WifiP2pServiceResponse.Status.SUCCESS) {
- return new WifiP2pDnsSdServiceResponse(status,
- transId, dev, null);
- }
- try {
- return new WifiP2pDnsSdServiceResponse(status,
- transId, dev, data);
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- }
- return null;
- }
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java
deleted file mode 100644
index 37b442b..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.nsd;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A class for storing service information that is advertised
- * over a Wi-Fi peer-to-peer setup
- *
- * @see WifiP2pUpnpServiceInfo
- * @see WifiP2pDnsSdServiceInfo
- */
-public class WifiP2pServiceInfo implements Parcelable {
-
- /**
- * All service protocol types.
- */
- public static final int SERVICE_TYPE_ALL = 0;
-
- /**
- * DNS based service discovery protocol.
- */
- public static final int SERVICE_TYPE_BONJOUR = 1;
-
- /**
- * UPnP protocol.
- */
- public static final int SERVICE_TYPE_UPNP = 2;
-
- /**
- * WS-Discovery protocol
- * @hide
- */
- public static final int SERVICE_TYPE_WS_DISCOVERY = 3;
-
- /**
- * Vendor Specific protocol
- */
- public static final int SERVICE_TYPE_VENDOR_SPECIFIC = 255;
-
- /**
- * the list of query string for wpa_supplicant
- *
- * e.g)
- * # IP Printing over TCP (PTR) (RDATA=MyPrinter._ipp._tcp.local.)
- * {"bonjour", "045f697070c00c000c01", "094d795072696e746572c027"
- *
- * # IP Printing over TCP (TXT) (RDATA=txtvers=1,pdl=application/postscript)
- * {"bonjour", "096d797072696e746572045f697070c00c001001",
- * "09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074"}
- *
- * [UPnP]
- * # UPnP uuid
- * {"upnp", "10", "uuid:6859dede-8574-59ab-9332-123456789012"}
- *
- * # UPnP rootdevice
- * {"upnp", "10", "uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice"}
- *
- * # UPnP device
- * {"upnp", "10", "uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp
- * -org:device:InternetGatewayDevice:1"}
- *
- * # UPnP service
- * {"upnp", "10", "uuid:6859dede-8574-59ab-9322-123456789012::urn:schemas-upnp
- * -org:service:ContentDirectory:2"}
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private List<String> mQueryList;
-
- /**
- * This is only used in subclass.
- *
- * @param queryList query string for wpa_supplicant
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- protected WifiP2pServiceInfo(List<String> queryList) {
- if (queryList == null) {
- throw new IllegalArgumentException("query list cannot be null");
- }
- mQueryList = queryList;
- }
-
- /**
- * Return the list of the query string for wpa_supplicant.
- *
- * @return the list of the query string for wpa_supplicant.
- * @hide
- */
- public List<String> getSupplicantQueryList() {
- return mQueryList;
- }
-
- /**
- * Converts byte array to hex string.
- *
- * @param data
- * @return hex string.
- * @hide
- */
- static String bin2HexStr(byte[] data) {
- StringBuffer sb = new StringBuffer();
-
- for (byte b: data) {
- String s = null;
- try {
- s = Integer.toHexString(b & 0xff);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- //add 0 padding
- if (s.length() == 1) {
- sb.append('0');
- }
- sb.append(s);
- }
- return sb.toString();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof WifiP2pServiceInfo)) {
- return false;
- }
-
- WifiP2pServiceInfo servInfo = (WifiP2pServiceInfo)o;
- return mQueryList.equals(servInfo.mQueryList);
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + (mQueryList == null ? 0 : mQueryList.hashCode());
- return result;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeStringList(mQueryList);
- }
-
- /** Implement the Parcelable interface {@hide} */
- @UnsupportedAppUsage
- public static final @android.annotation.NonNull Creator<WifiP2pServiceInfo> CREATOR =
- new Creator<WifiP2pServiceInfo>() {
- public WifiP2pServiceInfo createFromParcel(Parcel in) {
-
- List<String> data = new ArrayList<String>();
- in.readStringList(data);
- return new WifiP2pServiceInfo(data);
- }
-
- public WifiP2pServiceInfo[] newArray(int size) {
- return new WifiP2pServiceInfo[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java
deleted file mode 100644
index 68cbb88..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.nsd;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.wifi.p2p.WifiP2pManager;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Locale;
-
-/**
- * A class for creating a service discovery request for use with
- * {@link WifiP2pManager#addServiceRequest} and {@link WifiP2pManager#removeServiceRequest}
- *
- * <p>This class is used to create service discovery request for custom
- * vendor specific service discovery protocol {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}
- * or to search all service protocols {@link WifiP2pServiceInfo#SERVICE_TYPE_ALL}.
- *
- * <p>For the purpose of creating a UPnP or Bonjour service request, use
- * {@link WifiP2pUpnpServiceRequest} or {@link WifiP2pDnsSdServiceRequest} respectively.
- *
- * {@see WifiP2pManager}
- * {@see WifiP2pUpnpServiceRequest}
- * {@see WifiP2pDnsSdServiceRequest}
- */
-public class WifiP2pServiceRequest implements Parcelable {
-
- /**
- * Service discovery protocol. It's defined in table63 in Wi-Fi Direct specification.
- */
- private int mProtocolType;
-
- /**
- * The length of the service request TLV.
- * The value is equal to 2 plus the number of octets in the
- * query data field.
- */
- private int mLength;
-
- /**
- * Service transaction ID.
- * This is a nonzero value used to match the service request/response TLVs.
- */
- private int mTransId;
-
- /**
- * The hex dump string of query data for the requested service information.
- *
- * e.g) DnsSd apple file sharing over tcp (dns name=_afpovertcp._tcp.local.)
- * 0b5f6166706f766572746370c00c000c01
- */
- private String mQuery;
-
- /**
- * This constructor is only used in newInstance().
- *
- * @param protocolType service discovery protocol.
- * @param query The part of service specific query.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- protected WifiP2pServiceRequest(int protocolType, String query) {
- validateQuery(query);
-
- mProtocolType = protocolType;
- mQuery = query;
- if (query != null) {
- mLength = query.length()/2 + 2;
- } else {
- mLength = 2;
- }
- }
-
- /**
- * This constructor is only used in Parcelable.
- *
- * @param serviceType service discovery type.
- * @param length the length of service discovery packet.
- * @param transId the transaction id
- * @param query The part of service specific query.
- */
- private WifiP2pServiceRequest(int serviceType, int length,
- int transId, String query) {
- mProtocolType = serviceType;
- mLength = length;
- mTransId = transId;
- mQuery = query;
- }
-
- /**
- * Return transaction id.
- *
- * @return transaction id
- * @hide
- */
- public int getTransactionId() {
- return mTransId;
- }
-
- /**
- * Set transaction id.
- *
- * @param id
- * @hide
- */
- public void setTransactionId(int id) {
- mTransId = id;
- }
-
- /**
- * Return wpa_supplicant request string.
- *
- * The format is the hex dump of the following frame.
- * <pre>
- * _______________________________________________________________
- * | Length (2) | Type (1) | Transaction ID (1) |
- * | Query Data (variable) |
- * </pre>
- *
- * @return wpa_supplicant request string.
- * @hide
- */
- public String getSupplicantQuery() {
- StringBuffer sb = new StringBuffer();
- // length is retained as little endian format.
- sb.append(String.format(Locale.US, "%02x", (mLength) & 0xff));
- sb.append(String.format(Locale.US, "%02x", (mLength >> 8) & 0xff));
- sb.append(String.format(Locale.US, "%02x", mProtocolType));
- sb.append(String.format(Locale.US, "%02x", mTransId));
- if (mQuery != null) {
- sb.append(mQuery);
- }
-
- return sb.toString();
- }
-
- /**
- * Validate query.
- *
- * <p>If invalid, throw IllegalArgumentException.
- * @param query The part of service specific query.
- */
- private void validateQuery(String query) {
- if (query == null) {
- return;
- }
-
- int UNSIGNED_SHORT_MAX = 0xffff;
- if (query.length()%2 == 1) {
- throw new IllegalArgumentException(
- "query size is invalid. query=" + query);
- }
- if (query.length()/2 > UNSIGNED_SHORT_MAX) {
- throw new IllegalArgumentException(
- "query size is too large. len=" + query.length());
- }
-
- // check whether query is hex string.
- query = query.toLowerCase(Locale.ROOT);
- char[] chars = query.toCharArray();
- for (char c: chars) {
- if (!((c >= '0' && c <= '9') ||
- (c >= 'a' && c <= 'f'))){
- throw new IllegalArgumentException(
- "query should be hex string. query=" + query);
- }
- }
- }
-
- /**
- * Create a service discovery request.
- *
- * @param protocolType can be {@link WifiP2pServiceInfo#SERVICE_TYPE_ALL}
- * or {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}.
- * In order to create a UPnP or Bonjour service request, use
- * {@link WifiP2pUpnpServiceRequest} or {@link WifiP2pDnsSdServiceRequest}
- * respectively
- *
- * @param queryData hex string that is vendor specific. Can be null.
- * @return service discovery request.
- */
- public static WifiP2pServiceRequest newInstance(int protocolType, String queryData) {
- return new WifiP2pServiceRequest(protocolType, queryData);
- }
-
- /**
- * Create a service discovery request.
- *
- * @param protocolType can be {@link WifiP2pServiceInfo#SERVICE_TYPE_ALL}
- * or {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}.
- * In order to create a UPnP or Bonjour service request, use
- * {@link WifiP2pUpnpServiceRequest} or {@link WifiP2pDnsSdServiceRequest}
- * respectively
- *
- * @return service discovery request.
- */
- public static WifiP2pServiceRequest newInstance(int protocolType ) {
- return new WifiP2pServiceRequest(protocolType, null);
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof WifiP2pServiceRequest)) {
- return false;
- }
-
- WifiP2pServiceRequest req = (WifiP2pServiceRequest)o;
-
- /*
- * Not compare transaction id.
- * Transaction id may be changed on each service discovery operation.
- */
- if ((req.mProtocolType != mProtocolType) ||
- (req.mLength != mLength)) {
- return false;
- }
-
- if (req.mQuery == null && mQuery == null) {
- return true;
- } else if (req.mQuery != null) {
- return req.mQuery.equals(mQuery);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + mProtocolType;
- result = 31 * result + mLength;
- result = 31 * result + (mQuery == null ? 0 : mQuery.hashCode());
- return result;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mProtocolType);
- dest.writeInt(mLength);
- dest.writeInt(mTransId);
- dest.writeString(mQuery);
- }
-
- /** Implement the Parcelable interface {@hide} */
- @UnsupportedAppUsage
- public static final @android.annotation.NonNull Creator<WifiP2pServiceRequest> CREATOR =
- new Creator<WifiP2pServiceRequest>() {
- public WifiP2pServiceRequest createFromParcel(Parcel in) {
- int servType = in.readInt();
- int length = in.readInt();
- int transId = in.readInt();
- String query = in.readString();
- return new WifiP2pServiceRequest(servType, length, transId, query);
- }
-
- public WifiP2pServiceRequest[] newArray(int size) {
- return new WifiP2pServiceRequest[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.java
deleted file mode 100644
index 1b9c080..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.nsd;
-
-import android.net.wifi.p2p.WifiP2pDevice;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * The class for a response of service discovery.
- *
- * @hide
- */
-public class WifiP2pServiceResponse implements Parcelable {
-
- private static int MAX_BUF_SIZE = 1024;
-
- /**
- * Service type. It's defined in table63 in Wi-Fi Direct specification.
- */
- protected int mServiceType;
-
- /**
- * Status code of service discovery response.
- * It's defined in table65 in Wi-Fi Direct specification.
- * @see Status
- */
- protected int mStatus;
-
- /**
- * Service transaction ID.
- * This is a nonzero value used to match the service request/response TLVs.
- */
- protected int mTransId;
-
- /**
- * Source device.
- */
- protected WifiP2pDevice mDevice;
-
- /**
- * Service discovery response data based on the requested on
- * the service protocol type. The protocol format depends on the service type.
- */
- protected byte[] mData;
-
-
- /**
- * The status code of service discovery response.
- * Currently 4 status codes are defined and the status codes from 4 to 255
- * are reserved.
- *
- * See Wi-Fi Direct specification for the detail.
- */
- public static class Status {
- /** success */
- public static final int SUCCESS = 0;
-
- /** the service protocol type is not available */
- public static final int SERVICE_PROTOCOL_NOT_AVAILABLE = 1;
-
- /** the requested information is not available */
- public static final int REQUESTED_INFORMATION_NOT_AVAILABLE = 2;
-
- /** bad request */
- public static final int BAD_REQUEST = 3;
-
- /** @hide */
- public static String toString(int status) {
- switch(status) {
- case SUCCESS:
- return "SUCCESS";
- case SERVICE_PROTOCOL_NOT_AVAILABLE:
- return "SERVICE_PROTOCOL_NOT_AVAILABLE";
- case REQUESTED_INFORMATION_NOT_AVAILABLE:
- return "REQUESTED_INFORMATION_NOT_AVAILABLE";
- case BAD_REQUEST:
- return "BAD_REQUEST";
- default:
- return "UNKNOWN";
- }
- }
-
- /** not used */
- private Status() {}
- }
-
- /**
- * Hidden constructor. This is only used in framework.
- *
- * @param serviceType service discovery type.
- * @param status status code.
- * @param transId transaction id.
- * @param device source device.
- * @param data query data.
- */
- protected WifiP2pServiceResponse(int serviceType, int status, int transId,
- WifiP2pDevice device, byte[] data) {
- mServiceType = serviceType;
- mStatus = status;
- mTransId = transId;
- mDevice = device;
- mData = data;
- }
-
- /**
- * Return the service type of service discovery response.
- *
- * @return service discovery type.<br>
- * e.g) {@link WifiP2pServiceInfo#SERVICE_TYPE_BONJOUR}
- */
- public int getServiceType() {
- return mServiceType;
- }
-
- /**
- * Return the status code of service discovery response.
- *
- * @return status code.
- * @see Status
- */
- public int getStatus() {
- return mStatus;
- }
-
- /**
- * Return the transaction id of service discovery response.
- *
- * @return transaction id.
- * @hide
- */
- public int getTransactionId() {
- return mTransId;
- }
-
- /**
- * Return response data.
- *
- * <pre>Data format depends on service type
- *
- * @return a query or response data.
- */
- public byte[] getRawData() {
- return mData;
- }
-
- /**
- * Returns the source device of service discovery response.
- *
- * <pre>This is valid only when service discovery response.
- *
- * @return the source device of service discovery response.
- */
- public WifiP2pDevice getSrcDevice() {
- return mDevice;
- }
-
- /** @hide */
- public void setSrcDevice(WifiP2pDevice dev) {
- if (dev == null) return;
- this.mDevice = dev;
- }
-
-
- /**
- * Create the list of WifiP2pServiceResponse instance from supplicant event.
- *
- * @param srcAddr source address of the service response
- * @param tlvsBin byte array containing the binary tlvs data
- * @return if parse failed, return null
- * @hide
- */
- public static List<WifiP2pServiceResponse> newInstance(String srcAddr, byte[] tlvsBin) {
- //updateIndicator not used, and not passed up from supplicant
-
- List<WifiP2pServiceResponse> respList = new ArrayList<WifiP2pServiceResponse>();
- WifiP2pDevice dev = new WifiP2pDevice();
- dev.deviceAddress = srcAddr;
- if (tlvsBin == null) {
- return null;
- }
-
-
- DataInputStream dis = new DataInputStream(new ByteArrayInputStream(tlvsBin));
- try {
- while (dis.available() > 0) {
- /*
- * Service discovery header is as follows.
- * ______________________________________________________________
- * | Length(2byte) | Type(1byte) | TransId(1byte)}|
- * ______________________________________________________________
- * | status(1byte) | vendor specific(variable) |
- */
- // The length equals to 3 plus the number of octets in the vendor
- // specific content field. And this is little endian.
- int length = (dis.readUnsignedByte() +
- (dis.readUnsignedByte() << 8)) - 3;
- int type = dis.readUnsignedByte();
- int transId = dis.readUnsignedByte();
- int status = dis.readUnsignedByte();
- if (length < 0) {
- return null;
- }
- if (length == 0) {
- if (status == Status.SUCCESS) {
- respList.add(new WifiP2pServiceResponse(type, status,
- transId, dev, null));
- }
- continue;
- }
- if (length > MAX_BUF_SIZE) {
- dis.skip(length);
- continue;
- }
- byte[] data = new byte[length];
- dis.readFully(data);
-
- WifiP2pServiceResponse resp;
- if (type == WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR) {
- resp = WifiP2pDnsSdServiceResponse.newInstance(status,
- transId, dev, data);
- } else if (type == WifiP2pServiceInfo.SERVICE_TYPE_UPNP) {
- resp = WifiP2pUpnpServiceResponse.newInstance(status,
- transId, dev, data);
- } else {
- resp = new WifiP2pServiceResponse(type, status, transId, dev, data);
- }
- if (resp != null && resp.getStatus() == Status.SUCCESS) {
- respList.add(resp);
- }
- }
- return respList;
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- if (respList.size() > 0) {
- return respList;
- }
- return null;
- }
-
- /**
- * Converts hex string to byte array.
- *
- * @param hex hex string. if invalid, return null.
- * @return binary data.
- */
- private static byte[] hexStr2Bin(String hex) {
- int sz = hex.length()/2;
- byte[] b = new byte[hex.length()/2];
-
- for (int i=0;i<sz;i++) {
- try {
- b[i] = (byte)Integer.parseInt(hex.substring(i*2, i*2+2), 16);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
- return b;
- }
-
- @Override
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("serviceType:").append(mServiceType);
- sbuf.append(" status:").append(Status.toString(mStatus));
- sbuf.append(" srcAddr:").append(mDevice.deviceAddress);
- sbuf.append(" data:").append(Arrays.toString(mData));
- return sbuf.toString();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof WifiP2pServiceResponse)) {
- return false;
- }
-
- WifiP2pServiceResponse req = (WifiP2pServiceResponse)o;
-
- return (req.mServiceType == mServiceType) &&
- (req.mStatus == mStatus) &&
- equals(req.mDevice.deviceAddress, mDevice.deviceAddress) &&
- Arrays.equals(req.mData, mData);
- }
-
- private boolean equals(Object a, Object b) {
- if (a == null && b == null) {
- return true;
- } else if (a != null) {
- return a.equals(b);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + mServiceType;
- result = 31 * result + mStatus;
- result = 31 * result + mTransId;
- result = 31 * result + (mDevice.deviceAddress == null ?
- 0 : mDevice.deviceAddress.hashCode());
- result = 31 * result + (mData == null ? 0 : Arrays.hashCode(mData));
- return result;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mServiceType);
- dest.writeInt(mStatus);
- dest.writeInt(mTransId);
- dest.writeParcelable(mDevice, flags);
- if (mData == null || mData.length == 0) {
- dest.writeInt(0);
- } else {
- dest.writeInt(mData.length);
- dest.writeByteArray(mData);
- }
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<WifiP2pServiceResponse> CREATOR =
- new Creator<WifiP2pServiceResponse>() {
- public WifiP2pServiceResponse createFromParcel(Parcel in) {
-
- int type = in.readInt();
- int status = in.readInt();
- int transId = in.readInt();
- WifiP2pDevice dev = (WifiP2pDevice)in.readParcelable(null);
- int len = in.readInt();
- byte[] data = null;
- if (len > 0) {
- data = new byte[len];
- in.readByteArray(data);
- }
- if (type == WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR) {
- return WifiP2pDnsSdServiceResponse.newInstance(status,
- transId, dev, data);
- } else if (type == WifiP2pServiceInfo.SERVICE_TYPE_UPNP) {
- return WifiP2pUpnpServiceResponse.newInstance(status,
- transId, dev, data);
- }
- return new WifiP2pServiceResponse(type, status, transId, dev, data);
- }
-
- public WifiP2pServiceResponse[] newArray(int size) {
- return new WifiP2pServiceResponse[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java
deleted file mode 100644
index a4cdfd9..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.nsd;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.UUID;
-
-/**
- * A class for storing Upnp service information that is advertised
- * over a Wi-Fi peer-to-peer setup.
- *
- * {@see android.net.wifi.p2p.WifiP2pManager#addLocalService}
- * {@see android.net.wifi.p2p.WifiP2pManager#removeLocalService}
- * {@see WifiP2pServiceInfo}
- * {@see WifiP2pDnsSdServiceInfo}
- */
-public class WifiP2pUpnpServiceInfo extends WifiP2pServiceInfo {
-
- /**
- * UPnP version 1.0.
- *
- * <pre>Query Version should always be set to 0x10 if the query values are
- * compatible with UPnP Device Architecture 1.0.
- * @hide
- */
- public static final int VERSION_1_0 = 0x10;
-
- /**
- * This constructor is only used in newInstance().
- *
- * @param queryList
- */
- private WifiP2pUpnpServiceInfo(List<String> queryList) {
- super(queryList);
- }
-
- /**
- * Create UPnP service information object.
- *
- * @param uuid a string representation of this UUID in the following format,
- * as per <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.<br>
- * e.g) 6859dede-8574-59ab-9332-123456789012
- * @param device a string representation of this device in the following format,
- * as per
- * <a href="http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf">
- * UPnP Device Architecture1.1</a><br>
- * e.g) urn:schemas-upnp-org:device:MediaServer:1
- * @param services a string representation of this service in the following format,
- * as per
- * <a href="http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf">
- * UPnP Device Architecture1.1</a><br>
- * e.g) urn:schemas-upnp-org:service:ContentDirectory:1
- * @return UPnP service information object.
- */
- public static WifiP2pUpnpServiceInfo newInstance(String uuid,
- String device, List<String> services) {
- if (uuid == null || device == null) {
- throw new IllegalArgumentException("uuid or device cannnot be null");
- }
- UUID.fromString(uuid);
-
- ArrayList<String> info = new ArrayList<String>();
-
- info.add(createSupplicantQuery(uuid, null));
- info.add(createSupplicantQuery(uuid, "upnp:rootdevice"));
- info.add(createSupplicantQuery(uuid, device));
- if (services != null) {
- for (String service:services) {
- info.add(createSupplicantQuery(uuid, service));
- }
- }
-
- return new WifiP2pUpnpServiceInfo(info);
- }
-
- /**
- * Create wpa_supplicant service query for upnp.
- *
- * @param uuid
- * @param data
- * @return wpa_supplicant service query for upnp
- */
- private static String createSupplicantQuery(String uuid, String data) {
- StringBuffer sb = new StringBuffer();
- sb.append("upnp ");
- sb.append(String.format(Locale.US, "%02x ", VERSION_1_0));
- sb.append("uuid:");
- sb.append(uuid);
- if (data != null) {
- sb.append("::");
- sb.append(data);
- }
- return sb.toString();
- }
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java
deleted file mode 100644
index 98e447e..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.nsd;
-
-import android.net.wifi.p2p.WifiP2pManager;
-
-import java.util.Locale;
-
-/**
- * A class for creating a Upnp service discovery request for use with
- * {@link WifiP2pManager#addServiceRequest} and {@link WifiP2pManager#removeServiceRequest}
- *
- * {@see WifiP2pManager}
- * {@see WifiP2pServiceRequest}
- * {@see WifiP2pDnsSdServiceRequest}
- */
-public class WifiP2pUpnpServiceRequest extends WifiP2pServiceRequest {
-
- /**
- * This constructor is only used in newInstance().
- *
- * @param query The part of service specific query.
- * @hide
- */
- protected WifiP2pUpnpServiceRequest(String query) {
- super(WifiP2pServiceInfo.SERVICE_TYPE_UPNP, query);
- }
-
- /**
- * This constructor is only used in newInstance().
- * @hide
- */
- protected WifiP2pUpnpServiceRequest() {
- super(WifiP2pServiceInfo.SERVICE_TYPE_UPNP, null);
- }
-
- /**
- * Create a service discovery request to search all UPnP services.
- *
- * @return service request for UPnP.
- */
- public static WifiP2pUpnpServiceRequest newInstance() {
- return new WifiP2pUpnpServiceRequest();
- }
- /**
- * Create a service discovery request to search specified UPnP services.
- *
- * @param st ssdp search target. Cannot be null.<br>
- * e.g ) <br>
- * <ul>
- * <li>"ssdp:all"
- * <li>"upnp:rootdevice"
- * <li>"urn:schemas-upnp-org:device:MediaServer:2"
- * <li>"urn:schemas-upnp-org:service:ContentDirectory:2"
- * <li>"uuid:6859dede-8574-59ab-9332-123456789012"
- * </ul>
- * @return service request for UPnP.
- */
- public static WifiP2pUpnpServiceRequest newInstance(String st) {
- if (st == null) {
- throw new IllegalArgumentException("search target cannot be null");
- }
- StringBuffer sb = new StringBuffer();
- sb.append(String.format(Locale.US, "%02x", WifiP2pUpnpServiceInfo.VERSION_1_0));
- sb.append(WifiP2pServiceInfo.bin2HexStr(st.getBytes()));
- return new WifiP2pUpnpServiceRequest(sb.toString());
- }
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse.java
deleted file mode 100644
index ab95af6f6..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net.wifi.p2p.nsd;
-
-import android.net.wifi.p2p.WifiP2pDevice;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A class for a response of upnp service discovery.
- *
- * @hide
- */
-public class WifiP2pUpnpServiceResponse extends WifiP2pServiceResponse {
-
- /**
- * UPnP version. should be {@link WifiP2pUpnpServiceInfo#VERSION_1_0}
- */
- private int mVersion;
-
- /**
- * The list of Unique Service Name.
- * e.g)
- *{"uuid:6859dede-8574-59ab-9332-123456789012",
- *"uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice"}
- */
- private List<String> mUniqueServiceNames;
-
- /**
- * Return UPnP version number.
- *
- * @return version number.
- * @see WifiP2pUpnpServiceInfo#VERSION_1_0
- */
- public int getVersion() {
- return mVersion;
- }
-
- /**
- * Return Unique Service Name strings.
- *
- * @return Unique Service Name.<br>
- * e.g ) <br>
- * <ul>
- * <li>"uuid:6859dede-8574-59ab-9332-123456789012"
- * <li>"uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice"
- * <li>"uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:
- * MediaServer:2"
- * <li>"uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:service:
- * ContentDirectory:2"
- * </ul>
- */
- public List<String> getUniqueServiceNames() {
- return mUniqueServiceNames;
- }
-
- /**
- * hidden constructor.
- *
- * @param status status code
- * @param transId transaction id
- * @param dev source device
- * @param data UPnP response data.
- */
- protected WifiP2pUpnpServiceResponse(int status,
- int transId, WifiP2pDevice dev, byte[] data) {
- super(WifiP2pServiceInfo.SERVICE_TYPE_UPNP,
- status, transId, dev, data);
- if (!parse()) {
- throw new IllegalArgumentException("Malformed upnp service response");
- }
- }
-
- /**
- * Parse UPnP service discovery response
- *
- * @return {@code true} if the operation succeeded
- */
- private boolean parse() {
- /*
- * The data format is as follows.
- *
- * ______________________________________________________
- * | Version (1) | USN (Variable) |
- */
- if (mData == null) {
- // the empty is OK.
- return true;
- }
-
- if (mData.length < 1) {
- return false;
- }
-
- mVersion = mData[0] & 0xff;
- String[] names = new String(mData, 1, mData.length-1).split(",");
- mUniqueServiceNames = new ArrayList<String>();
- for (String name : names) {
- mUniqueServiceNames.add(name);
- }
- return true;
- }
-
- @Override
- public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("serviceType:UPnP(").append(mServiceType).append(")");
- sbuf.append(" status:").append(Status.toString(mStatus));
- sbuf.append(" srcAddr:").append(mDevice.deviceAddress);
- sbuf.append(" version:").append(String.format("%02x", mVersion));
- if (mUniqueServiceNames != null) {
- for (String name : mUniqueServiceNames) {
- sbuf.append(" usn:").append(name);
- }
- }
- return sbuf.toString();
- }
-
- /**
- * Create upnp service response.
- *
- * <pre>This is only used in{@link WifiP2pServiceResponse}
- *
- * @param status status code.
- * @param transId transaction id.
- * @param device source device.
- * @param data UPnP response data.
- * @return UPnP service response data.
- * @hide
- */
- static WifiP2pUpnpServiceResponse newInstance(int status,
- int transId, WifiP2pDevice device, byte[] data) {
- if (status != WifiP2pServiceResponse.Status.SUCCESS) {
- return new WifiP2pUpnpServiceResponse(status, transId, device, null);
- }
-
- try {
- return new WifiP2pUpnpServiceResponse(status, transId, device, data);
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- }
- return null;
- }
-}
diff --git a/wifi/java/android/net/wifi/p2p/package.html b/wifi/java/android/net/wifi/p2p/package.html
deleted file mode 100644
index 6a5e8e6..0000000
--- a/wifi/java/android/net/wifi/p2p/package.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes to create peer-to-peer (P2P) connections with Wi-Fi Direct.</p>
-
-<p>Using these APIs, you can discover and connect to other devices when each
-device supports Wi-Fi Direct, then communicate over a speedy connection across distances much longer
-than a Bluetooth connection. The primary class you need to work with is {@link
-android.net.wifi.p2p.WifiP2pManager}, which you can acquire by calling {@link
-android.app.Activity#getSystemService getSystemService(WIFI_P2P_SERVICE)}. The {@link
-android.net.wifi.p2p.WifiP2pManager} includes APIs that allow you to:</p>
-<ul>
-<li>Initialize your application for P2P connections by calling {@link
-android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</li>
-
-<li>Discover nearby devices by calling {@link android.net.wifi.p2p.WifiP2pManager#discoverPeers
-discoverPeers()}</li>
-
-<li>Start a P2P connection by calling {@link android.net.wifi.p2p.WifiP2pManager#connect
-connect()}</li>
-<li>And more</li>
-</ul>
-
-<p>Several other interfaces and classes are necessary as well, such as:</p>
-<ul>
-<li>The {@link android.net.wifi.p2p.WifiP2pManager.ActionListener} interface allows you to receive
-callbacks when an operation such as discovering peers or connecting to them succeeds or fails.</li>
-
-<li>{@link android.net.wifi.p2p.WifiP2pManager.PeerListListener} interface allows you to receive
-information about discovered peers. The callback provides a {@link
-android.net.wifi.p2p.WifiP2pDeviceList}, from which you can retrieve a {@link
-android.net.wifi.p2p.WifiP2pDevice} object for each device within range and get information such as
-the device name, address, device type, the WPS configurations the device supports, and more.</li>
-
-<li>The {@link android.net.wifi.p2p.WifiP2pManager.GroupInfoListener} interface allows you to
-receive information about a P2P group. The callback provides a {@link
-android.net.wifi.p2p.WifiP2pGroup} object, which provides group information such as the owner, the
-network name, and passphrase.</li>
-
-<li>{@link android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener} interface allows you to
-receive information about the current connection. The callback provides a {@link
-android.net.wifi.p2p.WifiP2pInfo} object, which has information such as whether a group has been
-formed and who is the group owner.</li>
-</ul>
-
-<p>In order to use the Wi-Fi P2P APIs, your app must request the following user permissions:</p>
-<ul>
-<li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
-<li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
-<li>{@link android.Manifest.permission#INTERNET} (although your app doesn’t technically connect
-to the Internet, communicating to Wi-Fi Direct peers with standard java sockets requires Internet
-permission).</li>
-</ul>
-
-<p>For example code, see the <a href="{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi
-Direct Demo</a> sample application.</p>
-
-<p class="note"><strong>Note:</strong> Not all Android-powered devices support Wi-Fi
-Direct. If your application uses Wi-Fi Direct, declare so with a <a
-href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}</a>
-element in the manifest file:</p>
-<pre>
-<manifest ...>
- <uses-feature android:name="android.hardware.wifi.direct" />
- ...
-</manifest>
-</pre>
-</BODY>
-</HTML>
diff --git a/wifi/java/android/net/wifi/package.html b/wifi/java/android/net/wifi/package.html
deleted file mode 100644
index b21d39d0..0000000
--- a/wifi/java/android/net/wifi/package.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes to manage Wi-Fi functionality on the device.</p>
-<p>The Wi-Fi APIs provide a means by which applications can communicate
-with the lower-level wireless stack that provides Wi-Fi network access. Almost all
-information from the device supplicant is available, including the connected network's
-link speed, IP address, negotiation state, and more, plus information about other
-networks that are available. Some other API features include the ability to
-scan, add, save, terminate and initiate Wi-Fi connections.</p>
-
-<p>Some APIs may require the following user permissions:</p>
-<ul>
- <li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
- <li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
- <li>{@link android.Manifest.permission#CHANGE_WIFI_MULTICAST_STATE}</li>
-</ul>
-
-<p class="note"><strong>Note:</strong> Not all Android-powered devices provide Wi-Fi functionality.
-If your application uses Wi-Fi, declare so with a <a
-href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}</a>
-element in the manifest file:</p>
-<pre>
-<manifest ...>
- <uses-feature android:name="android.hardware.wifi" />
- ...
-</manifest>
-</pre>
-</BODY>
-</HTML>
diff --git a/wifi/java/android/net/wifi/rtt/CivicLocation.java b/wifi/java/android/net/wifi/rtt/CivicLocation.java
deleted file mode 100644
index 1d41177..0000000
--- a/wifi/java/android/net/wifi/rtt/CivicLocation.java
+++ /dev/null
@@ -1,333 +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.net.wifi.rtt;
-
-import android.annotation.Nullable;
-import android.location.Address;
-import android.net.wifi.rtt.CivicLocationKeys.CivicLocationKeysType;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.Parcelable.Creator;
-import android.util.SparseArray;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Locale;
-import java.util.Objects;
-
-/**
- * Decodes the Type Length Value (TLV) elements found in a Location Civic Record as defined by IEEE
- * P802.11-REVmc/D8.0 section 9.4.2.22.13 using the format described in IETF RFC 4776.
- *
- * <p>The TLVs each define a key, value pair for a civic address type such as apt, street, city,
- * county, and country. The class provides a general getter method to extract a value for an element
- * key, returning null if not set.
- *
- * @hide
- */
-public final class CivicLocation implements Parcelable {
- // Address (class) line indexes
- private static final int ADDRESS_LINE_0_ROOM_DESK_FLOOR = 0;
- private static final int ADDRESS_LINE_1_NUMBER_ROAD_SUFFIX_APT = 1;
- private static final int ADDRESS_LINE_2_CITY = 2;
- private static final int ADDRESS_LINE_3_STATE_POSTAL_CODE = 3;
- private static final int ADDRESS_LINE_4_COUNTRY = 4;
-
- // Buffer management
- private static final int MIN_CIVIC_BUFFER_SIZE = 3;
- private static final int MAX_CIVIC_BUFFER_SIZE = 256;
- private static final int COUNTRY_CODE_LENGTH = 2;
- private static final int BYTE_MASK = 0xFF;
- private static final int TLV_TYPE_INDEX = 0;
- private static final int TLV_LENGTH_INDEX = 1;
- private static final int TLV_VALUE_INDEX = 2;
-
- private final boolean mIsValid;
- private final String mCountryCode; // Two character country code (ISO 3166 standard).
- private SparseArray<String> mCivicAddressElements =
- new SparseArray<>(MIN_CIVIC_BUFFER_SIZE);
-
-
- /**
- * Constructor
- *
- * @param civicTLVs a byte buffer containing parameters in the form type, length, value
- * @param countryCode the two letter code defined by the ISO 3166 standard
- *
- * @hide
- */
- public CivicLocation(@Nullable byte[] civicTLVs, @Nullable String countryCode) {
- this.mCountryCode = countryCode;
- if (countryCode == null || countryCode.length() != COUNTRY_CODE_LENGTH) {
- this.mIsValid = false;
- return;
- }
- boolean isValid = false;
- if (civicTLVs != null
- && civicTLVs.length >= MIN_CIVIC_BUFFER_SIZE
- && civicTLVs.length < MAX_CIVIC_BUFFER_SIZE) {
- isValid = parseCivicTLVs(civicTLVs);
- }
-
- mIsValid = isValid;
- }
-
- private CivicLocation(Parcel in) {
- mIsValid = in.readByte() != 0;
- mCountryCode = in.readString();
- mCivicAddressElements = in.readSparseArray(this.getClass().getClassLoader());
- }
-
- public static final @android.annotation.NonNull Creator<CivicLocation> CREATOR = new Creator<CivicLocation>() {
- @Override
- public CivicLocation createFromParcel(Parcel in) {
- return new CivicLocation(in);
- }
-
- @Override
- public CivicLocation[] newArray(int size) {
- return new CivicLocation[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeByte((byte) (mIsValid ? 1 : 0));
- parcel.writeString(mCountryCode);
- parcel.writeSparseArray((android.util.SparseArray) mCivicAddressElements);
- }
-
- /**
- * Check TLV format and store TLV key/value pairs in this object so they can be queried by key.
- *
- * @param civicTLVs the buffer of TLV elements
- * @return a boolean indicating success of the parsing process
- */
- private boolean parseCivicTLVs(byte[] civicTLVs) {
- int bufferPtr = 0;
- int bufferLength = civicTLVs.length;
-
- // Iterate through the sub-elements contained in the LCI IE checking the accumulated
- // element lengths do not overflow the total buffer length
- while (bufferPtr < bufferLength) {
- int civicAddressType = civicTLVs[bufferPtr + TLV_TYPE_INDEX] & BYTE_MASK;
- int civicAddressTypeLength = civicTLVs[bufferPtr + TLV_LENGTH_INDEX];
- if (civicAddressTypeLength != 0) {
- if (bufferPtr + TLV_VALUE_INDEX + civicAddressTypeLength > bufferLength) {
- return false;
- }
- mCivicAddressElements.put(civicAddressType,
- new String(civicTLVs, bufferPtr + TLV_VALUE_INDEX,
- civicAddressTypeLength, StandardCharsets.UTF_8));
- }
- bufferPtr += civicAddressTypeLength + TLV_VALUE_INDEX;
- }
- return true;
- }
-
- /**
- * Getter for the value of a civic Address element type.
- *
- * @param key an integer code for the element type key
- * @return the string value associated with that element type
- */
- @Nullable
- public String getCivicElementValue(@CivicLocationKeysType int key) {
- return mCivicAddressElements.get(key);
- }
-
- /**
- * Converts a CivicLocation object to a SparseArray.
- *
- * @return the SparseArray<string> representation of the CivicLocation
- */
- @Nullable
- public SparseArray<String> toSparseArray() {
- return mCivicAddressElements;
- }
-
- /**
- * Generates a comma separated string of all the defined elements.
- *
- * @return a compiled string representing all elements
- */
- @Override
- public String toString() {
- return mCivicAddressElements.toString();
- }
-
- /**
- * Converts Civic Location to the best effort Address Object.
- *
- * @return the {@link Address} object based on the Civic Location data
- */
- @Nullable
- public Address toAddress() {
- if (!mIsValid) {
- return null;
- }
- Address address = new Address(Locale.US);
- String room = formatAddressElement("Room: ", getCivicElementValue(CivicLocationKeys.ROOM));
- String desk =
- formatAddressElement(" Desk: ", getCivicElementValue(CivicLocationKeys.DESK));
- String floor =
- formatAddressElement(", Flr: ", getCivicElementValue(CivicLocationKeys.FLOOR));
- String houseNumber = formatAddressElement("", getCivicElementValue(CivicLocationKeys.HNO));
- String houseNumberSuffix =
- formatAddressElement("", getCivicElementValue(CivicLocationKeys.HNS));
- String road =
- formatAddressElement(" ", getCivicElementValue(
- CivicLocationKeys.PRIMARY_ROAD_NAME));
- String roadSuffix = formatAddressElement(" ", getCivicElementValue(CivicLocationKeys.STS));
- String apt = formatAddressElement(", Apt: ", getCivicElementValue(CivicLocationKeys.APT));
- String city = formatAddressElement("", getCivicElementValue(CivicLocationKeys.CITY));
- String state = formatAddressElement("", getCivicElementValue(CivicLocationKeys.STATE));
- String postalCode =
- formatAddressElement(" ", getCivicElementValue(CivicLocationKeys.POSTAL_CODE));
-
- // Aggregation into common address format
- String addressLine0 =
- new StringBuilder().append(room).append(desk).append(floor).toString();
- String addressLine1 =
- new StringBuilder().append(houseNumber).append(houseNumberSuffix).append(road)
- .append(roadSuffix).append(apt).toString();
- String addressLine2 = city;
- String addressLine3 = new StringBuilder().append(state).append(postalCode).toString();
- String addressLine4 = mCountryCode;
-
- // Setting Address object line fields by common convention.
- address.setAddressLine(ADDRESS_LINE_0_ROOM_DESK_FLOOR, addressLine0);
- address.setAddressLine(ADDRESS_LINE_1_NUMBER_ROAD_SUFFIX_APT, addressLine1);
- address.setAddressLine(ADDRESS_LINE_2_CITY, addressLine2);
- address.setAddressLine(ADDRESS_LINE_3_STATE_POSTAL_CODE, addressLine3);
- address.setAddressLine(ADDRESS_LINE_4_COUNTRY, addressLine4);
-
- // Other compatible fields between the CIVIC_ADDRESS and the Address Class.
- address.setFeatureName(getCivicElementValue(CivicLocationKeys.NAM)); // Structure name
- address.setSubThoroughfare(getCivicElementValue(CivicLocationKeys.HNO));
- address.setThoroughfare(getCivicElementValue(CivicLocationKeys.PRIMARY_ROAD_NAME));
- address.setSubLocality(getCivicElementValue(CivicLocationKeys.NEIGHBORHOOD));
- address.setSubAdminArea(getCivicElementValue(CivicLocationKeys.COUNTY));
- address.setAdminArea(getCivicElementValue(CivicLocationKeys.STATE));
- address.setPostalCode(getCivicElementValue(CivicLocationKeys.POSTAL_CODE));
- address.setCountryCode(mCountryCode); // Country
- return address;
- }
-
- /**
- * Prepares an address element so that it can be integrated into an address line convention.
- *
- * <p>If an address element is null, the return string will be empty e.g. "".
- *
- * @param label a string defining the type of address element
- * @param value a string defining the elements value
- * @return the formatted version of the value, with null values converted to empty strings
- */
- private String formatAddressElement(String label, String value) {
- if (value != null) {
- return label + value;
- } else {
- return "";
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof CivicLocation)) {
- return false;
- }
- CivicLocation other = (CivicLocation) obj;
- return mIsValid == other.mIsValid
- && Objects.equals(mCountryCode, other.mCountryCode)
- && isSparseArrayStringEqual(mCivicAddressElements, other.mCivicAddressElements);
- }
-
- @Override
- public int hashCode() {
- int[] civicAddressKeys = getSparseArrayKeys(mCivicAddressElements);
- String[] civicAddressValues = getSparseArrayValues(mCivicAddressElements);
- return Objects.hash(mIsValid, mCountryCode, civicAddressKeys, civicAddressValues);
- }
-
- /**
- * Tests if the Civic Location object is valid
- *
- * @return a boolean defining mIsValid
- */
- public boolean isValid() {
- return mIsValid;
- }
-
- /**
- * Tests if two sparse arrays are equal on a key for key basis
- *
- * @param sa1 the first sparse array
- * @param sa2 the second sparse array
- * @return the boolean result after comparing values key by key
- */
- private boolean isSparseArrayStringEqual(SparseArray<String> sa1, SparseArray<String> sa2) {
- int size = sa1.size();
- if (size != sa2.size()) {
- return false;
- }
- for (int i = 0; i < size; i++) {
- String sa1Value = sa1.valueAt(i);
- String sa2Value = sa2.valueAt(i);
- if (!sa1Value.equals(sa2Value)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Extract an array of all the keys in a SparseArray<String>
- *
- * @param sa the sparse array of Strings
- * @return an integer array of all keys in the SparseArray<String>
- */
- private int[] getSparseArrayKeys(SparseArray<String> sa) {
- int size = sa.size();
- int[] keys = new int[size];
- for (int i = 0; i < size; i++) {
- keys[i] = sa.keyAt(i);
- }
- return keys;
- }
-
- /**
- * Extract an array of all the String values in a SparseArray<String>
- *
- * @param sa the sparse array of Strings
- * @return a String array of all values in the SparseArray<String>
- */
- private String[] getSparseArrayValues(SparseArray<String> sa) {
- int size = sa.size();
- String[] values = new String[size];
- for (int i = 0; i < size; i++) {
- values[i] = sa.valueAt(i);
- }
- return values;
- }
-}
diff --git a/wifi/java/android/net/wifi/rtt/CivicLocationKeys.java b/wifi/java/android/net/wifi/rtt/CivicLocationKeys.java
deleted file mode 100644
index b03f4a9..0000000
--- a/wifi/java/android/net/wifi/rtt/CivicLocationKeys.java
+++ /dev/null
@@ -1,115 +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.net.wifi.rtt;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-
-/**
- * Civic Address key types used to define address elements.
- *
- * <p>These keys can be used with {@code ResponderLocation.toCivicLocationSparseArray()}
- * to look-up the corresponding string values.</p>
- */
-public class CivicLocationKeys {
-
- /**
- * An enumeration of all civic location keys.
- *
- * @hide
- */
- @Retention(SOURCE)
- @IntDef({LANGUAGE, STATE, COUNTY, CITY, BOROUGH, NEIGHBORHOOD, GROUP_OF_STREETS, PRD, POD, STS,
- HNO, HNS, LMK, LOC, NAM, POSTAL_CODE, BUILDING, APT, FLOOR, ROOM, TYPE_OF_PLACE, PCN,
- PO_BOX, ADDITIONAL_CODE, DESK, PRIMARY_ROAD_NAME, ROAD_SECTION, BRANCH_ROAD_NAME,
- SUBBRANCH_ROAD_NAME, STREET_NAME_PRE_MODIFIER, STREET_NAME_POST_MODIFIER, SCRIPT})
- public @interface CivicLocationKeysType {
- }
-
- /** Language key e.g. i-default. */
- public static final int LANGUAGE = 0;
- /** Category label A1 key e.g. California. */
- public static final int STATE = 1;
- /** Category label A2 key e.g. Marin. */
- public static final int COUNTY = 2;
- /** Category label A3 key e.g. San Francisco. */
- public static final int CITY = 3;
- /** Category label A4 key e.g. Westminster. */
- public static final int BOROUGH = 4;
- /** Category label A5 key e.g. Pacific Heights. */
- public static final int NEIGHBORHOOD = 5;
- /** Category label A6 key e.g. University District. */
- public static final int GROUP_OF_STREETS = 6;
- // 7 - 15 not defined
- /** Leading Street direction key e.g. N. */
- public static final int PRD = 16;
- /** Trailing street suffix key e.g. SW. */
- public static final int POD = 17;
- /** Street suffix or Type key e.g Ave, Platz. */
- public static final int STS = 18;
- /** House Number key e.g. 123. */
- public static final int HNO = 19;
- /** House number suffix key e.g. A, 1/2. */
- public static final int HNS = 20;
- /** Landmark or vanity address key e.g. Golden Gate Bridge. */
- public static final int LMK = 21;
- /** Additional Location info key e.g. South Wing. */
- public static final int LOC = 22;
- /** Name of residence key e.g. Joe's Barbershop. */
- public static final int NAM = 23;
- /** Postal or ZIP code key e.g. 10027-1234. */
- public static final int POSTAL_CODE = 24;
- /** Building key e.g. Lincoln Library. */
- public static final int BUILDING = 25;
- /** Apartment or suite key e.g. Apt 42. */
- public static final int APT = 26;
- /** Floor key e.g. 4. */
- public static final int FLOOR = 27;
- /** Room key e.g. 450F. */
- public static final int ROOM = 28;
- /** Type of place key e.g. office. */
- public static final int TYPE_OF_PLACE = 29;
- /** Postal community name key e.g. Leonia. */
- public static final int PCN = 30;
- /** Post Office Box key e.g. 12345. */
- public static final int PO_BOX = 31;
- /** Additional Code key e.g. 13203000003. */
- public static final int ADDITIONAL_CODE = 32;
- /** Seat, desk, pole, or cubical key e.g. WS 181. */
- public static final int DESK = 33;
- /** Primary road name key e.g. Shoreline. */
- public static final int PRIMARY_ROAD_NAME = 34;
- /** Road Section key e.g. 14. */
- public static final int ROAD_SECTION = 35;
- /** Branch Rd Name key e.g. Lane 7. */
- public static final int BRANCH_ROAD_NAME = 36;
- /** Subbranch Rd Name key e.g. Alley 8. */
- public static final int SUBBRANCH_ROAD_NAME = 37;
- /** Premodifier key e.g. Old. */
- public static final int STREET_NAME_PRE_MODIFIER = 38;
- /** Postmodifier key e.g. Service. */
- public static final int STREET_NAME_POST_MODIFIER = 39;
- /** Script key e.g. Latn. */
- public static final int SCRIPT = 128;
-
- /** private constructor */
- private CivicLocationKeys() {}
-}
-
diff --git a/wifi/java/android/net/wifi/rtt/IRttCallback.aidl b/wifi/java/android/net/wifi/rtt/IRttCallback.aidl
deleted file mode 100644
index 578dd1e..0000000
--- a/wifi/java/android/net/wifi/rtt/IRttCallback.aidl
+++ /dev/null
@@ -1,37 +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.net.wifi.rtt;
-
-import android.net.wifi.rtt.RangingResult;
-
-/**
- * Interface for RTT result callback.
- *
- * @hide
- */
-oneway interface IRttCallback
-{
- /**
- * Service to manager callback indicating failure.
- */
- void onRangingFailure(int status);
-
- /**
- * Service to manager callback indicating success and providing results.
- */
- void onRangingResults(in List<RangingResult> results);
-}
diff --git a/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl b/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl
deleted file mode 100644
index 7c92a6b..0000000
--- a/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import android.os.WorkSource;
-
-import android.net.wifi.rtt.IRttCallback;
-import android.net.wifi.rtt.RangingRequest;
-
-/**
- * @hide
- */
-interface IWifiRttManager
-{
- boolean isAvailable();
- void startRanging(in IBinder binder, in String callingPackage, in String callingFeatureId,
- in WorkSource workSource, in RangingRequest request, in IRttCallback callback);
- void cancelRanging(in WorkSource workSource);
-}
diff --git a/wifi/java/android/net/wifi/rtt/RangingRequest.java b/wifi/java/android/net/wifi/rtt/RangingRequest.java
deleted file mode 100644
index 318efa6..0000000
--- a/wifi/java/android/net/wifi/rtt/RangingRequest.java
+++ /dev/null
@@ -1,267 +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.net.wifi.rtt;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.net.wifi.ScanResult;
-import android.net.wifi.aware.AttachCallback;
-import android.net.wifi.aware.DiscoverySessionCallback;
-import android.net.wifi.aware.IdentityChangedListener;
-import android.net.wifi.aware.PeerHandle;
-import android.net.wifi.aware.WifiAwareManager;
-import android.os.Handler;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringJoiner;
-
-/**
- * Defines the ranging request to other devices. The ranging request is built using
- * {@link RangingRequest.Builder}.
- * A ranging request is executed using
- * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}.
- * <p>
- * The ranging request is a batch request - specifying a set of devices (specified using
- * {@link RangingRequest.Builder#addAccessPoint(ScanResult)} and
- * {@link RangingRequest.Builder#addAccessPoints(List)}).
- */
-public final class RangingRequest implements Parcelable {
- private static final int MAX_PEERS = 10;
-
- /**
- * Returns the maximum number of peers to range which can be specified in a single {@code
- * RangingRequest}. The limit applies no matter how the peers are added to the request, e.g.
- * through {@link RangingRequest.Builder#addAccessPoint(ScanResult)} or
- * {@link RangingRequest.Builder#addAccessPoints(List)}.
- *
- * @return Maximum number of peers.
- */
- public static int getMaxPeers() {
- return MAX_PEERS;
- }
-
- /** @hide */
- public final List<ResponderConfig> mRttPeers;
-
- /** @hide */
- private RangingRequest(List<ResponderConfig> rttPeers) {
- mRttPeers = rttPeers;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeList(mRttPeers);
- }
-
- public static final @android.annotation.NonNull Creator<RangingRequest> CREATOR = new Creator<RangingRequest>() {
- @Override
- public RangingRequest[] newArray(int size) {
- return new RangingRequest[size];
- }
-
- @Override
- public RangingRequest createFromParcel(Parcel in) {
- return new RangingRequest(in.readArrayList(null));
- }
- };
-
- /** @hide */
- @Override
- public String toString() {
- StringJoiner sj = new StringJoiner(", ", "RangingRequest: mRttPeers=[", "]");
- for (ResponderConfig rc : mRttPeers) {
- sj.add(rc.toString());
- }
- return sj.toString();
- }
-
- /** @hide */
- public void enforceValidity(boolean awareSupported) {
- if (mRttPeers.size() > MAX_PEERS) {
- throw new IllegalArgumentException(
- "Ranging to too many peers requested. Use getMaxPeers() API to get limit.");
- }
-
- for (ResponderConfig peer: mRttPeers) {
- if (!peer.isValid(awareSupported)) {
- throw new IllegalArgumentException("Invalid Responder specification");
- }
- }
- }
-
- /**
- * Builder class used to construct {@link RangingRequest} objects.
- */
- public static final class Builder {
- private List<ResponderConfig> mRttPeers = new ArrayList<>();
-
- /**
- * Add the device specified by the {@link ScanResult} to the list of devices with
- * which to measure range. The total number of peers added to a request cannot exceed the
- * limit specified by {@link #getMaxPeers()}.
- * <p>
- * Ranging may not be supported if the Access Point does not support IEEE 802.11mc. Use
- * {@link ScanResult#is80211mcResponder()} to verify the Access Point's capabilities. If
- * not supported the result status will be
- * {@link RangingResult#STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC}.
- *
- * @param apInfo Information of an Access Point (AP) obtained in a Scan Result.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder addAccessPoint(@NonNull ScanResult apInfo) {
- if (apInfo == null) {
- throw new IllegalArgumentException("Null ScanResult!");
- }
- return addResponder(ResponderConfig.fromScanResult(apInfo));
- }
-
- /**
- * Add the devices specified by the {@link ScanResult}s to the list of devices with
- * which to measure range. The total number of peers added to a request cannot exceed the
- * limit specified by {@link #getMaxPeers()}.
- * <p>
- * Ranging may not be supported if the Access Point does not support IEEE 802.11mc. Use
- * {@link ScanResult#is80211mcResponder()} to verify the Access Point's capabilities. If
- * not supported the result status will be
- * {@link RangingResult#STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC}.
- *
- * @param apInfos Information of an Access Points (APs) obtained in a Scan Result.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder addAccessPoints(@NonNull List<ScanResult> apInfos) {
- if (apInfos == null) {
- throw new IllegalArgumentException("Null list of ScanResults!");
- }
- for (ScanResult scanResult : apInfos) {
- addAccessPoint(scanResult);
- }
- return this;
- }
-
- /**
- * Add the device specified by the {@code peerMacAddress} to the list of devices with
- * which to measure range.
- * <p>
- * The MAC address may be obtained out-of-band from a peer Wi-Fi Aware device. A Wi-Fi
- * Aware device may obtain its MAC address using the {@link IdentityChangedListener}
- * provided to
- * {@link WifiAwareManager#attach(AttachCallback, IdentityChangedListener, Handler)}.
- * <p>
- * Note: in order to use this API the device must support Wi-Fi Aware
- * {@link android.net.wifi.aware}. The peer device which is being ranged to must be
- * configured to publish a service (with any name) with:
- * <li>Type {@link android.net.wifi.aware.PublishConfig#PUBLISH_TYPE_UNSOLICITED}.
- * <li>Ranging enabled
- * {@link android.net.wifi.aware.PublishConfig.Builder#setRangingEnabled(boolean)}.
- *
- * @param peerMacAddress The MAC address of the Wi-Fi Aware peer.
- * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder addWifiAwarePeer(@NonNull MacAddress peerMacAddress) {
- if (peerMacAddress == null) {
- throw new IllegalArgumentException("Null peer MAC address");
- }
- return addResponder(
- ResponderConfig.fromWifiAwarePeerMacAddressWithDefaults(peerMacAddress));
- }
-
- /**
- * Add a device specified by a {@link PeerHandle} to the list of devices with which to
- * measure range.
- * <p>
- * The {@link PeerHandle} may be obtained as part of the Wi-Fi Aware discovery process. E.g.
- * using {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], List)}.
- * <p>
- * Note: in order to use this API the device must support Wi-Fi Aware
- * {@link android.net.wifi.aware}. The peer device which is being ranged to must be
- * configured to publish a service (with any name) with:
- * <li>Type {@link android.net.wifi.aware.PublishConfig#PUBLISH_TYPE_UNSOLICITED}.
- * <li>Ranging enabled
- * {@link android.net.wifi.aware.PublishConfig.Builder#setRangingEnabled(boolean)}.
- *
- * @param peerHandle The peer handler of the peer Wi-Fi Aware device.
- * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder addWifiAwarePeer(@NonNull PeerHandle peerHandle) {
- if (peerHandle == null) {
- throw new IllegalArgumentException("Null peer handler (identifier)");
- }
-
- return addResponder(ResponderConfig.fromWifiAwarePeerHandleWithDefaults(peerHandle));
- }
-
- /**
- * Add the Responder device specified by the {@link ResponderConfig} to the list of devices
- * with which to measure range. The total number of peers added to the request cannot exceed
- * the limit specified by {@link #getMaxPeers()}.
- *
- * @param responder Information on the RTT Responder.
- * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
- *
- * @hide
- */
- @SystemApi
- public Builder addResponder(@NonNull ResponderConfig responder) {
- if (responder == null) {
- throw new IllegalArgumentException("Null Responder!");
- }
-
- mRttPeers.add(responder);
- return this;
- }
-
- /**
- * Build {@link RangingRequest} given the current configurations made on the
- * builder.
- */
- public RangingRequest build() {
- return new RangingRequest(mRttPeers);
- }
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof RangingRequest)) {
- return false;
- }
-
- RangingRequest lhs = (RangingRequest) o;
-
- return mRttPeers.size() == lhs.mRttPeers.size() && mRttPeers.containsAll(lhs.mRttPeers);
- }
-
- @Override
- public int hashCode() {
- return mRttPeers.hashCode();
- }
-}
diff --git a/wifi/java/android/net/wifi/rtt/RangingResult.java b/wifi/java/android/net/wifi/rtt/RangingResult.java
deleted file mode 100644
index a065bbc..0000000
--- a/wifi/java/android/net/wifi/rtt/RangingResult.java
+++ /dev/null
@@ -1,438 +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.net.wifi.rtt;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.net.wifi.aware.PeerHandle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Ranging result for a request started by
- * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}.
- * Results are returned in {@link RangingResultCallback#onRangingResults(List)}.
- * <p>
- * A ranging result is the distance measurement result for a single device specified in the
- * {@link RangingRequest}.
- */
-public final class RangingResult implements Parcelable {
- private static final String TAG = "RangingResult";
- private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-
- /** @hide */
- @IntDef({STATUS_SUCCESS, STATUS_FAIL, STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC})
- @Retention(RetentionPolicy.SOURCE)
- public @interface RangeResultStatus {
- }
-
- /**
- * Individual range request status, {@link #getStatus()}. Indicates ranging operation was
- * successful and distance value is valid.
- */
- public static final int STATUS_SUCCESS = 0;
-
- /**
- * Individual range request status, {@link #getStatus()}. Indicates ranging operation failed
- * and the distance value is invalid.
- */
- public static final int STATUS_FAIL = 1;
-
- /**
- * Individual range request status, {@link #getStatus()}. Indicates that the ranging operation
- * failed because the specified peer does not support IEEE 802.11mc RTT operations. Support by
- * an Access Point can be confirmed using
- * {@link android.net.wifi.ScanResult#is80211mcResponder()}.
- * <p>
- * On such a failure, the individual result fields of {@link RangingResult} such as
- * {@link RangingResult#getDistanceMm()} are invalid.
- */
- public static final int STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC = 2;
-
- private final int mStatus;
- private final MacAddress mMac;
- private final PeerHandle mPeerHandle;
- private final int mDistanceMm;
- private final int mDistanceStdDevMm;
- private final int mRssi;
- private final int mNumAttemptedMeasurements;
- private final int mNumSuccessfulMeasurements;
- private final byte[] mLci;
- private final byte[] mLcr;
- private final ResponderLocation mResponderLocation;
- private final long mTimestamp;
-
- /** @hide */
- public RangingResult(@RangeResultStatus int status, @NonNull MacAddress mac, int distanceMm,
- int distanceStdDevMm, int rssi, int numAttemptedMeasurements,
- int numSuccessfulMeasurements, byte[] lci, byte[] lcr,
- ResponderLocation responderLocation, long timestamp) {
- mStatus = status;
- mMac = mac;
- mPeerHandle = null;
- mDistanceMm = distanceMm;
- mDistanceStdDevMm = distanceStdDevMm;
- mRssi = rssi;
- mNumAttemptedMeasurements = numAttemptedMeasurements;
- mNumSuccessfulMeasurements = numSuccessfulMeasurements;
- mLci = lci == null ? EMPTY_BYTE_ARRAY : lci;
- mLcr = lcr == null ? EMPTY_BYTE_ARRAY : lcr;
- mResponderLocation = responderLocation;
- mTimestamp = timestamp;
- }
-
- /** @hide */
- public RangingResult(@RangeResultStatus int status, PeerHandle peerHandle, int distanceMm,
- int distanceStdDevMm, int rssi, int numAttemptedMeasurements,
- int numSuccessfulMeasurements, byte[] lci, byte[] lcr,
- ResponderLocation responderLocation, long timestamp) {
- mStatus = status;
- mMac = null;
- mPeerHandle = peerHandle;
- mDistanceMm = distanceMm;
- mDistanceStdDevMm = distanceStdDevMm;
- mRssi = rssi;
- mNumAttemptedMeasurements = numAttemptedMeasurements;
- mNumSuccessfulMeasurements = numSuccessfulMeasurements;
- mLci = lci == null ? EMPTY_BYTE_ARRAY : lci;
- mLcr = lcr == null ? EMPTY_BYTE_ARRAY : lcr;
- mResponderLocation = responderLocation;
- mTimestamp = timestamp;
- }
-
- /**
- * @return The status of ranging measurement: {@link #STATUS_SUCCESS} in case of success, and
- * {@link #STATUS_FAIL} in case of failure.
- */
- @RangeResultStatus
- public int getStatus() {
- return mStatus;
- }
-
- /**
- * @return The MAC address of the device whose range measurement was requested. Will correspond
- * to the MAC address of the device in the {@link RangingRequest}.
- * <p>
- * Will return a {@code null} for results corresponding to requests issued using a {@code
- * PeerHandle}, i.e. using the {@link RangingRequest.Builder#addWifiAwarePeer(PeerHandle)} API.
- */
- @Nullable
- public MacAddress getMacAddress() {
- return mMac;
- }
-
- /**
- * @return The PeerHandle of the device whose reange measurement was requested. Will correspond
- * to the PeerHandle of the devices requested using
- * {@link RangingRequest.Builder#addWifiAwarePeer(PeerHandle)}.
- * <p>
- * Will return a {@code null} for results corresponding to requests issued using a MAC address.
- */
- @Nullable public PeerHandle getPeerHandle() {
- return mPeerHandle;
- }
-
- /**
- * @return The distance (in mm) to the device specified by {@link #getMacAddress()} or
- * {@link #getPeerHandle()}.
- * <p>
- * Note: the measured distance may be negative for very close devices.
- * <p>
- * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
- * exception.
- */
- public int getDistanceMm() {
- if (mStatus != STATUS_SUCCESS) {
- throw new IllegalStateException(
- "getDistanceMm(): invoked on an invalid result: getStatus()=" + mStatus);
- }
- return mDistanceMm;
- }
-
- /**
- * @return The standard deviation of the measured distance (in mm) to the device specified by
- * {@link #getMacAddress()} or {@link #getPeerHandle()}. The standard deviation is calculated
- * over the measurements executed in a single RTT burst. The number of measurements is returned
- * by {@link #getNumSuccessfulMeasurements()} - 0 successful measurements indicate that the
- * standard deviation is not valid (a valid standard deviation requires at least 2 data points).
- * <p>
- * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
- * exception.
- */
- public int getDistanceStdDevMm() {
- if (mStatus != STATUS_SUCCESS) {
- throw new IllegalStateException(
- "getDistanceStdDevMm(): invoked on an invalid result: getStatus()=" + mStatus);
- }
- return mDistanceStdDevMm;
- }
-
- /**
- * @return The average RSSI, in units of dBm, observed during the RTT measurement.
- * <p>
- * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
- * exception.
- */
- public int getRssi() {
- if (mStatus != STATUS_SUCCESS) {
- throw new IllegalStateException(
- "getRssi(): invoked on an invalid result: getStatus()=" + mStatus);
- }
- return mRssi;
- }
-
- /**
- * @return The number of attempted measurements used in the RTT exchange resulting in this set
- * of results. The number of successful measurements is returned by
- * {@link #getNumSuccessfulMeasurements()} which at most, if there are no errors, will be 1 less
- * that the number of attempted measurements.
- * <p>
- * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
- * exception.
- */
- public int getNumAttemptedMeasurements() {
- if (mStatus != STATUS_SUCCESS) {
- throw new IllegalStateException(
- "getNumAttemptedMeasurements(): invoked on an invalid result: getStatus()="
- + mStatus);
- }
- return mNumAttemptedMeasurements;
- }
-
- /**
- * @return The number of successful measurements used to calculate the distance and standard
- * deviation. If the number of successful measurements if 1 then then standard deviation,
- * returned by {@link #getDistanceStdDevMm()}, is not valid (a 0 is returned for the standard
- * deviation).
- * <p>
- * The total number of measurement attempts is returned by
- * {@link #getNumAttemptedMeasurements()}. The number of successful measurements will be at
- * most 1 less then the number of attempted measurements.
- * <p>
- * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
- * exception.
- */
- public int getNumSuccessfulMeasurements() {
- if (mStatus != STATUS_SUCCESS) {
- throw new IllegalStateException(
- "getNumSuccessfulMeasurements(): invoked on an invalid result: getStatus()="
- + mStatus);
- }
- return mNumSuccessfulMeasurements;
- }
-
- /**
- * @return The unverified responder location represented as {@link ResponderLocation} which
- * captures location information the responder is programmed to broadcast. The responder
- * location is referred to as unverified, because we are relying on the device/site
- * administrator to correctly configure its location data.
- * <p>
- * Will return a {@code null} when the location information cannot be parsed.
- * <p>
- * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
- * exception.
- */
- @Nullable
- public ResponderLocation getUnverifiedResponderLocation() {
- if (mStatus != STATUS_SUCCESS) {
- throw new IllegalStateException(
- "getUnverifiedResponderLocation(): invoked on an invalid result: getStatus()="
- + mStatus);
- }
- return mResponderLocation;
- }
-
- /**
- * @return The Location Configuration Information (LCI) as self-reported by the peer. The format
- * is specified in the IEEE 802.11-2016 specifications, section 9.4.2.22.10.
- * <p>
- * Note: the information is NOT validated - use with caution. Consider validating it with
- * other sources of information before using it.
- *
- * @hide
- */
- @SystemApi
- @NonNull
- public byte[] getLci() {
- if (mStatus != STATUS_SUCCESS) {
- throw new IllegalStateException(
- "getLci(): invoked on an invalid result: getStatus()=" + mStatus);
- }
- return mLci;
- }
-
- /**
- * @return The Location Civic report (LCR) as self-reported by the peer. The format
- * is specified in the IEEE 802.11-2016 specifications, section 9.4.2.22.13.
- * <p>
- * Note: the information is NOT validated - use with caution. Consider validating it with
- * other sources of information before using it.
- *
- * @hide
- */
- @SystemApi
- @NonNull
- public byte[] getLcr() {
- if (mStatus != STATUS_SUCCESS) {
- throw new IllegalStateException(
- "getReportedLocationCivic(): invoked on an invalid result: getStatus()="
- + mStatus);
- }
- return mLcr;
- }
-
- /**
- * @return The timestamp at which the ranging operation was performed. The timestamp is in
- * milliseconds since boot, including time spent in sleep, corresponding to values provided by
- * {@link android.os.SystemClock#elapsedRealtime()}.
- * <p>
- * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
- * exception.
- */
- public long getRangingTimestampMillis() {
- if (mStatus != STATUS_SUCCESS) {
- throw new IllegalStateException(
- "getRangingTimestampMillis(): invoked on an invalid result: getStatus()="
- + mStatus);
- }
- return mTimestamp;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mStatus);
- if (mMac == null) {
- dest.writeBoolean(false);
- } else {
- dest.writeBoolean(true);
- mMac.writeToParcel(dest, flags);
- }
- if (mPeerHandle == null) {
- dest.writeBoolean(false);
- } else {
- dest.writeBoolean(true);
- dest.writeInt(mPeerHandle.peerId);
- }
- dest.writeInt(mDistanceMm);
- dest.writeInt(mDistanceStdDevMm);
- dest.writeInt(mRssi);
- dest.writeInt(mNumAttemptedMeasurements);
- dest.writeInt(mNumSuccessfulMeasurements);
- dest.writeByteArray(mLci);
- dest.writeByteArray(mLcr);
- dest.writeParcelable(mResponderLocation, flags);
- dest.writeLong(mTimestamp);
- }
-
- public static final @android.annotation.NonNull Creator<RangingResult> CREATOR = new Creator<RangingResult>() {
- @Override
- public RangingResult[] newArray(int size) {
- return new RangingResult[size];
- }
-
- @Override
- public RangingResult createFromParcel(Parcel in) {
- int status = in.readInt();
- boolean macAddressPresent = in.readBoolean();
- MacAddress mac = null;
- if (macAddressPresent) {
- mac = MacAddress.CREATOR.createFromParcel(in);
- }
- boolean peerHandlePresent = in.readBoolean();
- PeerHandle peerHandle = null;
- if (peerHandlePresent) {
- peerHandle = new PeerHandle(in.readInt());
- }
- int distanceMm = in.readInt();
- int distanceStdDevMm = in.readInt();
- int rssi = in.readInt();
- int numAttemptedMeasurements = in.readInt();
- int numSuccessfulMeasurements = in.readInt();
- byte[] lci = in.createByteArray();
- byte[] lcr = in.createByteArray();
- ResponderLocation responderLocation =
- in.readParcelable(this.getClass().getClassLoader());
- long timestamp = in.readLong();
- if (peerHandlePresent) {
- return new RangingResult(status, peerHandle, distanceMm, distanceStdDevMm, rssi,
- numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr,
- responderLocation, timestamp);
- } else {
- return new RangingResult(status, mac, distanceMm, distanceStdDevMm, rssi,
- numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr,
- responderLocation, timestamp);
- }
- }
- };
-
- /** @hide */
- @Override
- public String toString() {
- return new StringBuilder("RangingResult: [status=").append(mStatus).append(", mac=").append(
- mMac).append(", peerHandle=").append(
- mPeerHandle == null ? "<null>" : mPeerHandle.peerId).append(", distanceMm=").append(
- mDistanceMm).append(", distanceStdDevMm=").append(mDistanceStdDevMm).append(
- ", rssi=").append(mRssi).append(", numAttemptedMeasurements=").append(
- mNumAttemptedMeasurements).append(", numSuccessfulMeasurements=").append(
- mNumSuccessfulMeasurements).append(", lci=").append(mLci).append(", lcr=").append(
- mLcr).append(", responderLocation=").append(mResponderLocation)
- .append(", timestamp=").append(mTimestamp).append("]").toString();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof RangingResult)) {
- return false;
- }
-
- RangingResult lhs = (RangingResult) o;
-
- return mStatus == lhs.mStatus && Objects.equals(mMac, lhs.mMac) && Objects.equals(
- mPeerHandle, lhs.mPeerHandle) && mDistanceMm == lhs.mDistanceMm
- && mDistanceStdDevMm == lhs.mDistanceStdDevMm && mRssi == lhs.mRssi
- && mNumAttemptedMeasurements == lhs.mNumAttemptedMeasurements
- && mNumSuccessfulMeasurements == lhs.mNumSuccessfulMeasurements
- && Arrays.equals(mLci, lhs.mLci) && Arrays.equals(mLcr, lhs.mLcr)
- && mTimestamp == lhs.mTimestamp
- && Objects.equals(mResponderLocation, lhs.mResponderLocation);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mStatus, mMac, mPeerHandle, mDistanceMm, mDistanceStdDevMm, mRssi,
- mNumAttemptedMeasurements, mNumSuccessfulMeasurements, mLci, mLcr,
- mResponderLocation, mTimestamp);
- }
-}
diff --git a/wifi/java/android/net/wifi/rtt/RangingResultCallback.java b/wifi/java/android/net/wifi/rtt/RangingResultCallback.java
deleted file mode 100644
index fa7d79e..0000000
--- a/wifi/java/android/net/wifi/rtt/RangingResultCallback.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-/**
- * Base class for ranging result callbacks. Should be extended by applications and set when calling
- * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}.
- * If the ranging operation fails in whole (not attempted) then {@link #onRangingFailure(int)}
- * will be called with a failure code. If the ranging operation is performed for each of the
- * requested peers then the {@link #onRangingResults(List)} will be called with the set of
- * results (@link {@link RangingResult}, each of which has its own success/failure code
- * {@link RangingResult#getStatus()}.
- */
-public abstract class RangingResultCallback {
- /** @hide */
- @IntDef({STATUS_CODE_FAIL, STATUS_CODE_FAIL_RTT_NOT_AVAILABLE})
- @Retention(RetentionPolicy.SOURCE)
- public @interface RangingOperationStatus {
- }
-
- /**
- * A failure code for the whole ranging request operation. Indicates a failure.
- */
- public static final int STATUS_CODE_FAIL = 1;
-
- /**
- * A failure code for the whole ranging request operation. Indicates that the request failed due
- * to RTT not being available - e.g. Wi-Fi was disabled. Use the
- * {@link WifiRttManager#isAvailable()} and {@link WifiRttManager#ACTION_WIFI_RTT_STATE_CHANGED}
- * to track RTT availability.
- */
- public static final int STATUS_CODE_FAIL_RTT_NOT_AVAILABLE = 2;
-
- /**
- * Called when a ranging operation failed in whole - i.e. no ranging operation to any of the
- * devices specified in the request was attempted.
- *
- * @param code A status code indicating the type of failure.
- */
- public abstract void onRangingFailure(@RangingOperationStatus int code);
-
- /**
- * Called when a ranging operation was executed. The list of results corresponds to devices
- * specified in the ranging request.
- *
- * @param results List of range measurements, one per requested device.
- */
- public abstract void onRangingResults(@NonNull List<RangingResult> results);
-}
diff --git a/wifi/java/android/net/wifi/rtt/ResponderConfig.java b/wifi/java/android/net/wifi/rtt/ResponderConfig.java
deleted file mode 100644
index be4eecc..0000000
--- a/wifi/java/android/net/wifi/rtt/ResponderConfig.java
+++ /dev/null
@@ -1,514 +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.net.wifi.rtt;
-
-import static android.net.wifi.ScanResult.InformationElement.EID_EXTENSION_PRESENT;
-import static android.net.wifi.ScanResult.InformationElement.EID_EXT_HE_CAPABILITIES;
-import static android.net.wifi.ScanResult.InformationElement.EID_HT_CAPABILITIES;
-import static android.net.wifi.ScanResult.InformationElement.EID_VHT_CAPABILITIES;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.net.wifi.ScanResult;
-import android.net.wifi.aware.PeerHandle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Defines the configuration of an IEEE 802.11mc Responder. The Responder may be an Access Point
- * (AP), a Wi-Fi Aware device, or a manually configured Responder.
- * <p>
- * A Responder configuration may be constructed from a {@link ScanResult} or manually (with the
- * data obtained out-of-band from a peer).
- *
- * @hide
- */
-@SystemApi
-public final class ResponderConfig implements Parcelable {
- private static final String TAG = "ResponderConfig";
- private static final int AWARE_BAND_2_DISCOVERY_CHANNEL = 2437;
-
- /** @hide */
- @IntDef({RESPONDER_AP, RESPONDER_STA, RESPONDER_P2P_GO, RESPONDER_P2P_CLIENT, RESPONDER_AWARE})
- @Retention(RetentionPolicy.SOURCE)
- public @interface ResponderType {
- }
-
- /**
- * Responder is an AP.
- */
- public static final int RESPONDER_AP = 0;
- /**
- * Responder is a STA.
- */
- public static final int RESPONDER_STA = 1;
- /**
- * Responder is a Wi-Fi Direct Group Owner (GO).
- */
- public static final int RESPONDER_P2P_GO = 2;
- /**
- * Responder is a Wi-Fi Direct Group Client.
- */
- public static final int RESPONDER_P2P_CLIENT = 3;
- /**
- * Responder is a Wi-Fi Aware device.
- */
- public static final int RESPONDER_AWARE = 4;
-
-
- /** @hide */
- @IntDef({
- CHANNEL_WIDTH_20MHZ, CHANNEL_WIDTH_40MHZ, CHANNEL_WIDTH_80MHZ, CHANNEL_WIDTH_160MHZ,
- CHANNEL_WIDTH_80MHZ_PLUS_MHZ})
- @Retention(RetentionPolicy.SOURCE)
- public @interface ChannelWidth {
- }
-
- /**
- * Channel bandwidth is 20 MHZ
- */
- public static final int CHANNEL_WIDTH_20MHZ = 0;
- /**
- * Channel bandwidth is 40 MHZ
- */
- public static final int CHANNEL_WIDTH_40MHZ = 1;
- /**
- * Channel bandwidth is 80 MHZ
- */
- public static final int CHANNEL_WIDTH_80MHZ = 2;
- /**
- * Channel bandwidth is 160 MHZ
- */
- public static final int CHANNEL_WIDTH_160MHZ = 3;
- /**
- * Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ
- */
- public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4;
-
- /** @hide */
- @IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT, PREAMBLE_HE})
- @Retention(RetentionPolicy.SOURCE)
- public @interface PreambleType {
- }
-
- /**
- * Preamble type: Legacy.
- */
- public static final int PREAMBLE_LEGACY = 0;
-
- /**
- * Preamble type: HT.
- */
- public static final int PREAMBLE_HT = 1;
-
- /**
- * Preamble type: VHT.
- */
- public static final int PREAMBLE_VHT = 2;
-
- /**
- * Preamble type: HE.
- */
- public static final int PREAMBLE_HE = 3;
-
- /**
- * The MAC address of the Responder. Will be null if a Wi-Fi Aware peer identifier (the
- * peerHandle field) ise used to identify the Responder.
- */
- public final MacAddress macAddress;
-
- /**
- * The peer identifier of a Wi-Fi Aware Responder. Will be null if a MAC Address (the macAddress
- * field) is used to identify the Responder.
- */
- public final PeerHandle peerHandle;
-
- /**
- * The device type of the Responder.
- */
- public final int responderType;
-
- /**
- * Indicates whether the Responder device supports IEEE 802.11mc.
- */
- public final boolean supports80211mc;
-
- /**
- * Responder channel bandwidth, specified using {@link ChannelWidth}.
- */
- public final int channelWidth;
-
- /**
- * The primary 20 MHz frequency (in MHz) of the channel of the Responder.
- */
- public final int frequency;
-
- /**
- * Not used if the {@link #channelWidth} is 20 MHz. If the Responder uses 40, 80 or 160 MHz,
- * this is the center frequency (in MHz), if the Responder uses 80 + 80 MHz, this is the
- * center frequency of the first segment (in MHz).
- */
- public final int centerFreq0;
-
- /**
- * Only used if the {@link #channelWidth} is 80 + 80 MHz. If the Responder uses 80 + 80 MHz,
- * this is the center frequency of the second segment (in MHz).
- */
- public final int centerFreq1;
-
- /**
- * The preamble used by the Responder, specified using {@link PreambleType}.
- */
- public final int preamble;
-
- /**
- * Constructs Responder configuration, using a MAC address to identify the Responder.
- *
- * @param macAddress The MAC address of the Responder.
- * @param responderType The type of the responder device, specified using
- * {@link ResponderType}.
- * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc.
- * @param channelWidth Responder channel bandwidth, specified using {@link ChannelWidth}.
- * @param frequency The primary 20 MHz frequency (in MHz) of the channel of the Responder.
- * @param centerFreq0 Not used if the {@code channelWidth} is 20 MHz. If the Responder uses
- * 40, 80 or 160 MHz, this is the center frequency (in MHz), if the
- * Responder uses 80 + 80 MHz, this is the center frequency of the first
- * segment (in MHz).
- * @param centerFreq1 Only used if the {@code channelWidth} is 80 + 80 MHz. If the
- * Responder
- * uses 80 + 80 MHz, this is the center frequency of the second segment
- * (in
- * MHz).
- * @param preamble The preamble used by the Responder, specified using
- * {@link PreambleType}.
- */
- public ResponderConfig(@NonNull MacAddress macAddress, @ResponderType int responderType,
- boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0,
- int centerFreq1, @PreambleType int preamble) {
- if (macAddress == null) {
- throw new IllegalArgumentException(
- "Invalid ResponderConfig - must specify a MAC address");
- }
- this.macAddress = macAddress;
- this.peerHandle = null;
- this.responderType = responderType;
- this.supports80211mc = supports80211mc;
- this.channelWidth = channelWidth;
- this.frequency = frequency;
- this.centerFreq0 = centerFreq0;
- this.centerFreq1 = centerFreq1;
- this.preamble = preamble;
- }
-
- /**
- * Constructs Responder configuration, using a Wi-Fi Aware PeerHandle to identify the Responder.
- *
- * @param peerHandle The Wi-Fi Aware peer identifier of the Responder.
- * @param responderType The type of the responder device, specified using
- * {@link ResponderType}.
- * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc.
- * @param channelWidth Responder channel bandwidth, specified using {@link ChannelWidth}.
- * @param frequency The primary 20 MHz frequency (in MHz) of the channel of the Responder.
- * @param centerFreq0 Not used if the {@code channelWidth} is 20 MHz. If the Responder uses
- * 40, 80 or 160 MHz, this is the center frequency (in MHz), if the
- * Responder uses 80 + 80 MHz, this is the center frequency of the first
- * segment (in MHz).
- * @param centerFreq1 Only used if the {@code channelWidth} is 80 + 80 MHz. If the
- * Responder
- * uses 80 + 80 MHz, this is the center frequency of the second segment
- * (in
- * MHz).
- * @param preamble The preamble used by the Responder, specified using
- * {@link PreambleType}.
- */
- public ResponderConfig(@NonNull PeerHandle peerHandle, @ResponderType int responderType,
- boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0,
- int centerFreq1, @PreambleType int preamble) {
- this.macAddress = null;
- this.peerHandle = peerHandle;
- this.responderType = responderType;
- this.supports80211mc = supports80211mc;
- this.channelWidth = channelWidth;
- this.frequency = frequency;
- this.centerFreq0 = centerFreq0;
- this.centerFreq1 = centerFreq1;
- this.preamble = preamble;
- }
-
- /**
- * Constructs Responder configuration. This is an internal-only constructor which specifies both
- * a MAC address and a Wi-Fi PeerHandle to identify the Responder.
- *
- * @param macAddress The MAC address of the Responder.
- * @param peerHandle The Wi-Fi Aware peer identifier of the Responder.
- * @param responderType The type of the responder device, specified using
- * {@link ResponderType}.
- * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc.
- * @param channelWidth Responder channel bandwidth, specified using {@link ChannelWidth}.
- * @param frequency The primary 20 MHz frequency (in MHz) of the channel of the Responder.
- * @param centerFreq0 Not used if the {@code channelWidth} is 20 MHz. If the Responder uses
- * 40, 80 or 160 MHz, this is the center frequency (in MHz), if the
- * Responder uses 80 + 80 MHz, this is the center frequency of the first
- * segment (in MHz).
- * @param centerFreq1 Only used if the {@code channelWidth} is 80 + 80 MHz. If the
- * Responder
- * uses 80 + 80 MHz, this is the center frequency of the second segment
- * (in
- * MHz).
- * @param preamble The preamble used by the Responder, specified using
- * {@link PreambleType}.
- * @hide
- */
- public ResponderConfig(@NonNull MacAddress macAddress, @NonNull PeerHandle peerHandle,
- @ResponderType int responderType, boolean supports80211mc,
- @ChannelWidth int channelWidth, int frequency, int centerFreq0, int centerFreq1,
- @PreambleType int preamble) {
- this.macAddress = macAddress;
- this.peerHandle = peerHandle;
- this.responderType = responderType;
- this.supports80211mc = supports80211mc;
- this.channelWidth = channelWidth;
- this.frequency = frequency;
- this.centerFreq0 = centerFreq0;
- this.centerFreq1 = centerFreq1;
- this.preamble = preamble;
- }
-
- /**
- * Creates a Responder configuration from a {@link ScanResult} corresponding to an Access
- * Point (AP), which can be obtained from {@link android.net.wifi.WifiManager#getScanResults()}.
- */
- public static ResponderConfig fromScanResult(ScanResult scanResult) {
- MacAddress macAddress = MacAddress.fromString(scanResult.BSSID);
- int responderType = RESPONDER_AP;
- boolean supports80211mc = scanResult.is80211mcResponder();
- int channelWidth = translateScanResultChannelWidth(scanResult.channelWidth);
- int frequency = scanResult.frequency;
- int centerFreq0 = scanResult.centerFreq0;
- int centerFreq1 = scanResult.centerFreq1;
-
- int preamble;
- if (scanResult.informationElements != null && scanResult.informationElements.length != 0) {
- boolean htCapabilitiesPresent = false;
- boolean vhtCapabilitiesPresent = false;
- boolean heCapabilitiesPresent = false;
-
- for (ScanResult.InformationElement ie : scanResult.informationElements) {
- if (ie.id == EID_HT_CAPABILITIES) {
- htCapabilitiesPresent = true;
- } else if (ie.id == EID_VHT_CAPABILITIES) {
- vhtCapabilitiesPresent = true;
- } else if (ie.id == EID_EXTENSION_PRESENT && ie.idExt == EID_EXT_HE_CAPABILITIES) {
- heCapabilitiesPresent = true;
- }
- }
-
- if (heCapabilitiesPresent) {
- preamble = PREAMBLE_HE;
- } else if (vhtCapabilitiesPresent) {
- preamble = PREAMBLE_VHT;
- } else if (htCapabilitiesPresent) {
- preamble = PREAMBLE_HT;
- } else {
- preamble = PREAMBLE_LEGACY;
- }
- } else {
- Log.e(TAG, "Scan Results do not contain IEs - using backup method to select preamble");
- if (channelWidth == CHANNEL_WIDTH_80MHZ || channelWidth == CHANNEL_WIDTH_160MHZ) {
- preamble = PREAMBLE_VHT;
- } else {
- preamble = PREAMBLE_HT;
- }
- }
-
- return new ResponderConfig(macAddress, responderType, supports80211mc, channelWidth,
- frequency, centerFreq0, centerFreq1, preamble);
- }
-
- /**
- * Creates a Responder configuration from a MAC address corresponding to a Wi-Fi Aware
- * Responder. The Responder parameters are set to defaults.
- */
- public static ResponderConfig fromWifiAwarePeerMacAddressWithDefaults(MacAddress macAddress) {
- /* Note: the parameters are those of the Aware discovery channel (channel 6). A Responder
- * is expected to be brought up and available to negotiate a maximum accuracy channel
- * (i.e. Band 5 @ 80MHz). A Responder is brought up on the peer by starting an Aware
- * Unsolicited Publisher with Ranging enabled.
- */
- return new ResponderConfig(macAddress, RESPONDER_AWARE, true, CHANNEL_WIDTH_20MHZ,
- AWARE_BAND_2_DISCOVERY_CHANNEL, 0, 0, PREAMBLE_HT);
- }
-
- /**
- * Creates a Responder configuration from a {@link PeerHandle} corresponding to a Wi-Fi Aware
- * Responder. The Responder parameters are set to defaults.
- */
- public static ResponderConfig fromWifiAwarePeerHandleWithDefaults(PeerHandle peerHandle) {
- /* Note: the parameters are those of the Aware discovery channel (channel 6). A Responder
- * is expected to be brought up and available to negotiate a maximum accuracy channel
- * (i.e. Band 5 @ 80MHz). A Responder is brought up on the peer by starting an Aware
- * Unsolicited Publisher with Ranging enabled.
- */
- return new ResponderConfig(peerHandle, RESPONDER_AWARE, true, CHANNEL_WIDTH_20MHZ,
- AWARE_BAND_2_DISCOVERY_CHANNEL, 0, 0, PREAMBLE_HT);
- }
-
- /**
- * Check whether the Responder configuration is valid.
- *
- * @return true if valid, false otherwise.
- * @hide
- */
- public boolean isValid(boolean awareSupported) {
- if (macAddress == null && peerHandle == null || macAddress != null && peerHandle != null) {
- return false;
- }
- if (!awareSupported && responderType == RESPONDER_AWARE) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- if (macAddress == null) {
- dest.writeBoolean(false);
- } else {
- dest.writeBoolean(true);
- macAddress.writeToParcel(dest, flags);
- }
- if (peerHandle == null) {
- dest.writeBoolean(false);
- } else {
- dest.writeBoolean(true);
- dest.writeInt(peerHandle.peerId);
- }
- dest.writeInt(responderType);
- dest.writeInt(supports80211mc ? 1 : 0);
- dest.writeInt(channelWidth);
- dest.writeInt(frequency);
- dest.writeInt(centerFreq0);
- dest.writeInt(centerFreq1);
- dest.writeInt(preamble);
- }
-
- public static final @android.annotation.NonNull Creator<ResponderConfig> CREATOR = new Creator<ResponderConfig>() {
- @Override
- public ResponderConfig[] newArray(int size) {
- return new ResponderConfig[size];
- }
-
- @Override
- public ResponderConfig createFromParcel(Parcel in) {
- boolean macAddressPresent = in.readBoolean();
- MacAddress macAddress = null;
- if (macAddressPresent) {
- macAddress = MacAddress.CREATOR.createFromParcel(in);
- }
- boolean peerHandlePresent = in.readBoolean();
- PeerHandle peerHandle = null;
- if (peerHandlePresent) {
- peerHandle = new PeerHandle(in.readInt());
- }
- int responderType = in.readInt();
- boolean supports80211mc = in.readInt() == 1;
- int channelWidth = in.readInt();
- int frequency = in.readInt();
- int centerFreq0 = in.readInt();
- int centerFreq1 = in.readInt();
- int preamble = in.readInt();
-
- if (peerHandle == null) {
- return new ResponderConfig(macAddress, responderType, supports80211mc, channelWidth,
- frequency, centerFreq0, centerFreq1, preamble);
- } else {
- return new ResponderConfig(peerHandle, responderType, supports80211mc, channelWidth,
- frequency, centerFreq0, centerFreq1, preamble);
- }
- }
- };
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof ResponderConfig)) {
- return false;
- }
-
- ResponderConfig lhs = (ResponderConfig) o;
-
- return Objects.equals(macAddress, lhs.macAddress) && Objects.equals(peerHandle,
- lhs.peerHandle) && responderType == lhs.responderType
- && supports80211mc == lhs.supports80211mc && channelWidth == lhs.channelWidth
- && frequency == lhs.frequency && centerFreq0 == lhs.centerFreq0
- && centerFreq1 == lhs.centerFreq1 && preamble == lhs.preamble;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(macAddress, peerHandle, responderType, supports80211mc, channelWidth,
- frequency, centerFreq0, centerFreq1, preamble);
- }
-
- /** @hide */
- @Override
- public String toString() {
- return new StringBuffer("ResponderConfig: macAddress=").append(macAddress).append(
- ", peerHandle=").append(peerHandle == null ? "<null>" : peerHandle.peerId).append(
- ", responderType=").append(responderType).append(", supports80211mc=").append(
- supports80211mc).append(", channelWidth=").append(channelWidth).append(
- ", frequency=").append(frequency).append(", centerFreq0=").append(
- centerFreq0).append(", centerFreq1=").append(centerFreq1).append(
- ", preamble=").append(preamble).toString();
- }
-
- /** @hide */
- static int translateScanResultChannelWidth(int scanResultChannelWidth) {
- switch (scanResultChannelWidth) {
- case ScanResult.CHANNEL_WIDTH_20MHZ:
- return CHANNEL_WIDTH_20MHZ;
- case ScanResult.CHANNEL_WIDTH_40MHZ:
- return CHANNEL_WIDTH_40MHZ;
- case ScanResult.CHANNEL_WIDTH_80MHZ:
- return CHANNEL_WIDTH_80MHZ;
- case ScanResult.CHANNEL_WIDTH_160MHZ:
- return CHANNEL_WIDTH_160MHZ;
- case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ:
- return CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
- default:
- throw new IllegalArgumentException(
- "translateScanResultChannelWidth: bad " + scanResultChannelWidth);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/rtt/ResponderLocation.java b/wifi/java/android/net/wifi/rtt/ResponderLocation.java
deleted file mode 100644
index 218b2dca..0000000
--- a/wifi/java/android/net/wifi/rtt/ResponderLocation.java
+++ /dev/null
@@ -1,1427 +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.net.wifi.rtt;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.location.Address;
-import android.location.Location;
-import android.net.MacAddress;
-import android.net.Uri;
-import android.net.wifi.rtt.CivicLocationKeys.CivicLocationKeysType;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.SparseArray;
-import android.webkit.MimeTypeMap;
-
-import java.lang.annotation.Retention;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * ResponderLocation is both a Location Configuration Information (LCI) decoder and a Location Civic
- * Report (LCR) decoder for information received from a Wi-Fi Access Point (AP) during Wi-Fi RTT
- * ranging process.
- *
- * <p>This is based on the IEEE P802.11-REVmc/D8.0 spec section 9.4.2.22, under Measurement Report
- * Element. Subelement location data-fields parsed from separate input LCI and LCR Information
- * Elements are unified in this class.</p>
- *
- * <p>Note: The information provided by this class is broadcast by a responder (usually an Access
- * Point), and passed on as-is. There is no guarantee this information is accurate or correct, and
- * as a result developers should carefully consider how this information should be used and provide
- * corresponding advice to users.</p>
- */
-public final class ResponderLocation implements Parcelable {
- private static final int BYTE_MASK = 0xFF;
- private static final int LSB_IN_BYTE = 0x01;
- private static final int MSB_IN_BYTE = 0x80;
- private static final int MIN_BUFFER_SIZE = 3; // length of LEAD_LCI_ELEMENT_BYTES
- private static final int MAX_BUFFER_SIZE = 256;
-
- // Information Element (IE) fields
- private static final byte MEASUREMENT_TOKEN_AUTONOMOUS = 0x01;
- private static final byte MEASUREMENT_REPORT_MODE = 0x00;
- private static final byte MEASUREMENT_TYPE_LCI = 0x08;
- private static final byte MEASUREMENT_TYPE_LCR = 0x0b;
-
- // LCI Subelement IDs
- private static final byte SUBELEMENT_LCI = 0x00;
- private static final byte SUBELEMENT_Z = 0x04;
- private static final byte SUBELEMENT_USAGE = 0x06;
- private static final byte SUBELEMENT_BSSID_LIST = 0x07;
-
- // LCI Subelement Lengths
- private static final int SUBELEMENT_LCI_LENGTH = 16;
- private static final int SUBELEMENT_Z_LENGTH = 6;
- private static final int SUBELEMENT_USAGE_LENGTH1 = 1;
- private static final int SUBELEMENT_USAGE_LENGTH3 = 3;
- private static final int SUBELEMENT_BSSID_LIST_MIN_BUFFER_LENGTH = 1;
-
- private static final byte[] LEAD_LCI_ELEMENT_BYTES = {
- MEASUREMENT_TOKEN_AUTONOMOUS, MEASUREMENT_REPORT_MODE, MEASUREMENT_TYPE_LCI
- };
-
- // Subelement LCI constants
-
- /* The LCI subelement bit-field lengths are described in Figure 9-214 of the REVmc spec and
- represented here as a an array of integers */
- private static final int[] SUBELEMENT_LCI_BIT_FIELD_LENGTHS = {
- 6, 34, 6, 34, 4, 6, 30, 3, 1, 1, 1, 2
- };
- private static final int LATLNG_FRACTION_BITS = 25;
- private static final int LATLNG_UNCERTAINTY_BASE = 8;
- private static final int ALTITUDE_FRACTION_BITS = 8;
- private static final int ALTITUDE_UNCERTAINTY_BASE = 21;
- private static final double LAT_ABS_LIMIT = 90.0;
- private static final double LNG_ABS_LIMIT = 180.0;
- private static final int UNCERTAINTY_UNDEFINED = 0;
-
- // Subelement LCI fields indices
- private static final int SUBELEMENT_LCI_LAT_UNCERTAINTY_INDEX = 0;
- private static final int SUBELEMENT_LCI_LAT_INDEX = 1;
- private static final int SUBELEMENT_LCI_LNG_UNCERTAINTY_INDEX = 2;
- private static final int SUBELEMENT_LCI_LNG_INDEX = 3;
- private static final int SUBELEMENT_LCI_ALT_TYPE_INDEX = 4;
- private static final int SUBELEMENT_LCI_ALT_UNCERTAINTY_INDEX = 5;
- private static final int SUBELEMENT_LCI_ALT_INDEX = 6;
- private static final int SUBELEMENT_LCI_DATUM_INDEX = 7;
- private static final int SUBELEMENT_LCI_REGLOC_AGREEMENT_INDEX = 8;
- private static final int SUBELEMENT_LCI_REGLOC_DSE_INDEX = 9;
- private static final int SUBELEMENT_LCI_DEPENDENT_STA_INDEX = 10;
- private static final int SUBELEMENT_LCI_VERSION_INDEX = 11;
-
- /**
- * The Altitude value is interpreted based on the Altitude Type, and the selected mDatum.
- *
- * @hide
- */
- @Retention(SOURCE)
- @IntDef({ALTITUDE_UNDEFINED, ALTITUDE_METERS, ALTITUDE_FLOORS})
- public @interface AltitudeType {
- }
-
- /**
- * Altitude is not defined for the Responder.
- * The altitude and altitude uncertainty should not be used: see section 2.4 of IETF RFC 6225.
- */
- public static final int ALTITUDE_UNDEFINED = 0;
- /** Responder Altitude is measured in meters. */
- public static final int ALTITUDE_METERS = 1;
- /** Responder Altitude is measured in floors. */
- public static final int ALTITUDE_FLOORS = 2;
-
- /**
- * The Datum value determines how coordinates are organized in relation to the real world.
- *
- * @hide
- */
- @Retention(SOURCE)
- @IntDef({DATUM_UNDEFINED, DATUM_WGS84, DATUM_NAD83_NAV88, DATUM_NAD83_MLLW})
- public @interface DatumType {
- }
-
- /** Datum is not defined. */
- public static final int DATUM_UNDEFINED = 0;
- /** Datum used is WGS84. */
- public static final int DATUM_WGS84 = 1;
- /** Datum used is NAD83 NAV88. */
- public static final int DATUM_NAD83_NAV88 = 2;
- /** Datum used is NAD83 MLLW. */
- public static final int DATUM_NAD83_MLLW = 3;
-
-
- /** Version of the LCI protocol is 1.0, the only defined protocol at this time. */
- public static final int LCI_VERSION_1 = 1;
-
- /** Provider/Source of the location */
- private static final String LOCATION_PROVIDER = "WiFi Access Point";
-
- // LCI Subelement Z constants
- private static final int[] SUBELEMENT_Z_BIT_FIELD_LENGTHS = {2, 14, 24, 8};
- private static final int Z_FLOOR_NUMBER_FRACTION_BITS = 4;
- private static final int Z_FLOOR_HEIGHT_FRACTION_BITS = 12;
- private static final int Z_MAX_HEIGHT_UNCERTAINTY_FACTOR = 25;
-
- // LCI Subelement Z fields indices
- private static final int SUBELEMENT_Z_LAT_EXPECTED_TO_MOVE_INDEX = 0;
- private static final int SUBELEMENT_Z_FLOOR_NUMBER_INDEX = 1;
- private static final int SUBELEMENT_Z_HEIGHT_ABOVE_FLOOR_INDEX = 2;
- private static final int SUBELEMENT_Z_HEIGHT_ABOVE_FLOOR_UNCERTAINTY_INDEX = 3;
-
- // LCI Subelement Usage Rules constants
- private static final int SUBELEMENT_USAGE_MASK_RETRANSMIT = 0x01;
- private static final int SUBELEMENT_USAGE_MASK_RETENTION_EXPIRES = 0x02;
- private static final int SUBELEMENT_USAGE_MASK_STA_LOCATION_POLICY = 0x04;
-
- // LCI Subelement Usage Rules field indices
- private static final int SUBELEMENT_USAGE_PARAMS_INDEX = 0; // 8 bits
-
- // LCI Subelement BSSID List
- private static final int SUBELEMENT_BSSID_MAX_INDICATOR_INDEX = 0;
- private static final int SUBELEMENT_BSSID_LIST_INDEX = 1;
- private static final int BYTES_IN_A_BSSID = 6;
-
- /**
- * The Expected-To-Move value determines how mobile we expect the STA to be.
- *
- * @hide
- */
- @Retention(SOURCE)
- @IntDef({LOCATION_FIXED, LOCATION_VARIABLE, LOCATION_MOVEMENT_UNKNOWN, LOCATION_RESERVED})
- public @interface ExpectedToMoveType {
- }
-
- /** Location of responder is fixed (does not move) */
- public static final int LOCATION_FIXED = 0;
- /** Location of the responder is variable, and may move */
- public static final int LOCATION_VARIABLE = 1;
- /** Location of the responder is not known to be either fixed or variable. */
- public static final int LOCATION_MOVEMENT_UNKNOWN = 2;
- /** Location of the responder status is a reserved value */
- public static final int LOCATION_RESERVED = 3;
-
- // LCR Subelement IDs
- private static final byte SUBELEMENT_LOCATION_CIVIC = 0x00;
- private static final byte SUBELEMENT_MAP_IMAGE = 0x05;
-
- // LCR Subelement Lengths
- private static final int SUBELEMENT_LOCATION_CIVIC_MIN_LENGTH = 2;
- private static final int SUBELEMENT_LOCATION_CIVIC_MAX_LENGTH = 256;
- private static final int SUBELEMENT_MAP_IMAGE_URL_MAX_LENGTH = 256;
-
- private static final byte[] LEAD_LCR_ELEMENT_BYTES = {
- MEASUREMENT_TOKEN_AUTONOMOUS, MEASUREMENT_REPORT_MODE, MEASUREMENT_TYPE_LCR
- };
-
- // LCR Location Civic Subelement
- private static final int CIVIC_COUNTRY_CODE_INDEX = 0;
- private static final int CIVIC_TLV_LIST_INDEX = 2;
-
- // LCR Map Image Subelement field indexes.
- private static final int SUBELEMENT_IMAGE_MAP_TYPE_INDEX = 0;
- private static final int MAP_TYPE_URL_DEFINED = 0;
- private static final String[] SUPPORTED_IMAGE_FILE_EXTENSIONS = {
- "",
- "png",
- "gif",
- "jpg",
- "svg",
- "dxf",
- "dwg",
- "dwf",
- "cad",
- "tif",
- "gml",
- "kml",
- "bmp",
- "pgm",
- "ppm",
- "xbm",
- "xpm",
- "ico"
- };
-
- // General LCI and LCR state
- private final boolean mIsValid;
-
- /*
- These members are not final because we are not sure if the corresponding subelement will be
- present until after the parsing process. However, the default value should be set as listed.
- */
- private boolean mIsLciValid = false;
- private boolean mIsZValid = false;
- private boolean mIsUsageValid = true; // By default this is assumed true
- private boolean mIsBssidListValid = false;
- private boolean mIsLocationCivicValid = false;
- private boolean mIsMapImageValid = false;
-
- // LCI Subelement LCI state
- private double mLatitudeUncertainty;
- private double mLatitude;
- private double mLongitudeUncertainty;
- private double mLongitude;
- private int mAltitudeType;
- private double mAltitudeUncertainty;
- private double mAltitude;
- private int mDatum;
- private boolean mLciRegisteredLocationAgreement;
- private boolean mLciRegisteredLocationDse;
- private boolean mLciDependentStation;
- private int mLciVersion;
-
- // LCI Subelement Z state
- private int mExpectedToMove;
- private double mFloorNumber;
- private double mHeightAboveFloorMeters;
- private double mHeightAboveFloorUncertaintyMeters;
-
- // LCI Subelement Usage Rights state
- private boolean mUsageRetransmit;
- private boolean mUsageRetentionExpires;
- private boolean mUsageExtraInfoOnAssociation;
-
- // LCI Subelement BSSID List state
- private ArrayList<MacAddress> mBssidList;
-
- // LCR Subelement Location Civic state
- private String mCivicLocationCountryCode;
- private String mCivicLocationString;
- private CivicLocation mCivicLocation;
-
- // LCR Subelement Map Image state
- private int mMapImageType;
- private Uri mMapImageUri;
-
- /**
- * Constructor
- *
- * @param lciBuffer the bytes received in the LCI Measurement Report Information Element
- * @param lcrBuffer the bytes received in the LCR Measurement Report Information Element
- *
- * @hide
- */
- public ResponderLocation(byte[] lciBuffer, byte[] lcrBuffer) {
- boolean isLciIeValid = false;
- boolean isLcrIeValid = false;
- setLciSubelementDefaults();
- setZaxisSubelementDefaults();
- setUsageSubelementDefaults();
- setBssidListSubelementDefaults();
- setCivicLocationSubelementDefaults();
- setMapImageSubelementDefaults();
- if (lciBuffer != null && lciBuffer.length > LEAD_LCI_ELEMENT_BYTES.length) {
- isLciIeValid = parseInformationElementBuffer(
- MEASUREMENT_TYPE_LCI, lciBuffer, LEAD_LCI_ELEMENT_BYTES);
- }
- if (lcrBuffer != null && lcrBuffer.length > LEAD_LCR_ELEMENT_BYTES.length) {
- isLcrIeValid = parseInformationElementBuffer(
- MEASUREMENT_TYPE_LCR, lcrBuffer, LEAD_LCR_ELEMENT_BYTES);
- }
-
- boolean isLciValid = isLciIeValid && mIsUsageValid
- && (mIsLciValid || mIsZValid || mIsBssidListValid);
-
- boolean isLcrValid = isLcrIeValid && mIsUsageValid
- && (mIsLocationCivicValid || mIsMapImageValid);
-
- mIsValid = isLciValid || isLcrValid;
-
- if (!mIsValid) {
- setLciSubelementDefaults();
- setZaxisSubelementDefaults();
- setCivicLocationSubelementDefaults();
- setMapImageSubelementDefaults();
- }
- }
-
- private ResponderLocation(Parcel in) {
- // Object Validation
- mIsValid = in.readByte() != 0;
- mIsLciValid = in.readByte() != 0;
- mIsZValid = in.readByte() != 0;
- mIsUsageValid = in.readByte() != 0;
- mIsBssidListValid = in.readByte() != 0;
- mIsLocationCivicValid = in.readByte() != 0;
- mIsMapImageValid = in.readByte() != 0;
-
- // LCI Subelement LCI state
- mLatitudeUncertainty = in.readDouble();
- mLatitude = in.readDouble();
- mLongitudeUncertainty = in.readDouble();
- mLongitude = in.readDouble();
- mAltitudeType = in.readInt();
- mAltitudeUncertainty = in.readDouble();
- mAltitude = in.readDouble();
- mDatum = in.readInt();
- mLciRegisteredLocationAgreement = in.readByte() != 0;
- mLciRegisteredLocationDse = in.readByte() != 0;
- mLciDependentStation = in.readByte() != 0;
- mLciVersion = in.readInt();
-
- // LCI Subelement Z state
- mExpectedToMove = in.readInt();
- mFloorNumber = in.readDouble();
- mHeightAboveFloorMeters = in.readDouble();
- mHeightAboveFloorUncertaintyMeters = in.readDouble();
-
- // LCI Usage Rights
- mUsageRetransmit = in.readByte() != 0;
- mUsageRetentionExpires = in.readByte() != 0;
- mUsageExtraInfoOnAssociation = in.readByte() != 0;
-
- // LCI Subelement BSSID List
- mBssidList = in.readArrayList(MacAddress.class.getClassLoader());
-
- // LCR Subelement Location Civic
- mCivicLocationCountryCode = in.readString();
- mCivicLocationString = in.readString();
- mCivicLocation = in.readParcelable(this.getClass().getClassLoader());
-
- // LCR Subelement Map Image
- mMapImageType = in.readInt();
- String urlString = in.readString();
- if (TextUtils.isEmpty(urlString)) {
- mMapImageUri = null;
- } else {
- mMapImageUri = Uri.parse(urlString);
- }
- }
-
- public static final @android.annotation.NonNull Creator<ResponderLocation> CREATOR = new Creator<ResponderLocation>() {
- @Override
- public ResponderLocation createFromParcel(Parcel in) {
- return new ResponderLocation(in);
- }
-
- @Override
- public ResponderLocation[] newArray(int size) {
- return new ResponderLocation[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel parcel, int flags) {
- // Object
- parcel.writeByte((byte) (mIsValid ? 1 : 0));
- parcel.writeByte((byte) (mIsLciValid ? 1 : 0));
- parcel.writeByte((byte) (mIsZValid ? 1 : 0));
- parcel.writeByte((byte) (mIsUsageValid ? 1 : 0));
- parcel.writeByte((byte) (mIsBssidListValid ? 1 : 0));
- parcel.writeByte((byte) (mIsLocationCivicValid ? 1 : 0));
- parcel.writeByte((byte) (mIsMapImageValid ? 1 : 0));
-
- // LCI Subelement LCI state
- parcel.writeDouble(mLatitudeUncertainty);
- parcel.writeDouble(mLatitude);
- parcel.writeDouble(mLongitudeUncertainty);
- parcel.writeDouble(mLongitude);
- parcel.writeInt(mAltitudeType);
- parcel.writeDouble(mAltitudeUncertainty);
- parcel.writeDouble(mAltitude);
- parcel.writeInt(mDatum);
- parcel.writeByte((byte) (mLciRegisteredLocationAgreement ? 1 : 0));
- parcel.writeByte((byte) (mLciRegisteredLocationDse ? 1 : 0));
- parcel.writeByte((byte) (mLciDependentStation ? 1 : 0));
- parcel.writeInt(mLciVersion);
-
- // LCI Subelement Z state
- parcel.writeInt(mExpectedToMove);
- parcel.writeDouble(mFloorNumber);
- parcel.writeDouble(mHeightAboveFloorMeters);
- parcel.writeDouble(mHeightAboveFloorUncertaintyMeters);
-
- // LCI Usage Rights
- parcel.writeByte((byte) (mUsageRetransmit ? 1 : 0));
- parcel.writeByte((byte) (mUsageRetentionExpires ? 1 : 0));
- parcel.writeByte((byte) (mUsageExtraInfoOnAssociation ? 1 : 0));
-
- // LCI Subelement BSSID List
- parcel.writeList(mBssidList);
-
- // LCR Subelement Location Civic
- parcel.writeString(mCivicLocationCountryCode);
- parcel.writeString(mCivicLocationString);
- parcel.writeParcelable(mCivicLocation, flags);
-
- // LCR Subelement Map Image
- parcel.writeInt(mMapImageType);
- if (mMapImageUri != null) {
- parcel.writeString(mMapImageUri.toString());
- } else {
- parcel.writeString("");
- }
- }
-
- /**
- * Test if the Information Element (IE) is in the correct format, and then parse its Subelements
- * based on their type, and setting state in this object when present.
- *
- * @return a boolean indicating the success of the parsing function
- */
- private boolean parseInformationElementBuffer(
- int ieType, byte[] buffer, byte[] expectedLeadBytes) {
- int bufferPtr = 0;
- int bufferLength = buffer.length;
-
- // Ensure the buffer size is within expected limits
- if (bufferLength < MIN_BUFFER_SIZE || bufferLength > MAX_BUFFER_SIZE) {
- return false;
- }
-
- // Ensure the IE contains the correct leading bytes
- byte[] leadBufferBytes = Arrays.copyOfRange(buffer, bufferPtr, expectedLeadBytes.length);
- if (!Arrays.equals(leadBufferBytes, expectedLeadBytes)) {
- return false;
- }
-
- // Iterate through the sub-elements contained in the Information Element (IE)
- bufferPtr += expectedLeadBytes.length;
- // Loop over the buffer ensuring there are 2-bytes available for each new subelement tested.
- while (bufferPtr + 1 < bufferLength) {
- byte subelement = buffer[bufferPtr++];
- int subelementLength = buffer[bufferPtr++];
- // Check there is enough data for the next subelement
- if ((bufferPtr + subelementLength) > bufferLength || subelementLength <= 0) {
- return false;
- }
-
- byte[] subelementData =
- Arrays.copyOfRange(buffer, bufferPtr, bufferPtr + subelementLength);
-
- if (ieType == MEASUREMENT_TYPE_LCI) {
- switch (subelement) {
- case SUBELEMENT_LCI:
- mIsLciValid = parseSubelementLci(subelementData);
- if (!mIsLciValid || mLciVersion != LCI_VERSION_1) {
- setLciSubelementDefaults();
- }
- break;
- case SUBELEMENT_Z:
- mIsZValid = parseSubelementZ(subelementData);
- if (!mIsZValid) {
- setZaxisSubelementDefaults();
- }
- break;
- case SUBELEMENT_USAGE:
- mIsUsageValid = parseSubelementUsage(subelementData);
- // Note: if the Usage Subelement is not valid, don't reset the state, as
- // it is now indicating the whole ResponderLocation is invalid.
- break;
- case SUBELEMENT_BSSID_LIST:
- mIsBssidListValid = parseSubelementBssidList(subelementData);
- if (!mIsBssidListValid) {
- setBssidListSubelementDefaults();
- }
- break;
- default:
- break; // skip over unused or vendor specific subelements
- }
- } else if (ieType == MEASUREMENT_TYPE_LCR) {
- switch (subelement) {
- case SUBELEMENT_LOCATION_CIVIC:
- mIsLocationCivicValid = parseSubelementLocationCivic(subelementData);
- if (!mIsLocationCivicValid) {
- setCivicLocationSubelementDefaults();
- }
- break;
- case SUBELEMENT_MAP_IMAGE:
- mIsMapImageValid = parseSubelementMapImage(subelementData);
- if (!mIsMapImageValid) {
- setMapImageSubelementDefaults();
- }
- break;
- default:
- break; // skip over unused or other vendor specific subelements
- }
- }
-
- bufferPtr += subelementLength;
- }
- return true;
- }
-
- /**
- * Parse the LCI Sub-Element in the LCI Information Element (IE).
- *
- * @param buffer a buffer containing the subelement
- * @return boolean true indicates success
- */
- private boolean parseSubelementLci(byte[] buffer) {
- if (buffer.length > SUBELEMENT_LCI_LENGTH) {
- return false;
- }
- swapEndianByteByByte(buffer);
- long[] subelementLciFields = getFieldData(buffer, SUBELEMENT_LCI_BIT_FIELD_LENGTHS);
- if (subelementLciFields == null) {
- return false;
- }
- // Set member state based on parsed buffer data
- mLatitudeUncertainty = decodeLciLatLngUncertainty(
- subelementLciFields[SUBELEMENT_LCI_LAT_UNCERTAINTY_INDEX]);
- mLatitude = decodeLciLatLng(subelementLciFields, SUBELEMENT_LCI_BIT_FIELD_LENGTHS,
- SUBELEMENT_LCI_LAT_INDEX, LAT_ABS_LIMIT);
- mLongitudeUncertainty = decodeLciLatLngUncertainty(
- subelementLciFields[SUBELEMENT_LCI_LNG_UNCERTAINTY_INDEX]);
- mLongitude =
- decodeLciLatLng(subelementLciFields, SUBELEMENT_LCI_BIT_FIELD_LENGTHS,
- SUBELEMENT_LCI_LNG_INDEX, LNG_ABS_LIMIT);
- mAltitudeType = (int) subelementLciFields[SUBELEMENT_LCI_ALT_TYPE_INDEX] & BYTE_MASK;
- mAltitudeUncertainty =
- decodeLciAltUncertainty(subelementLciFields[SUBELEMENT_LCI_ALT_UNCERTAINTY_INDEX]);
- mAltitude =
- Math.scalb(subelementLciFields[SUBELEMENT_LCI_ALT_INDEX], -ALTITUDE_FRACTION_BITS);
- mDatum = (int) subelementLciFields[SUBELEMENT_LCI_DATUM_INDEX] & BYTE_MASK;
- mLciRegisteredLocationAgreement =
- (subelementLciFields[SUBELEMENT_LCI_REGLOC_AGREEMENT_INDEX] == 1);
- mLciRegisteredLocationDse =
- (subelementLciFields[SUBELEMENT_LCI_REGLOC_DSE_INDEX] == 1);
- mLciDependentStation =
- (subelementLciFields[SUBELEMENT_LCI_DEPENDENT_STA_INDEX] == 1);
- mLciVersion = (int) subelementLciFields[SUBELEMENT_LCI_VERSION_INDEX];
- return true;
- }
-
- /**
- * Decode the floating point value of an encoded lat or lng in the LCI subelement field.
- *
- * @param fields the array of field data represented as longs
- * @param bitFieldSizes the lengths of each field
- * @param offset the offset of the field being decoded
- * @param limit the maximum absolute value (note: different for lat vs lng)
- * @return the floating point value of the lat or lng
- */
- private double decodeLciLatLng(long[] fields, int[] bitFieldSizes, int offset, double limit) {
- double angle;
- if ((fields[offset] & (long) Math.pow(2, bitFieldSizes[offset] - 1)) != 0) {
- // Negative 2's complement value
- // Note: The Math.pow(...) method cannot return a NaN value because the bitFieldSize
- // for Lat or Lng is limited to exactly 34 bits.
- angle = Math.scalb((double) fields[offset] - Math.pow(2, bitFieldSizes[offset]),
- -LATLNG_FRACTION_BITS);
- } else {
- // Positive 2's complement value
- angle = Math.scalb((double) fields[offset], -LATLNG_FRACTION_BITS);
- }
- if (angle > limit) {
- angle = limit;
- } else if (angle < -limit) {
- angle = -limit;
- }
- return angle;
- }
-
- /**
- * Coverts an encoded Lat/Lng uncertainty into a number of degrees.
- *
- * @param encodedValue the encoded uncertainty
- * @return the value in degrees
- */
- private double decodeLciLatLngUncertainty(long encodedValue) {
- return Math.pow(2, LATLNG_UNCERTAINTY_BASE - encodedValue);
- }
-
- /**
- * Converts an encoded Alt uncertainty into a number of degrees.
- *
- * @param encodedValue the encoded uncertainty
- * @return the value in degrees
- */
- private double decodeLciAltUncertainty(long encodedValue) {
- return Math.pow(2, ALTITUDE_UNCERTAINTY_BASE - encodedValue);
- }
-
- /**
- * Parse the Z subelement of the LCI IE.
- *
- * @param buffer a buffer containing the subelement
- * @return boolean true indicates success
- */
- private boolean parseSubelementZ(byte[] buffer) {
- if (buffer.length != SUBELEMENT_Z_LENGTH) {
- return false;
- }
- swapEndianByteByByte(buffer);
- long[] subelementZFields = getFieldData(buffer, SUBELEMENT_Z_BIT_FIELD_LENGTHS);
- if (subelementZFields == null) {
- return false;
- }
-
- mExpectedToMove =
- (int) subelementZFields[SUBELEMENT_Z_LAT_EXPECTED_TO_MOVE_INDEX] & BYTE_MASK;
- mFloorNumber = decodeZUnsignedToSignedValue(subelementZFields,
- SUBELEMENT_Z_BIT_FIELD_LENGTHS, SUBELEMENT_Z_FLOOR_NUMBER_INDEX,
- Z_FLOOR_NUMBER_FRACTION_BITS);
-
- mHeightAboveFloorMeters = decodeZUnsignedToSignedValue(subelementZFields,
- SUBELEMENT_Z_BIT_FIELD_LENGTHS, SUBELEMENT_Z_HEIGHT_ABOVE_FLOOR_INDEX,
- Z_FLOOR_HEIGHT_FRACTION_BITS);
-
- long zHeightUncertainty =
- subelementZFields[SUBELEMENT_Z_HEIGHT_ABOVE_FLOOR_UNCERTAINTY_INDEX];
- if (zHeightUncertainty > 0 && zHeightUncertainty < Z_MAX_HEIGHT_UNCERTAINTY_FACTOR) {
- mHeightAboveFloorUncertaintyMeters =
- Math.pow(2, Z_FLOOR_HEIGHT_FRACTION_BITS - zHeightUncertainty - 1);
- } else {
- return false;
- }
- return true;
- }
-
- /**
- * Decode a two's complement encoded value, to a signed double based on the field length.
- *
- * @param fieldValues the array of field values reprented as longs
- * @param fieldLengths the array of field lengths
- * @param index the index of the field being decoded
- * @param fraction the number of fractional bits in the value
- * @return the signed value represented as a double
- */
- private double decodeZUnsignedToSignedValue(long[] fieldValues, int[] fieldLengths, int index,
- int fraction) {
- int value = (int) fieldValues[index];
- int maxPositiveValue = (int) Math.pow(2, fieldLengths[index] - 1) - 1;
- if (value > maxPositiveValue) {
- value -= Math.pow(2, fieldLengths[index]);
- }
- return Math.scalb(value, -fraction);
- }
-
- /**
- * Parse Subelement Usage Rights
- */
- private boolean parseSubelementUsage(byte[] buffer) {
- if (buffer.length != SUBELEMENT_USAGE_LENGTH1
- && buffer.length != SUBELEMENT_USAGE_LENGTH3) {
- return false;
- }
- mUsageRetransmit =
- (buffer[SUBELEMENT_USAGE_PARAMS_INDEX] & SUBELEMENT_USAGE_MASK_RETRANSMIT) != 0;
- mUsageRetentionExpires =
- (buffer[SUBELEMENT_USAGE_PARAMS_INDEX] & SUBELEMENT_USAGE_MASK_RETENTION_EXPIRES)
- != 0;
- mUsageExtraInfoOnAssociation =
- (buffer[SUBELEMENT_USAGE_PARAMS_INDEX] & SUBELEMENT_USAGE_MASK_STA_LOCATION_POLICY)
- != 0;
- // Note: the Retransmit flag must be true, and RetentionExpires, false for the
- // ResponderLocation object to be usable by public applications.
- return (mUsageRetransmit && !mUsageRetentionExpires);
- }
-
- /**
- * Parse the BSSID List Subelement of the LCI IE.
- *
- * @param buffer a buffer containing the subelement
- * @return boolean true indicates success
- */
- private boolean parseSubelementBssidList(byte[] buffer) {
- if (buffer.length < SUBELEMENT_BSSID_LIST_MIN_BUFFER_LENGTH) {
- return false;
- }
- if ((buffer.length - 1) % BYTES_IN_A_BSSID != 0) {
- return false;
- }
-
- int maxBssidIndicator = (int) buffer[SUBELEMENT_BSSID_MAX_INDICATOR_INDEX] & BYTE_MASK;
- int bssidListLength = (buffer.length - 1) / BYTES_IN_A_BSSID;
- // The maxBSSIDIndicator is ignored. Its use is still being clarified in 802.11REVmd,
- // which is not published at this time. This field will be used in a future
- // release of Android after 802.11REVmd is public. Here, we interpret the following
- // params as an explicit list of BSSIDs.
-
-
- int bssidOffset = SUBELEMENT_BSSID_LIST_INDEX;
- for (int i = 0; i < bssidListLength; i++) {
- byte[] bssid = Arrays.copyOfRange(buffer, bssidOffset, bssidOffset + BYTES_IN_A_BSSID);
- MacAddress macAddress = MacAddress.fromBytes(bssid);
- mBssidList.add(macAddress);
- bssidOffset += BYTES_IN_A_BSSID;
- }
- return true;
- }
-
- /**
- * Parse the Location Civic subelement in the LCR IE.
- *
- * @param buffer a buffer containing the subelement
- * @return boolean true indicates success
- */
- private boolean parseSubelementLocationCivic(byte[] buffer) {
- if (buffer.length < SUBELEMENT_LOCATION_CIVIC_MIN_LENGTH
- || buffer.length > SUBELEMENT_LOCATION_CIVIC_MAX_LENGTH) {
- return false;
- }
- mCivicLocationCountryCode =
- new String(Arrays.copyOfRange(buffer, CIVIC_COUNTRY_CODE_INDEX,
- CIVIC_TLV_LIST_INDEX)).toUpperCase();
- CivicLocation civicLocation =
- new CivicLocation(
- Arrays.copyOfRange(buffer, CIVIC_TLV_LIST_INDEX, buffer.length),
- mCivicLocationCountryCode);
- if (!civicLocation.isValid()) {
- return false;
- }
- this.mCivicLocation = civicLocation;
- mCivicLocationString = civicLocation.toString();
- return true;
- }
-
- /**
- * Parse the Map Image subelement in the LCR IE.
- *
- * @param buffer a buffer containing the subelement
- * @return boolean true indicates success
- */
- private boolean parseSubelementMapImage(byte[] buffer) {
- if (buffer.length > SUBELEMENT_MAP_IMAGE_URL_MAX_LENGTH) {
- return false;
- }
- int mapImageType = buffer[SUBELEMENT_IMAGE_MAP_TYPE_INDEX];
- int supportedTypesMax = SUPPORTED_IMAGE_FILE_EXTENSIONS.length - 1;
- if (mapImageType < MAP_TYPE_URL_DEFINED || mapImageType > supportedTypesMax) {
- return false;
- }
- this.mMapImageType = mapImageType;
- byte[] urlBytes = Arrays.copyOfRange(buffer, 1, buffer.length);
- mMapImageUri = Uri.parse(new String(urlBytes, StandardCharsets.UTF_8));
- return true;
- }
-
- /**
- * Convert an image type code to a Mime type
- *
- * @param imageTypeCode encoded as an integer
- * @return the mime type of the image file
- */
- private String imageTypeToMime(int imageTypeCode, String imageUrl) {
- int supportedExtensionsMax = SUPPORTED_IMAGE_FILE_EXTENSIONS.length - 1;
- if ((imageTypeCode == 0 && imageUrl == null) || imageTypeCode > supportedExtensionsMax) {
- return null;
- }
- MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
- if (imageTypeCode == 0) {
- return mimeTypeMap.getMimeTypeFromExtension(
- MimeTypeMap.getFileExtensionFromUrl(imageUrl));
- } else {
- return mimeTypeMap.getMimeTypeFromExtension(
- SUPPORTED_IMAGE_FILE_EXTENSIONS[imageTypeCode]);
- }
- }
-
- /**
- * Converts a byte array containing fields of variable size, into an array of longs where the
- * field boundaries are defined in a constant int array passed as an argument.
- *
- * @param buffer the byte array containing all the fields
- * @param bitFieldSizes the int array defining the size of each field
- */
- private long[] getFieldData(byte[] buffer, int[] bitFieldSizes) {
- int bufferLengthBits = buffer.length * Byte.SIZE;
- int sumBitFieldSizes = 0;
- for (int i : bitFieldSizes) {
- if (i > Long.SIZE) {
- return null;
- }
- sumBitFieldSizes += i;
- }
- if (bufferLengthBits != sumBitFieldSizes) {
- return null;
- }
- long[] fieldData = new long[bitFieldSizes.length];
- int bufferBitPos = 0;
- for (int fieldIndex = 0; fieldIndex < bitFieldSizes.length; fieldIndex++) {
- int bitFieldSize = bitFieldSizes[fieldIndex];
- long field = 0;
- for (int n = 0; n < bitFieldSize; n++) {
- field |= ((long) getBitAtBitOffsetInByteArray(buffer, bufferBitPos + n) << n);
- }
- fieldData[fieldIndex] = field;
- bufferBitPos += bitFieldSize;
- }
- return fieldData;
- }
-
- /**
- * Retrieves state of a bit at the bit-offset in a byte array, where the offset represents the
- * bytes in contiguous data with each value in big endian order.
- *
- * @param buffer the data buffer of bytes containing all the fields
- * @param bufferBitOffset the bit offset into the entire buffer
- * @return a zero or one value, representing the state of that bit.
- */
- private int getBitAtBitOffsetInByteArray(byte[] buffer, int bufferBitOffset) {
- int bufferIndex = bufferBitOffset / Byte.SIZE; // The byte index that contains the bit
- int bitOffsetInByte = bufferBitOffset % Byte.SIZE; // The bit offset within that byte
- int result = (buffer[bufferIndex] & (MSB_IN_BYTE >> bitOffsetInByte)) == 0 ? 0 : 1;
- return result;
- }
-
- /**
- * Reverses the order of the bits in each byte of a byte array.
- *
- * @param buffer the array containing each byte that will be reversed
- */
- private void swapEndianByteByByte(byte[] buffer) {
- for (int n = 0; n < buffer.length; n++) {
- byte currentByte = buffer[n];
- byte reversedByte = 0; // Cleared value
- byte bitSelectorMask = LSB_IN_BYTE;
- for (int i = 0; i < Byte.SIZE; i++) {
- reversedByte = (byte) (reversedByte << 1);
- if ((currentByte & bitSelectorMask) != 0) {
- reversedByte = (byte) (reversedByte | LSB_IN_BYTE);
- }
- bitSelectorMask = (byte) (bitSelectorMask << 1);
- }
- buffer[n] = reversedByte;
- }
- }
-
- /**
- * Sets the LCI subelement fields to the default undefined values.
- */
- private void setLciSubelementDefaults() {
- mIsLciValid = false;
- mLatitudeUncertainty = UNCERTAINTY_UNDEFINED;
- mLatitude = 0;
- mLongitudeUncertainty = UNCERTAINTY_UNDEFINED;
- mLongitude = 0;
- mAltitudeType = ALTITUDE_UNDEFINED;
- mAltitudeUncertainty = UNCERTAINTY_UNDEFINED;
- mAltitude = 0;
- mDatum = DATUM_UNDEFINED;
- mLciRegisteredLocationAgreement = false;
- mLciRegisteredLocationDse = false;
- mLciDependentStation = false;
- mLciVersion = 0;
- }
-
- /**
- * Sets the Z subelement fields to the default values when undefined.
- */
- private void setZaxisSubelementDefaults() {
- mIsZValid = false;
- mExpectedToMove = 0;
- mFloorNumber = 0;
- mHeightAboveFloorMeters = 0;
- mHeightAboveFloorUncertaintyMeters = 0;
- }
-
- /**
- * Sets the Usage Policy subelement fields to the default undefined values.
- */
- private void setUsageSubelementDefaults() {
- mUsageRetransmit = true;
- mUsageRetentionExpires = false;
- mUsageExtraInfoOnAssociation = false;
- }
-
- /**
- * Sets the BSSID List subelement fields to the default values when undefined.
- */
- private void setBssidListSubelementDefaults() {
- mIsBssidListValid = false;
- mBssidList = new ArrayList<>();
- }
-
- /**
- * Sets the LCR Civic Location subelement field to the default undefined value.
- *
- * @hide
- */
- public void setCivicLocationSubelementDefaults() {
- mIsLocationCivicValid = false;
- mCivicLocationCountryCode = "";
- mCivicLocationString = "";
- mCivicLocation = null;
- }
-
- /**
- * Sets the LCR Map Image subelement field to the default values when undefined.
- */
- private void setMapImageSubelementDefaults() {
- mIsMapImageValid = false;
- mMapImageType = MAP_TYPE_URL_DEFINED;
- mMapImageUri = null;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- ResponderLocation other = (ResponderLocation) obj;
- return mIsValid == other.mIsValid
- && mIsLciValid == other.mIsLciValid
- && mIsZValid == other.mIsZValid
- && mIsUsageValid == other.mIsUsageValid
- && mIsBssidListValid == other.mIsBssidListValid
- && mIsLocationCivicValid == other.mIsLocationCivicValid
- && mIsMapImageValid == other.mIsMapImageValid
- && mLatitudeUncertainty == other.mLatitudeUncertainty
- && mLatitude == other.mLatitude
- && mLongitudeUncertainty == other.mLongitudeUncertainty
- && mLongitude == other.mLongitude
- && mAltitudeType == other.mAltitudeType
- && mAltitudeUncertainty == other.mAltitudeUncertainty
- && mAltitude == other.mAltitude
- && mDatum == other.mDatum
- && mLciRegisteredLocationAgreement == other.mLciRegisteredLocationAgreement
- && mLciRegisteredLocationDse == other.mLciRegisteredLocationDse
- && mLciDependentStation == other.mLciDependentStation
- && mLciVersion == other.mLciVersion
- && mExpectedToMove == other.mExpectedToMove
- && mFloorNumber == other.mFloorNumber
- && mHeightAboveFloorMeters == other.mHeightAboveFloorMeters
- && mHeightAboveFloorUncertaintyMeters
- == other.mHeightAboveFloorUncertaintyMeters
- && mUsageRetransmit == other.mUsageRetransmit
- && mUsageRetentionExpires == other.mUsageRetentionExpires
- && mUsageExtraInfoOnAssociation == other.mUsageExtraInfoOnAssociation
- && mBssidList.equals(other.mBssidList)
- && mCivicLocationCountryCode.equals(other.mCivicLocationCountryCode)
- && mCivicLocationString.equals(other.mCivicLocationString)
- && Objects.equals(mCivicLocation, other.mCivicLocation)
- && mMapImageType == other.mMapImageType
- && Objects.equals(mMapImageUri, other.mMapImageUri);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mIsValid, mIsLciValid, mIsZValid, mIsUsageValid, mIsBssidListValid,
- mIsLocationCivicValid, mIsMapImageValid, mLatitudeUncertainty, mLatitude,
- mLongitudeUncertainty, mLongitude, mAltitudeType, mAltitudeUncertainty, mAltitude,
- mDatum, mLciRegisteredLocationAgreement,
- mLciRegisteredLocationDse, mLciDependentStation, mLciVersion,
- mExpectedToMove, mFloorNumber, mHeightAboveFloorMeters,
- mHeightAboveFloorUncertaintyMeters, mUsageRetransmit, mUsageRetentionExpires,
- mUsageExtraInfoOnAssociation, mBssidList, mCivicLocationCountryCode,
- mCivicLocationString, mCivicLocation, mMapImageType, mMapImageUri);
- }
-
- /**
- * @return true if the ResponderLocation object is valid and contains useful information
- * relevant to the location of the Responder. If this is ever false, this object will not be
- * available to developers, and have a null value.
- *
- * @hide
- */
- public boolean isValid() {
- return mIsValid;
- }
-
- /**
- * @return true if the LCI subelement (containing Latitude, Longitude and Altitude) is valid.
- *
- * <p> This method tells us if the responder has provided its Location Configuration
- * Information (LCI) directly, and is useful when an external database of responder locations
- * is not available</p>
- *
- * <p>If isLciSubelementValid() returns true, all the LCI values provided by the corresponding
- * getter methods will have been set as described by the responder, or else if false, they
- * should not be used and will throw an IllegalStateException.</p>
- */
- public boolean isLciSubelementValid() {
- return mIsLciValid;
- }
-
- /**
- * @return the latitude uncertainty in degrees.
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- * </p>
- * <p> An unknown uncertainty is indicated by 0.</p>
- */
- public double getLatitudeUncertainty() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getLatitudeUncertainty(): invoked on an invalid result: mIsLciValid = false.");
- }
- return mLatitudeUncertainty;
- }
-
- /**
- * @return the latitude in degrees
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- */
- public double getLatitude() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getLatitude(): invoked on an invalid result: mIsLciValid = false.");
- }
- return mLatitude;
- }
-
- /**
- * @return the Longitude uncertainty in degrees.
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- * </p>
- * <p> An unknown uncertainty is indicated by 0.</p>
- */
- public double getLongitudeUncertainty() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getLongitudeUncertainty(): invoked on an invalid result: mIsLciValid = false.");
- }
- return mLongitudeUncertainty;
- }
-
- /**
- * @return the Longitude in degrees..
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- */
- public double getLongitude() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getLatitudeUncertainty(): invoked on an invalid result: mIsLciValid = false.");
- }
- return mLongitude;
- }
-
- /**
- * @return the Altitude type.
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- */
- @AltitudeType
- public int getAltitudeType() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getLatitudeUncertainty(): invoked on an invalid result: mIsLciValid = false.");
- }
- return mAltitudeType;
- }
-
- /**
- * @return the Altitude uncertainty in meters.
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- * </p>
- * <p>An unknown uncertainty is indicated by 0.</p>
- */
- public double getAltitudeUncertainty() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getLatitudeUncertainty(): invoked on an invalid result: mIsLciValid = false.");
- }
- return mAltitudeUncertainty;
- }
-
- /**
- * @return the Altitude in units defined by the altitude type.
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- */
- public double getAltitude() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getAltitude(): invoked on an invalid result: mIsLciValid = false.");
- }
- return mAltitude;
- }
-
- /**
- * @return the Datum used for the LCI positioning information.
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- */
- @DatumType
- public int getDatum() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getDatum(): invoked on an invalid result: mIsLciValid = false.");
- }
- return mDatum;
- }
-
- /**
- * @return true if the station is operating within a national policy area or an international
- * agreement area near a national border, otherwise false
- * (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- */
- public boolean getRegisteredLocationAgreementIndication() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getRegisteredLocationAgreementIndication(): "
- + "invoked on an invalid result: mIsLciValid = false.");
- }
- return mLciRegisteredLocationAgreement;
- }
-
- /**
- * @return true indicating this is an enabling station, enabling the operation of nearby STAs
- * with Dynamic Station Enablement (DSE), otherwise false.
- * (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- *
- * @hide
- */
- public boolean getRegisteredLocationDseIndication() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getRegisteredLocationDseIndication(): "
- + "invoked on an invalid result: mIsLciValid = false.");
- }
- return mLciRegisteredLocationDse;
- }
-
- /**
- * @return true indicating this is a dependent station that is operating with the enablement of
- * an enabling station whose LCI is being reported, otherwise false.
- * (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- *
- * @hide
- */
- public boolean getDependentStationIndication() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getDependentStationIndication(): "
- + "invoked on an invalid result: mIsLciValid = false.");
- }
- return mLciDependentStation;
- }
-
- /**
- * @return a value greater or equal to 1, indicating the current version number
- * of the LCI protocol.
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- */
- public int getLciVersion() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "getLciVersion(): "
- + "invoked on an invalid result: mIsLciValid = false.");
- }
- return mLciVersion;
- }
-
- /**
- * @return the LCI location represented as a {@link Location} object (best effort).
- * <p>
- * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
- */
- @NonNull
- public Location toLocation() {
- if (!mIsLciValid) {
- throw new IllegalStateException(
- "toLocation(): "
- + "invoked on an invalid result: mIsLciValid = false.");
- }
- Location location = new Location(LOCATION_PROVIDER);
- location.setLatitude(mLatitude);
- location.setLongitude(mLongitude);
- location.setAccuracy((float) (mLatitudeUncertainty + mLongitudeUncertainty) / 2);
- location.setAltitude(mAltitude);
- location.setVerticalAccuracyMeters((float) mAltitudeUncertainty);
- location.setTime(System.currentTimeMillis());
- return location;
- }
-
- /**
- * @return if the Z subelement (containing mobility, Floor, Height above floor) is valid.
- */
- public boolean isZaxisSubelementValid() {
- return mIsZValid;
- }
-
- /**
- * @return an integer representing the mobility of the responder.
- * <p>
- * Only valid if {@link #isZaxisSubelementValid()} returns true, or will throw an exception.
- */
- @ExpectedToMoveType
- public int getExpectedToMove() {
- if (!mIsZValid) {
- throw new IllegalStateException(
- "getExpectedToMove(): invoked on an invalid result: mIsZValid = false.");
- }
- return mExpectedToMove;
- }
-
- /**
- * @return the Z sub element Floor Number.
- * <p>
- * Only valid if {@link #isZaxisSubelementValid()} returns true, or will throw an exception.
- * </p>
- * <p>Note: this number can be positive or negative, with value increments of +/- 1/16 of a
- * floor.</p>.
- */
- public double getFloorNumber() {
- if (!mIsZValid) {
- throw new IllegalStateException(
- "getFloorNumber(): invoked on an invalid result: mIsZValid = false)");
- }
- return mFloorNumber;
- }
-
- /**
- * @return the Z subelement Height above the floor in meters.
- * <p>
- * Only valid if {@link #isZaxisSubelementValid()} returns true, or will throw an exception.
- * </p>
- * <p>This value can be positive or negative. </p>
- */
- public double getHeightAboveFloorMeters() {
- if (!mIsZValid) {
- throw new IllegalStateException(
- "getHeightAboveFloorMeters(): invoked on an invalid result: mIsZValid = false)");
- }
- return mHeightAboveFloorMeters;
- }
-
- /**
- * @return the Z subelement Height above the floor uncertainty in meters.
- * <p>
- * Only valid if {@link #isZaxisSubelementValid()} returns true, or will throw an exception.
- * </p>
- * <p>An unknown uncertainty is indicated by 0.</p>
- */
- public double getHeightAboveFloorUncertaintyMeters() {
- if (!mIsZValid) {
- throw new IllegalStateException(
- "getHeightAboveFloorUncertaintyMeters():"
- + "invoked on an invalid result: mIsZValid = false)");
- }
- return mHeightAboveFloorUncertaintyMeters;
- }
-
- /**
- * @return true if the location information received from the responder can be
- * retransmitted to another device, physically separate from the one that received it.
- *
- * @hide
- */
- public boolean getRetransmitPolicyIndication() {
- return mUsageRetransmit;
- }
-
- /**
- * @return true if location-data received should expire (and be deleted)
- * by the time provided in the getRelativeExpirationTimeHours() method.
- *
- * @hide
- */
- public boolean getRetentionExpiresIndication() {
- return mUsageRetentionExpires;
- }
-
- /**
- * @return true if there is extra location info available on association.
- *
- * @hide
- */
- @SystemApi
- public boolean getExtraInfoOnAssociationIndication() {
- return mUsageExtraInfoOnAssociation;
- }
-
- /**
- * @return the Immutable list of colocated BSSIDs at the responder.
- *
- * <p> Will return an empty list when there are no bssids listed.
- */
- public List<MacAddress> getColocatedBssids() {
- return Collections.unmodifiableList(mBssidList);
- }
-
- /**
- * @return the civic location represented as an {@link Address} object (best effort).
- *
- * <p> Will return a {@code null} when there is no Civic Location defined.
- */
- @Nullable
- public Address toCivicLocationAddress() {
- if (mCivicLocation != null && mCivicLocation.isValid()) {
- return mCivicLocation.toAddress();
- } else {
- return null;
- }
- }
-
- /**
- * @return the civic location represented as a {@link SparseArray}
- * <p>
- * Valid keys to access the SparseArray can be found in {@code CivicLocationKeys}.
- * </p>
- * <p> Will return a {@code null} when there is no Civic Location defined.
- *
- */
- @Nullable
- @SuppressLint("ChangedType")
- public SparseArray<String> toCivicLocationSparseArray() {
- if (mCivicLocation != null && mCivicLocation.isValid()) {
- return mCivicLocation.toSparseArray();
- } else {
- return null;
- }
- }
-
- /**
- * @return the civic location two upper-case ASCII character country code defined in ISO 3166.
- *
- * <p> Will return a {@code null} when there is no country code defined.
- *
- * @hide
- */
- @Nullable
- public String getCivicLocationCountryCode() {
- return mCivicLocationCountryCode;
- }
-
- /**
- * @return the value of the Civic Location String associated with a key.
- *
- * <p> Will return a {@code null} when there is no value associated with the key provided.
- *
- * @param key used to find a corresponding value in the Civic Location Tuple list
- *
- * @hide
- */
- @Nullable
- public String getCivicLocationElementValue(@CivicLocationKeysType int key) {
- return mCivicLocation.getCivicElementValue(key);
- }
-
- /**
- * @return the Map Image file Mime type, referred to by getMapImageUrl().
- */
- @Nullable
- public String getMapImageMimeType() {
- if (mMapImageUri == null) {
- return null;
- } else {
- return imageTypeToMime(mMapImageType, mMapImageUri.toString());
- }
- }
-
- /**
- * @return a URI referencing a map-file showing the local floor plan.
- *
- * <p> Will return a {@code null} when there is no URI defined.
- */
- @Nullable
- public Uri getMapImageUri() {
- return mMapImageUri;
- }
-}
diff --git a/wifi/java/android/net/wifi/rtt/WifiRttManager.java b/wifi/java/android/net/wifi/rtt/WifiRttManager.java
deleted file mode 100644
index 865702a..0000000
--- a/wifi/java/android/net/wifi/rtt/WifiRttManager.java
+++ /dev/null
@@ -1,190 +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.net.wifi.rtt;
-
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
-import static android.Manifest.permission.ACCESS_WIFI_STATE;
-import static android.Manifest.permission.CHANGE_WIFI_STATE;
-import static android.Manifest.permission.LOCATION_HARDWARE;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.content.Context;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.os.WorkSource;
-import android.util.Log;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * This class provides the primary API for measuring distance (range) to other devices using the
- * IEEE 802.11mc Wi-Fi Round Trip Time (RTT) technology.
- * <p>
- * The devices which can be ranged include:
- * <li>Access Points (APs)
- * <li>Wi-Fi Aware peers
- * <p>
- * Ranging requests are triggered using
- * {@link #startRanging(RangingRequest, Executor, RangingResultCallback)}. Results (in case of
- * successful operation) are returned in the {@link RangingResultCallback#onRangingResults(List)}
- * callback.
- * <p>
- * Wi-Fi RTT may not be usable at some points, e.g. when Wi-Fi is disabled. To validate that
- * the functionality is available use the {@link #isAvailable()} function. To track
- * changes in RTT usability register for the {@link #ACTION_WIFI_RTT_STATE_CHANGED}
- * broadcast. Note that this broadcast is not sticky - you should register for it and then
- * check the above API to avoid a race condition.
- */
-@SystemService(Context.WIFI_RTT_RANGING_SERVICE)
-public class WifiRttManager {
- private static final String TAG = "WifiRttManager";
- private static final boolean VDBG = false;
-
- private final Context mContext;
- private final IWifiRttManager mService;
-
- /**
- * Broadcast intent action to indicate that the state of Wi-Fi RTT availability has changed.
- * Use the {@link #isAvailable()} to query the current status.
- * This broadcast is <b>not</b> sticky, use the {@link #isAvailable()} API after registering
- * the broadcast to check the current state of Wi-Fi RTT.
- * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
- * components will be launched.
- */
- @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_WIFI_RTT_STATE_CHANGED =
- "android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED";
-
- /** @hide */
- public WifiRttManager(@NonNull Context context, @NonNull IWifiRttManager service) {
- mContext = context;
- mService = service;
- }
-
- /**
- * Returns the current status of RTT API: whether or not RTT is available. To track
- * changes in the state of RTT API register for the
- * {@link #ACTION_WIFI_RTT_STATE_CHANGED} broadcast.
- * <p>Note: availability of RTT does not mean that the app can use the API. The app's
- * permissions and platform Location Mode are validated at run-time.
- *
- * @return A boolean indicating whether the app can use the RTT API at this time (true) or
- * not (false).
- */
- public boolean isAvailable() {
- try {
- return mService.isAvailable();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Initiate a request to range to a set of devices specified in the {@link RangingRequest}.
- * Results will be returned in the {@link RangingResultCallback} set of callbacks.
- *
- * @param request A request specifying a set of devices whose distance measurements are
- * requested.
- * @param executor The Executor on which to run the callback.
- * @param callback A callback for the result of the ranging request.
- */
- @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, CHANGE_WIFI_STATE, ACCESS_WIFI_STATE})
- public void startRanging(@NonNull RangingRequest request,
- @NonNull @CallbackExecutor Executor executor, @NonNull RangingResultCallback callback) {
- startRanging(null, request, executor, callback);
- }
-
- /**
- * Initiate a request to range to a set of devices specified in the {@link RangingRequest}.
- * Results will be returned in the {@link RangingResultCallback} set of callbacks.
- *
- * @param workSource A mechanism to specify an alternative work-source for the request.
- * @param request A request specifying a set of devices whose distance measurements are
- * requested.
- * @param executor The Executor on which to run the callback.
- * @param callback A callback for the result of the ranging request.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION, CHANGE_WIFI_STATE,
- ACCESS_WIFI_STATE})
- public void startRanging(@Nullable WorkSource workSource, @NonNull RangingRequest request,
- @NonNull @CallbackExecutor Executor executor, @NonNull RangingResultCallback callback) {
- if (VDBG) {
- Log.v(TAG, "startRanging: workSource=" + workSource + ", request=" + request
- + ", callback=" + callback + ", executor=" + executor);
- }
-
- if (executor == null) {
- throw new IllegalArgumentException("Null executor provided");
- }
- if (callback == null) {
- throw new IllegalArgumentException("Null callback provided");
- }
-
- Binder binder = new Binder();
- try {
- mService.startRanging(binder, mContext.getOpPackageName(),
- mContext.getAttributionTag(), workSource, request, new IRttCallback.Stub() {
- @Override
- public void onRangingFailure(int status) throws RemoteException {
- clearCallingIdentity();
- executor.execute(() -> callback.onRangingFailure(status));
- }
-
- @Override
- public void onRangingResults(List<RangingResult> results)
- throws RemoteException {
- clearCallingIdentity();
- executor.execute(() -> callback.onRangingResults(results));
- }
- });
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Cancel all ranging requests for the specified work sources. The requests have been requested
- * using {@link #startRanging(WorkSource, RangingRequest, Executor, RangingResultCallback)}.
- *
- * @param workSource The work-sources of the requesters.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(allOf = {LOCATION_HARDWARE})
- public void cancelRanging(@Nullable WorkSource workSource) {
- if (VDBG) {
- Log.v(TAG, "cancelRanging: workSource=" + workSource);
- }
-
- try {
- mService.cancelRanging(workSource);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/rtt/package.html b/wifi/java/android/net/wifi/rtt/package.html
deleted file mode 100644
index 4a32f52..0000000
--- a/wifi/java/android/net/wifi/rtt/package.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes which allow applications to use Wi-Fi RTT (IEEE 802.11mc) to measure distance
- to supporting Access Points and peer devices.</p>
-<p>The primary entry point to Wi-Fi RTT capabilities is the
- {@link android.net.wifi.rtt.WifiRttManager} class, which is acquired by calling
- {@link android.content.Context#getSystemService(String)
- Context.getSystemService(Context.WIFI_RTT_RANGING_SERVICE)}</p>
-
-<p>Some APIs may require the following user permissions:</p>
-<ul>
- <li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
- <li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
- <li>{@link android.Manifest.permission#ACCESS_FINE_LOCATION}</li>
-</ul>
-<p>Usage of the API is also gated by the device's Location Mode: whether it permits Wi-Fi based
-location to be queried.</p>
-
-<p class="note"><strong>Note:</strong> Not all Android-powered devices support Wi-Fi RTT
- functionality.
- If your application only works with Wi-Fi RTT (i.e. it should only be installed on devices which
- support Wi-Fi RTT), declare so with a <a
- href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
- {@code <uses-feature>}</a>
- element in the manifest file:</p>
-<pre>
-<manifest ...>
- <uses-feature android:name="android.hardware.wifi.rtt" />
- ...
-</manifest>
-</pre>
-<p>Alternatively, if your application does not require Wi-Fi RTT but can take advantage of it if
- available, you can perform
- the check at run-time in your code using {@link
- android.content.pm.PackageManager#hasSystemFeature(String)} with {@link
- android.content.pm.PackageManager#FEATURE_WIFI_RTT}:</p>
-<pre>
- getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
-</pre>
-
-<p>For an example of this functionality, see
-<a href="{@docRoot}guide/topics/connectivity/wifi-rtt" class="external">Wi-Fi location: ranging
-with RTT</a>.</p>
-</BODY>
-</HTML>
diff --git a/wifi/java/android/net/wifi/util/HexEncoding.java b/wifi/java/android/net/wifi/util/HexEncoding.java
deleted file mode 100644
index 9ebf947..0000000
--- a/wifi/java/android/net/wifi/util/HexEncoding.java
+++ /dev/null
@@ -1,183 +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.
- */
-
-package android.net.wifi.util;
-
-/**
- * Hexadecimal encoding where each byte is represented by two hexadecimal digits.
- *
- * Note: this is copied from {@link libcore.util.HexEncoding}.
- *
- * @hide
- */
-public class HexEncoding {
-
- private static final char[] LOWER_CASE_DIGITS = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
- };
-
- private static final char[] UPPER_CASE_DIGITS = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
- };
-
- /** Hidden constructor to prevent instantiation. */
- private HexEncoding() {}
-
- /**
- * Encodes the provided byte as a two-digit hexadecimal String value.
- */
- public static String encodeToString(byte b, boolean upperCase) {
- char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS;
- char[] buf = new char[2]; // We always want two digits.
- buf[0] = digits[(b >> 4) & 0xf];
- buf[1] = digits[b & 0xf];
- return new String(buf, 0, 2);
- }
-
- /**
- * Encodes the provided data as a sequence of hexadecimal characters.
- */
- public static char[] encode(byte[] data) {
- return encode(data, 0, data.length, true /* upperCase */);
- }
-
- /**
- * Encodes the provided data as a sequence of hexadecimal characters.
- */
- public static char[] encode(byte[] data, boolean upperCase) {
- return encode(data, 0, data.length, upperCase);
- }
-
- /**
- * Encodes the provided data as a sequence of hexadecimal characters.
- */
- public static char[] encode(byte[] data, int offset, int len) {
- return encode(data, offset, len, true /* upperCase */);
- }
-
- /**
- * Encodes the provided data as a sequence of hexadecimal characters.
- */
- private static char[] encode(byte[] data, int offset, int len, boolean upperCase) {
- char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS;
- char[] result = new char[len * 2];
- for (int i = 0; i < len; i++) {
- byte b = data[offset + i];
- int resultIndex = 2 * i;
- result[resultIndex] = (digits[(b >> 4) & 0x0f]);
- result[resultIndex + 1] = (digits[b & 0x0f]);
- }
-
- return result;
- }
-
- /**
- * Encodes the provided data as a sequence of hexadecimal characters.
- */
- public static String encodeToString(byte[] data) {
- return encodeToString(data, true /* upperCase */);
- }
-
- /**
- * Encodes the provided data as a sequence of hexadecimal characters.
- */
- public static String encodeToString(byte[] data, boolean upperCase) {
- return new String(encode(data, upperCase));
- }
-
- /**
- * Decodes the provided hexadecimal string into a byte array. Odd-length inputs
- * are not allowed.
- *
- * Throws an {@code IllegalArgumentException} if the input is malformed.
- */
- public static byte[] decode(String encoded) throws IllegalArgumentException {
- return decode(encoded.toCharArray());
- }
-
- /**
- * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
- * is {@code true} odd-length inputs are allowed and the first character is interpreted
- * as the lower bits of the first result byte.
- *
- * Throws an {@code IllegalArgumentException} if the input is malformed.
- */
- public static byte[] decode(String encoded, boolean allowSingleChar)
- throws IllegalArgumentException {
- return decode(encoded.toCharArray(), allowSingleChar);
- }
-
- /**
- * Decodes the provided hexadecimal string into a byte array. Odd-length inputs
- * are not allowed.
- *
- * Throws an {@code IllegalArgumentException} if the input is malformed.
- */
- public static byte[] decode(char[] encoded) throws IllegalArgumentException {
- return decode(encoded, false);
- }
-
- /**
- * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
- * is {@code true} odd-length inputs are allowed and the first character is interpreted
- * as the lower bits of the first result byte.
- *
- * Throws an {@code IllegalArgumentException} if the input is malformed.
- */
- public static byte[] decode(char[] encoded, boolean allowSingleChar)
- throws IllegalArgumentException {
- int encodedLength = encoded.length;
- int resultLengthBytes = (encodedLength + 1) / 2;
- byte[] result = new byte[resultLengthBytes];
-
- int resultOffset = 0;
- int i = 0;
- if (allowSingleChar) {
- if ((encodedLength % 2) != 0) {
- // Odd number of digits -- the first digit is the lower 4 bits of the first result
- // byte.
- result[resultOffset++] = (byte) toDigit(encoded, i);
- i++;
- }
- } else {
- if ((encodedLength % 2) != 0) {
- throw new IllegalArgumentException("Invalid input length: " + encodedLength);
- }
- }
-
- for (; i < encodedLength; i += 2) {
- result[resultOffset++] = (byte) ((toDigit(encoded, i) << 4) | toDigit(encoded, i + 1));
- }
-
- return result;
- }
-
- private static int toDigit(char[] str, int offset) throws IllegalArgumentException {
- // NOTE: that this isn't really a code point in the traditional sense, since we're
- // just rejecting surrogate pairs outright.
- int pseudoCodePoint = str[offset];
-
- if ('0' <= pseudoCodePoint && pseudoCodePoint <= '9') {
- return pseudoCodePoint - '0';
- } else if ('a' <= pseudoCodePoint && pseudoCodePoint <= 'f') {
- return 10 + (pseudoCodePoint - 'a');
- } else if ('A' <= pseudoCodePoint && pseudoCodePoint <= 'F') {
- return 10 + (pseudoCodePoint - 'A');
- }
-
- throw new IllegalArgumentException("Illegal char: " + str[offset] + " at offset " + offset);
- }
-}
diff --git a/wifi/java/android/net/wifi/SoftApConfToXmlMigrationUtil.java b/wifi/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java
similarity index 100%
rename from wifi/java/android/net/wifi/SoftApConfToXmlMigrationUtil.java
rename to wifi/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java
diff --git a/wifi/java/src/android/net/wifi/WifiMigration.java b/wifi/java/src/android/net/wifi/WifiMigration.java
new file mode 100755
index 0000000..4fabc0b
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/WifiMigration.java
@@ -0,0 +1,558 @@
+/*
+ * 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.net.wifi;
+
+import static android.os.Environment.getDataMiscCeDirectory;
+import static android.os.Environment.getDataMiscDirectory;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.AtomicFile;
+import android.util.SparseArray;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Class used to provide one time hooks for existing OEM devices to migrate their config store
+ * data and other settings to the wifi apex.
+ * @hide
+ */
+@SystemApi
+public final class WifiMigration {
+ /**
+ * Directory to read the wifi config store files from under.
+ */
+ private static final String LEGACY_WIFI_STORE_DIRECTORY_NAME = "wifi";
+ /**
+ * Config store file for general shared store file.
+ * AOSP Path on Android 10: /data/misc/wifi/WifiConfigStore.xml
+ */
+ public static final int STORE_FILE_SHARED_GENERAL = 0;
+ /**
+ * Config store file for softap shared store file.
+ * AOSP Path on Android 10: /data/misc/wifi/softap.conf
+ */
+ public static final int STORE_FILE_SHARED_SOFTAP = 1;
+ /**
+ * Config store file for general user store file.
+ * AOSP Path on Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStore.xml
+ */
+ public static final int STORE_FILE_USER_GENERAL = 2;
+ /**
+ * Config store file for network suggestions user store file.
+ * AOSP Path on Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStoreNetworkSuggestions.xml
+ */
+ public static final int STORE_FILE_USER_NETWORK_SUGGESTIONS = 3;
+
+ /** @hide */
+ @IntDef(prefix = { "STORE_FILE_SHARED_" }, value = {
+ STORE_FILE_SHARED_GENERAL,
+ STORE_FILE_SHARED_SOFTAP,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SharedStoreFileId { }
+
+ /** @hide */
+ @IntDef(prefix = { "STORE_FILE_USER_" }, value = {
+ STORE_FILE_USER_GENERAL,
+ STORE_FILE_USER_NETWORK_SUGGESTIONS
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface UserStoreFileId { }
+
+ /**
+ * Mapping of Store file Id to Store file names.
+ *
+ * NOTE: This is the default path for the files on AOSP devices. If the OEM has modified
+ * the path or renamed the files, please edit this appropriately.
+ */
+ private static final SparseArray<String> STORE_ID_TO_FILE_NAME =
+ new SparseArray<String>() {{
+ put(STORE_FILE_SHARED_GENERAL, "WifiConfigStore.xml");
+ put(STORE_FILE_SHARED_SOFTAP, "WifiConfigStoreSoftAp.xml");
+ put(STORE_FILE_USER_GENERAL, "WifiConfigStore.xml");
+ put(STORE_FILE_USER_NETWORK_SUGGESTIONS, "WifiConfigStoreNetworkSuggestions.xml");
+ }};
+
+ /**
+ * Pre-apex wifi shared folder.
+ */
+ private static File getLegacyWifiSharedDirectory() {
+ return new File(getDataMiscDirectory(), LEGACY_WIFI_STORE_DIRECTORY_NAME);
+ }
+
+ /**
+ * Pre-apex wifi user folder.
+ */
+ private static File getLegacyWifiUserDirectory(int userId) {
+ return new File(getDataMiscCeDirectory(userId), LEGACY_WIFI_STORE_DIRECTORY_NAME);
+ }
+
+ /**
+ * Legacy files were stored as AtomicFile. So, always use AtomicFile to operate on it to ensure
+ * data integrity.
+ */
+ private static AtomicFile getSharedAtomicFile(@SharedStoreFileId int storeFileId) {
+ return new AtomicFile(new File(
+ getLegacyWifiSharedDirectory(),
+ STORE_ID_TO_FILE_NAME.get(storeFileId)));
+ }
+
+ /**
+ * Legacy files were stored as AtomicFile. So, always use AtomicFile to operate on it to ensure
+ * data integrity.
+ */
+ private static AtomicFile getUserAtomicFile(@UserStoreFileId int storeFileId, int userId) {
+ return new AtomicFile(new File(
+ getLegacyWifiUserDirectory(userId),
+ STORE_ID_TO_FILE_NAME.get(storeFileId)));
+ }
+
+ private WifiMigration() { }
+
+ /**
+ * Load data from legacy shared wifi config store file.
+ * <p>
+ * Expected AOSP format is available in the sample files under {@code
+ * frameworks/base/wifi/non-updatable/migration_samples/}.
+ * </p>
+ * <p>
+ * Note:
+ * <li>OEMs need to change the implementation of
+ * {@link #convertAndRetrieveSharedConfigStoreFile(int)} only if their existing config store
+ * format or file locations differs from the vanilla AOSP implementation.</li>
+ * <li>The wifi apex will invoke
+ * {@link #convertAndRetrieveSharedConfigStoreFile(int)}
+ * method on every bootup, it is the responsibility of the OEM implementation to ensure that
+ * they perform the necessary in place conversion of their config store file to conform to the
+ * AOSP format. The OEM should ensure that the method should only return the
+ * {@link InputStream} stream for the data to be migrated only on the first bootup.</li>
+ * <li>Once the migration is done, the apex will invoke
+ * {@link #removeSharedConfigStoreFile(int)} to delete the store file.</li>
+ * <li>The only relevant invocation of {@link #convertAndRetrieveSharedConfigStoreFile(int)}
+ * occurs when a previously released device upgrades to the wifi apex from an OEM
+ * implementation of the wifi stack.
+ * <li>Ensure that the legacy file paths are accessible to the wifi module (sepolicy rules, file
+ * permissions, etc). Since the wifi service continues to run inside system_server process, this
+ * method will be called from the same context (so ideally the file should still be accessible).
+ * </li>
+ *
+ * @param storeFileId Identifier for the config store file. One of
+ * {@link #STORE_FILE_SHARED_GENERAL} or {@link #STORE_FILE_SHARED_GENERAL}
+ * @return Instance of {@link InputStream} for migrating data, null if no migration is
+ * necessary.
+ * @throws IllegalArgumentException on invalid storeFileId.
+ */
+ @Nullable
+ public static InputStream convertAndRetrieveSharedConfigStoreFile(
+ @SharedStoreFileId int storeFileId) {
+ if (storeFileId != STORE_FILE_SHARED_GENERAL && storeFileId != STORE_FILE_SHARED_SOFTAP) {
+ throw new IllegalArgumentException("Invalid shared store file id");
+ }
+ try {
+ // OEMs should do conversions necessary here before returning the stream.
+ return getSharedAtomicFile(storeFileId).openRead();
+ } catch (FileNotFoundException e) {
+ // Special handling for softap.conf.
+ // Note: OEM devices upgrading from Q -> R will only have the softap.conf file.
+ // Test devices running previous R builds however may have already migrated to the
+ // XML format. So, check for that above before falling back to check for legacy file.
+ if (storeFileId == STORE_FILE_SHARED_SOFTAP) {
+ return SoftApConfToXmlMigrationUtil.convert();
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Remove the legacy shared wifi config store file.
+ *
+ * @param storeFileId Identifier for the config store file. One of
+ * {@link #STORE_FILE_SHARED_GENERAL} or {@link #STORE_FILE_SHARED_GENERAL}
+ * @throws IllegalArgumentException on invalid storeFileId.
+ */
+ public static void removeSharedConfigStoreFile(@SharedStoreFileId int storeFileId) {
+ if (storeFileId != STORE_FILE_SHARED_GENERAL && storeFileId != STORE_FILE_SHARED_SOFTAP) {
+ throw new IllegalArgumentException("Invalid shared store file id");
+ }
+ AtomicFile file = getSharedAtomicFile(storeFileId);
+ if (file.exists()) {
+ file.delete();
+ return;
+ }
+ // Special handling for softap.conf.
+ // Note: OEM devices upgrading from Q -> R will only have the softap.conf file.
+ // Test devices running previous R builds however may have already migrated to the
+ // XML format. So, check for that above before falling back to check for legacy file.
+ if (storeFileId == STORE_FILE_SHARED_SOFTAP) {
+ SoftApConfToXmlMigrationUtil.remove();
+ }
+ }
+
+ /**
+ * Load data from legacy user wifi config store file.
+ * <p>
+ * Expected AOSP format is available in the sample files under {@code
+ * frameworks/base/wifi/non-updatable/migration_samples/}.
+ * </p>
+ * <p>
+ * Note:
+ * <li>OEMs need to change the implementation of
+ * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)} only if their existing config
+ * store format or file locations differs from the vanilla AOSP implementation.</li>
+ * <li>The wifi apex will invoke
+ * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)}
+ * method on every bootup, it is the responsibility of the OEM implementation to ensure that
+ * they perform the necessary in place conversion of their config store file to conform to the
+ * AOSP format. The OEM should ensure that the method should only return the
+ * {@link InputStream} stream for the data to be migrated only on the first bootup.</li>
+ * <li>Once the migration is done, the apex will invoke
+ * {@link #removeUserConfigStoreFile(int, UserHandle)} to delete the store file.</li>
+ * <li>The only relevant invocation of
+ * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)} occurs when a previously
+ * released device upgrades to the wifi apex from an OEM implementation of the wifi
+ * stack.
+ * </li>
+ * <li>Ensure that the legacy file paths are accessible to the wifi module (sepolicy rules, file
+ * permissions, etc). Since the wifi service continues to run inside system_server process, this
+ * method will be called from the same context (so ideally the file should still be accessible).
+ * </li>
+ *
+ * @param storeFileId Identifier for the config store file. One of
+ * {@link #STORE_FILE_USER_GENERAL} or {@link #STORE_FILE_USER_NETWORK_SUGGESTIONS}
+ * @param userHandle User handle.
+ * @return Instance of {@link InputStream} for migrating data, null if no migration is
+ * necessary.
+ * @throws IllegalArgumentException on invalid storeFileId or userHandle.
+ */
+ @Nullable
+ public static InputStream convertAndRetrieveUserConfigStoreFile(
+ @UserStoreFileId int storeFileId, @NonNull UserHandle userHandle) {
+ if (storeFileId != STORE_FILE_USER_GENERAL
+ && storeFileId != STORE_FILE_USER_NETWORK_SUGGESTIONS) {
+ throw new IllegalArgumentException("Invalid user store file id");
+ }
+ Objects.requireNonNull(userHandle);
+ try {
+ // OEMs should do conversions necessary here before returning the stream.
+ return getUserAtomicFile(storeFileId, userHandle.getIdentifier()).openRead();
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Remove the legacy user wifi config store file.
+ *
+ * @param storeFileId Identifier for the config store file. One of
+ * {@link #STORE_FILE_USER_GENERAL} or {@link #STORE_FILE_USER_NETWORK_SUGGESTIONS}
+ * @param userHandle User handle.
+ * @throws IllegalArgumentException on invalid storeFileId or userHandle.
+ */
+ public static void removeUserConfigStoreFile(
+ @UserStoreFileId int storeFileId, @NonNull UserHandle userHandle) {
+ if (storeFileId != STORE_FILE_USER_GENERAL
+ && storeFileId != STORE_FILE_USER_NETWORK_SUGGESTIONS) {
+ throw new IllegalArgumentException("Invalid user store file id");
+ }
+ Objects.requireNonNull(userHandle);
+ AtomicFile file = getUserAtomicFile(storeFileId, userHandle.getIdentifier());
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+
+ /**
+ * Container for all the wifi settings data to migrate.
+ */
+ public static final class SettingsMigrationData implements Parcelable {
+ private final boolean mScanAlwaysAvailable;
+ private final boolean mP2pFactoryResetPending;
+ private final String mP2pDeviceName;
+ private final boolean mSoftApTimeoutEnabled;
+ private final boolean mWakeupEnabled;
+ private final boolean mScanThrottleEnabled;
+ private final boolean mVerboseLoggingEnabled;
+
+ private SettingsMigrationData(boolean scanAlwaysAvailable, boolean p2pFactoryResetPending,
+ @Nullable String p2pDeviceName, boolean softApTimeoutEnabled, boolean wakeupEnabled,
+ boolean scanThrottleEnabled, boolean verboseLoggingEnabled) {
+ mScanAlwaysAvailable = scanAlwaysAvailable;
+ mP2pFactoryResetPending = p2pFactoryResetPending;
+ mP2pDeviceName = p2pDeviceName;
+ mSoftApTimeoutEnabled = softApTimeoutEnabled;
+ mWakeupEnabled = wakeupEnabled;
+ mScanThrottleEnabled = scanThrottleEnabled;
+ mVerboseLoggingEnabled = verboseLoggingEnabled;
+ }
+
+ public static final @NonNull Parcelable.Creator<SettingsMigrationData> CREATOR =
+ new Parcelable.Creator<SettingsMigrationData>() {
+ @Override
+ public SettingsMigrationData createFromParcel(Parcel in) {
+ boolean scanAlwaysAvailable = in.readBoolean();
+ boolean p2pFactoryResetPending = in.readBoolean();
+ String p2pDeviceName = in.readString();
+ boolean softApTimeoutEnabled = in.readBoolean();
+ boolean wakeupEnabled = in.readBoolean();
+ boolean scanThrottleEnabled = in.readBoolean();
+ boolean verboseLoggingEnabled = in.readBoolean();
+ return new SettingsMigrationData(
+ scanAlwaysAvailable, p2pFactoryResetPending,
+ p2pDeviceName, softApTimeoutEnabled, wakeupEnabled,
+ scanThrottleEnabled, verboseLoggingEnabled);
+ }
+
+ @Override
+ public SettingsMigrationData[] newArray(int size) {
+ return new SettingsMigrationData[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeBoolean(mScanAlwaysAvailable);
+ dest.writeBoolean(mP2pFactoryResetPending);
+ dest.writeString(mP2pDeviceName);
+ dest.writeBoolean(mSoftApTimeoutEnabled);
+ dest.writeBoolean(mWakeupEnabled);
+ dest.writeBoolean(mScanThrottleEnabled);
+ dest.writeBoolean(mVerboseLoggingEnabled);
+ }
+
+ /**
+ * @return True if scans are allowed even when wifi is toggled off, false otherwise.
+ */
+ public boolean isScanAlwaysAvailable() {
+ return mScanAlwaysAvailable;
+ }
+
+ /**
+ * @return indicate whether factory reset request is pending.
+ */
+ public boolean isP2pFactoryResetPending() {
+ return mP2pFactoryResetPending;
+ }
+
+ /**
+ * @return the Wi-Fi peer-to-peer device name
+ */
+ public @Nullable String getP2pDeviceName() {
+ return mP2pDeviceName;
+ }
+
+ /**
+ * @return Whether soft AP will shut down after a timeout period when no devices are
+ * connected.
+ */
+ public boolean isSoftApTimeoutEnabled() {
+ return mSoftApTimeoutEnabled;
+ }
+
+ /**
+ * @return whether Wi-Fi Wakeup feature is enabled.
+ */
+ public boolean isWakeUpEnabled() {
+ return mWakeupEnabled;
+ }
+
+ /**
+ * @return Whether wifi scan throttle is enabled or not.
+ */
+ public boolean isScanThrottleEnabled() {
+ return mScanThrottleEnabled;
+ }
+
+ /**
+ * @return Whether to enable verbose logging in Wi-Fi.
+ */
+ public boolean isVerboseLoggingEnabled() {
+ return mVerboseLoggingEnabled;
+ }
+
+ /**
+ * Builder to create instance of {@link SettingsMigrationData}.
+ */
+ public static final class Builder {
+ private boolean mScanAlwaysAvailable;
+ private boolean mP2pFactoryResetPending;
+ private String mP2pDeviceName;
+ private boolean mSoftApTimeoutEnabled;
+ private boolean mWakeupEnabled;
+ private boolean mScanThrottleEnabled;
+ private boolean mVerboseLoggingEnabled;
+
+ public Builder() {
+ }
+
+ /**
+ * Setting to allow scans even when wifi is toggled off.
+ *
+ * @param available true if available, false otherwise.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public @NonNull Builder setScanAlwaysAvailable(boolean available) {
+ mScanAlwaysAvailable = available;
+ return this;
+ }
+
+ /**
+ * Indicate whether factory reset request is pending.
+ *
+ * @param pending true if pending, false otherwise.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public @NonNull Builder setP2pFactoryResetPending(boolean pending) {
+ mP2pFactoryResetPending = pending;
+ return this;
+ }
+
+ /**
+ * The Wi-Fi peer-to-peer device name
+ *
+ * @param name Name if set, null otherwise.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public @NonNull Builder setP2pDeviceName(@Nullable String name) {
+ mP2pDeviceName = name;
+ return this;
+ }
+
+ /**
+ * Whether soft AP will shut down after a timeout period when no devices are connected.
+ *
+ * @param enabled true if enabled, false otherwise.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public @NonNull Builder setSoftApTimeoutEnabled(boolean enabled) {
+ mSoftApTimeoutEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Value to specify if Wi-Fi Wakeup feature is enabled.
+ *
+ * @param enabled true if enabled, false otherwise.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public @NonNull Builder setWakeUpEnabled(boolean enabled) {
+ mWakeupEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Whether wifi scan throttle is enabled or not.
+ *
+ * @param enabled true if enabled, false otherwise.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public @NonNull Builder setScanThrottleEnabled(boolean enabled) {
+ mScanThrottleEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Setting to enable verbose logging in Wi-Fi.
+ *
+ * @param enabled true if enabled, false otherwise.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public @NonNull Builder setVerboseLoggingEnabled(boolean enabled) {
+ mVerboseLoggingEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Build an instance of {@link SettingsMigrationData}.
+ *
+ * @return Instance of {@link SettingsMigrationData}.
+ */
+ public @NonNull SettingsMigrationData build() {
+ return new SettingsMigrationData(mScanAlwaysAvailable, mP2pFactoryResetPending,
+ mP2pDeviceName, mSoftApTimeoutEnabled, mWakeupEnabled, mScanThrottleEnabled,
+ mVerboseLoggingEnabled);
+ }
+ }
+ }
+
+ /**
+ * Load data from Settings.Global values.
+ *
+ * <p>
+ * Note:
+ * <li> This is method is invoked once on the first bootup. OEM can safely delete these settings
+ * once the migration is complete. The first & only relevant invocation of
+ * {@link #loadFromSettings(Context)} ()} occurs when a previously released
+ * device upgrades to the wifi apex from an OEM implementation of the wifi stack.
+ * </li>
+ *
+ * @param context Context to use for loading the settings provider.
+ * @return Instance of {@link SettingsMigrationData} for migrating data.
+ */
+ @NonNull
+ public static SettingsMigrationData loadFromSettings(@NonNull Context context) {
+ if (Settings.Global.getInt(
+ context.getContentResolver(), Settings.Global.WIFI_MIGRATION_COMPLETED, 0) == 1) {
+ // migration already complete, ignore.
+ return null;
+ }
+ SettingsMigrationData data = new SettingsMigrationData.Builder()
+ .setScanAlwaysAvailable(
+ Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1)
+ .setP2pFactoryResetPending(
+ Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.WIFI_P2P_PENDING_FACTORY_RESET, 0) == 1)
+ .setP2pDeviceName(
+ Settings.Global.getString(context.getContentResolver(),
+ Settings.Global.WIFI_P2P_DEVICE_NAME))
+ .setSoftApTimeoutEnabled(
+ Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.SOFT_AP_TIMEOUT_ENABLED, 1) == 1)
+ .setWakeUpEnabled(
+ Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1)
+ .setScanThrottleEnabled(
+ Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1) == 1)
+ .setVerboseLoggingEnabled(
+ Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0) == 1)
+ .build();
+ Settings.Global.putInt(
+ context.getContentResolver(), Settings.Global.WIFI_MIGRATION_COMPLETED, 1);
+ return data;
+
+ }
+}
diff --git a/wifi/java/src/android/net/wifi/WifiNetworkScoreCache.java b/wifi/java/src/android/net/wifi/WifiNetworkScoreCache.java
new file mode 100755
index 0000000..3903658
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/WifiNetworkScoreCache.java
@@ -0,0 +1,316 @@
+/*
+ * 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.
+ */
+
+package android.net.wifi;
+
+import android.Manifest.permission;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.net.INetworkScoreCache;
+import android.net.NetworkKey;
+import android.net.ScoredNetwork;
+import android.os.Handler;
+import android.os.Process;
+import android.util.Log;
+import android.util.LruCache;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * {@link INetworkScoreCache} implementation for Wifi Networks.
+ *
+ * TODO: This should not be part of wifi mainline module.
+ * @hide
+ */
+public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
+ private static final String TAG = "WifiNetworkScoreCache";
+ private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+
+ // A Network scorer returns a score in the range [-128, +127]
+ // We treat the lowest possible score as though there were no score, effectively allowing the
+ // scorer to provide an RSSI threshold below which a network should not be used.
+ public static final int INVALID_NETWORK_SCORE = Byte.MIN_VALUE;
+
+ /** Default number entries to be stored in the {@link LruCache}. */
+ private static final int DEFAULT_MAX_CACHE_SIZE = 100;
+
+ // See {@link #CacheListener}.
+ @Nullable
+ @GuardedBy("mLock")
+ private CacheListener mListener;
+
+ private final Context mContext;
+ private final Object mLock = new Object();
+
+ // The key is of the form "<ssid>"<bssid>
+ // TODO: What about SSIDs that can't be encoded as UTF-8?
+ @GuardedBy("mLock")
+ private final LruCache<String, ScoredNetwork> mCache;
+
+ public WifiNetworkScoreCache(Context context) {
+ this(context, null /* listener */);
+ }
+
+ /**
+ * Instantiates a WifiNetworkScoreCache.
+ *
+ * @param context Application context
+ * @param listener CacheListener for cache updates
+ */
+ public WifiNetworkScoreCache(Context context, @Nullable CacheListener listener) {
+ this(context, listener, DEFAULT_MAX_CACHE_SIZE);
+ }
+
+ public WifiNetworkScoreCache(
+ Context context, @Nullable CacheListener listener, int maxCacheSize) {
+ mContext = context.getApplicationContext();
+ mListener = listener;
+ mCache = new LruCache<>(maxCacheSize);
+ }
+
+ @Override public final void updateScores(List<ScoredNetwork> networks) {
+ if (networks == null || networks.isEmpty()) {
+ return;
+ }
+ if (DBG) {
+ Log.d(TAG, "updateScores list size=" + networks.size());
+ }
+
+ boolean changed = false;
+
+ synchronized (mLock) {
+ for (ScoredNetwork network : networks) {
+ String networkKey = buildNetworkKey(network);
+ if (networkKey == null) {
+ if (DBG) {
+ Log.d(TAG, "Failed to build network key for ScoredNetwork" + network);
+ }
+ continue;
+ }
+ mCache.put(networkKey, network);
+ changed = true;
+ }
+
+ if (mListener != null && changed) {
+ mListener.post(networks);
+ }
+ }
+ }
+
+ @Override public final void clearScores() {
+ synchronized (mLock) {
+ mCache.evictAll();
+ }
+ }
+
+ /**
+ * Returns whether there is any score info for the given ScanResult.
+ *
+ * This includes null-score info, so it should only be used when determining whether to request
+ * scores from the network scorer.
+ */
+ public boolean isScoredNetwork(ScanResult result) {
+ return getScoredNetwork(result) != null;
+ }
+
+ /**
+ * Returns whether there is a non-null score curve for the given ScanResult.
+ *
+ * A null score curve has special meaning - we should never connect to an ephemeral network if
+ * the score curve is null.
+ */
+ public boolean hasScoreCurve(ScanResult result) {
+ ScoredNetwork network = getScoredNetwork(result);
+ return network != null && network.rssiCurve != null;
+ }
+
+ public int getNetworkScore(ScanResult result) {
+ int score = INVALID_NETWORK_SCORE;
+
+ ScoredNetwork network = getScoredNetwork(result);
+ if (network != null && network.rssiCurve != null) {
+ score = network.rssiCurve.lookupScore(result.level);
+ if (DBG) {
+ Log.d(TAG, "getNetworkScore found scored network " + network.networkKey
+ + " score " + Integer.toString(score)
+ + " RSSI " + result.level);
+ }
+ }
+ return score;
+ }
+
+ /**
+ * Returns the ScoredNetwork metered hint for a given ScanResult.
+ *
+ * If there is no ScoredNetwork associated with the ScanResult then false will be returned.
+ */
+ public boolean getMeteredHint(ScanResult result) {
+ ScoredNetwork network = getScoredNetwork(result);
+ return network != null && network.meteredHint;
+ }
+
+ public int getNetworkScore(ScanResult result, boolean isActiveNetwork) {
+ int score = INVALID_NETWORK_SCORE;
+
+ ScoredNetwork network = getScoredNetwork(result);
+ if (network != null && network.rssiCurve != null) {
+ score = network.rssiCurve.lookupScore(result.level, isActiveNetwork);
+ if (DBG) {
+ Log.d(TAG, "getNetworkScore found scored network " + network.networkKey
+ + " score " + Integer.toString(score)
+ + " RSSI " + result.level
+ + " isActiveNetwork " + isActiveNetwork);
+ }
+ }
+ return score;
+ }
+
+ @Nullable
+ public ScoredNetwork getScoredNetwork(ScanResult result) {
+ String key = buildNetworkKey(result);
+ if (key == null) return null;
+
+ synchronized (mLock) {
+ ScoredNetwork network = mCache.get(key);
+ return network;
+ }
+ }
+
+ /** Returns the ScoredNetwork for the given key. */
+ @Nullable
+ public ScoredNetwork getScoredNetwork(NetworkKey networkKey) {
+ String key = buildNetworkKey(networkKey);
+ if (key == null) {
+ if (DBG) {
+ Log.d(TAG, "Could not build key string for Network Key: " + networkKey);
+ }
+ return null;
+ }
+ synchronized (mLock) {
+ return mCache.get(key);
+ }
+ }
+
+ private String buildNetworkKey(ScoredNetwork network) {
+ if (network == null) {
+ return null;
+ }
+ return buildNetworkKey(network.networkKey);
+ }
+
+ private String buildNetworkKey(NetworkKey networkKey) {
+ if (networkKey == null) {
+ return null;
+ }
+ if (networkKey.wifiKey == null) return null;
+ if (networkKey.type == NetworkKey.TYPE_WIFI) {
+ String key = networkKey.wifiKey.ssid;
+ if (key == null) return null;
+ if (networkKey.wifiKey.bssid != null) {
+ key = key + networkKey.wifiKey.bssid;
+ }
+ return key;
+ }
+ return null;
+ }
+
+ private String buildNetworkKey(ScanResult result) {
+ if (result == null || result.SSID == null) {
+ return null;
+ }
+ StringBuilder key = new StringBuilder("\"");
+ key.append(result.SSID);
+ key.append("\"");
+ if (result.BSSID != null) {
+ key.append(result.BSSID);
+ }
+ return key.toString();
+ }
+
+ @Override protected final void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
+ String header = String.format("WifiNetworkScoreCache (%s/%d)",
+ mContext.getPackageName(), Process.myUid());
+ writer.println(header);
+ writer.println(" All score curves:");
+ synchronized (mLock) {
+ for (ScoredNetwork score : mCache.snapshot().values()) {
+ writer.println(" " + score);
+ }
+ writer.println(" Network scores for latest ScanResults:");
+ WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ for (ScanResult scanResult : wifiManager.getScanResults()) {
+ writer.println(
+ " " + buildNetworkKey(scanResult) + ": " + getNetworkScore(scanResult));
+ }
+ }
+ }
+
+ /** Registers a CacheListener instance, replacing the previous listener if it existed. */
+ public void registerListener(CacheListener listener) {
+ synchronized (mLock) {
+ mListener = listener;
+ }
+ }
+
+ /** Removes the registered CacheListener. */
+ public void unregisterListener() {
+ synchronized (mLock) {
+ mListener = null;
+ }
+ }
+
+ /** Listener for updates to the cache inside WifiNetworkScoreCache. */
+ public abstract static class CacheListener {
+ private Handler mHandler;
+
+ /**
+ * Constructor for CacheListener.
+ *
+ * @param handler the Handler on which to invoke the {@link #networkCacheUpdated} method.
+ * This cannot be null.
+ */
+ public CacheListener(@NonNull Handler handler) {
+ Objects.requireNonNull(handler);
+ mHandler = handler;
+ }
+
+ /** Invokes the {@link #networkCacheUpdated(List<ScoredNetwork>)} method on the handler. */
+ void post(List<ScoredNetwork> updatedNetworks) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ networkCacheUpdated(updatedNetworks);
+ }
+ });
+ }
+
+ /**
+ * Invoked whenever the cache is updated.
+ *
+ * <p>Clearing the cache does not invoke this method.
+ *
+ * @param updatedNetworks the networks that were updated
+ */
+ public abstract void networkCacheUpdated(List<ScoredNetwork> updatedNetworks);
+ }
+}
diff --git a/wifi/java/android/net/wifi/nl80211/ChannelSettings.java b/wifi/java/src/android/net/wifi/nl80211/ChannelSettings.java
similarity index 100%
rename from wifi/java/android/net/wifi/nl80211/ChannelSettings.java
rename to wifi/java/src/android/net/wifi/nl80211/ChannelSettings.java
diff --git a/wifi/java/android/net/wifi/nl80211/DeviceWiphyCapabilities.java b/wifi/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
similarity index 100%
rename from wifi/java/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
rename to wifi/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
diff --git a/wifi/java/android/net/wifi/nl80211/HiddenNetwork.java b/wifi/java/src/android/net/wifi/nl80211/HiddenNetwork.java
similarity index 100%
rename from wifi/java/android/net/wifi/nl80211/HiddenNetwork.java
rename to wifi/java/src/android/net/wifi/nl80211/HiddenNetwork.java
diff --git a/wifi/java/android/net/wifi/nl80211/NativeScanResult.java b/wifi/java/src/android/net/wifi/nl80211/NativeScanResult.java
similarity index 100%
rename from wifi/java/android/net/wifi/nl80211/NativeScanResult.java
rename to wifi/java/src/android/net/wifi/nl80211/NativeScanResult.java
diff --git a/wifi/java/android/net/wifi/nl80211/NativeWifiClient.java b/wifi/java/src/android/net/wifi/nl80211/NativeWifiClient.java
similarity index 100%
rename from wifi/java/android/net/wifi/nl80211/NativeWifiClient.java
rename to wifi/java/src/android/net/wifi/nl80211/NativeWifiClient.java
diff --git a/wifi/java/android/net/wifi/nl80211/PnoNetwork.java b/wifi/java/src/android/net/wifi/nl80211/PnoNetwork.java
similarity index 100%
rename from wifi/java/android/net/wifi/nl80211/PnoNetwork.java
rename to wifi/java/src/android/net/wifi/nl80211/PnoNetwork.java
diff --git a/wifi/java/android/net/wifi/nl80211/PnoSettings.java b/wifi/java/src/android/net/wifi/nl80211/PnoSettings.java
similarity index 100%
rename from wifi/java/android/net/wifi/nl80211/PnoSettings.java
rename to wifi/java/src/android/net/wifi/nl80211/PnoSettings.java
diff --git a/wifi/java/android/net/wifi/nl80211/RadioChainInfo.java b/wifi/java/src/android/net/wifi/nl80211/RadioChainInfo.java
similarity index 100%
rename from wifi/java/android/net/wifi/nl80211/RadioChainInfo.java
rename to wifi/java/src/android/net/wifi/nl80211/RadioChainInfo.java
diff --git a/wifi/java/android/net/wifi/nl80211/SingleScanSettings.java b/wifi/java/src/android/net/wifi/nl80211/SingleScanSettings.java
similarity index 100%
rename from wifi/java/android/net/wifi/nl80211/SingleScanSettings.java
rename to wifi/java/src/android/net/wifi/nl80211/SingleScanSettings.java
diff --git a/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
similarity index 100%
rename from wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java
rename to wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
diff --git a/wifi/java/android/net/wifi/migration_samples/README.txt b/wifi/migration_samples/README.txt
similarity index 100%
rename from wifi/java/android/net/wifi/migration_samples/README.txt
rename to wifi/migration_samples/README.txt
diff --git a/wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStore.xml b/wifi/migration_samples/Shared_WifiConfigStore.xml
similarity index 100%
rename from wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStore.xml
rename to wifi/migration_samples/Shared_WifiConfigStore.xml
diff --git a/wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml b/wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml
similarity index 100%
rename from wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml
rename to wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml
diff --git a/wifi/java/android/net/wifi/migration_samples/User_WifiConfigStore.xml b/wifi/migration_samples/User_WifiConfigStore.xml
similarity index 100%
rename from wifi/java/android/net/wifi/migration_samples/User_WifiConfigStore.xml
rename to wifi/migration_samples/User_WifiConfigStore.xml
diff --git a/wifi/java/android/net/wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml b/wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
similarity index 100%
rename from wifi/java/android/net/wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
rename to wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp
index 6a39959..3f5cacf 100644
--- a/wifi/tests/Android.bp
+++ b/wifi/tests/Android.bp
@@ -12,15 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Make test APK
-// ============================================================
-
android_test {
- name: "FrameworksWifiApiTests",
+ name: "FrameworksWifiNonUpdatableApiTests",
defaults: ["framework-wifi-test-defaults"],
- srcs: ["**/*.java"],
+ srcs: ["src/**/*.java"],
jacoco: {
include_filter: ["android.net.wifi.*"],
@@ -30,11 +27,9 @@
static_libs: [
"androidx.test.rules",
- "core-test-rules",
+ "frameworks-base-testutils",
"guava",
"mockito-target-minus-junit4",
- "net-tests-utils",
- "frameworks-base-testutils",
"truth-prebuilt",
],
@@ -44,7 +39,6 @@
],
test_suites: [
- "device-tests",
- "mts",
+ "general-tests",
],
}
diff --git a/wifi/tests/AndroidManifest.xml b/wifi/tests/AndroidManifest.xml
index b6c38bc..b4b6b2d 100644
--- a/wifi/tests/AndroidManifest.xml
+++ b/wifi/tests/AndroidManifest.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-
<!--
- ~ Copyright (C) 2016 The Android Open Source Project
+ ~ 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.
@@ -17,22 +16,23 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.net.wifi.test">
+ package="android.net.wifi.test">
<application>
- <uses-library android:name="android.test.runner" />
+ <uses-library android:name="android.test.runner"/>
<activity android:label="WifiTestDummyLabel"
- android:name="WifiTestDummyName">
+ android:name="WifiTestDummyName"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
+ <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.net.wifi.test"
- android:label="Frameworks Wifi API Tests">
+ android:targetPackage="android.net.wifi.test"
+ android:label="Frameworks Wifi Non-updatable API Tests">
</instrumentation>
</manifest>
diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml
index 34e2e3a..5f3fdd4 100644
--- a/wifi/tests/AndroidTest.xml
+++ b/wifi/tests/AndroidTest.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- 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.
@@ -13,22 +13,16 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<configuration description="Runs Frameworks Wifi API Tests.">
+<configuration description="Runs Frameworks Wifi Non-updatable API Tests.">
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="test-file-name" value="FrameworksWifiApiTests.apk" />
+ <option name="test-file-name" value="FrameworksWifiNonUpdatableApiTests.apk" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
- <option name="test-tag" value="FrameworksWifiApiTests" />
+ <option name="test-tag" value="FrameworksWifiNonUpdatableApiTests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.net.wifi.test" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
</test>
-
- <!-- Only run FrameworksWifiApiTests in MTS if the Wifi Mainline module is installed. -->
- <object type="module_controller"
- class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
- <option name="mainline-module-package-name" value="com.google.android.wifi" />
- </object>
</configuration>
diff --git a/wifi/tests/README.md b/wifi/tests/README.md
index f909404..ad535f4 100644
--- a/wifi/tests/README.md
+++ b/wifi/tests/README.md
@@ -1,5 +1,6 @@
-# Wifi Unit Tests
-This package contains unit tests for the android wifi framework APIs based on the
+# Wifi Non-Updatable Framework Unit Tests
+This package contains unit tests for the non-updatable part (i.e. outside the Wifi module) of the
+Android Wifi framework APIs based on the
[Android Testing Support Library](http://developer.android.com/tools/testing-support-library/index.html).
The test cases are built using the [JUnit](http://junit.org/) and [Mockito](http://mockito.org/)
libraries.
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64
deleted file mode 100644
index 760c839..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w
-cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK
-UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW
-RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV
-SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj
-R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u
-ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy
-NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH
-VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx
-bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1
-dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB
-OFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0FnCklDQWdJQ0E4TDA1
-dlpHVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStSbEZF
-VGp3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSthRzkwYzNCdmRDNWxlR0Z0
-Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhP
-YjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6CmIzSjBhWFZ0
-VDBrOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFO
-alk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ
-Q0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldVK1EzSmxaR1Z1ZEdsaGJEd3ZU
-bTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrClpVNWhi
-V1UrVW1WaGJHMDhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbVY0WVcxd2JH
-VXVZMjl0UEM5V1lXeDEKWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObApjbTVoYldWUVlYTnpkMjl5WkR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2ClpH
-Vk9ZVzFsUGxWelpYSnVZVzFsUEM5T2IyUmxUbUZ0WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhW
-bFBuVnpaWEk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNB
-Z1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdApaVDVRWVhOemQyOXlaRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5rZG1OdFVUMDhMMVpo
-CmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFn
-SUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNUZRVkJOWlhSb2IyUThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZwpJQ0E4VG05a1pVNWhiV1Ur
-UlVGUVZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqSXhQ
-QzlXCllXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThU
-bTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1NXNXVaWEpOWlhSb2IyUThM
-MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TgpVeTFEU0VGUUxWWXlQ
-QzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nCklDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnMKUTJWeWRHbG1hV05oZEdVOEwwNXZaR1ZPWVcxbFBn
-b2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbApUbUZ0WlQ1RFpY
-SjBhV1pwWTJGMFpWUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV
-K2VEVXdPWFl6ClBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNB
-Z0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQTgKVG05a1pVNWhiV1UrUTJWeWRGTklRVEkxTmta
-cGJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpG
-bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt
-TVdZeFpqRm1NV1l4ClpqRm1NV1l4WmpGbU1XWThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlP
-YjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWcKSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn
-SUNBZ0lEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRTV2
-WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVKVFZOSlBDOU9iMlJsVG1GdFpUNEtJ
-Q0FnSUNBZ0lDQWdJQ0FnClBGWmhiSFZsUGpFeU16UTFOaW84TDFaaGJIVmxQZ29nSUNBZ0lDQWdJ
-Q0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9i
-MlJsVG1GdFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApi
-SFZsUGpJelBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEww
-NXZaR1UrQ2lBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lEd3ZUbTlrWlQ0S0lDQThMMDV2WkdVK0Nq
-d3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gt
-eDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKTFMwdExTMUNS
-VWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFowRjNTVUpCWjBsS1FV
-bE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFrbDRSVVJCVDBKblRs
-WUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJURk5SRVV4VjJoalRr
-MXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVWM1pFWlIKVmtGblVU
-QkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRoQlRVbEpRa05uUzBO
-QlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhKVFNWcFZTMjFXVlhO
-V2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0had2JqaERjMk5DTVN0
-dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQxY0VwbWNUSlUKUlVG
-RFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRWYlhNNE5FbDJTMmhT
-UWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pKT1ZGa2FHZ3JVR0py
-TUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5UTNZMmFqQjNRa3Mz
-YUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENLelZTZFhCU0swbGEK
-YVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFNUXA0Y0VnMVVHNVdN
-Mmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVWbEl3VDBKQ1dVVkdT
-WGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJNVlZrU1hkUk4wMUVi
-VUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEwWkVRVk1LVFZKQmQw
-Um4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6WnpkMFJCV1VSV1Vq
-QlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVWbEtTMjlhU1doMlkw
-NUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJtRnpORUpaZDBoRkNq
-bEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhsdFRVUmFNQzlVU1hk
-SlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdoMVNUUnpUbkpPUTA5
-MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNoSFJuRjZhSGxPYlcx
-V1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZRClkzQkZVWGcyZUUx
-dVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050V1RKdE9EbFdhSHBo
-U0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJxU1VkcVQxaHlaekZL
-VUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFLV25CdlRHdFBMM1Jr
-VGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJRU5GClVsUkpSa2xE
-UVZSRkxTMHRMUzBLCi0te2JvdW5kYXJ5fS0tCg==
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf
deleted file mode 100644
index 5b4e4cb..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf
+++ /dev/null
@@ -1,74 +0,0 @@
-MIME-Version: 1.0
-Content-Type: multipart/mixed; boundary={boundary}; charset=UTF-8
-Content-Transfer-Encoding: base64
-
---{boundary}
-Content-Type: application/x-passpoint-profile; charset=UTF-8
-Content-Transfer-Encoding: base64
-
-PE1nbXRUcmVlIHhtbG5zPSJzeW5jbWw6ZG1kZGYxLjIiPgogIDxWZXJEVEQ+MS4yPC9WZXJEVEQ+
-CiAgPE5vZGU+CiAgICA8Tm9kZU5hbWU+UGVyUHJvdmlkZXJTdWJzY3JpcHRpb248L05vZGVOYW1l
-PgogICAgPFJUUHJvcGVydGllcz4KICAgICAgPFR5cGU+CiAgICAgICAgPERERk5hbWU+dXJuOndm
-YTptbzpob3RzcG90MmRvdDAtcGVycHJvdmlkZXJzdWJzY3JpcHRpb246MS4wPC9EREZOYW1lPgog
-ICAgICA8L1R5cGU+CiAgICA8L1JUUHJvcGVydGllcz4KICAgIDxOb2RlPgogICAgICA8Tm9kZU5h
-bWU+aTAwMTwvTm9kZU5hbWU+CiAgICAgIDxOb2RlPgogICAgICAgIDxOb2RlTmFtZT5Ib21lU1A8
-L05vZGVOYW1lPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPkZyaWVuZGx5TmFt
-ZTwvTm9kZU5hbWU+CiAgICAgICAgICA8VmFsdWU+RXhhbXBsZSBOZXR3b3JrPC9WYWx1ZT4KICAg
-ICAgICA8L05vZGU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+RlFETjwvTm9k
-ZU5hbWU+CiAgICAgICAgICA8VmFsdWU+aG90c3BvdC5leGFtcGxlLm5ldDwvVmFsdWU+CiAgICAg
-ICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlJvYW1pbmdDb25z
-b3J0aXVtT0k8L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPjExMjIzMyw0NDU1NjY8L1ZhbHVl
-PgogICAgICAgIDwvTm9kZT4KICAgICAgPC9Ob2RlPgogICAgICA8Tm9kZT4KICAgICAgICA8Tm9k
-ZU5hbWU+Q3JlZGVudGlhbDwvTm9kZU5hbWU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9k
-ZU5hbWU+UmVhbG08L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPmV4YW1wbGUuY29tPC9WYWx1
-ZT4KICAgICAgICA8L05vZGU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+VXNl
-cm5hbWVQYXNzd29yZDwvTm9kZU5hbWU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5v
-ZGVOYW1lPlVzZXJuYW1lPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZhbHVlPnVzZXI8L1ZhbHVl
-PgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFt
-ZT5QYXNzd29yZDwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxWYWx1ZT5jR0Z6YzNkdmNtUT08L1Zh
-bHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2Rl
-TmFtZT5FQVBNZXRob2Q8L05vZGVOYW1lPgogICAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAg
-ICA8Tm9kZU5hbWU+RUFQVHlwZTwvTm9kZU5hbWU+CiAgICAgICAgICAgICAgPFZhbHVlPjIxPC9W
-YWx1ZT4KICAgICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAg
-ICA8Tm9kZU5hbWU+SW5uZXJNZXRob2Q8L05vZGVOYW1lPgogICAgICAgICAgICAgIDxWYWx1ZT5N
-Uy1DSEFQLVYyPC9WYWx1ZT4KICAgICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPC9Ob2RlPgog
-ICAgICAgIDwvTm9kZT4KICAgICAgICA8Tm9kZT4KICAgICAgICAgIDxOb2RlTmFtZT5EaWdpdGFs
-Q2VydGlmaWNhdGU8L05vZGVOYW1lPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2Rl
-TmFtZT5DZXJ0aWZpY2F0ZVR5cGU8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFsdWU+eDUwOXYz
-PC9WYWx1ZT4KICAgICAgICAgIDwvTm9kZT4KICAgICAgICAgIDxOb2RlPgogICAgICAgICAgICA8
-Tm9kZU5hbWU+Q2VydFNIQTI1NkZpbmdlcnByaW50PC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZh
-bHVlPjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYx
-ZjFmMWYxZjFmMWY8L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgIDwvTm9kZT4KICAg
-ICAgICA8Tm9kZT4KICAgICAgICAgIDxOb2RlTmFtZT5TSU08L05vZGVOYW1lPgogICAgICAgICAg
-PE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFtZT5JTVNJPC9Ob2RlTmFtZT4KICAgICAgICAgICAg
-PFZhbHVlPjEyMzQ1Nio8L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+
-CiAgICAgICAgICAgIDxOb2RlTmFtZT5FQVBUeXBlPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZh
-bHVlPjIzPC9WYWx1ZT4KICAgICAgICAgIDwvTm9kZT4KICAgICAgICA8L05vZGU+CiAgICAgIDwv
-Tm9kZT4KICAgIDwvTm9kZT4KICA8L05vZGU+CjwvTWdtdFRyZWU+
-
---{boundary}
-Content-Type: application/x-x509-ca-cert
-Content-Transfer-Encoding: base64
-
-LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURLRENDQWhDZ0F3SUJBZ0lKQUlMbEZkd3pM
-VnVyTUEwR0NTcUdTSWIzRFFFQkN3VUFNQkl4RURBT0JnTlYKQkFNVEIwVkJVQ0JEUVRFd0hoY05N
-VFl3TVRFeU1URTFNREUxV2hjTk1qWXdNVEE1TVRFMU1ERTFXakFTTVJBdwpEZ1lEVlFRREV3ZEZR
-VkFnUTBFeE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBCnpuQVBV
-ejI2TXNhZTR3czQzY3pSNDEvSjJRdHJTSVpVS21WVXNWdW1EYllIclBOdlRYS1NNWEFjZXdPUkRR
-WVgKUnF2SHZwbjhDc2NCMStvR1hadkh3eGo0elYwV0tvSzJ6ZVhrYXUzdmN5bDNISUt1cEpmcTJU
-RUFDZWZWamowdApKVytYMzVQR1dwOS9INXpJVU5WTlZqUzdVbXM4NEl2S2hSQjg1MTJQQjlVeUhh
-Z1hZVlg1R1dwQWNWcHlmcmxSCkZJOVFkaGgrUGJrMHV5a3RkYmYvQ2RmZ0hPb2ViclR0d1Jsak0w
-b0R0WCsyQ3Y2ajB3Qks3aEQ4cFB2ZjErdXkKR3pjemlnQVUvNEt3N2VacXlkZjlCKzVSdXBSK0la
-aXBYNDF4RWlJcktSd3FpNTE3V1d6WGNqYUcyY05iZjQ1MQp4cEg1UG5WM2kxdHEwNGpNR1FVekZ3
-SURBUUFCbzRHQU1INHdIUVlEVlIwT0JCWUVGSXdYNHZzOEJpQmNTY29kCjVub1pIUk04RTQraU1F
-SUdBMVVkSXdRN01EbUFGSXdYNHZzOEJpQmNTY29kNW5vWkhSTThFNCtpb1Jha0ZEQVMKTVJBd0Rn
-WURWUVFERXdkRlFWQWdRMEV4Z2drQWd1VVYzRE10VzZzd0RBWURWUjBUQkFVd0F3RUIvekFMQmdO
-VgpIUThFQkFNQ0FRWXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRmZRcU9UQTdSdjdLK2x1UTdw
-bmFzNEJZd0hFCjlHRVAvdW9odjZLT3kwVEdRRmJyUlRqRm9MVk5COUJaMXltTURaMC9USXdJVWM3
-d2k3YTh0NW1FcVlIMTUzd1cKYVdvb2lTanlMTGh1STRzTnJOQ090aXNkQnEycjJNRlh0NmgwbUFR
-WU9QdjhSOEs3L2ZnU3hHRnF6aHlObW1WTAoxcUJKbGR4MzRTcHdzVEFMUVZQYjRoR3dKelpmcjFQ
-Y3BFUXg2eE1uVGw4eEVXWkUzTXM5OXVhVXhiUXFJd1J1CkxnQU9rTkNtWTJtODlWaHphSEoxdVY4
-NUFkTS90RCtZc21sbm5qdDlMUkNlamJCaXBqSUdqT1hyZzFKUCtseFYKbXVNNHZIK1AvbWxteHNQ
-UHowZDY1YitFR21KWnBvTGtPL3RkTk52Q1l6akpwVEVXcEVzTzZOTWhLWW89Ci0tLS0tRU5EIENF
-UlRJRklDQVRFLS0tLS0K
---{boundary}--
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64
deleted file mode 100644
index 2775a9f..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9wYXNzcG9pbnQtcHJv
-ZmlsZTsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKClBF
-MW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lEeFdaWEpFVkVR
-K01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJXVStVR1Z5VUhK
-dmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BGSlVVSEp2Y0dW
-eWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRt
-CllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNKcGNIUnBiMjQ2
-TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFKVVVISnZjR1Z5
-ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRBd01Ud3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxV
-MUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZa
-R1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThW
-bUZzZFdVK1JYaGhiWEJzWlNCT1pYUjNiM0pyUEM5V1lXeDFaVDRLSUNBZwpJQ0FnSUNBOEwwNXZa
-R1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUmxGRVRq
-d3ZUbTlrClpVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrYUc5MGMzQnZkQzVsZUdGdGNH
-eGxMbTVsZER3dlZtRnNkV1UrQ2lBZ0lDQWcKSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2Iy
-UmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxKdllXMXBibWREYjI1egpiM0owYVhWdFQw
-azhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV4TWpJek15dzBORFUxTmpZ
-OEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNB
-Z0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWsKWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldV
-K1VtVmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUG1WNFlXMXdiR1V1
-WTI5dFBDOVdZV3gxClpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1Ur
-Q2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1ZYTmwKY201aGJXVlFZWE56ZDI5eVpEd3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dgpaR1ZP
-WVcxbFBsVnpaWEp1WVcxbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQ
-blZ6WlhJOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQ
-RTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnQKWlQ1UVlYTnpkMjl5WkR3dlRtOWta
-VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNWpSMFo2WXpOa2RtTnRVVDA4TDFaaApi
-SFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lD
-QWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVGUVZCTlpYUm9iMlE4TDA1dlpHVk9ZVzFsUGdvZ0lD
-QWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1JV
-RlFWSGx3WlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakl4UEM5
-VwpZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05
-a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnCklDQThUbTlrWlU1aGJXVStTVzV1WlhKTlpYUm9iMlE4TDA1
-dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNU4KVXkxRFNFRlFMVll5UEM5
-V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJs
-UGdvZwpJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0Fn
-SUR4T2IyUmxUbUZ0WlQ1RWFXZHBkR0ZzClEyVnlkR2xtYVdOaGRHVThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEow
-YVdacFkyRjBaVlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStl
-RFV3T1hZegpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJ
-RHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4ClRtOWtaVTVoYldVK1EyVnlkRk5JUVRJMU5rWnBi
-bWRsY25CeWFXNTBQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhWbFBqRm1N
-V1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1X
-WXhaakZtTVdZeApaakZtTVdZeFpqRm1NV1k4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVUU1UwOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWcKUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SlRWTkpQQzlPYjJSbFRtRnRaVDRLSUNB
-Z0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBqRXlNelExTmlvOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNB
-Z1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhW
-bFBqSXpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQThMMDV2
-WkdVK0NpQWdJQ0FnSUR3dgpUbTlrWlQ0S0lDQWdJRHd2VG05a1pUNEtJQ0E4TDA1dlpHVStDand2
-VFdkdGRGUnlaV1UrCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1
-MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVk
-SlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxN
-YkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlL
-UWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFx
-V1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJG
-ZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJV
-VVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldk
-VzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZS
-MWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRa
-V1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1Fq
-ZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1I
-VjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FF
-UTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFY
-QllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJr
-eGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hk
-WU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVG
-R1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJu
-CldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJV
-UWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVC
-VVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxI
-UlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpW
-V00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBh
-WE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdU
-QW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVW
-R3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNF
-b3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VD
-dHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1Rr
-NTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFW
-UkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64
deleted file mode 100644
index 7023453..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w
-cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK
-UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW
-RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV
-SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj
-R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u
-ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy
-NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH
-VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx
-bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1
-dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB
-OFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0FnCklDQWdJQ0E4TDA1
-dlpHVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStSbEZF
-VGp3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSthRzkwYzNCdmRDNWxlR0Z0
-Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhP
-YjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6CmIzSjBhWFZ0
-VDBrOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFO
-alk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ
-Q0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldVK1EzSmxaR1Z1ZEdsaGJEd3ZU
-bTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrClpVNWhi
-V1UrVW1WaGJHMDhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbVY0WVcxd2JH
-VXVZMjl0UEM5V1lXeDEKWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObApjbTVoYldWUVlYTnpkMjl5WkR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2ClpH
-Vk9ZVzFsUGxWelpYSnVZVzFsUEM5T2IyUmxUbUZ0WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhW
-bFBuVnpaWEk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNB
-Z1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdApaVDVRWVhOemQyOXlaRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5rZG1OdFVUMDhMMVpo
-CmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFn
-SUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNUZRVkJOWlhSb2IyUThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZwpJQ0E4VG05a1pVNWhiV1Ur
-UlVGUVZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqSXhQ
-QzlXCllXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThU
-bTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1NXNXVaWEpOWlhSb2IyUThM
-MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TgpVeTFEU0VGUUxWWXlQ
-QzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nCklDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnMKUTJWeWRHbG1hV05oZEdVOEwwNXZaR1ZPWVcxbFBn
-b2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbApUbUZ0WlQ1RFpY
-SjBhV1pwWTJGMFpWUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV
-K2VEVXdPWFl6ClBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNB
-Z0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQTgKVG05a1pVNWhiV1UrUTJWeWRGTklRVEkxTmta
-cGJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpG
-bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt
-TVdZeFpqRm1NV1l4ClpqRm1NV1l4WmpGbU1XWThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlP
-YjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWcKSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn
-SUNBZ0lEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRTV2
-WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVKVFZOSlBDOU9iMlJsVG1GdFpUNEtJ
-Q0FnSUNBZ0lDQWdJQ0FnClBGWmhiSFZsUGpFeU16UTFOaW84TDFaaGJIVmxQZ29nSUNBZ0lDQWdJ
-Q0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9i
-MlJsVG1GdFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApi
-SFZsUGpJelBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEww
-NXZaR1UrQ2lBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lEd3ZUbTlrWlQ0S0lDQThMMDV2WkdVK0Nq
-d3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gt
-eDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKTFMwdExTMUNS
-VWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFowRjNTVUpCWjBsS1FV
-bE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFrbDRSVVJCVDBKblRs
-WUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJURk5SRVV4VjJoalRr
-MXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVWM1pFWlIKVmtGblVU
-QkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRoQlRVbEpRa05uUzBO
-QlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhKVFNWcFZTMjFXVlhO
-V2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0had2JqaERjMk5DTVN0
-dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQxY0VwbWNUSlUKUlVG
-RFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRWYlhNNE5FbDJTMmhT
-UWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pKT1ZGa2FHZ3JVR0py
-TUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5UTNZMmFqQjNRa3Mz
-YUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENLelZTZFhCU0swbGEK
-YVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFNUXA0Y0VnMVVHNVdN
-Mmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVWbEl3VDBKQ1dVVkdT
-WGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJNVlZrU1hkUk4wMUVi
-VUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEwWkVRVk1LVFZKQmQw
-Um4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6WnpkMFJCV1VSV1Vq
-QlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVWbEtTMjlhU1doMlkw
-NUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJtRnpORUpaZDBoRkNq
-bEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhsdFRVUmFNQzlVU1hk
-SlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdoMVNUUnpUbkpPUTA5
-MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNoSFJuRjZhSGxPYlcx
-V1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZRClkzQkZVWGcyZUUx
-dVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050V1RKdE9EbFdhSHBo
-U0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJxU1VkcVQxaHlaekZL
-VUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFLV25CdlRHdFBMM1Jr
-VGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJRU5GClVsUkpSa2xE
-UVZSRkxTMHRMUzBLCg==
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64
deleted file mode 100644
index 5c23f61..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogOGJp
-dAoKLS17Ym91bmRhcnl9CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC1wYXNzcG9pbnQtcHJv
-ZmlsZTsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKClBF
-MW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lEeFdaWEpFVkVR
-K01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJXVStVR1Z5VUhK
-dmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BGSlVVSEp2Y0dW
-eWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRt
-CllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNKcGNIUnBiMjQ2
-TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFKVVVISnZjR1Z5
-ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRBd01Ud3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxV
-MUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZa
-R1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThW
-bUZzZFdVK1JYaGhiWEJzWlNCT1pYUjNiM0pyUEM5V1lXeDFaVDRLSUNBZwpJQ0FnSUNBOEwwNXZa
-R1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUmxGRVRq
-d3ZUbTlrClpVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrYUc5MGMzQnZkQzVsZUdGdGNH
-eGxMbTVsZER3dlZtRnNkV1UrQ2lBZ0lDQWcKSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2Iy
-UmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxKdllXMXBibWREYjI1egpiM0owYVhWdFQw
-azhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV4TWpJek15dzBORFUxTmpZ
-OEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNB
-Z0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWsKWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldV
-K1VtVmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUG1WNFlXMXdiR1V1
-WTI5dFBDOVdZV3gxClpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1Ur
-Q2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1ZYTmwKY201aGJXVlFZWE56ZDI5eVpEd3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dgpaR1ZP
-WVcxbFBsVnpaWEp1WVcxbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQ
-blZ6WlhJOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQ
-RTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnQKWlQ1UVlYTnpkMjl5WkR3dlRtOWta
-VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNWpSMFo2WXpOa2RtTnRVVDA4TDFaaApi
-SFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lD
-QWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVGUVZCTlpYUm9iMlE4TDA1dlpHVk9ZVzFsUGdvZ0lD
-QWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1JV
-RlFWSGx3WlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakl4UEM5
-VwpZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05
-a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnCklDQThUbTlrWlU1aGJXVStTVzV1WlhKTlpYUm9iMlE4TDA1
-dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNU4KVXkxRFNFRlFMVll5UEM5
-V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJs
-UGdvZwpJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0Fn
-SUR4T2IyUmxUbUZ0WlQ1RWFXZHBkR0ZzClEyVnlkR2xtYVdOaGRHVThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEow
-YVdacFkyRjBaVlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStl
-RFV3T1hZegpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJ
-RHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4ClRtOWtaVTVoYldVK1EyVnlkRk5JUVRJMU5rWnBi
-bWRsY25CeWFXNTBQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhWbFBqRm1N
-V1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1X
-WXhaakZtTVdZeApaakZtTVdZeFpqRm1NV1k4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVUU1UwOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWcKUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SlRWTkpQQzlPYjJSbFRtRnRaVDRLSUNB
-Z0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBqRXlNelExTmlvOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNB
-Z1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhW
-bFBqSXpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQThMMDV2
-WkdVK0NpQWdJQ0FnSUR3dgpUbTlrWlQ0S0lDQWdJRHd2VG05a1pUNEtJQ0E4TDA1dlpHVStDand2
-VFdkdGRGUnlaV1UrCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1
-MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVk
-SlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxN
-YkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlL
-UWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFx
-V1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJG
-ZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJV
-VVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldk
-VzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZS
-MWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRa
-V1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1Fq
-ZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1I
-VjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FF
-UTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFY
-QllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJr
-eGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hk
-WU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVG
-R1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJu
-CldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJV
-UWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVC
-VVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxI
-UlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpW
-V00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBh
-WE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdU
-QW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVW
-R3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNF
-b3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VD
-dHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1Rr
-NTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFW
-UkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64
deleted file mode 100644
index bab7607..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64
+++ /dev/null
@@ -1,88 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w
-cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK
-UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW
-RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV
-SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj
-R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u
-ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy
-NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH
-VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVStWWEJrWVhSbFNX
-UmxiblJwWm1sbGNqd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lEeFdZV3gxWlQ0eE1qTTBQQzlXWVd4
-MVpUNEsKSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoYldV
-K2FUQXdNVHd2VG05a1pVNWhiV1UrQ2lBZwpJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVJYjIxbFUxQThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJRHhPCmIyUmxQZ29nSUNB
-Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdFpUd3ZUbTlrWlU1aGJXVStDaUFn
-SUNBZ0lDQWcKSUNBOFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0Fn
-SUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZwpQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlr
-WlU1aGJXVStSbEZFVGp3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthRzkw
-YzNCdmRDNWxlR0Z0Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ
-Q0FnSUNBZ0lEeE8KYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERi
-MjV6YjNKMGFYVnRUMGs4TDA1dlpHVk9ZVzFsUGdvZwpJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhN
-akl6TXl3ME5EVTFOalk4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdQ
-QzlPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUTNKbFpH
-VnVkR2xoYkR3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lD
-QThUbTlrWlU1aGJXVStVbVZoYkcwOEwwNXZaR1ZPWVcxbApQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJI
-VmxQbVY0WVcxd2JHVXVZMjl0UEM5V1lXeDFaVDRLSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnCklD
-QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObGNtNWhiV1ZRWVhO
-emQyOXlaRHd2VG05a1pVNWgKYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNB
-Z0lDQWdQRTV2WkdWT1lXMWxQbFZ6WlhKdVlXMWxQQzlPYjJSbApUbUZ0WlQ0S0lDQWdJQ0FnSUNB
-Z0lDQWdQRlpoYkhWbFBuVnpaWEk4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29n
-CklDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdFpUNVFZWE56
-ZDI5eVpEd3ZUbTlrWlU1aGJXVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5r
-ZG1OdFVUMDhMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbApQZ29nSUNBZ0lDQWdJQ0Fn
-UEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1RlFWQk5aWFJvYjJROEwwNXZa
-R1ZPCllXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQThU
-bTlrWlU1aGJXVStSVUZRVkhsd1pUd3YKVG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQ
-RlpoYkhWbFBqSXhQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5TwpiMlJsUGdvZ0lDQWdJ
-Q0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrU1c1dVpY
-Sk5aWFJvCmIyUThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TlV5
-MURTRUZRTFZZeVBDOVdZV3gxWlQ0S0lDQWcKSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD
-QWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZwpJQ0E4VG05a1pU
-NEtJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnNRMlZ5ZEdsbWFXTmhkR1U4TDA1
-dlpHVk9ZVzFsClBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVEWlhKMGFXWnBZMkYwWlZSNWNHVTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNB
-Z0lDQThWbUZzZFdVK2VEVXdPWFl6UEM5V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUR3dgpUbTlrWlQ0
-S0lDQWdJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRMlZ5
-ZEZOSVFUSTFOa1pwCmJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0Fn
-UEZaaGJIVmxQakZtTVdZeFpqRm1NV1l4WmpGbU1XWXgKWmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4
-WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZOEwxWmhiSFZsUGdvZwpJQ0Fn
-SUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWta
-VDRLSUNBZ0lDQWdJQ0FnCklEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJ
-Q0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKVFZOSlBDOU9i
-MlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV5TXpRMU5pbzhMMVpoYkhWbApQ
-Z29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lD
-QWdJQ0FnSUR4T2IyUmxUbUZ0ClpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lD
-QWdJQ0FnUEZaaGJIVmxQakl6UEM5V1lXeDFaVDRLSUNBZ0lDQWcKSUNBZ0lEd3ZUbTlrWlQ0S0lD
-QWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUR3dlRtOWtaVDRLSUNB
-OApMMDV2WkdVK0Nqd3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFw
-cGxpY2F0aW9uL3gteDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2
-NAoKTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFow
-RjNTVUpCWjBsS1FVbE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFr
-bDRSVVJCVDBKblRsWUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJU
-Rk5SRVV4VjJoalRrMXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVW
-M1pFWlIKVmtGblVUQkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRo
-QlRVbEpRa05uUzBOQlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhK
-VFNWcFZTMjFXVlhOV2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0ha
-d2JqaERjMk5DTVN0dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQx
-Y0VwbWNUSlUKUlVGRFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRW
-YlhNNE5FbDJTMmhTUWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pK
-T1ZGa2FHZ3JVR0pyTUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5
-UTNZMmFqQjNRa3MzYUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENL
-elZTZFhCU0swbGEKYVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFN
-UXA0Y0VnMVVHNVdNMmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVW
-bEl3VDBKQ1dVVkdTWGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJN
-VlZrU1hkUk4wMUViVUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEw
-WkVRVk1LVFZKQmQwUm4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6
-WnpkMFJCV1VSV1VqQlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVW
-bEtTMjlhU1doMlkwNUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJt
-RnpORUpaZDBoRkNqbEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhs
-dFRVUmFNQzlVU1hkSlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdo
-MVNUUnpUbkpPUTA5MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNo
-SFJuRjZhSGxPYlcxV1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZR
-ClkzQkZVWGcyZUUxdVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050
-V1RKdE9EbFdhSHBoU0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJx
-U1VkcVQxaHlaekZLVUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFL
-V25CdlRHdFBMM1JrVGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJ
-RU5GClVsUkpSa2xEUVZSRkxTMHRMUzBLCi0te2JvdW5kYXJ5fS0tCg==
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithoutProfile.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithoutProfile.base64
deleted file mode 100644
index 833c527..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithoutProfile.base64
+++ /dev/null
@@ -1,31 +0,0 @@
-Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu
-dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh
-cHBsaWNhdGlvbi94LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNl
-NjQKCkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERa
-MEYzU1VKQlowbEtRVWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5R
-a2w0UlVSQlQwSm5UbFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVS
-VEZOUkVVeFYyaGpUazFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJF
-VjNaRVpSClZrRm5VVEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVU
-aEJUVWxKUWtOblMwTkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRI
-SlRTVnBWUzIxV1ZYTldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNI
-WndiamhEYzJOQ01TdHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0
-MWNFcG1jVEpVClJVRkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpk
-VmJYTTRORWwyUzJoU1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2ta
-Sk9WRmthR2dyVUdKck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0Nz
-eVEzWTJhakIzUWtzM2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxD
-S3pWU2RYQlNLMGxhCmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalEx
-TVFwNGNFZzFVRzVXTTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxF
-VmxJd1QwSkNXVVZHU1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRC
-TVZWa1NYZFJOMDFFYlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhh
-MFpFUVZNS1RWSkJkMFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBW
-elp6ZDBSQldVUldVakJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVV
-VmxLUzI5YVNXaDJZMDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpi
-bUZ6TkVKWmQwaEZDamxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1Y
-bHRUVVJhTUM5VVNYZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRH
-aDFTVFJ6VG5KT1EwOTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUz
-aEhSbkY2YUhsT2JXMVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pG
-UQpZM0JGVVhnMmVFMXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtO
-dFdUSnRPRGxXYUhwaFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhC
-cVNVZHFUMWh5WnpGS1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIx
-S1duQnZUR3RQTDNSa1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVF
-SUVORgpVbFJKUmtsRFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
diff --git a/wifi/tests/assets/hsr1/README.txt b/wifi/tests/assets/hsr1/README.txt
deleted file mode 100644
index 9f3cdc2..0000000
--- a/wifi/tests/assets/hsr1/README.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-HSR1ProfileWithCACert.conf - unencoded installation file that contains a Passpoint profile and a CA Certificate
-HSR1ProfileWithCACert.base64 - base64 encoded of the data contained in HSR1ProfileWithCAWith.conf
-HSR1ProfileWithNonBase64Part.base64 - base64 encoded installation file that contains a part of non-base64 encoding type
-HSR1ProfileWithMissingBoundary.base64 - base64 encoded installation file with missing end-boundary in the MIME data
-HSR1ProfileWithInvalidContentType.base64 - base64 encoded installation file with that contains a MIME part with an invalid content type
-HSR1ProfileWithUpdateIdentifier.base64 - base64 encoded installation file with that contains an R2 update identifier
diff --git a/wifi/tests/assets/pps/PerProviderSubscription.xml b/wifi/tests/assets/pps/PerProviderSubscription.xml
deleted file mode 100644
index e9afb35..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription.xml
+++ /dev/null
@@ -1,430 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
- <VerDTD>1.2</VerDTD>
- <Node>
- <NodeName>PerProviderSubscription</NodeName>
- <RTProperties>
- <Type>
- <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
- </Type>
- </RTProperties>
- <Node>
- <NodeName>UpdateIdentifier</NodeName>
- <Value>12</Value>
- </Node>
- <Node>
- <NodeName>i001</NodeName>
- <Node>
- <NodeName>Extension</NodeName>
- <Node>
- <NodeName>VendorSpecific</NodeName>
- <Value>Test</Value>
- </Node>
- <Node>
- <NodeName>VendorExtension</NodeName>
- <Node>
- <NodeName>VendorAttribute</NodeName>
- <Value>VendorValue</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>Android</NodeName>
- <Node>
- <NodeName>AAAServerTrustedNames</NodeName>
- <Node>
- <NodeName>FQDN</NodeName>
- <Value>trusted.fqdn.com;another-trusted.fqdn.com</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>NewSubTree</NodeName>
- <Node>
- <NodeName>NewAttribute</NodeName>
- <Value>NewValue</Value>
- </Node>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>HomeSP</NodeName>
- <Node>
- <NodeName>FriendlyName</NodeName>
- <Value>Century House</Value>
- </Node>
- <Node>
- <NodeName>FQDN</NodeName>
- <Value>mi6.co.uk</Value>
- </Node>
- <Node>
- <NodeName>RoamingConsortiumOI</NodeName>
- <Value>112233,445566</Value>
- </Node>
- <Node>
- <NodeName>IconURL</NodeName>
- <Value>icon.test.com</Value>
- </Node>
- <Node>
- <NodeName>NetworkID</NodeName>
- <Node>
- <NodeName>n001</NodeName>
- <Node>
- <NodeName>SSID</NodeName>
- <Value>TestSSID</Value>
- </Node>
- <Node>
- <NodeName>HESSID</NodeName>
- <Value>12345678</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>n002</NodeName>
- <Node>
- <NodeName>SSID</NodeName>
- <Value>NullHESSID</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>HomeOIList</NodeName>
- <Node>
- <NodeName>h001</NodeName>
- <Node>
- <NodeName>HomeOI</NodeName>
- <Value>11223344</Value>
- </Node>
- <Node>
- <NodeName>HomeOIRequired</NodeName>
- <Value>true</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>h002</NodeName>
- <Node>
- <NodeName>HomeOI</NodeName>
- <Value>55667788</Value>
- </Node>
- <Node>
- <NodeName>HomeOIRequired</NodeName>
- <Value>false</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>OtherHomePartners</NodeName>
- <Node>
- <NodeName>o001</NodeName>
- <Node>
- <NodeName>FQDN</NodeName>
- <Value>other.fqdn.com</Value>
- </Node>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>Credential</NodeName>
- <Node>
- <NodeName>CreationDate</NodeName>
- <Value>2016-01-01T10:00:00Z</Value>
- </Node>
- <Node>
- <NodeName>ExpirationDate</NodeName>
- <Value>2016-02-01T10:00:00Z</Value>
- </Node>
- <Node>
- <NodeName>Realm</NodeName>
- <Value>shaken.stirred.com</Value>
- </Node>
- <Node>
- <NodeName>CheckAAAServerCertStatus</NodeName>
- <Value>true</Value>
- </Node>
- <Node>
- <NodeName>UsernamePassword</NodeName>
- <Node>
- <NodeName>Username</NodeName>
- <Value>james</Value>
- </Node>
- <Node>
- <NodeName>Password</NodeName>
- <Value>Ym9uZDAwNw==</Value>
- </Node>
- <Node>
- <NodeName>MachineManaged</NodeName>
- <Value>true</Value>
- </Node>
- <Node>
- <NodeName>SoftTokenApp</NodeName>
- <Value>TestApp</Value>
- </Node>
- <Node>
- <NodeName>AbleToShare</NodeName>
- <Value>true</Value>
- </Node>
- <Node>
- <NodeName>EAPMethod</NodeName>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>21</Value>
- </Node>
- <Node>
- <NodeName>InnerMethod</NodeName>
- <Value>MS-CHAP-V2</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>DigitalCertificate</NodeName>
- <Node>
- <NodeName>CertificateType</NodeName>
- <Value>x509v3</Value>
- </Node>
- <Node>
- <NodeName>CertSHA256Fingerprint</NodeName>
- <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>SIM</NodeName>
- <Node>
- <NodeName>IMSI</NodeName>
- <Value>imsi</Value>
- </Node>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>24</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>Policy</NodeName>
- <Node>
- <NodeName>PreferredRoamingPartnerList</NodeName>
- <Node>
- <NodeName>p001</NodeName>
- <Node>
- <NodeName>FQDN_Match</NodeName>
- <Value>test1.fqdn.com,exactMatch</Value>
- </Node>
- <Node>
- <NodeName>Priority</NodeName>
- <Value>127</Value>
- </Node>
- <Node>
- <NodeName>Country</NodeName>
- <Value>us,fr</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>p002</NodeName>
- <Node>
- <NodeName>FQDN_Match</NodeName>
- <Value>test2.fqdn.com,includeSubdomains</Value>
- </Node>
- <Node>
- <NodeName>Priority</NodeName>
- <Value>200</Value>
- </Node>
- <Node>
- <NodeName>Country</NodeName>
- <Value>*</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>MinBackhaulThreshold</NodeName>
- <Node>
- <NodeName>m001</NodeName>
- <Node>
- <NodeName>NetworkType</NodeName>
- <Value>home</Value>
- </Node>
- <Node>
- <NodeName>DLBandwidth</NodeName>
- <Value>23412</Value>
- </Node>
- <Node>
- <NodeName>ULBandwidth</NodeName>
- <Value>9823</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>m002</NodeName>
- <Node>
- <NodeName>NetworkType</NodeName>
- <Value>roaming</Value>
- </Node>
- <Node>
- <NodeName>DLBandwidth</NodeName>
- <Value>9271</Value>
- </Node>
- <Node>
- <NodeName>ULBandwidth</NodeName>
- <Value>2315</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>PolicyUpdate</NodeName>
- <Node>
- <NodeName>UpdateInterval</NodeName>
- <Value>120</Value>
- </Node>
- <Node>
- <NodeName>UpdateMethod</NodeName>
- <Value>OMA-DM-ClientInitiated</Value>
- </Node>
- <Node>
- <NodeName>Restriction</NodeName>
- <Value>HomeSP</Value>
- </Node>
- <Node>
- <NodeName>URI</NodeName>
- <Value>policy.update.com</Value>
- </Node>
- <Node>
- <NodeName>UsernamePassword</NodeName>
- <Node>
- <NodeName>Username</NodeName>
- <Value>updateUser</Value>
- </Node>
- <Node>
- <NodeName>Password</NodeName>
- <Value>updatePass</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>TrustRoot</NodeName>
- <Node>
- <NodeName>CertURL</NodeName>
- <Value>update.cert.com</Value>
- </Node>
- <Node>
- <NodeName>CertSHA256Fingerprint</NodeName>
- <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>SPExclusionList</NodeName>
- <Node>
- <NodeName>s001</NodeName>
- <Node>
- <NodeName>SSID</NodeName>
- <Value>excludeSSID</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>RequiredProtoPortTuple</NodeName>
- <Node>
- <NodeName>r001</NodeName>
- <Node>
- <NodeName>IPProtocol</NodeName>
- <Value>12</Value>
- </Node>
- <Node>
- <NodeName>PortNumber</NodeName>
- <Value>34,92,234</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>MaximumBSSLoadValue</NodeName>
- <Value>23</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>CredentialPriority</NodeName>
- <Value>99</Value>
- </Node>
- <Node>
- <NodeName>AAAServerTrustRoot</NodeName>
- <Node>
- <NodeName>a001</NodeName>
- <Node>
- <NodeName>CertURL</NodeName>
- <Value>server1.trust.root.com</Value>
- </Node>
- <Node>
- <NodeName>CertSHA256Fingerprint</NodeName>
- <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>SubscriptionUpdate</NodeName>
- <Node>
- <NodeName>UpdateInterval</NodeName>
- <Value>120</Value>
- </Node>
- <Node>
- <NodeName>UpdateMethod</NodeName>
- <Value>SSP-ClientInitiated</Value>
- </Node>
- <Node>
- <NodeName>Restriction</NodeName>
- <Value>RoamingPartner</Value>
- </Node>
- <Node>
- <NodeName>URI</NodeName>
- <Value>subscription.update.com</Value>
- </Node>
- <Node>
- <NodeName>UsernamePassword</NodeName>
- <Node>
- <NodeName>Username</NodeName>
- <Value>subscriptionUser</Value>
- </Node>
- <Node>
- <NodeName>Password</NodeName>
- <Value>subscriptionPass</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>TrustRoot</NodeName>
- <Node>
- <NodeName>CertURL</NodeName>
- <Value>subscription.update.cert.com</Value>
- </Node>
- <Node>
- <NodeName>CertSHA256Fingerprint</NodeName>
- <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>SubscriptionParameters</NodeName>
- <Node>
- <NodeName>CreationDate</NodeName>
- <Value>2016-02-01T10:00:00Z</Value>
- </Node>
- <Node>
- <NodeName>ExpirationDate</NodeName>
- <Value>2016-03-01T10:00:00Z</Value>
- </Node>
- <Node>
- <NodeName>TypeOfSubscription</NodeName>
- <Value>Gold</Value>
- </Node>
- <Node>
- <NodeName>UsageLimits</NodeName>
- <Node>
- <NodeName>DataLimit</NodeName>
- <Value>921890</Value>
- </Node>
- <Node>
- <NodeName>StartDate</NodeName>
- <Value>2016-12-01T10:00:00Z</Value>
- </Node>
- <Node>
- <NodeName>TimeLimit</NodeName>
- <Value>120</Value>
- </Node>
- <Node>
- <NodeName>UsageTimePeriod</NodeName>
- <Value>99910</Value>
- </Node>
- </Node>
- </Node>
- </Node>
- </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml b/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml
deleted file mode 100644
index e13eb2a..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
- <VerDTD>1.2</VerDTD>
- <Node>
- <NodeName>PerProviderSubscription</NodeName>
- <RTProperties>
- <Type>
- <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
- </Type>
- </RTProperties>
- <Node>
- <NodeName>i001</NodeName>
- <Node>
- <NodeName>HomeSP</NodeName>
- <Node>
- <NodeName>FriendlyName</NodeName>
- <Value>Century House</Value>
- </Node>
- <Node>
- <NodeName>FQDN</NodeName>
- <Value>mi6.co.uk</Value>
- </Node>
- <Node>
- <NodeName>RoamingConsortiumOI</NodeName>
- <Value>112233,445566</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>HomeSP</NodeName>
- <Node>
- <NodeName>FriendlyName</NodeName>
- <Value>Century House</Value>
- </Node>
- <Node>
- <NodeName>FQDN</NodeName>
- <Value>mi6.co.uk</Value>
- </Node>
- <Node>
- <NodeName>RoamingConsortiumOI</NodeName>
- <Value>112233,445566</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>Credential</NodeName>
- <Node>
- <NodeName>Realm</NodeName>
- <Value>shaken.stirred.com</Value>
- </Node>
- <Node>
- <NodeName>UsernamePassword</NodeName>
- <Node>
- <NodeName>Username</NodeName>
- <Value>james</Value>
- </Node>
- <Node>
- <NodeName>Password</NodeName>
- <Value>Ym9uZDAwNw==</Value>
- </Node>
- <Node>
- <NodeName>EAPMethod</NodeName>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>21</Value>
- </Node>
- <Node>
- <NodeName>InnerMethod</NodeName>
- <Value>MS-CHAP-V2</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>DigitalCertificate</NodeName>
- <Node>
- <NodeName>CertificateType</NodeName>
- <Value>x509v3</Value>
- </Node>
- <Node>
- <NodeName>CertSHA256FingerPrint</NodeName>
- <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>SIM</NodeName>
- <Node>
- <NodeName>IMSI</NodeName>
- <Value>imsi</Value>
- </Node>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>24</Value>
- </Node>
- </Node>
- </Node>
- </Node>
- </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml b/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml
deleted file mode 100644
index 8719ffa..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
- <VerDTD>1.2</VerDTD>
- <Node>
- <NodeName>PerProviderSubscription</NodeName>
- <RTProperties>
- <Type>
- <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
- </Type>
- </RTProperties>
- <Node>
- <NodeName>i001</NodeName>
- <Node>
- <NodeName>HomeSP</NodeName>
- <Node>
- <NodeName>FriendlyName</NodeName>
- <Value>Century House</Value>
- <Value>Century House</Value>
- </Node>
- <Node>
- <NodeName>FQDN</NodeName>
- <Value>mi6.co.uk</Value>
- </Node>
- <Node>
- <NodeName>RoamingConsortiumOI</NodeName>
- <Value>112233,445566</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>Credential</NodeName>
- <Node>
- <NodeName>Realm</NodeName>
- <Value>shaken.stirred.com</Value>
- </Node>
- <Node>
- <NodeName>UsernamePassword</NodeName>
- <Node>
- <NodeName>Username</NodeName>
- <Value>james</Value>
- </Node>
- <Node>
- <NodeName>Password</NodeName>
- <Value>Ym9uZDAwNw==</Value>
- </Node>
- <Node>
- <NodeName>EAPMethod</NodeName>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>21</Value>
- </Node>
- <Node>
- <NodeName>InnerMethod</NodeName>
- <Value>MS-CHAP-V2</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>DigitalCertificate</NodeName>
- <Node>
- <NodeName>CertificateType</NodeName>
- <Value>x509v3</Value>
- </Node>
- <Node>
- <NodeName>CertSHA256FingerPrint</NodeName>
- <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>SIM</NodeName>
- <Node>
- <NodeName>IMSI</NodeName>
- <Value>imsi</Value>
- </Node>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>24</Value>
- </Node>
- </Node>
- </Node>
- </Node>
- </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml b/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml
deleted file mode 100644
index c761237..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
- <VerDTD>1.2</VerDTD>
- <Node>
- <NodeName>PerProviderSubscription</NodeName>
- <RTProperties>
- <Type>
- <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
- </Type>
- </RTProperties>
- <Node>
- <NodeName>i001</NodeName>
- <Node>
- <NodeName>HomeSP</NodeName>
- <Node>
- <NodeName>FriendName</NodeName>
- <Value>Century House</Value>
- </Node>
- <Node>
- <NodeName>FQDN</NodeName>
- <Value>mi6.co.uk</Value>
- </Node>
- <Node>
- <NodeName>RoamingConsortiumOI</NodeName>
- <Value>112233,445566</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>Credential</NodeName>
- <Node>
- <NodeName>Realm</NodeName>
- <Value>shaken.stirred.com</Value>
- </Node>
- <Node>
- <NodeName>UsernamePassword</NodeName>
- <Node>
- <NodeName>Username</NodeName>
- <Value>james</Value>
- </Node>
- <Node>
- <NodeName>Password</NodeName>
- <Value>Ym9uZDAwNw==</Value>
- </Node>
- <Node>
- <NodeName>EAPMethod</NodeName>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>21</Value>
- </Node>
- <Node>
- <NodeName>InnerMethod</NodeName>
- <Value>MS-CHAP-V2</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>DigitalCertificate</NodeName>
- <Node>
- <NodeName>CertificateType</NodeName>
- <Value>x509v3</Value>
- </Node>
- <Node>
- <NodeName>CertSHA256FingerPrint</NodeName>
- <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>SIM</NodeName>
- <Node>
- <NodeName>IMSI</NodeName>
- <Value>imsi</Value>
- </Node>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>24</Value>
- </Node>
- </Node>
- </Node>
- </Node>
- </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml b/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml
deleted file mode 100644
index 6b807af..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
- <VerDTD>1.2</VerDTD>
- <Node>
- <NodeName>PerProviderSubscription</NodeName>
- <RTProperties>
- <Type>
- <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
- </Type>
- </RTProperties>
- <Node>
- <NodeName>i001</NodeName>
- <Node>
- <NodeName>HomeSP</NodeName>
- <Node>
- <NodeName>FriendlyName</NodeName>
- <Value>Century House</Value>
- </Node>
- <Node>
- <NodeName>FQDN</NodeName>
- <Value>mi6.co.uk</Value>
- <Node>
- <NodeName>InvalidNode</NodeName>
- <Value>Test</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>RoamingConsortiumOI</NodeName>
- <Value>112233,445566</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>Credential</NodeName>
- <Node>
- <NodeName>Realm</NodeName>
- <Value>shaken.stirred.com</Value>
- </Node>
- <Node>
- <NodeName>UsernamePassword</NodeName>
- <Node>
- <NodeName>Username</NodeName>
- <Value>james</Value>
- </Node>
- <Node>
- <NodeName>Password</NodeName>
- <Value>Ym9uZDAwNw==</Value>
- </Node>
- <Node>
- <NodeName>EAPMethod</NodeName>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>21</Value>
- </Node>
- <Node>
- <NodeName>InnerMethod</NodeName>
- <Value>MS-CHAP-V2</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>DigitalCertificate</NodeName>
- <Node>
- <NodeName>CertificateType</NodeName>
- <Value>x509v3</Value>
- </Node>
- <Node>
- <NodeName>CertSHA256FingerPrint</NodeName>
- <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>SIM</NodeName>
- <Node>
- <NodeName>IMSI</NodeName>
- <Value>imsi</Value>
- </Node>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>24</Value>
- </Node>
- </Node>
- </Node>
- </Node>
- </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml b/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml
deleted file mode 100644
index ed06b47..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
- <VerDTD>1.2</VerDTD>
- <Node>
- <NodeName>PerProviderSubscription</NodeName>
- <RTProperties>
- <Type>
- <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
- </Type>
- </RTProperties>
- <Node>
- <NodeName>i001</NodeName>
- <Node>
- <Node>
- <NodeName>FriendlyName</NodeName>
- <Value>Century House</Value>
- </Node>
- <Node>
- <NodeName>FQDN</NodeName>
- <Value>mi6.co.uk</Value>
- </Node>
- <Node>
- <NodeName>RoamingConsortiumOI</NodeName>
- <Value>112233,445566</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>Credential</NodeName>
- <Node>
- <NodeName>Realm</NodeName>
- <Value>shaken.stirred.com</Value>
- </Node>
- <Node>
- <NodeName>UsernamePassword</NodeName>
- <Node>
- <NodeName>Username</NodeName>
- <Value>james</Value>
- </Node>
- <Node>
- <NodeName>Password</NodeName>
- <Value>Ym9uZDAwNw==</Value>
- </Node>
- <Node>
- <NodeName>EAPMethod</NodeName>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>21</Value>
- </Node>
- <Node>
- <NodeName>InnerMethod</NodeName>
- <Value>MS-CHAP-V2</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>DigitalCertificate</NodeName>
- <Node>
- <NodeName>CertificateType</NodeName>
- <Value>x509v3</Value>
- </Node>
- <Node>
- <NodeName>CertSHA256FingerPrint</NodeName>
- <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>SIM</NodeName>
- <Node>
- <NodeName>IMSI</NodeName>
- <Value>imsi</Value>
- </Node>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>24</Value>
- </Node>
- </Node>
- </Node>
- </Node>
- </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml b/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml
deleted file mode 100644
index f7e35dd..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
- <VerDTD>1.2</VerDTD>
- <Node>
- <NodeName>PerProviderSubscription</NodeName>
- <RTProperties>
- <Type>
- <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
- </Type>
- </RTProperties>
- <Node>
- <NodeName>i001</NodeName>
- <Node>
- <NodeName>HomeSP</NodeName>
- <Node>
- <NodeName>FriendlyName</NodeName>
- </Node>
- <Node>
- <NodeName>FQDN</NodeName>
- <Value>mi6.co.uk</Value>
- </Node>
- <Node>
- <NodeName>RoamingConsortiumOI</NodeName>
- <Value>112233,445566</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>Credential</NodeName>
- <Node>
- <NodeName>Realm</NodeName>
- <Value>shaken.stirred.com</Value>
- </Node>
- <Node>
- <NodeName>UsernamePassword</NodeName>
- <Node>
- <NodeName>Username</NodeName>
- <Value>james</Value>
- </Node>
- <Node>
- <NodeName>Password</NodeName>
- <Value>Ym9uZDAwNw==</Value>
- </Node>
- <Node>
- <NodeName>EAPMethod</NodeName>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>21</Value>
- </Node>
- <Node>
- <NodeName>InnerMethod</NodeName>
- <Value>MS-CHAP-V2</Value>
- </Node>
- </Node>
- </Node>
- <Node>
- <NodeName>DigitalCertificate</NodeName>
- <Node>
- <NodeName>CertificateType</NodeName>
- <Value>x509v3</Value>
- </Node>
- <Node>
- <NodeName>CertSHA256FingerPrint</NodeName>
- <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
- </Node>
- </Node>
- <Node>
- <NodeName>SIM</NodeName>
- <Node>
- <NodeName>IMSI</NodeName>
- <Value>imsi</Value>
- </Node>
- <Node>
- <NodeName>EAPType</NodeName>
- <Value>24</Value>
- </Node>
- </Node>
- </Node>
- </Node>
- </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/README.txt b/wifi/tests/assets/pps/README.txt
deleted file mode 100644
index 369c0a9..0000000
--- a/wifi/tests/assets/pps/README.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-PerProviderSubscription.xml - valid PPS XML file
-PerProviderSubscription_DuplicateHomeSP.xml - containing multiple HomeSP node
-PerProviderSubscription_DuplicateValue.xml - FriendlyName node contains multiple Value
-PerProviderSubscription_MissingValue.xml - FriendlyName node is missing Value
-PerProviderSubscription_MissingName.xml - HomeSP node is missing NodeName
-PerProviderSubscription_InvalidNode.xml - FQDN node contains both Value and a child node
-PerProviderSubscription_InvalidName.xml - FriendlyName node have a typo in its name
diff --git a/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java b/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java
deleted file mode 100644
index b101414..0000000
--- a/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java
+++ /dev/null
@@ -1,84 +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.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.util.SparseArray;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.EasyConnectStatusCallbackTest}.
- */
-@SmallTest
-public class EasyConnectStatusCallbackTest {
- private EasyConnectStatusCallback mEasyConnectStatusCallback = new EasyConnectStatusCallback() {
- @Override
- public void onEnrolleeSuccess(int newNetworkId) {
-
- }
-
- @Override
- public void onConfiguratorSuccess(int code) {
-
- }
-
- @Override
- public void onProgress(int code) {
-
- }
-
- @Override
- public void onFailure(int code) {
- mOnFailureR1EventReceived = true;
- mLastCode = code;
- }
- };
- private boolean mOnFailureR1EventReceived;
- private int mLastCode;
-
- @Before
- public void setUp() {
- mOnFailureR1EventReceived = false;
- mLastCode = 0;
- }
-
- /**
- * Test that the legacy R1 onFailure is called by default if the R2 onFailure is not overridden
- * by the app.
- */
- @Test
- public void testR1OnFailureCalled() {
-
- SparseArray<int[]> channelList = new SparseArray<>();
- int[] channelArray = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
-
- channelList.append(81, channelArray);
- mEasyConnectStatusCallback.onFailure(
- EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK,
- "SomeSSID", channelList, new int[] {81});
-
- assertTrue(mOnFailureR1EventReceived);
- assertEquals(mLastCode,
- EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK);
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/FakeKeys.java b/wifi/tests/src/android/net/wifi/FakeKeys.java
deleted file mode 100644
index c0d60c3..0000000
--- a/wifi/tests/src/android/net/wifi/FakeKeys.java
+++ /dev/null
@@ -1,237 +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.net.wifi;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-
-/**
- * A class containing test certificates and private keys.
- */
-public class FakeKeys {
- private static final String CA_CERT0_STRING = "-----BEGIN CERTIFICATE-----\n" +
- "MIIDKDCCAhCgAwIBAgIJAILlFdwzLVurMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" +
- "BAMTB0VBUCBDQTEwHhcNMTYwMTEyMTE1MDE1WhcNMjYwMTA5MTE1MDE1WjASMRAw\n" +
- "DgYDVQQDEwdFQVAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" +
- "znAPUz26Msae4ws43czR41/J2QtrSIZUKmVUsVumDbYHrPNvTXKSMXAcewORDQYX\n" +
- "RqvHvpn8CscB1+oGXZvHwxj4zV0WKoK2zeXkau3vcyl3HIKupJfq2TEACefVjj0t\n" +
- "JW+X35PGWp9/H5zIUNVNVjS7Ums84IvKhRB8512PB9UyHagXYVX5GWpAcVpyfrlR\n" +
- "FI9Qdhh+Pbk0uyktdbf/CdfgHOoebrTtwRljM0oDtX+2Cv6j0wBK7hD8pPvf1+uy\n" +
- "GzczigAU/4Kw7eZqydf9B+5RupR+IZipX41xEiIrKRwqi517WWzXcjaG2cNbf451\n" +
- "xpH5PnV3i1tq04jMGQUzFwIDAQABo4GAMH4wHQYDVR0OBBYEFIwX4vs8BiBcScod\n" +
- "5noZHRM8E4+iMEIGA1UdIwQ7MDmAFIwX4vs8BiBcScod5noZHRM8E4+ioRakFDAS\n" +
- "MRAwDgYDVQQDEwdFQVAgQ0ExggkAguUV3DMtW6swDAYDVR0TBAUwAwEB/zALBgNV\n" +
- "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFfQqOTA7Rv7K+luQ7pnas4BYwHE\n" +
- "9GEP/uohv6KOy0TGQFbrRTjFoLVNB9BZ1ymMDZ0/TIwIUc7wi7a8t5mEqYH153wW\n" +
- "aWooiSjyLLhuI4sNrNCOtisdBq2r2MFXt6h0mAQYOPv8R8K7/fgSxGFqzhyNmmVL\n" +
- "1qBJldx34SpwsTALQVPb4hGwJzZfr1PcpEQx6xMnTl8xEWZE3Ms99uaUxbQqIwRu\n" +
- "LgAOkNCmY2m89VhzaHJ1uV85AdM/tD+Ysmlnnjt9LRCejbBipjIGjOXrg1JP+lxV\n" +
- "muM4vH+P/mlmxsPPz0d65b+EGmJZpoLkO/tdNNvCYzjJpTEWpEsO6NMhKYo=\n" +
- "-----END CERTIFICATE-----\n";
- public static final X509Certificate CA_CERT0 = loadCertificate(CA_CERT0_STRING);
-
- private static final String CA_CERT1_STRING = "-----BEGIN CERTIFICATE-----\n" +
- "MIIDKDCCAhCgAwIBAgIJAOM5SzKO2pzCMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" +
- "BAMTB0VBUCBDQTAwHhcNMTYwMTEyMDAxMDQ3WhcNMjYwMTA5MDAxMDQ3WjASMRAw\n" +
- "DgYDVQQDEwdFQVAgQ0EwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" +
- "89ug+IEKVQXnJGKg5g4uVHg6J/8iRUxR5k2eH5o03hrJNMfN2D+cBe/wCiZcnWbI\n" +
- "GbGZACWm2nQth2wy9Zgm2LOd3b4ocrHYls3XLq6Qb5Dd7a0JKU7pdGufiNVEkrmF\n" +
- "EB+N64wgwH4COTvCiN4erp5kyJwkfqAl2xLkZo0C464c9XoyQOXbmYD9A8v10wZu\n" +
- "jyNsEo7Nr2USyw+qhjWSbFbEirP77Tvx+7pJQJwdtk1V9Tn73T2dGF2WHYejei9S\n" +
- "mcWpdIUqsu9etYH+zDmtu7I1xlkwiaVsNr2+D+qaCJyOYqrDTKVNK5nmbBPXDWZc\n" +
- "NoDbTOoqquX7xONpq9M6jQIDAQABo4GAMH4wHQYDVR0OBBYEFAZ3A2S4qJZZwuNY\n" +
- "wkJ6mAdc0gVdMEIGA1UdIwQ7MDmAFAZ3A2S4qJZZwuNYwkJ6mAdc0gVdoRakFDAS\n" +
- "MRAwDgYDVQQDEwdFQVAgQ0EwggkA4zlLMo7anMIwDAYDVR0TBAUwAwEB/zALBgNV\n" +
- "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHmdMwEhtys4d0E+t7owBmoVR+lU\n" +
- "hMCcRtWs8YKX5WIM2kTweT0h/O1xwE1mWmRv/IbDAEb8od4BjAQLhIcolStr2JaO\n" +
- "9ZzyxjOnNzqeErh/1DHDbb/moPpqfeJ8YiEz7nH/YU56Q8iCPO7TsgS0sNNE7PfN\n" +
- "IUsBW0yHRgpQ4OxWmiZG2YZWiECRzAC0ecPzo59N5iH4vLQIMTMYquiDeMPQnn1e\n" +
- "NDGxG8gCtDKIaS6tMg3a28MvWB094pr2ETou8O1C8Ji0Y4hE8QJmSdT7I4+GZjgW\n" +
- "g94DZ5RiL7sdp3vC48CXOmeT61YBIvhGUsE1rPhXqkpqQ3Z3C4TFF0jXZZc=\n" +
- "-----END CERTIFICATE-----\n";
- public static final X509Certificate CA_CERT1 = loadCertificate(CA_CERT1_STRING);
-
- private static final String CLIENT_CERT_STR = "-----BEGIN CERTIFICATE-----\n" +
- "MIIE/DCCAuQCAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxCzAJBgNV\n" +
- "BAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdUZXN0aW5n\n" +
- "MB4XDTE2MDkzMDIwNTQyOFoXDTE3MDkzMDIwNTQyOFowRDELMAkGA1UEBhMCVVMx\n" +
- "CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdU\n" +
- "ZXN0aW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpmcbuaeHfnJ\n" +
- "k+2QNvxmdVFTawyFMNk0USCq5sexscwmxbewG/Rb8YnixwJWS44v2XkSujB67z5C\n" +
- "s2qudFEhRXKdEuC6idbAuA97KjipHh0AAniWMsyv61fvbgsUC0b0canx3LiDq81p\n" +
- "y28NNGmAvoazLZUZ4AhBRiwYZY6FKk723gmZoGbEIeG7J1dlXPusc1662rIjz4eU\n" +
- "zlmmlvqyHfNqnNk8L14Vug6Xh+lOEGN85xhu1YHAEKGrS89kZxs5rum/cZU8KH2V\n" +
- "v6eKnY03kxjiVLQtnLpm/7VUEoCMGHyruRj+p3my4+DgqMsmsH52RZCBsjyGlpbU\n" +
- "NOwOTIX6xh+Rqloduz4AnrMYYIiIw2s8g+2zJM7VbcVKx0fGS26BKdrxgrXWfmNE\n" +
- "nR0/REQ5AxDGw0jfTUvtdTkXAf+K4MDjcNLEZ+MA4rHfAfQWZtUR5BkHCQYxNpJk\n" +
- "pA0gyk+BpKdC4WdzI14NSWsu5sRCmBCFqH6BTOSEq/V1cNorBxNwLSSTwFFqUDqx\n" +
- "Y5nQLXygkJf9WHZWtSKeSjtOYgilz7UKzC2s3CsjmIyGFe+SwpuHJnuE4Uc8Z5Cb\n" +
- "bjNGHPzqL6XnmzZHJp7RF8kBdKdjGC7dCUltzOfICZeKlzOOq+Kw42T/nXjuXvpb\n" +
- "nkXNxg741Nwd6RecykXJbseFwm3EYxkCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA\n" +
- "Ga1mGwI9aXkL2fTPXO9YkAPzoGeX8aeuVYSQaSkNq+5vnogYCyAt3YDHjRG+ewTT\n" +
- "WbnPA991xRAPac+biJeXWmwvgGj0YuT7e79phAiGkTTnbAjFHGfYnBy/tI/v7btO\n" +
- "hRNElA5yTJ1m2fVbBEKXzMR83jrT9iyI+YLRN86zUZIaC86xxSbqnrdWN2jOK6MX\n" +
- "dS8Arp9tPQjC/4gW+2Ilxv68jiYh+5auWHQZVjppWVY//iu4mAbkq1pTwQEhZ8F8\n" +
- "Zrmh9DHh60hLFcfSuhIAwf/NMzppwdkjy1ruKVrpijhGKGp4OWu8nvOUgHSzxc7F\n" +
- "PwpVZ5N2Ku4L8MLO6BG2VasRJK7l17TzDXlfLZHJjkuryOFxVaQKt8ZNFgTOaCXS\n" +
- "E+gpTLksKU7riYckoiP4+H1sn9qcis0e8s4o/uf1UVc8GSdDw61ReGM5oZEDm1u8\n" +
- "H9x20QU6igLqzyBpqvCKv7JNgU1uB2PAODHH78zJiUfnKd1y+o+J1iWzaGj3EFji\n" +
- "T8AXksbTP733FeFXfggXju2dyBH+Z1S5BBTEOd1brWgXlHSAZGm97MKZ94r6/tkX\n" +
- "qfv3fCos0DKz0oV7qBxYS8wiYhzrRVxG6ITAoH8uuUVVQaZF+G4nJ2jEqNbfuKyX\n" +
- "ATQsVNjNNlDA0J33GobPMjT326wa4YAWMx8PI5PJZ3g=\n" +
- "-----END CERTIFICATE-----\n";
- public static final X509Certificate CLIENT_CERT = loadCertificate(CLIENT_CERT_STR);
-
- private static final byte[] FAKE_RSA_KEY_1 = new byte[] {
- (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
- (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
- (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
- (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
- (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
- (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
- (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
- (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
- (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
- (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
- (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
- (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
- (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
- (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
- (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
- (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
- (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
- (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
- (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
- (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
- (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
- (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
- (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
- (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
- (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
- (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
- (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
- (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
- (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
- (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
- (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
- (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
- (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
- (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
- (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
- (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
- (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
- (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
- (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
- (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
- (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
- (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
- (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
- (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
- (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
- (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
- (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
- (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
- (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
- (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
- (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
- (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
- (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
- (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
- (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
- (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
- (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
- (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
- (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
- (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
- (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
- (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
- (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
- (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
- (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
- (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
- (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
- (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
- (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
- (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
- (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
- (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
- (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
- (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
- (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
- (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
- (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
- (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
- (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
- (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
- (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
- (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
- (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
- (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
- (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
- (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
- (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
- (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
- (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
- (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
- (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
- (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
- (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
- (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
- (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
- (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
- (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
- (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
- (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
- (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
- (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
- (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
- (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
- (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
- (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
- (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
- };
- public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1);
-
- private static X509Certificate loadCertificate(String blob) {
- try {
- final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- InputStream stream = new ByteArrayInputStream(blob.getBytes(StandardCharsets.UTF_8));
-
- return (X509Certificate) certFactory.generateCertificate(stream);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) {
- try {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey));
- } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
- return null;
- }
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/ParcelUtilTest.java b/wifi/tests/src/android/net/wifi/ParcelUtilTest.java
deleted file mode 100644
index 917b1df..0000000
--- a/wifi/tests/src/android/net/wifi/ParcelUtilTest.java
+++ /dev/null
@@ -1,112 +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.net.wifi;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-/**
- * Unit tests for {@link android.net.wifi.ParcelUtil}.
- */
-@SmallTest
-public class ParcelUtilTest {
- private Parcel mParcel;
-
- @Before
- public void setUp() throws Exception {
- mParcel = Parcel.obtain();
- }
-
- @Test
- public void readWriteNullPrivateKey() throws Exception {
- ParcelUtil.writePrivateKey(mParcel, null);
-
- mParcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- PrivateKey readKey = ParcelUtil.readPrivateKey(mParcel);
- assertNull(readKey);
- }
-
- @Test
- public void readWriteValidPrivateKey() throws Exception {
- PrivateKey writeKey = FakeKeys.RSA_KEY1;
- ParcelUtil.writePrivateKey(mParcel, writeKey);
-
- mParcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- PrivateKey readKey = ParcelUtil.readPrivateKey(mParcel);
- assertNotNull(readKey);
- assertEquals(writeKey.getAlgorithm(), readKey.getAlgorithm());
- assertArrayEquals(writeKey.getEncoded(), readKey.getEncoded());
- }
-
- @Test
- public void readWriteNullCertificate() throws Exception {
- ParcelUtil.writeCertificate(mParcel, null);
-
- mParcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- X509Certificate readCert = ParcelUtil.readCertificate(mParcel);
- assertNull(readCert);
- }
-
- @Test
- public void readWriteValidCertificate() throws Exception {
- X509Certificate writeCert = FakeKeys.CA_CERT1;
- ParcelUtil.writeCertificate(mParcel, writeCert);
-
- mParcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- X509Certificate readCert = ParcelUtil.readCertificate(mParcel);
- assertNotNull(readCert);
- assertArrayEquals(writeCert.getEncoded(), readCert.getEncoded());
- }
-
- @Test
- public void readWriteNullCertificates() throws Exception {
- ParcelUtil.writeCertificates(mParcel, null);
-
- mParcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- X509Certificate[] readCerts = ParcelUtil.readCertificates(mParcel);
- assertNull(readCerts);
- }
-
- @Test
- public void readWriteValidCertificates() throws Exception {
- X509Certificate[] writeCerts = new X509Certificate[2];
- writeCerts[0] = FakeKeys.CA_CERT0;
- writeCerts[1] = FakeKeys.CA_CERT1;
- ParcelUtil.writeCertificates(mParcel, writeCerts);
-
- mParcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- X509Certificate[] readCerts = ParcelUtil.readCertificates(mParcel);
- assertNotNull(readCerts);
- assertEquals(writeCerts.length, readCerts.length);
- for (int i = 0; i < writeCerts.length; i++) {
- assertNotNull(readCerts[i]);
- assertArrayEquals(writeCerts[i].getEncoded(), readCerts[i].getEncoded());
- }
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/ScanResultTest.java b/wifi/tests/src/android/net/wifi/ScanResultTest.java
deleted file mode 100644
index 5516f43..0000000
--- a/wifi/tests/src/android/net/wifi/ScanResultTest.java
+++ /dev/null
@@ -1,300 +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.net.wifi;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.validateMockitoUsage;
-
-import android.net.wifi.ScanResult.InformationElement;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiScanner}.
- */
-@SmallTest
-public class ScanResultTest {
- public static final String TEST_SSID = "\"test_ssid\"";
- public static final String TEST_BSSID = "04:ac:fe:45:34:10";
- public static final String TEST_CAPS = "CCMP";
- public static final int TEST_LEVEL = -56;
- public static final int TEST_FREQUENCY = 2412;
- public static final long TEST_TSF = 04660l;
- public static final @WifiAnnotations.WifiStandard int TEST_WIFI_STANDARD =
- ScanResult.WIFI_STANDARD_11AC;
-
- /**
- * Frequency to channel map. This include some frequencies used outside the US.
- * Representing it using a vector (instead of map) for simplification.
- */
- private static final int[] FREQUENCY_TO_CHANNEL_MAP = {
- 2412, WifiScanner.WIFI_BAND_24_GHZ, 1,
- 2417, WifiScanner.WIFI_BAND_24_GHZ, 2,
- 2422, WifiScanner.WIFI_BAND_24_GHZ, 3,
- 2427, WifiScanner.WIFI_BAND_24_GHZ, 4,
- 2432, WifiScanner.WIFI_BAND_24_GHZ, 5,
- 2437, WifiScanner.WIFI_BAND_24_GHZ, 6,
- 2442, WifiScanner.WIFI_BAND_24_GHZ, 7,
- 2447, WifiScanner.WIFI_BAND_24_GHZ, 8,
- 2452, WifiScanner.WIFI_BAND_24_GHZ, 9,
- 2457, WifiScanner.WIFI_BAND_24_GHZ, 10,
- 2462, WifiScanner.WIFI_BAND_24_GHZ, 11,
- /* 12, 13 are only legitimate outside the US. */
- 2467, WifiScanner.WIFI_BAND_24_GHZ, 12,
- 2472, WifiScanner.WIFI_BAND_24_GHZ, 13,
- /* 14 is for Japan, DSSS and CCK only. */
- 2484, WifiScanner.WIFI_BAND_24_GHZ, 14,
- /* 34 valid in Japan. */
- 5170, WifiScanner.WIFI_BAND_5_GHZ, 34,
- 5180, WifiScanner.WIFI_BAND_5_GHZ, 36,
- 5190, WifiScanner.WIFI_BAND_5_GHZ, 38,
- 5200, WifiScanner.WIFI_BAND_5_GHZ, 40,
- 5210, WifiScanner.WIFI_BAND_5_GHZ, 42,
- 5220, WifiScanner.WIFI_BAND_5_GHZ, 44,
- 5230, WifiScanner.WIFI_BAND_5_GHZ, 46,
- 5240, WifiScanner.WIFI_BAND_5_GHZ, 48,
- 5260, WifiScanner.WIFI_BAND_5_GHZ, 52,
- 5280, WifiScanner.WIFI_BAND_5_GHZ, 56,
- 5300, WifiScanner.WIFI_BAND_5_GHZ, 60,
- 5320, WifiScanner.WIFI_BAND_5_GHZ, 64,
- 5500, WifiScanner.WIFI_BAND_5_GHZ, 100,
- 5520, WifiScanner.WIFI_BAND_5_GHZ, 104,
- 5540, WifiScanner.WIFI_BAND_5_GHZ, 108,
- 5560, WifiScanner.WIFI_BAND_5_GHZ, 112,
- 5580, WifiScanner.WIFI_BAND_5_GHZ, 116,
- /* 120, 124, 128 valid in Europe/Japan. */
- 5600, WifiScanner.WIFI_BAND_5_GHZ, 120,
- 5620, WifiScanner.WIFI_BAND_5_GHZ, 124,
- 5640, WifiScanner.WIFI_BAND_5_GHZ, 128,
- /* 132+ valid in US. */
- 5660, WifiScanner.WIFI_BAND_5_GHZ, 132,
- 5680, WifiScanner.WIFI_BAND_5_GHZ, 136,
- 5700, WifiScanner.WIFI_BAND_5_GHZ, 140,
- /* 144 is supported by a subset of WiFi chips. */
- 5720, WifiScanner.WIFI_BAND_5_GHZ, 144,
- 5745, WifiScanner.WIFI_BAND_5_GHZ, 149,
- 5765, WifiScanner.WIFI_BAND_5_GHZ, 153,
- 5785, WifiScanner.WIFI_BAND_5_GHZ, 157,
- 5805, WifiScanner.WIFI_BAND_5_GHZ, 161,
- 5825, WifiScanner.WIFI_BAND_5_GHZ, 165,
- 5845, WifiScanner.WIFI_BAND_5_GHZ, 169,
- 5865, WifiScanner.WIFI_BAND_5_GHZ, 173,
- /* Now some 6GHz channels */
- 5945, WifiScanner.WIFI_BAND_6_GHZ, 1,
- 5960, WifiScanner.WIFI_BAND_6_GHZ, 4,
- 6100, WifiScanner.WIFI_BAND_6_GHZ, 32
- };
-
- /**
- * Setup before tests.
- */
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- }
-
- /**
- * Clean up after tests.
- */
- @After
- public void cleanup() {
- validateMockitoUsage();
- }
-
- /**
- * Verify parcel read/write for ScanResult.
- */
- @Test
- public void verifyScanResultParcelWithoutRadioChainInfo() throws Exception {
- ScanResult writeScanResult = createScanResult();
- ScanResult readScanResult = parcelReadWrite(writeScanResult);
- assertScanResultEquals(writeScanResult, readScanResult);
- }
-
- /**
- * Verify parcel read/write for ScanResult.
- */
- @Test
- public void verifyScanResultParcelWithZeroRadioChainInfo() throws Exception {
- ScanResult writeScanResult = createScanResult();
- writeScanResult.radioChainInfos = new ScanResult.RadioChainInfo[0];
- ScanResult readScanResult = parcelReadWrite(writeScanResult);
- assertNull(readScanResult.radioChainInfos);
- }
-
- /**
- * Verify parcel read/write for ScanResult.
- */
- @Test
- public void verifyScanResultParcelWithRadioChainInfo() throws Exception {
- ScanResult writeScanResult = createScanResult();
- writeScanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
- writeScanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
- writeScanResult.radioChainInfos[0].id = 0;
- writeScanResult.radioChainInfos[0].level = -45;
- writeScanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
- writeScanResult.radioChainInfos[1].id = 1;
- writeScanResult.radioChainInfos[1].level = -54;
- ScanResult readScanResult = parcelReadWrite(writeScanResult);
- assertScanResultEquals(writeScanResult, readScanResult);
- }
-
- /**
- * Verify copy constructor for ScanResult.
- */
- @Test
- public void verifyScanResultCopyWithoutRadioChainInfo() throws Exception {
- ScanResult scanResult = createScanResult();
- ScanResult copyScanResult = new ScanResult(scanResult);
- assertScanResultEquals(scanResult, copyScanResult);
- }
-
- /**
- * Verify copy constructor for ScanResult.
- */
- @Test
- public void verifyScanResultCopyWithRadioChainInfo() throws Exception {
- ScanResult scanResult = createScanResult();
- scanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
- scanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
- scanResult.radioChainInfos[0].id = 0;
- scanResult.radioChainInfos[0].level = -45;
- scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
- scanResult.radioChainInfos[1].id = 1;
- scanResult.radioChainInfos[1].level = -54;
- ScanResult copyScanResult = new ScanResult(scanResult);
- assertScanResultEquals(scanResult, copyScanResult);
- }
-
- /**
- * Verify parcel read/write for ScanResult with Information Element
- */
- @Test
- public void verifyScanResultParcelWithInformationElement() throws Exception {
- ScanResult writeScanResult = createScanResult();
- writeScanResult.informationElements = new ScanResult.InformationElement[2];
- writeScanResult.informationElements[0] = new ScanResult.InformationElement();
- writeScanResult.informationElements[0].id = InformationElement.EID_HT_OPERATION;
- writeScanResult.informationElements[0].idExt = 0;
- writeScanResult.informationElements[0].bytes = new byte[]{0x11, 0x22, 0x33};
- writeScanResult.informationElements[1] = new ScanResult.InformationElement();
- writeScanResult.informationElements[1].id = InformationElement.EID_EXTENSION_PRESENT;
- writeScanResult.informationElements[1].idExt = InformationElement.EID_EXT_HE_OPERATION;
- writeScanResult.informationElements[1].bytes = new byte[]{0x44, 0x55, 0x66};
- ScanResult readScanResult = new ScanResult(writeScanResult);
- assertScanResultEquals(writeScanResult, readScanResult);
- }
-
- /**
- * Verify toString for ScanResult.
- */
- @Test
- public void verifyScanResultToStringWithoutRadioChainInfo() throws Exception {
- ScanResult scanResult = createScanResult();
- assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, "
- + "level: -56, frequency: 2412, timestamp: 2480, "
- + "distance: 0(cm), distanceSd: 0(cm), "
- + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
- + "standard: 11ac, "
- + "80211mcResponder: is not supported, "
- + "Radio Chain Infos: null", scanResult.toString());
- }
-
- /**
- * Verify toString for ScanResult.
- */
- @Test
- public void verifyScanResultToStringWithRadioChainInfo() throws Exception {
- ScanResult scanResult = createScanResult();
- scanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
- scanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
- scanResult.radioChainInfos[0].id = 0;
- scanResult.radioChainInfos[0].level = -45;
- scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
- scanResult.radioChainInfos[1].id = 1;
- scanResult.radioChainInfos[1].level = -54;
- assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, "
- + "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), "
- + "distanceSd: 0(cm), "
- + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
- + "standard: 11ac, "
- + "80211mcResponder: is not supported, "
- + "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, "
- + "RadioChainInfo: id=1, level=-54]", scanResult.toString());
- }
-
- /**
- * verify frequency to channel conversion for all possible frequencies.
- */
- @Test
- public void convertFrequencyToChannel() throws Exception {
- for (int i = 0; i < FREQUENCY_TO_CHANNEL_MAP.length; i += 3) {
- assertEquals(FREQUENCY_TO_CHANNEL_MAP[i + 2],
- ScanResult.convertFrequencyMhzToChannel(FREQUENCY_TO_CHANNEL_MAP[i]));
- }
- }
-
- /**
- * Verify frequency to channel conversion failed for an invalid frequency.
- */
- @Test
- public void convertFrequencyToChannelWithInvalidFreq() throws Exception {
- assertEquals(-1, ScanResult.convertFrequencyMhzToChannel(8000));
- }
-
- /**
- * Write the provided {@link ScanResult} to a parcel and deserialize it.
- */
- private static ScanResult parcelReadWrite(ScanResult writeResult) throws Exception {
- Parcel parcel = Parcel.obtain();
- writeResult.writeToParcel(parcel, 0);
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- return ScanResult.CREATOR.createFromParcel(parcel);
- }
-
- private static ScanResult createScanResult() {
- ScanResult result = new ScanResult();
- result.wifiSsid = WifiSsid.createFromAsciiEncoded(TEST_SSID);
- result.BSSID = TEST_BSSID;
- result.capabilities = TEST_CAPS;
- result.level = TEST_LEVEL;
- result.frequency = TEST_FREQUENCY;
- result.timestamp = TEST_TSF;
- result.setWifiStandard(TEST_WIFI_STANDARD);
- return result;
- }
-
- private static void assertScanResultEquals(ScanResult expected, ScanResult actual) {
- assertEquals(expected.SSID, actual.SSID);
- assertEquals(expected.BSSID, actual.BSSID);
- assertEquals(expected.capabilities, actual.capabilities);
- assertEquals(expected.level, actual.level);
- assertEquals(expected.frequency, actual.frequency);
- assertEquals(expected.timestamp, actual.timestamp);
- assertEquals(expected.getWifiStandard(), actual.getWifiStandard());
- assertArrayEquals(expected.radioChainInfos, actual.radioChainInfos);
- assertArrayEquals(expected.informationElements, actual.informationElements);
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java
deleted file mode 100644
index 73b501a..0000000
--- a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java
+++ /dev/null
@@ -1,73 +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.net.wifi;
-
-import android.os.Parcel;
-
-import static org.junit.Assert.assertEquals;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.SoftApCapability}.
- */
-@SmallTest
-public class SoftApCapabilityTest {
-
- /**
- * Verifies copy constructor.
- */
- @Test
- public void testCopyOperator() throws Exception {
- long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT
- | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD;
- SoftApCapability capability = new SoftApCapability(testSoftApFeature);
- capability.setMaxSupportedClients(10);
-
- SoftApCapability copiedCapability = new SoftApCapability(capability);
-
- assertEquals(capability, copiedCapability);
- assertEquals(capability.hashCode(), copiedCapability.hashCode());
- }
-
- /**
- * Verifies parcel serialization/deserialization.
- */
- @Test
- public void testParcelOperation() throws Exception {
- long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT
- | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD;
- SoftApCapability capability = new SoftApCapability(testSoftApFeature);
- capability.setMaxSupportedClients(10);
-
- Parcel parcelW = Parcel.obtain();
- capability.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- SoftApCapability fromParcel = SoftApCapability.CREATOR.createFromParcel(parcelR);
-
- assertEquals(capability, fromParcel);
- assertEquals(capability.hashCode(), fromParcel.hashCode());
- }
-
-}
diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
deleted file mode 100644
index 1a44270..0000000
--- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
+++ /dev/null
@@ -1,334 +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.net.wifi;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertNull;
-
-import android.net.MacAddress;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-@SmallTest
-public class SoftApConfigurationTest {
- private static final String TEST_CHAR_SET_AS_STRING = "abcdefghijklmnopqrstuvwxyz0123456789";
-
- private SoftApConfiguration parcelUnparcel(SoftApConfiguration configIn) {
- Parcel parcel = Parcel.obtain();
- parcel.writeParcelable(configIn, 0);
- parcel.setDataPosition(0);
- SoftApConfiguration configOut =
- parcel.readParcelable(SoftApConfiguration.class.getClassLoader());
- parcel.recycle();
- return configOut;
- }
-
- /**
- * Helper method to generate random string.
- *
- * Note: this method has limited use as a random string generator.
- * The characters used in this method do no not cover all valid inputs.
- * @param length number of characters to generate for the string
- * @return String generated string of random characters
- */
- private String generateRandomString(int length) {
- Random random = new Random();
- StringBuilder stringBuilder = new StringBuilder(length);
- int index = -1;
- while (stringBuilder.length() < length) {
- index = random.nextInt(TEST_CHAR_SET_AS_STRING.length());
- stringBuilder.append(TEST_CHAR_SET_AS_STRING.charAt(index));
- }
- return stringBuilder.toString();
- }
-
- @Test
- public void testBasicSettings() {
- SoftApConfiguration original = new SoftApConfiguration.Builder()
- .setSsid("ssid")
- .setBssid(MacAddress.fromString("11:22:33:44:55:66"))
- .build();
- assertThat(original.getSsid()).isEqualTo("ssid");
- assertThat(original.getBssid()).isEqualTo(MacAddress.fromString("11:22:33:44:55:66"));
- assertThat(original.getPassphrase()).isNull();
- assertThat(original.getSecurityType()).isEqualTo(SoftApConfiguration.SECURITY_TYPE_OPEN);
- assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ);
- assertThat(original.getChannel()).isEqualTo(0);
- assertThat(original.isHiddenSsid()).isEqualTo(false);
- assertThat(original.getMaxNumberOfClients()).isEqualTo(0);
-
- SoftApConfiguration unparceled = parcelUnparcel(original);
- assertThat(unparceled).isNotSameAs(original);
- assertThat(unparceled).isEqualTo(original);
- assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
- SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
- assertThat(copy).isNotSameAs(original);
- assertThat(copy).isEqualTo(original);
- assertThat(copy.hashCode()).isEqualTo(original.hashCode());
- }
-
- @Test
- public void testWpa2() {
- SoftApConfiguration original = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
- .build();
- assertThat(original.getPassphrase()).isEqualTo("secretsecret");
- assertThat(original.getSecurityType()).isEqualTo(
- SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
- assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ);
- assertThat(original.getChannel()).isEqualTo(0);
- assertThat(original.isHiddenSsid()).isEqualTo(false);
- assertThat(original.getMaxNumberOfClients()).isEqualTo(0);
-
- SoftApConfiguration unparceled = parcelUnparcel(original);
- assertThat(unparceled).isNotSameAs(original);
- assertThat(unparceled).isEqualTo(original);
- assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
- SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
- assertThat(copy).isNotSameAs(original);
- assertThat(copy).isEqualTo(original);
- assertThat(copy.hashCode()).isEqualTo(original.hashCode());
- }
-
- @Test
- public void testWpa2WithAllFieldCustomized() {
- List<MacAddress> testBlockedClientList = new ArrayList<>();
- List<MacAddress> testAllowedClientList = new ArrayList<>();
- testBlockedClientList.add(MacAddress.fromString("11:22:33:44:55:66"));
- testAllowedClientList.add(MacAddress.fromString("aa:bb:cc:dd:ee:ff"));
- SoftApConfiguration original = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
- .setChannel(149, SoftApConfiguration.BAND_5GHZ)
- .setHiddenSsid(true)
- .setMaxNumberOfClients(10)
- .setAutoShutdownEnabled(true)
- .setShutdownTimeoutMillis(500000)
- .setClientControlByUserEnabled(true)
- .setBlockedClientList(testBlockedClientList)
- .setAllowedClientList(testAllowedClientList)
- .build();
- assertThat(original.getPassphrase()).isEqualTo("secretsecret");
- assertThat(original.getSecurityType()).isEqualTo(
- SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
- assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ);
- assertThat(original.getChannel()).isEqualTo(149);
- assertThat(original.isHiddenSsid()).isEqualTo(true);
- assertThat(original.getMaxNumberOfClients()).isEqualTo(10);
- assertThat(original.isAutoShutdownEnabled()).isEqualTo(true);
- assertThat(original.getShutdownTimeoutMillis()).isEqualTo(500000);
- assertThat(original.isClientControlByUserEnabled()).isEqualTo(true);
- assertThat(original.getBlockedClientList()).isEqualTo(testBlockedClientList);
- assertThat(original.getAllowedClientList()).isEqualTo(testAllowedClientList);
-
- SoftApConfiguration unparceled = parcelUnparcel(original);
- assertThat(unparceled).isNotSameAs(original);
- assertThat(unparceled).isEqualTo(original);
- assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
- SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
- assertThat(copy).isNotSameAs(original);
- assertThat(copy).isEqualTo(original);
- assertThat(copy.hashCode()).isEqualTo(original.hashCode());
- }
-
- @Test
- public void testWpa3Sae() {
- SoftApConfiguration original = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
- .setChannel(149, SoftApConfiguration.BAND_5GHZ)
- .setHiddenSsid(true)
- .build();
- assertThat(original.getPassphrase()).isEqualTo("secretsecret");
- assertThat(original.getSecurityType()).isEqualTo(
- SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
- assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ);
- assertThat(original.getChannel()).isEqualTo(149);
- assertThat(original.isHiddenSsid()).isEqualTo(true);
-
-
- SoftApConfiguration unparceled = parcelUnparcel(original);
- assertThat(unparceled).isNotSameAs(original);
- assertThat(unparceled).isEqualTo(original);
- assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
- SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
- assertThat(copy).isNotSameAs(original);
- assertThat(copy).isEqualTo(original);
- assertThat(copy.hashCode()).isEqualTo(original.hashCode());
- }
-
- @Test
- public void testWpa3SaeTransition() {
- SoftApConfiguration original = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret",
- SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
- .setChannel(149, SoftApConfiguration.BAND_5GHZ)
- .setHiddenSsid(true)
- .build();
- assertThat(original.getSecurityType()).isEqualTo(
- SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION);
- assertThat(original.getPassphrase()).isEqualTo("secretsecret");
- assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ);
- assertThat(original.getChannel()).isEqualTo(149);
- assertThat(original.isHiddenSsid()).isEqualTo(true);
-
-
- SoftApConfiguration unparceled = parcelUnparcel(original);
- assertThat(unparceled).isNotSameAs(original);
- assertThat(unparceled).isEqualTo(original);
- assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
- SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
- assertThat(copy).isNotSameAs(original);
- assertThat(copy).isEqualTo(original);
- assertThat(copy.hashCode()).isEqualTo(original.hashCode());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidShortPasswordLengthForWpa2() {
- SoftApConfiguration original = new SoftApConfiguration.Builder()
- .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1),
- SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
- .setChannel(149, SoftApConfiguration.BAND_5GHZ)
- .setHiddenSsid(true)
- .build();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidLongPasswordLengthForWpa2() {
- SoftApConfiguration original = new SoftApConfiguration.Builder()
- .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1),
- SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
- .setChannel(149, SoftApConfiguration.BAND_5GHZ)
- .setHiddenSsid(true)
- .build();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidShortPasswordLengthForWpa3SaeTransition() {
- SoftApConfiguration original = new SoftApConfiguration.Builder()
- .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1),
- SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
- .setChannel(149, SoftApConfiguration.BAND_5GHZ)
- .setHiddenSsid(true)
- .build();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidLongPasswordLengthForWpa3SaeTransition() {
- SoftApConfiguration original = new SoftApConfiguration.Builder()
- .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1),
- SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
- .setChannel(149, SoftApConfiguration.BAND_5GHZ)
- .setHiddenSsid(true)
- .build();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalieShutdownTimeoutMillis() {
- SoftApConfiguration original = new SoftApConfiguration.Builder()
- .setShutdownTimeoutMillis(-1)
- .build();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSetClientListExceptionWhenExistMacAddressInBothList() {
- final MacAddress testMacAddress_1 = MacAddress.fromString("22:33:44:55:66:77");
- final MacAddress testMacAddress_2 = MacAddress.fromString("aa:bb:cc:dd:ee:ff");
- ArrayList<MacAddress> testAllowedClientList = new ArrayList<>();
- testAllowedClientList.add(testMacAddress_1);
- testAllowedClientList.add(testMacAddress_2);
- ArrayList<MacAddress> testBlockedClientList = new ArrayList<>();
- testBlockedClientList.add(testMacAddress_1);
- SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder();
- configBuilder.setBlockedClientList(testBlockedClientList)
- .setAllowedClientList(testAllowedClientList)
- .build();
- }
-
- @Test
- public void testToWifiConfigurationWithUnsupportedParameter() {
- SoftApConfiguration sae_config = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
- .build();
-
- assertNull(sae_config.toWifiConfiguration());
- SoftApConfiguration band_6g_config = new SoftApConfiguration.Builder()
- .setBand(SoftApConfiguration.BAND_6GHZ)
- .build();
-
- assertNull(band_6g_config.toWifiConfiguration());
- SoftApConfiguration sae_transition_config = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret",
- SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
- .build();
-
- assertNull(sae_transition_config.toWifiConfiguration());
- }
-
- @Test
- public void testToWifiConfigurationWithSupportedParameter() {
- SoftApConfiguration softApConfig_2g = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret",
- SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
- .setChannel(11, SoftApConfiguration.BAND_2GHZ)
- .setHiddenSsid(true)
- .build();
- WifiConfiguration wifiConfig_2g = softApConfig_2g.toWifiConfiguration();
- assertThat(wifiConfig_2g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
- assertThat(wifiConfig_2g.preSharedKey).isEqualTo("secretsecret");
- assertThat(wifiConfig_2g.apBand).isEqualTo(WifiConfiguration.AP_BAND_2GHZ);
- assertThat(wifiConfig_2g.apChannel).isEqualTo(11);
- assertThat(wifiConfig_2g.hiddenSSID).isEqualTo(true);
-
- SoftApConfiguration softApConfig_5g = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret",
- SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
- .setChannel(149, SoftApConfiguration.BAND_5GHZ)
- .setHiddenSsid(true)
- .build();
- WifiConfiguration wifiConfig_5g = softApConfig_5g.toWifiConfiguration();
- assertThat(wifiConfig_5g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
- assertThat(wifiConfig_5g.preSharedKey).isEqualTo("secretsecret");
- assertThat(wifiConfig_5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_5GHZ);
- assertThat(wifiConfig_5g.apChannel).isEqualTo(149);
- assertThat(wifiConfig_5g.hiddenSSID).isEqualTo(true);
-
- SoftApConfiguration softApConfig_2g5g = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret",
- SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
- .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ)
- .setHiddenSsid(true)
- .build();
- WifiConfiguration wifiConfig_2g5g = softApConfig_2g5g.toWifiConfiguration();
- assertThat(wifiConfig_2g5g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
- assertThat(wifiConfig_2g5g.preSharedKey).isEqualTo("secretsecret");
- assertThat(wifiConfig_2g5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_ANY);
- assertThat(wifiConfig_2g5g.apChannel).isEqualTo(0);
- assertThat(wifiConfig_2g5g.hiddenSSID).isEqualTo(true);
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/SoftApInfoTest.java b/wifi/tests/src/android/net/wifi/SoftApInfoTest.java
deleted file mode 100644
index 929f3ab..0000000
--- a/wifi/tests/src/android/net/wifi/SoftApInfoTest.java
+++ /dev/null
@@ -1,71 +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.net.wifi;
-
-import android.os.Parcel;
-
-import static org.junit.Assert.assertEquals;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.SoftApInfo}.
- */
-@SmallTest
-public class SoftApInfoTest {
-
- /**
- * Verifies copy constructor.
- */
- @Test
- public void testCopyOperator() throws Exception {
- SoftApInfo info = new SoftApInfo();
- info.setFrequency(2412);
- info.setBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ);
-
- SoftApInfo copiedInfo = new SoftApInfo(info);
-
- assertEquals(info, copiedInfo);
- assertEquals(info.hashCode(), copiedInfo.hashCode());
- }
-
- /**
- * Verifies parcel serialization/deserialization.
- */
- @Test
- public void testParcelOperation() throws Exception {
- SoftApInfo info = new SoftApInfo();
- info.setFrequency(2412);
- info.setBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ);
-
- Parcel parcelW = Parcel.obtain();
- info.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- SoftApInfo fromParcel = SoftApInfo.CREATOR.createFromParcel(parcelR);
-
- assertEquals(info, fromParcel);
- assertEquals(info.hashCode(), fromParcel.hashCode());
- }
-
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiClientTest.java b/wifi/tests/src/android/net/wifi/WifiClientTest.java
deleted file mode 100644
index 42cab55..0000000
--- a/wifi/tests/src/android/net/wifi/WifiClientTest.java
+++ /dev/null
@@ -1,75 +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.net.wifi;
-
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import android.net.MacAddress;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiClient}.
- */
-@SmallTest
-public class WifiClientTest {
- private static final String INTERFACE_NAME = "wlan0";
- private static final String MAC_ADDRESS_STRING = "00:0a:95:9d:68:16";
- private static final MacAddress MAC_ADDRESS = MacAddress.fromString(MAC_ADDRESS_STRING);
-
- /**
- * Verify parcel write/read with WifiClient.
- */
- @Test
- public void testWifiClientParcelWriteRead() throws Exception {
- WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS);
-
- assertParcelSane(writeWifiClient, 1);
- }
-
- /**
- * Verify equals with WifiClient.
- */
- @Test
- public void testWifiClientEquals() throws Exception {
- WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS);
- WifiClient writeWifiClientEquals = new WifiClient(MAC_ADDRESS);
-
- assertEquals(writeWifiClient, writeWifiClientEquals);
- assertEquals(writeWifiClient.hashCode(), writeWifiClientEquals.hashCode());
- assertFieldCountEquals(1, WifiClient.class);
- }
-
- /**
- * Verify not-equals with WifiClient.
- */
- @Test
- public void testWifiClientNotEquals() throws Exception {
- final MacAddress macAddressNotEquals = MacAddress.fromString("00:00:00:00:00:00");
- WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS);
- WifiClient writeWifiClientNotEquals = new WifiClient(macAddressNotEquals);
-
- assertNotEquals(writeWifiClient, writeWifiClientNotEquals);
- assertNotEquals(writeWifiClient.hashCode(), writeWifiClientNotEquals.hashCode());
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
deleted file mode 100644
index a7b6765..0000000
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ /dev/null
@@ -1,540 +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.net.wifi;
-
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OPEN;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OWE;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_PSK;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_SAE;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_WAPI_PSK;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-import android.net.util.MacAddressUtils;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiConfiguration}.
- */
-@SmallTest
-public class WifiConfigurationTest {
-
- @Before
- public void setUp() {
- }
-
- /**
- * Check that parcel marshalling/unmarshalling works
- *
- * Create and populate a WifiConfiguration.
- * Marshall and unmashall it, and expect to recover a copy of the original.
- * Marshall the resulting object, and expect the bytes to match the
- * first marshall result.
- */
- @Test
- public void testWifiConfigurationParcel() {
- String cookie = "C O.o |<IE";
- WifiConfiguration config = new WifiConfiguration();
- config.setPasspointManagementObjectTree(cookie);
- config.trusted = false;
- config.updateIdentifier = "1234";
- config.fromWifiNetworkSpecifier = true;
- config.fromWifiNetworkSuggestion = true;
- config.setRandomizedMacAddress(MacAddressUtils.createRandomUnicastAddress());
- MacAddress macBeforeParcel = config.getRandomizedMacAddress();
- Parcel parcelW = Parcel.obtain();
- config.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiConfiguration reconfig = WifiConfiguration.CREATOR.createFromParcel(parcelR);
-
- // lacking a useful config.equals, check two fields near the end.
- assertEquals(cookie, reconfig.getMoTree());
- assertEquals(macBeforeParcel, reconfig.getRandomizedMacAddress());
- assertEquals(config.updateIdentifier, reconfig.updateIdentifier);
- assertFalse(reconfig.trusted);
- assertTrue(config.fromWifiNetworkSpecifier);
- assertTrue(config.fromWifiNetworkSuggestion);
-
- Parcel parcelWW = Parcel.obtain();
- reconfig.writeToParcel(parcelWW, 0);
- byte[] rebytes = parcelWW.marshall();
- parcelWW.recycle();
-
- assertArrayEquals(bytes, rebytes);
- }
-
- @Test
- public void testIsOpenNetwork_IsOpen_NullWepKeys() {
- WifiConfiguration config = new WifiConfiguration();
- config.allowedKeyManagement.clear();
- config.wepKeys = null;
-
- assertTrue(config.isOpenNetwork());
- }
-
- @Test
- public void testIsOpenNetwork_IsOpen_ZeroLengthWepKeysArray() {
- WifiConfiguration config = new WifiConfiguration();
- config.allowedKeyManagement.clear();
- config.wepKeys = new String[0];
-
- assertTrue(config.isOpenNetwork());
- }
-
- @Test
- public void testIsOpenNetwork_IsOpen_NullWepKeysArray() {
- WifiConfiguration config = new WifiConfiguration();
- config.allowedKeyManagement.clear();
- config.wepKeys = new String[1];
-
- assertTrue(config.isOpenNetwork());
- }
-
- @Test
- public void testIsOpenNetwork_NotOpen_HasWepKeys() {
- WifiConfiguration config = new WifiConfiguration();
- config.allowedKeyManagement.clear();
- config.wepKeys = new String[] {"test"};
-
- assertFalse(config.isOpenNetwork());
- }
-
- @Test
- public void testIsOpenNetwork_NotOpen_HasNullWepKeyFollowedByNonNullKey() {
- WifiConfiguration config = new WifiConfiguration();
- config.allowedKeyManagement.clear();
- config.wepKeys = new String[] {null, null, "test"};
-
- assertFalse(config.isOpenNetwork());
- }
-
- @Test
- public void testIsOpenNetwork_NotOpen_HasAuthType() {
- for (int keyMgmt = 0; keyMgmt < WifiConfiguration.KeyMgmt.strings.length; keyMgmt++) {
- if (keyMgmt == WifiConfiguration.KeyMgmt.NONE
- || keyMgmt == WifiConfiguration.KeyMgmt.OWE) {
- continue;
- }
- WifiConfiguration config = new WifiConfiguration();
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(keyMgmt);
- config.wepKeys = null;
-
- assertFalse("Open network reported when key mgmt was set to "
- + WifiConfiguration.KeyMgmt.strings[keyMgmt], config.isOpenNetwork());
- }
- }
-
- @Test
- public void testIsOpenNetwork_NotOpen_HasAuthTypeNoneAndMore() {
- WifiConfiguration config = new WifiConfiguration();
- config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
- config.wepKeys = null;
-
- assertFalse(config.isOpenNetwork());
- }
-
- @Test
- public void testSetRandomizedMacAddress_ChangesSavedAddress() {
- WifiConfiguration config = new WifiConfiguration();
- MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
- assertEquals(defaultMac, config.getRandomizedMacAddress());
-
- MacAddress macToChangeInto = MacAddressUtils.createRandomUnicastAddress();
- config.setRandomizedMacAddress(macToChangeInto);
- MacAddress macAfterChange = config.getRandomizedMacAddress();
-
- assertEquals(macToChangeInto, macAfterChange);
- }
-
- @Test
- public void testSetRandomizedMacAddress_DoesNothingWhenNull() {
- WifiConfiguration config = new WifiConfiguration();
- MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
- config.setRandomizedMacAddress(null);
- assertEquals(defaultMac, config.getRandomizedMacAddress());
- }
-
- /**
- * Verifies that updateIdentifier should be copied for copy constructor.
- */
- @Test
- public void testUpdateIdentifierForCopyConstructor() {
- WifiConfiguration config = new WifiConfiguration();
- config.updateIdentifier = "1234";
- WifiConfiguration copyConfig = new WifiConfiguration(config);
-
- assertEquals(config.updateIdentifier, copyConfig.updateIdentifier);
- }
-
- /**
- * Verifies that getKeyIdForCredentials returns the expected string for Enterprise networks
- * @throws Exception
- */
- @Test
- public void testGetKeyIdForCredentials() throws Exception {
- WifiConfiguration config = new WifiConfiguration();
- final String mSsid = "TestAP";
- config.SSID = mSsid;
-
- // Test various combinations
- // EAP with TLS
- config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
- config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
- config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
- String keyId = config.getKeyIdForCredentials(config);
- assertEquals(keyId, mSsid + "_WPA_EAP_TLS_NULL");
-
- // EAP with TTLS & MSCHAPv2
- config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
- config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
- config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
- keyId = config.getKeyIdForCredentials(config);
- assertEquals(keyId, mSsid + "_WPA_EAP_TTLS_MSCHAPV2");
-
- // Suite-B 192 with PWD & GTC
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
- config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PWD);
- config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
- keyId = config.getKeyIdForCredentials(config);
- assertEquals(keyId, mSsid + "_SUITE_B_192_PWD_GTC");
-
- // IEEE8021X with SIM
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
- config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
- config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
- keyId = config.getKeyIdForCredentials(config);
- assertEquals(keyId, mSsid + "_IEEE8021X_SIM_NULL");
-
- // Try calling this method with non-Enterprise network, expect an exception
- boolean exceptionThrown = false;
- try {
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
- config.preSharedKey = "TestPsk";
- keyId = config.getKeyIdForCredentials(config);
- } catch (IllegalStateException e) {
- exceptionThrown = true;
- }
- assertTrue(exceptionThrown);
- }
-
- /**
- * Verifies that getKeyIdForCredentials returns the expected string for Suggestion Enterprise
- * networks
- * @throws Exception
- */
- @Test
- public void testGetKeyIdForCredentialsForSuggestion() throws Exception {
- WifiConfiguration config = new WifiConfiguration();
- final String mSsid = "TestAP";
- final String packageName = "TestApp";
- final String bSsid = MacAddressUtils.createRandomUnicastAddress().toString();
- String suggestionSuffix = "_" + bSsid + "_" + packageName;
- config.SSID = mSsid;
- config.fromWifiNetworkSuggestion = true;
- config.creatorName = packageName;
- config.BSSID = bSsid;
-
- // Test various combinations
- // EAP with TLS
- config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
- config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
- config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
- String keyId = config.getKeyIdForCredentials(config);
- assertEquals(keyId, mSsid + "_WPA_EAP_TLS_NULL" + suggestionSuffix);
-
- // EAP with TTLS & MSCHAPv2
- config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
- config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
- config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
- keyId = config.getKeyIdForCredentials(config);
- assertEquals(keyId, mSsid + "_WPA_EAP_TTLS_MSCHAPV2" + suggestionSuffix);
-
- // Suite-B 192 with PWD & GTC
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
- config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PWD);
- config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
- keyId = config.getKeyIdForCredentials(config);
- assertEquals(keyId, mSsid + "_SUITE_B_192_PWD_GTC" + suggestionSuffix);
-
- // IEEE8021X with SIM
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
- config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
- config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
- keyId = config.getKeyIdForCredentials(config);
- assertEquals(keyId, mSsid + "_IEEE8021X_SIM_NULL" + suggestionSuffix);
-
- // Try calling this method with non-Enterprise network, expect an exception
- boolean exceptionThrown = false;
- try {
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
- config.preSharedKey = "TestPsk";
- keyId = config.getKeyIdForCredentials(config);
- } catch (IllegalStateException e) {
- exceptionThrown = true;
- }
- assertTrue(exceptionThrown);
- }
-
- /**
- * Verifies that getSsidAndSecurityTypeString returns the correct String for networks of
- * various different security types
- */
- @Test
- public void testGetSsidAndSecurityTypeString() {
- WifiConfiguration config = new WifiConfiguration();
- final String mSsid = "TestAP";
- config.SSID = mSsid;
-
- // Test various combinations
- config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
- assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WPA_PSK],
- config.getSsidAndSecurityTypeString());
-
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
- assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WPA_EAP],
- config.getSsidAndSecurityTypeString());
-
- config.wepKeys[0] = "TestWep";
- config.allowedKeyManagement.clear();
- assertEquals(mSsid + "WEP", config.getSsidAndSecurityTypeString());
-
- // set WEP key and give a valid index.
- config.wepKeys[0] = null;
- config.wepKeys[2] = "TestWep";
- config.wepTxKeyIndex = 2;
- config.allowedKeyManagement.clear();
- assertEquals(mSsid + "WEP", config.getSsidAndSecurityTypeString());
-
- // set WEP key but does not give a valid index.
- config.wepKeys[0] = null;
- config.wepKeys[2] = "TestWep";
- config.wepTxKeyIndex = 0;
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.OWE);
- assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.OWE], config.getSsidAndSecurityTypeString());
-
- config.wepKeys[0] = null;
- config.wepTxKeyIndex = 0;
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.OWE);
- assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.OWE], config.getSsidAndSecurityTypeString());
-
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.SAE);
- assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.SAE], config.getSsidAndSecurityTypeString());
-
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
- assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.SUITE_B_192],
- config.getSsidAndSecurityTypeString());
-
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.NONE);
- assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.NONE], config.getSsidAndSecurityTypeString());
-
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.WAPI_PSK);
- assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WAPI_PSK],
- config.getSsidAndSecurityTypeString());
-
- config.allowedKeyManagement.clear();
- config.allowedKeyManagement.set(KeyMgmt.WAPI_CERT);
- assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WAPI_CERT],
- config.getSsidAndSecurityTypeString());
- }
-
- /**
- * Ensure that the {@link NetworkSelectionStatus.DisableReasonInfo}s are populated in
- * {@link NetworkSelectionStatus#DISABLE_REASON_INFOS} for reason codes from 0 to
- * {@link NetworkSelectionStatus#NETWORK_SELECTION_DISABLED_MAX} - 1.
- */
- @Test
- public void testNetworkSelectionDisableReasonInfosPopulated() {
- assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX,
- NetworkSelectionStatus.DISABLE_REASON_INFOS.size());
- for (int i = 0; i < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; i++) {
- assertNotNull(NetworkSelectionStatus.DISABLE_REASON_INFOS.get(i));
- }
- }
-
- /**
- * Ensure that {@link NetworkSelectionStatus#getMaxNetworkSelectionDisableReason()} returns
- * the maximum disable reason.
- */
- @Test
- public void testNetworkSelectionGetMaxNetworkSelectionDisableReason() {
- int maxReason = Integer.MIN_VALUE;
- for (int i = 0; i < NetworkSelectionStatus.DISABLE_REASON_INFOS.size(); i++) {
- int reason = NetworkSelectionStatus.DISABLE_REASON_INFOS.keyAt(i);
- maxReason = Math.max(maxReason, reason);
- }
- assertEquals(maxReason, NetworkSelectionStatus.getMaxNetworkSelectionDisableReason());
- }
-
- /**
- * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the
- * {@link WifiConfiguration} object correctly for SAE security type.
- * @throws Exception
- */
- @Test
- public void testSetSecurityParamsForSae() throws Exception {
- WifiConfiguration config = new WifiConfiguration();
-
- config.setSecurityParams(SECURITY_TYPE_SAE);
-
- assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE));
- assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP));
- assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256));
- assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP));
- assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256));
- assertTrue(config.requirePmf);
- }
-
- /**
- * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the
- * {@link WifiConfiguration} object correctly for OWE security type.
- * @throws Exception
- */
- @Test
- public void testSetSecurityParamsForOwe() throws Exception {
- WifiConfiguration config = new WifiConfiguration();
-
- config.setSecurityParams(SECURITY_TYPE_OWE);
-
- assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE));
- assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP));
- assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256));
- assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP));
- assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256));
- assertTrue(config.requirePmf);
- }
-
- /**
- * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the
- * {@link WifiConfiguration} object correctly for Suite-B security type.
- * @throws Exception
- */
- @Test
- public void testSetSecurityParamsForSuiteB() throws Exception {
- WifiConfiguration config = new WifiConfiguration();
-
- config.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B);
-
- assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192));
- assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP));
- assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
- assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256));
- assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256));
- assertTrue(config.allowedGroupManagementCiphers
- .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
- assertTrue(config.requirePmf);
- }
-
- /**
- * Test that the NetworkSelectionStatus Builder returns the same values that was set, and that
- * calling build multiple times returns different instances.
- */
- @Test
- public void testNetworkSelectionStatusBuilder() throws Exception {
- NetworkSelectionStatus.Builder builder = new NetworkSelectionStatus.Builder()
- .setNetworkSelectionDisableReason(
- NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION)
- .setNetworkSelectionStatus(
- NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
-
- NetworkSelectionStatus status1 = builder.build();
-
- assertEquals(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION,
- status1.getNetworkSelectionDisableReason());
- assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED,
- status1.getNetworkSelectionStatus());
-
- NetworkSelectionStatus status2 = builder
- .setNetworkSelectionDisableReason(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD)
- .build();
-
- // different instances
- assertNotSame(status1, status2);
-
- // assert that status1 didn't change
- assertEquals(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION,
- status1.getNetworkSelectionDisableReason());
- assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED,
- status1.getNetworkSelectionStatus());
-
- // assert that status2 changed
- assertEquals(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD,
- status2.getNetworkSelectionDisableReason());
- assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED,
- status2.getNetworkSelectionStatus());
- }
-
- @Test
- public void testNeedsPreSharedKey() throws Exception {
- WifiConfiguration configuration = new WifiConfiguration();
-
- configuration.setSecurityParams(SECURITY_TYPE_PSK);
- assertTrue(configuration.needsPreSharedKey());
-
- configuration.setSecurityParams(SECURITY_TYPE_SAE);
- assertTrue(configuration.needsPreSharedKey());
-
- configuration.setSecurityParams(SECURITY_TYPE_WAPI_PSK);
- assertTrue(configuration.needsPreSharedKey());
-
- configuration.setSecurityParams(SECURITY_TYPE_OPEN);
- assertFalse(configuration.needsPreSharedKey());
-
- configuration.setSecurityParams(SECURITY_TYPE_OWE);
- assertFalse(configuration.needsPreSharedKey());
-
- configuration.setSecurityParams(SECURITY_TYPE_EAP);
- assertFalse(configuration.needsPreSharedKey());
-
- configuration.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B);
- assertFalse(configuration.needsPreSharedKey());
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
deleted file mode 100644
index 62485ec..0000000
--- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
+++ /dev/null
@@ -1,577 +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.net.wifi;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.wifi.WifiEnterpriseConfig.Eap;
-import android.net.wifi.WifiEnterpriseConfig.Phase2;
-import android.os.Parcel;
-import android.security.Credentials;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiEnterpriseConfig}.
- */
-@SmallTest
-public class WifiEnterpriseConfigTest {
- // Maintain a ground truth of the keystore uri prefix which is expected by wpa_supplicant.
- public static final String KEYSTORE_URI = "keystore://";
- public static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE;
- public static final String KEYSTORES_URI = "keystores://";
- private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
-
- private WifiEnterpriseConfig mEnterpriseConfig;
-
- @Before
- public void setUp() throws Exception {
- mEnterpriseConfig = new WifiEnterpriseConfig();
- }
-
- @Test
- public void testGetEmptyCaCertificate() {
- // A newly-constructed WifiEnterpriseConfig object should have no CA certificate.
- assertNull(mEnterpriseConfig.getCaCertificate());
- assertNull(mEnterpriseConfig.getCaCertificates());
- // Setting CA certificate to null explicitly.
- mEnterpriseConfig.setCaCertificate(null);
- assertNull(mEnterpriseConfig.getCaCertificate());
- // Setting CA certificate to null using setCaCertificates().
- mEnterpriseConfig.setCaCertificates(null);
- assertNull(mEnterpriseConfig.getCaCertificates());
- // Setting CA certificate to zero-length array.
- mEnterpriseConfig.setCaCertificates(new X509Certificate[0]);
- assertNull(mEnterpriseConfig.getCaCertificates());
- }
-
- @Test
- public void testSetGetSingleCaCertificate() {
- X509Certificate cert0 = FakeKeys.CA_CERT0;
- mEnterpriseConfig.setCaCertificate(cert0);
- assertEquals(mEnterpriseConfig.getCaCertificate(), cert0);
- }
-
- @Test
- public void testSetGetMultipleCaCertificates() {
- X509Certificate cert0 = FakeKeys.CA_CERT0;
- X509Certificate cert1 = FakeKeys.CA_CERT1;
- mEnterpriseConfig.setCaCertificates(new X509Certificate[] {cert0, cert1});
- X509Certificate[] result = mEnterpriseConfig.getCaCertificates();
- assertEquals(result.length, 2);
- assertTrue(result[0] == cert0 && result[1] == cert1);
- }
-
- @Test
- public void testSetClientKeyEntryWithNull() {
- mEnterpriseConfig.setClientKeyEntry(null, null);
- assertNull(mEnterpriseConfig.getClientCertificateChain());
- assertNull(mEnterpriseConfig.getClientCertificate());
- mEnterpriseConfig.setClientKeyEntryWithCertificateChain(null, null);
- assertNull(mEnterpriseConfig.getClientCertificateChain());
- assertNull(mEnterpriseConfig.getClientCertificate());
-
- // Setting the client certificate to null should clear the existing chain.
- PrivateKey clientKey = FakeKeys.RSA_KEY1;
- X509Certificate clientCert0 = FakeKeys.CLIENT_CERT;
- X509Certificate clientCert1 = FakeKeys.CA_CERT1;
- mEnterpriseConfig.setClientKeyEntry(clientKey, clientCert0);
- assertNotNull(mEnterpriseConfig.getClientCertificate());
- mEnterpriseConfig.setClientKeyEntry(null, null);
- assertNull(mEnterpriseConfig.getClientCertificate());
- assertNull(mEnterpriseConfig.getClientCertificateChain());
-
- // Setting the chain to null should clear the existing chain.
- X509Certificate[] clientChain = new X509Certificate[] {clientCert0, clientCert1};
- mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
- assertNotNull(mEnterpriseConfig.getClientCertificateChain());
- mEnterpriseConfig.setClientKeyEntryWithCertificateChain(null, null);
- assertNull(mEnterpriseConfig.getClientCertificate());
- assertNull(mEnterpriseConfig.getClientCertificateChain());
- }
-
- @Test
- public void testSetClientCertificateChain() {
- PrivateKey clientKey = FakeKeys.RSA_KEY1;
- X509Certificate cert0 = FakeKeys.CLIENT_CERT;
- X509Certificate cert1 = FakeKeys.CA_CERT1;
- X509Certificate[] clientChain = new X509Certificate[] {cert0, cert1};
- mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
- X509Certificate[] result = mEnterpriseConfig.getClientCertificateChain();
- assertEquals(result.length, 2);
- assertTrue(result[0] == cert0 && result[1] == cert1);
- assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
- }
-
- private boolean isClientCertificateChainInvalid(X509Certificate[] clientChain) {
- boolean exceptionThrown = false;
- try {
- PrivateKey clientKey = FakeKeys.RSA_KEY1;
- mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
- } catch (IllegalArgumentException e) {
- exceptionThrown = true;
- }
- return exceptionThrown;
- }
-
- @Test
- public void testSetInvalidClientCertificateChain() {
- X509Certificate clientCert = FakeKeys.CLIENT_CERT;
- X509Certificate caCert = FakeKeys.CA_CERT1;
- assertTrue("Invalid client certificate",
- isClientCertificateChainInvalid(new X509Certificate[] {caCert, caCert}));
- assertTrue("Invalid CA certificate",
- isClientCertificateChainInvalid(new X509Certificate[] {clientCert, clientCert}));
- assertTrue("Both certificates invalid",
- isClientCertificateChainInvalid(new X509Certificate[] {caCert, clientCert}));
- }
-
- @Test
- public void testSaveSingleCaCertificateAlias() {
- final String alias = "single_alias 0";
- mEnterpriseConfig.setCaCertificateAliases(new String[] {alias});
- assertEquals(getCaCertField(), CA_CERT_PREFIX + alias);
- }
-
- @Test
- public void testLoadSingleCaCertificateAlias() {
- final String alias = "single_alias 1";
- setCaCertField(CA_CERT_PREFIX + alias);
- String[] aliases = mEnterpriseConfig.getCaCertificateAliases();
- assertEquals(aliases.length, 1);
- assertEquals(aliases[0], alias);
- }
-
- @Test
- public void testSaveMultipleCaCertificates() {
- final String alias0 = "single_alias 0";
- final String alias1 = "single_alias 1";
- mEnterpriseConfig.setCaCertificateAliases(new String[] {alias0, alias1});
- assertEquals(getCaCertField(), String.format("%s%s %s",
- KEYSTORES_URI,
- WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias0),
- WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias1)));
- }
-
- @Test
- public void testLoadMultipleCaCertificates() {
- final String alias0 = "single_alias 0";
- final String alias1 = "single_alias 1";
- setCaCertField(String.format("%s%s %s",
- KEYSTORES_URI,
- WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias0),
- WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias1)));
- String[] aliases = mEnterpriseConfig.getCaCertificateAliases();
- assertEquals(aliases.length, 2);
- assertEquals(aliases[0], alias0);
- assertEquals(aliases[1], alias1);
- }
-
- private String getCaCertField() {
- return mEnterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY);
- }
-
- private void setCaCertField(String value) {
- mEnterpriseConfig.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, value);
- }
-
- // Retrieves the value for a specific key supplied to wpa_supplicant.
- private class SupplicantConfigExtractor implements WifiEnterpriseConfig.SupplicantSaver {
- private String mValue = null;
- private String mKey;
-
- SupplicantConfigExtractor(String key) {
- mKey = key;
- }
-
- @Override
- public boolean saveValue(String key, String value) {
- if (key.equals(mKey)) {
- mValue = value;
- }
- return true;
- }
-
- public String getValue() {
- return mValue;
- }
- }
-
- private String getSupplicantEapMethod() {
- SupplicantConfigExtractor entryExtractor = new SupplicantConfigExtractor(
- WifiEnterpriseConfig.EAP_KEY);
- mEnterpriseConfig.saveToSupplicant(entryExtractor);
- return entryExtractor.getValue();
- }
-
- private String getSupplicantPhase2Method() {
- SupplicantConfigExtractor entryExtractor = new SupplicantConfigExtractor(
- WifiEnterpriseConfig.PHASE2_KEY);
- mEnterpriseConfig.saveToSupplicant(entryExtractor);
- return entryExtractor.getValue();
- }
-
- /** Verifies the default value for EAP outer and inner methods */
- @Test
- public void eapInnerDefault() {
- assertEquals(null, getSupplicantEapMethod());
- assertEquals(null, getSupplicantPhase2Method());
- }
-
- /** Verifies that the EAP inner method is reset when we switch to TLS */
- @Test
- public void eapPhase2MethodForTls() {
- // Initially select an EAP method that supports an phase2.
- mEnterpriseConfig.setEapMethod(Eap.PEAP);
- mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
- assertEquals("PEAP", getSupplicantEapMethod());
- assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
-
- // Change the EAP method to another type which supports a phase2.
- mEnterpriseConfig.setEapMethod(Eap.TTLS);
- assertEquals("TTLS", getSupplicantEapMethod());
- assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
-
- // Change the EAP method to TLS which does not support a phase2.
- mEnterpriseConfig.setEapMethod(Eap.TLS);
- assertEquals(null, getSupplicantPhase2Method());
- }
-
- /** Verfies that the EAP inner method is reset when we switch phase2 to NONE */
- @Test
- public void eapPhase2None() {
- // Initially select an EAP method that supports an phase2.
- mEnterpriseConfig.setEapMethod(Eap.PEAP);
- mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
- assertEquals("PEAP", getSupplicantEapMethod());
- assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
-
- // Change the phase2 method to NONE and ensure the value is cleared.
- mEnterpriseConfig.setPhase2Method(Phase2.NONE);
- assertEquals(null, getSupplicantPhase2Method());
- }
-
- /** Verfies that the correct "autheap" parameter is supplied for TTLS/GTC. */
- @Test
- public void peapGtcToTtls() {
- mEnterpriseConfig.setEapMethod(Eap.PEAP);
- mEnterpriseConfig.setPhase2Method(Phase2.GTC);
- assertEquals("PEAP", getSupplicantEapMethod());
- assertEquals("\"auth=GTC\"", getSupplicantPhase2Method());
-
- mEnterpriseConfig.setEapMethod(Eap.TTLS);
- assertEquals("TTLS", getSupplicantEapMethod());
- assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
- }
-
- /** Verfies that the correct "auth" parameter is supplied for PEAP/GTC. */
- @Test
- public void ttlsGtcToPeap() {
- mEnterpriseConfig.setEapMethod(Eap.TTLS);
- mEnterpriseConfig.setPhase2Method(Phase2.GTC);
- assertEquals("TTLS", getSupplicantEapMethod());
- assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
-
- mEnterpriseConfig.setEapMethod(Eap.PEAP);
- assertEquals("PEAP", getSupplicantEapMethod());
- assertEquals("\"auth=GTC\"", getSupplicantPhase2Method());
- }
-
- /** Verfies PEAP/SIM, PEAP/AKA, PEAP/AKA'. */
- @Test
- public void peapSimAkaAkaPrime() {
- mEnterpriseConfig.setEapMethod(Eap.PEAP);
- mEnterpriseConfig.setPhase2Method(Phase2.SIM);
- assertEquals("PEAP", getSupplicantEapMethod());
- assertEquals("\"auth=SIM\"", getSupplicantPhase2Method());
-
- mEnterpriseConfig.setPhase2Method(Phase2.AKA);
- assertEquals("\"auth=AKA\"", getSupplicantPhase2Method());
-
- mEnterpriseConfig.setPhase2Method(Phase2.AKA_PRIME);
- assertEquals("\"auth=AKA'\"", getSupplicantPhase2Method());
- }
-
- /**
- * Verifies that the copy constructor preseves both the masked password and inner method
- * information.
- */
- @Test
- public void copyConstructor() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setPassword("*");
- enterpriseConfig.setEapMethod(Eap.TTLS);
- enterpriseConfig.setPhase2Method(Phase2.GTC);
- mEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
- assertEquals("TTLS", getSupplicantEapMethod());
- assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
- assertEquals("*", mEnterpriseConfig.getPassword());
- }
-
- /**
- * Verifies that the copy from external ignores masked passwords and preserves the
- * inner method information.
- */
- @Test
- public void copyFromExternal() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setPassword("*");
- enterpriseConfig.setEapMethod(Eap.TTLS);
- enterpriseConfig.setPhase2Method(Phase2.GTC);
- enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
- mEnterpriseConfig = new WifiEnterpriseConfig();
- mEnterpriseConfig.copyFromExternal(enterpriseConfig, "*");
- assertEquals("TTLS", getSupplicantEapMethod());
- assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
- assertNotEquals("*", mEnterpriseConfig.getPassword());
- assertEquals(enterpriseConfig.getOcsp(), mEnterpriseConfig.getOcsp());
- }
-
- /** Verfies that parceling a WifiEnterpriseConfig preseves method information. */
- @Test
- public void parcelConstructor() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setEapMethod(Eap.TTLS);
- enterpriseConfig.setPhase2Method(Phase2.GTC);
- Parcel parcel = Parcel.obtain();
- enterpriseConfig.writeToParcel(parcel, 0);
- parcel.setDataPosition(0); // Allow parcel to be read from the beginning.
- mEnterpriseConfig = WifiEnterpriseConfig.CREATOR.createFromParcel(parcel);
- assertEquals("TTLS", getSupplicantEapMethod());
- assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
- }
-
- /**
- * Verifies that parceling a WifiEnterpriseConfig preserves the key
- * and certificates information.
- */
- @Test
- public void parcelConfigWithKeyAndCerts() throws Exception {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- PrivateKey clientKey = FakeKeys.RSA_KEY1;
- X509Certificate clientCert = FakeKeys.CLIENT_CERT;
- X509Certificate[] caCerts = new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1};
- enterpriseConfig.setClientKeyEntry(clientKey, clientCert);
- enterpriseConfig.setCaCertificates(caCerts);
- Parcel parcel = Parcel.obtain();
- enterpriseConfig.writeToParcel(parcel, 0);
-
- parcel.setDataPosition(0); // Allow parcel to be read from the beginning.
- mEnterpriseConfig = WifiEnterpriseConfig.CREATOR.createFromParcel(parcel);
- PrivateKey actualClientKey = mEnterpriseConfig.getClientPrivateKey();
- X509Certificate actualClientCert = mEnterpriseConfig.getClientCertificate();
- X509Certificate[] actualCaCerts = mEnterpriseConfig.getCaCertificates();
-
- /* Verify client private key. */
- assertNotNull(actualClientKey);
- assertEquals(clientKey.getAlgorithm(), actualClientKey.getAlgorithm());
- assertArrayEquals(clientKey.getEncoded(), actualClientKey.getEncoded());
-
- /* Verify client certificate. */
- assertNotNull(actualClientCert);
- assertArrayEquals(clientCert.getEncoded(), actualClientCert.getEncoded());
-
- /* Verify CA certificates. */
- assertNotNull(actualCaCerts);
- assertEquals(caCerts.length, actualCaCerts.length);
- for (int i = 0; i < caCerts.length; i++) {
- assertNotNull(actualCaCerts[i]);
- assertArrayEquals(caCerts[i].getEncoded(), actualCaCerts[i].getEncoded());
- }
- }
-
- /** Verifies proper operation of the getKeyId() method. */
- @Test
- public void getKeyId() {
- assertEquals("NULL", mEnterpriseConfig.getKeyId(null));
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setEapMethod(Eap.TTLS);
- enterpriseConfig.setPhase2Method(Phase2.GTC);
- assertEquals("TTLS_GTC", mEnterpriseConfig.getKeyId(enterpriseConfig));
- mEnterpriseConfig.setEapMethod(Eap.PEAP);
- mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
- assertEquals("PEAP_MSCHAPV2", mEnterpriseConfig.getKeyId(enterpriseConfig));
- }
-
- /** Verifies that passwords are not displayed in toString. */
- @Test
- public void passwordNotInToString() {
- String password = "supersecret";
- mEnterpriseConfig.setPassword(password);
- assertFalse(mEnterpriseConfig.toString().contains(password));
- }
-
- /** Verifies that certificate ownership flag is set correctly */
- @Test
- public void testIsAppInstalledDeviceKeyAndCert() {
- // First make sure that app didn't install anything
- assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
- assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
-
- // Then app loads keys via the enterprise config API
- PrivateKey clientKey = FakeKeys.RSA_KEY1;
- X509Certificate cert0 = FakeKeys.CLIENT_CERT;
- X509Certificate cert1 = FakeKeys.CA_CERT1;
- X509Certificate[] clientChain = new X509Certificate[] {cert0, cert1};
- mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
- X509Certificate[] result = mEnterpriseConfig.getClientCertificateChain();
- assertEquals(result.length, 2);
- assertTrue(result[0] == cert0 && result[1] == cert1);
- assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
-
- // Make sure it is the owner now
- assertTrue(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
- assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
- }
-
- /** Verifies that certificate ownership flag is set correctly */
- @Test
- public void testIsAppInstalledCaCert() {
- // First make sure that app didn't install anything
- assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
- assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
-
- // Then app loads CA cert via the enterprise config API
- X509Certificate cert = FakeKeys.CA_CERT1;
- mEnterpriseConfig.setCaCertificate(cert);
- X509Certificate result = mEnterpriseConfig.getCaCertificate();
- assertTrue(result == cert);
-
- // Make sure it is the owner now
- assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
- assertTrue(mEnterpriseConfig.isAppInstalledCaCert());
- }
-
- /** Verifies that certificate ownership flag is set correctly */
- @Test
- public void testIsAppInstalledCaCerts() {
- // First make sure that app didn't install anything
- assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
- assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
-
- // Then app loads CA cert via the enterprise config API
- X509Certificate cert0 = FakeKeys.CA_CERT0;
- X509Certificate cert1 = FakeKeys.CA_CERT1;
- X509Certificate[] cert = new X509Certificate[] {cert0, cert1};
-
- mEnterpriseConfig.setCaCertificates(cert);
- X509Certificate[] result = mEnterpriseConfig.getCaCertificates();
- assertEquals(result.length, 2);
- assertTrue(result[0] == cert0 && result[1] == cert1);
-// assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
-
- // Make sure it is the owner now
- assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
- assertTrue(mEnterpriseConfig.isAppInstalledCaCert());
- }
-
- /** Verifies that OCSP value is set correctly. */
- @Test
- public void testOcspSetGet() throws Exception {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-
- enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_NONE);
- assertEquals(WifiEnterpriseConfig.OCSP_NONE, enterpriseConfig.getOcsp());
-
- enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
- assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS, enterpriseConfig.getOcsp());
-
- enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS);
- assertEquals(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS, enterpriseConfig.getOcsp());
-
- enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
- assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS,
- enterpriseConfig.getOcsp());
- }
-
- /** Verifies that an exception is thrown when invalid OCSP is set. */
- @Test
- public void testInvalidOcspValue() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- try {
- enterpriseConfig.setOcsp(-1);
- fail("Should raise an IllegalArgumentException here.");
- } catch (IllegalArgumentException e) {
- // expected exception.
- }
- }
-
- /** Verifies that the EAP inner method is reset when we switch to Unauth-TLS */
- @Test
- public void eapPhase2MethodForUnauthTls() {
- // Initially select an EAP method that supports an phase2.
- mEnterpriseConfig.setEapMethod(Eap.PEAP);
- mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
- assertEquals("PEAP", getSupplicantEapMethod());
- assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
-
- // Change the EAP method to another type which supports a phase2.
- mEnterpriseConfig.setEapMethod(Eap.TTLS);
- assertEquals("TTLS", getSupplicantEapMethod());
- assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
-
- // Change the EAP method to Unauth-TLS which does not support a phase2.
- mEnterpriseConfig.setEapMethod(Eap.UNAUTH_TLS);
- assertEquals(null, getSupplicantPhase2Method());
- }
-
- @Test
- public void testIsEnterpriseConfigSecure() {
- WifiEnterpriseConfig baseConfig = new WifiEnterpriseConfig();
- baseConfig.setEapMethod(Eap.PEAP);
- baseConfig.setPhase2Method(Phase2.MSCHAPV2);
- assertTrue(baseConfig.isInsecure());
-
- WifiEnterpriseConfig noMatchConfig = new WifiEnterpriseConfig(baseConfig);
- noMatchConfig.setCaCertificate(FakeKeys.CA_CERT0);
- // Missing match is insecure.
- assertTrue(noMatchConfig.isInsecure());
-
- WifiEnterpriseConfig noCaConfig = new WifiEnterpriseConfig(baseConfig);
- noCaConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
- // Missing CA certificate is insecure.
- assertTrue(noCaConfig.isInsecure());
-
- WifiEnterpriseConfig secureConfig = new WifiEnterpriseConfig();
- secureConfig.setEapMethod(Eap.PEAP);
- secureConfig.setPhase2Method(Phase2.MSCHAPV2);
- secureConfig.setCaCertificate(FakeKeys.CA_CERT0);
- secureConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
- assertFalse(secureConfig.isInsecure());
-
- WifiEnterpriseConfig secureConfigWithCaAlias = new WifiEnterpriseConfig();
- secureConfigWithCaAlias.setEapMethod(Eap.PEAP);
- secureConfigWithCaAlias.setPhase2Method(Phase2.MSCHAPV2);
- secureConfigWithCaAlias.setCaCertificateAliases(new String[]{"alias1", "alisa2"});
- secureConfigWithCaAlias.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
- assertFalse(secureConfigWithCaAlias.isInsecure());
- }
-
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java
deleted file mode 100644
index 311bbc4..0000000
--- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java
+++ /dev/null
@@ -1,151 +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.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiInfo}.
- */
-@SmallTest
-public class WifiInfoTest {
- private static final long TEST_TX_SUCCESS = 1;
- private static final long TEST_TX_RETRIES = 2;
- private static final long TEST_TX_BAD = 3;
- private static final long TEST_RX_SUCCESS = 4;
- private static final String TEST_PACKAGE_NAME = "com.test.example";
- private static final String TEST_FQDN = "test.com";
- private static final String TEST_PROVIDER_NAME = "test";
- private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC;
- private static final int TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 866;
- private static final int TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 1200;
- private static final String TEST_SSID = "Test123";
- private static final String TEST_BSSID = "12:12:12:12:12:12";
- private static final int TEST_RSSI = -60;
- private static final int TEST_NETWORK_ID = 5;
- private static final int TEST_NETWORK_ID2 = 6;
-
- /**
- * Verify parcel write/read with WifiInfo.
- */
- @Test
- public void testWifiInfoParcelWriteRead() throws Exception {
- WifiInfo writeWifiInfo = new WifiInfo();
- writeWifiInfo.txSuccess = TEST_TX_SUCCESS;
- writeWifiInfo.txRetries = TEST_TX_RETRIES;
- writeWifiInfo.txBad = TEST_TX_BAD;
- writeWifiInfo.rxSuccess = TEST_RX_SUCCESS;
- writeWifiInfo.setTrusted(true);
- writeWifiInfo.setOsuAp(true);
- writeWifiInfo.setFQDN(TEST_FQDN);
- writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME);
- writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME);
- writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD);
- writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
- writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
-
- Parcel parcel = Parcel.obtain();
- writeWifiInfo.writeToParcel(parcel, 0);
- // Rewind the pointer to the head of the parcel.
- parcel.setDataPosition(0);
- WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
-
- assertNotNull(readWifiInfo);
- assertEquals(TEST_TX_SUCCESS, readWifiInfo.txSuccess);
- assertEquals(TEST_TX_RETRIES, readWifiInfo.txRetries);
- assertEquals(TEST_TX_BAD, readWifiInfo.txBad);
- assertEquals(TEST_RX_SUCCESS, readWifiInfo.rxSuccess);
- assertTrue(readWifiInfo.isTrusted());
- assertTrue(readWifiInfo.isOsuAp());
- assertTrue(readWifiInfo.isPasspointAp());
- assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName());
- assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn());
- assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName());
- assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard());
- assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS,
- readWifiInfo.getMaxSupportedTxLinkSpeedMbps());
- assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS,
- readWifiInfo.getMaxSupportedRxLinkSpeedMbps());
- }
-
- /**
- * Verify values after reset()
- */
- @Test
- public void testWifiInfoResetValue() throws Exception {
- WifiInfo wifiInfo = new WifiInfo();
- wifiInfo.reset();
- assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedTxLinkSpeedMbps());
- assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedRxLinkSpeedMbps());
- assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getTxLinkSpeedMbps());
- assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getRxLinkSpeedMbps());
- assertEquals(WifiInfo.INVALID_RSSI, wifiInfo.getRssi());
- assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID());
- assertEquals(null, wifiInfo.getBSSID());
- assertEquals(-1, wifiInfo.getNetworkId());
- }
-
- /**
- * Test that the WifiInfo Builder returns the same values that was set, and that
- * calling build multiple times returns different instances.
- */
- @Test
- public void testWifiInfoBuilder() throws Exception {
- WifiInfo.Builder builder = new WifiInfo.Builder()
- .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
- .setBssid(TEST_BSSID)
- .setRssi(TEST_RSSI)
- .setNetworkId(TEST_NETWORK_ID);
-
- WifiInfo info1 = builder.build();
-
- assertEquals("\"" + TEST_SSID + "\"", info1.getSSID());
- assertEquals(TEST_BSSID, info1.getBSSID());
- assertEquals(TEST_RSSI, info1.getRssi());
- assertEquals(TEST_NETWORK_ID, info1.getNetworkId());
-
- WifiInfo info2 = builder
- .setNetworkId(TEST_NETWORK_ID2)
- .build();
-
- // different instances
- assertNotSame(info1, info2);
-
- // assert that info1 didn't change
- assertEquals("\"" + TEST_SSID + "\"", info1.getSSID());
- assertEquals(TEST_BSSID, info1.getBSSID());
- assertEquals(TEST_RSSI, info1.getRssi());
- assertEquals(TEST_NETWORK_ID, info1.getNetworkId());
-
- // assert that info2 changed
- assertEquals("\"" + TEST_SSID + "\"", info2.getSSID());
- assertEquals(TEST_BSSID, info2.getBSSID());
- assertEquals(TEST_RSSI, info2.getRssi());
- assertEquals(TEST_NETWORK_ID2, info2.getNetworkId());
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
deleted file mode 100644
index 1398bfe..0000000
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ /dev/null
@@ -1,2389 +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.net.wifi;
-
-import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED;
-import static android.net.wifi.WifiManager.ActionListener;
-import static android.net.wifi.WifiManager.BUSY;
-import static android.net.wifi.WifiManager.ERROR;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED;
-import static android.net.wifi.WifiManager.NOT_AUTHORIZED;
-import static android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener;
-import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
-import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
-import static android.net.wifi.WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_P2P;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_SCANNER;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
-import static android.net.wifi.WifiManager.WpsCallback;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyList;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.net.DhcpInfo;
-import android.net.MacAddress;
-import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
-import android.net.wifi.WifiManager.LocalOnlyHotspotObserver;
-import android.net.wifi.WifiManager.LocalOnlyHotspotReservation;
-import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription;
-import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
-import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
-import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener;
-import android.net.wifi.WifiManager.ScanResultsCallback;
-import android.net.wifi.WifiManager.SoftApCallback;
-import android.net.wifi.WifiManager.SuggestionConnectionStatusListener;
-import android.net.wifi.WifiManager.TrafficStateCallback;
-import android.net.wifi.WifiManager.WifiConnectedNetworkScorer;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.connectivity.WifiActivityEnergyInfo;
-import android.os.test.TestLooper;
-import android.util.SparseArray;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiManager}.
- */
-@SmallTest
-public class WifiManagerTest {
-
- private static final int ERROR_NOT_SET = -1;
- private static final int ERROR_TEST_REASON = 5;
- private static final int TEST_UID = 14553;
- private static final int TEST_NETWORK_ID = 143;
- private static final String TEST_PACKAGE_NAME = "TestPackage";
- private static final String TEST_FEATURE_ID = "TestFeature";
- private static final String TEST_COUNTRY_CODE = "US";
- private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"};
- private static final int TEST_AP_FREQUENCY = 2412;
- private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ;
-
- @Mock Context mContext;
- @Mock android.net.wifi.IWifiManager mWifiService;
- @Mock ApplicationInfo mApplicationInfo;
- @Mock WifiConfiguration mApConfig;
- @Mock SoftApCallback mSoftApCallback;
- @Mock TrafficStateCallback mTrafficStateCallback;
- @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback;
- @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
- @Mock OnWifiActivityEnergyInfoListener mOnWifiActivityEnergyInfoListener;
- @Mock SuggestionConnectionStatusListener mListener;
- @Mock Runnable mRunnable;
- @Mock Executor mExecutor;
- @Mock Executor mAnotherExecutor;
- @Mock ActivityManager mActivityManager;
- @Mock WifiConnectedNetworkScorer mWifiConnectedNetworkScorer;
-
- private Handler mHandler;
- private TestLooper mLooper;
- private WifiManager mWifiManager;
- private WifiNetworkSuggestion mWifiNetworkSuggestion;
- private ScanResultsCallback mScanResultsCallback;
- private WifiActivityEnergyInfo mWifiActivityEnergyInfo;
-
- /**
- * Util function to check public field which used for softap in WifiConfiguration
- * same as the value in SoftApConfiguration.
- *
- */
- private boolean compareWifiAndSoftApConfiguration(
- SoftApConfiguration softApConfig, WifiConfiguration wifiConfig) {
- if (!Objects.equals(wifiConfig.SSID, softApConfig.getSsid())) {
- return false;
- }
- if (!Objects.equals(wifiConfig.BSSID, softApConfig.getBssid())) {
- return false;
- }
- if (!Objects.equals(wifiConfig.preSharedKey, softApConfig.getPassphrase())) {
- return false;
- }
-
- if (wifiConfig.hiddenSSID != softApConfig.isHiddenSsid()) {
- return false;
- }
- switch (softApConfig.getSecurityType()) {
- case SoftApConfiguration.SECURITY_TYPE_OPEN:
- if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.NONE) {
- return false;
- }
- break;
- case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK:
- if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.WPA2_PSK) {
- return false;
- }
- break;
- default:
- return false;
- }
- return true;
- }
-
- private SoftApConfiguration generatorTestSoftApConfig() {
- return new SoftApConfiguration.Builder()
- .setSsid("TestSSID")
- .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
- .build();
- }
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mLooper = new TestLooper();
- mHandler = spy(new Handler(mLooper.getLooper()));
- mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
- when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
- when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
- mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
- verify(mWifiService).getVerboseLoggingLevel();
- mWifiNetworkSuggestion = new WifiNetworkSuggestion();
- mScanResultsCallback = new ScanResultsCallback() {
- @Override
- public void onScanResultsAvailable() {
- mRunnable.run();
- }
- };
- mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0);
- }
-
- /**
- * Check the call to startSoftAp calls WifiService to startSoftAp with the provided
- * WifiConfiguration. Verify that the return value is propagated to the caller.
- */
- @Test
- public void testStartSoftApCallsServiceWithWifiConfig() throws Exception {
- when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(true);
- assertTrue(mWifiManager.startSoftAp(mApConfig));
-
- when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(false);
- assertFalse(mWifiManager.startSoftAp(mApConfig));
- }
-
- /**
- * Check the call to startSoftAp calls WifiService to startSoftAp with a null config. Verify
- * that the return value is propagated to the caller.
- */
- @Test
- public void testStartSoftApCallsServiceWithNullConfig() throws Exception {
- when(mWifiService.startSoftAp(eq(null))).thenReturn(true);
- assertTrue(mWifiManager.startSoftAp(null));
-
- when(mWifiService.startSoftAp(eq(null))).thenReturn(false);
- assertFalse(mWifiManager.startSoftAp(null));
- }
-
- /**
- * Check the call to stopSoftAp calls WifiService to stopSoftAp.
- */
- @Test
- public void testStopSoftApCallsService() throws Exception {
- when(mWifiService.stopSoftAp()).thenReturn(true);
- assertTrue(mWifiManager.stopSoftAp());
-
- when(mWifiService.stopSoftAp()).thenReturn(false);
- assertFalse(mWifiManager.stopSoftAp());
- }
-
- /**
- * Check the call to startSoftAp calls WifiService to startSoftAp with the provided
- * WifiConfiguration. Verify that the return value is propagated to the caller.
- */
- @Test
- public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception {
- SoftApConfiguration softApConfig = generatorTestSoftApConfig();
- when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(true);
- assertTrue(mWifiManager.startTetheredHotspot(softApConfig));
-
- when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(false);
- assertFalse(mWifiManager.startTetheredHotspot(softApConfig));
- }
-
- /**
- * Check the call to startSoftAp calls WifiService to startSoftAp with a null config. Verify
- * that the return value is propagated to the caller.
- */
- @Test
- public void testStartTetheredHotspotCallsServiceWithNullConfig() throws Exception {
- when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(true);
- assertTrue(mWifiManager.startTetheredHotspot(null));
-
- when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(false);
- assertFalse(mWifiManager.startTetheredHotspot(null));
- }
-
- /**
- * Test creation of a LocalOnlyHotspotReservation and verify that close properly calls
- * WifiService.stopLocalOnlyHotspot.
- */
- @Test
- public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
- SoftApConfiguration softApConfig = generatorTestSoftApConfig();
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
- nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-
- callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));
-
- assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
- WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
- assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
-
- callback.mRes.close();
- verify(mWifiService).stopLocalOnlyHotspot();
- }
-
- /**
- * Verify stopLOHS is called when try-with-resources is used properly.
- */
- @Test
- public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
- throws Exception {
- SoftApConfiguration softApConfig = generatorTestSoftApConfig();
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
- nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-
- callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));
-
- try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) {
- assertEquals(softApConfig, res.getSoftApConfiguration());
- WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
- assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
- }
-
- verify(mWifiService).stopLocalOnlyHotspot();
- }
-
- /**
- * Test creation of a LocalOnlyHotspotSubscription.
- * TODO: when registrations are tracked, verify removal on close.
- */
- @Test
- public void testCreationOfLocalOnlyHotspotSubscription() throws Exception {
- try (WifiManager.LocalOnlyHotspotSubscription sub =
- mWifiManager.new LocalOnlyHotspotSubscription()) {
- sub.close();
- }
- }
-
- public class TestLocalOnlyHotspotCallback extends LocalOnlyHotspotCallback {
- public boolean mOnStartedCalled = false;
- public boolean mOnStoppedCalled = false;
- public int mFailureReason = -1;
- public LocalOnlyHotspotReservation mRes = null;
- public long mCallingThreadId = -1;
-
- @Override
- public void onStarted(LocalOnlyHotspotReservation r) {
- mRes = r;
- mOnStartedCalled = true;
- mCallingThreadId = Thread.currentThread().getId();
- }
-
- @Override
- public void onStopped() {
- mOnStoppedCalled = true;
- mCallingThreadId = Thread.currentThread().getId();
- }
-
- @Override
- public void onFailed(int reason) {
- mFailureReason = reason;
- mCallingThreadId = Thread.currentThread().getId();
- }
- }
-
- /**
- * Verify callback is properly plumbed when called.
- */
- @Test
- public void testLocalOnlyHotspotCallback() {
- SoftApConfiguration softApConfig = generatorTestSoftApConfig();
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- assertFalse(callback.mOnStartedCalled);
- assertFalse(callback.mOnStoppedCalled);
- assertEquals(ERROR_NOT_SET, callback.mFailureReason);
- assertEquals(null, callback.mRes);
-
- // test onStarted
- WifiManager.LocalOnlyHotspotReservation res =
- mWifiManager.new LocalOnlyHotspotReservation(softApConfig);
- callback.onStarted(res);
- assertEquals(res, callback.mRes);
- assertTrue(callback.mOnStartedCalled);
- assertFalse(callback.mOnStoppedCalled);
- assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-
- // test onStopped
- callback.onStopped();
- assertEquals(res, callback.mRes);
- assertTrue(callback.mOnStartedCalled);
- assertTrue(callback.mOnStoppedCalled);
- assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-
- // test onFailed
- callback.onFailed(ERROR_TEST_REASON);
- assertEquals(res, callback.mRes);
- assertTrue(callback.mOnStartedCalled);
- assertTrue(callback.mOnStoppedCalled);
- assertEquals(ERROR_TEST_REASON, callback.mFailureReason);
- }
-
- public class TestLocalOnlyHotspotObserver extends LocalOnlyHotspotObserver {
- public boolean mOnRegistered = false;
- public boolean mOnStartedCalled = false;
- public boolean mOnStoppedCalled = false;
- public SoftApConfiguration mConfig = null;
- public LocalOnlyHotspotSubscription mSub = null;
- public long mCallingThreadId = -1;
-
- @Override
- public void onRegistered(LocalOnlyHotspotSubscription sub) {
- mOnRegistered = true;
- mSub = sub;
- mCallingThreadId = Thread.currentThread().getId();
- }
-
- @Override
- public void onStarted(SoftApConfiguration config) {
- mOnStartedCalled = true;
- mConfig = config;
- mCallingThreadId = Thread.currentThread().getId();
- }
-
- @Override
- public void onStopped() {
- mOnStoppedCalled = true;
- mCallingThreadId = Thread.currentThread().getId();
- }
- }
-
- /**
- * Verify observer is properly plumbed when called.
- */
- @Test
- public void testLocalOnlyHotspotObserver() {
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
- SoftApConfiguration softApConfig = generatorTestSoftApConfig();
- assertFalse(observer.mOnRegistered);
- assertFalse(observer.mOnStartedCalled);
- assertFalse(observer.mOnStoppedCalled);
- assertEquals(null, observer.mConfig);
- assertEquals(null, observer.mSub);
-
- WifiManager.LocalOnlyHotspotSubscription sub =
- mWifiManager.new LocalOnlyHotspotSubscription();
- observer.onRegistered(sub);
- assertTrue(observer.mOnRegistered);
- assertFalse(observer.mOnStartedCalled);
- assertFalse(observer.mOnStoppedCalled);
- assertEquals(null, observer.mConfig);
- assertEquals(sub, observer.mSub);
-
- observer.onStarted(softApConfig);
- assertTrue(observer.mOnRegistered);
- assertTrue(observer.mOnStartedCalled);
- assertFalse(observer.mOnStoppedCalled);
- assertEquals(softApConfig, observer.mConfig);
- assertEquals(sub, observer.mSub);
-
- observer.onStopped();
- assertTrue(observer.mOnRegistered);
- assertTrue(observer.mOnStartedCalled);
- assertTrue(observer.mOnStoppedCalled);
- assertEquals(softApConfig, observer.mConfig);
- assertEquals(sub, observer.mSub);
- }
-
- /**
- * Verify call to startLocalOnlyHotspot goes to WifiServiceImpl.
- */
- @Test
- public void testStartLocalOnlyHotspot() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-
- verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
- anyString(), nullable(String.class), eq(null));
- }
-
- /**
- * Verify a SecurityException is thrown for callers without proper permissions for
- * startLocalOnlyHotspot.
- */
- @Test(expected = SecurityException.class)
- public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot(
- any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class),
- eq(null));
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- }
-
- /**
- * Verify an IllegalStateException is thrown for callers that already have a pending request for
- * startLocalOnlyHotspot.
- */
- @Test(expected = IllegalStateException.class)
- public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- doThrow(new IllegalStateException()).when(mWifiService).startLocalOnlyHotspot(
- any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class),
- eq(null));
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- }
-
- /**
- * Verify that the handler provided by the caller is used for the callbacks.
- */
- @Test
- public void testCorrectLooperIsUsedForHandler() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
- nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- mLooper.dispatchAll();
- assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
- verify(mContext, never()).getMainLooper();
- verify(mContext, never()).getMainExecutor();
- }
-
- /**
- * Verify that the main looper's thread is used if a handler is not provided by the reqiestomg
- * application.
- */
- @Test
- public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception {
- // record thread from looper.getThread and check ids.
- TestLooper altLooper = new TestLooper();
- when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor());
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
- nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
- mWifiManager.startLocalOnlyHotspot(callback, null);
- altLooper.dispatchAll();
- assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
- assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
- verify(mContext).getMainExecutor();
- }
-
- /**
- * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
- * message from WifiServiceImpl.
- */
- @Test
- public void testOnStartedIsCalledWithReservation() throws Exception {
- SoftApConfiguration softApConfig = generatorTestSoftApConfig();
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- TestLooper callbackLooper = new TestLooper();
- Handler callbackHandler = new Handler(callbackLooper.getLooper());
- ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
- ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
- when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
- nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
- mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
- callbackLooper.dispatchAll();
- mLooper.dispatchAll();
- assertFalse(callback.mOnStartedCalled);
- assertEquals(null, callback.mRes);
- // now trigger the callback
- internalCallback.getValue().onHotspotStarted(softApConfig);
- mLooper.dispatchAll();
- callbackLooper.dispatchAll();
- assertTrue(callback.mOnStartedCalled);
- assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
- WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
- assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
- }
-
- /**
- * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
- * message from WifiServiceImpl when softap enabled with SAE security type.
- */
- @Test
- public void testOnStartedIsCalledWithReservationAndSaeSoftApConfig() throws Exception {
- SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
- .setSsid("TestSSID")
- .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
- .build();
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- TestLooper callbackLooper = new TestLooper();
- Handler callbackHandler = new Handler(callbackLooper.getLooper());
- ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
- ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
- when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
- nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
- mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
- callbackLooper.dispatchAll();
- mLooper.dispatchAll();
- assertFalse(callback.mOnStartedCalled);
- assertEquals(null, callback.mRes);
- // now trigger the callback
- internalCallback.getValue().onHotspotStarted(softApConfig);
- mLooper.dispatchAll();
- callbackLooper.dispatchAll();
- assertTrue(callback.mOnStartedCalled);
- assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
- assertEquals(null, callback.mRes.getWifiConfiguration());
- }
-
- /**
- * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_STARTED message with a null
- * config.
- */
- @Test
- public void testOnStartedIsCalledWithNullConfig() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- TestLooper callbackLooper = new TestLooper();
- Handler callbackHandler = new Handler(callbackLooper.getLooper());
- ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
- ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
- when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
- nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
- mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
- callbackLooper.dispatchAll();
- mLooper.dispatchAll();
- assertFalse(callback.mOnStartedCalled);
- assertEquals(null, callback.mRes);
- // now trigger the callback
- internalCallback.getValue().onHotspotStarted(null);
- mLooper.dispatchAll();
- callbackLooper.dispatchAll();
- assertFalse(callback.mOnStartedCalled);
- assertEquals(ERROR_GENERIC, callback.mFailureReason);
- }
-
- /**
- * Verify onStopped is called if WifiServiceImpl sends a HOTSPOT_STOPPED message.
- */
- @Test
- public void testOnStoppedIsCalled() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- TestLooper callbackLooper = new TestLooper();
- Handler callbackHandler = new Handler(callbackLooper.getLooper());
- ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
- ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
- when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
- nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
- mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
- callbackLooper.dispatchAll();
- mLooper.dispatchAll();
- assertFalse(callback.mOnStoppedCalled);
- // now trigger the callback
- internalCallback.getValue().onHotspotStopped();
- mLooper.dispatchAll();
- callbackLooper.dispatchAll();
- assertTrue(callback.mOnStoppedCalled);
- }
-
- /**
- * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_FAILED message.
- */
- @Test
- public void testOnFailedIsCalled() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- TestLooper callbackLooper = new TestLooper();
- Handler callbackHandler = new Handler(callbackLooper.getLooper());
- ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
- ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
- when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
- nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
- mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
- callbackLooper.dispatchAll();
- mLooper.dispatchAll();
- assertEquals(ERROR_NOT_SET, callback.mFailureReason);
- // now trigger the callback
- internalCallback.getValue().onHotspotFailed(ERROR_NO_CHANNEL);
- mLooper.dispatchAll();
- callbackLooper.dispatchAll();
- assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
- }
-
- /**
- * Verify callback triggered from startLocalOnlyHotspot with an incompatible mode failure.
- */
- @Test
- public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
- nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- mLooper.dispatchAll();
- assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
- assertFalse(callback.mOnStartedCalled);
- assertFalse(callback.mOnStoppedCalled);
- assertEquals(null, callback.mRes);
- }
-
- /**
- * Verify callback triggered from startLocalOnlyHotspot with a tethering disallowed failure.
- */
- @Test
- public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
- nullable(String.class), eq(null))).thenReturn(ERROR_TETHERING_DISALLOWED);
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- mLooper.dispatchAll();
- assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason);
- assertFalse(callback.mOnStartedCalled);
- assertFalse(callback.mOnStoppedCalled);
- assertEquals(null, callback.mRes);
- }
-
- /**
- * Verify a SecurityException resulting from an application without necessary permissions will
- * bubble up through the call to start LocalOnlyHotspot and will not trigger other callbacks.
- */
- @Test(expected = SecurityException.class)
- public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot(
- any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class),
- eq(null));
- try {
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- } catch (SecurityException e) {
- assertEquals(ERROR_NOT_SET, callback.mFailureReason);
- assertFalse(callback.mOnStartedCalled);
- assertFalse(callback.mOnStoppedCalled);
- assertEquals(null, callback.mRes);
- throw e;
- }
-
- }
-
- /**
- * Verify the handler passed to startLocalOnlyHotspot is correctly used for callbacks when
- * SoftApMode fails due to a underlying error.
- */
- @Test
- public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
- nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- mLooper.dispatchAll();
- //assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
- assertFalse(callback.mOnStartedCalled);
- assertFalse(callback.mOnStoppedCalled);
- assertEquals(null, callback.mRes);
- }
-
- /**
- * Verify that the call to cancel a LOHS request does call stopLOHS.
- */
- @Test
- public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
- nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- mWifiManager.cancelLocalOnlyHotspotRequest();
- verify(mWifiService).stopLocalOnlyHotspot();
- }
-
- /**
- * Verify that we do not crash if cancelLocalOnlyHotspotRequest is called without an existing
- * callback stored.
- */
- @Test
- public void testCancelLocalOnlyHotspotReturnsWithoutExistingRequest() {
- mWifiManager.cancelLocalOnlyHotspotRequest();
- }
-
- /**
- * Verify that the callback is not triggered if the LOHS request was already cancelled.
- */
- @Test
- public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
- nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- mWifiManager.cancelLocalOnlyHotspotRequest();
- verify(mWifiService).stopLocalOnlyHotspot();
- mLooper.dispatchAll();
- assertEquals(ERROR_NOT_SET, callback.mFailureReason);
- assertFalse(callback.mOnStartedCalled);
- assertFalse(callback.mOnStoppedCalled);
- assertEquals(null, callback.mRes);
- }
-
- /**
- * Verify that calling cancel LOHS request does not crash if an error callback was already
- * handled.
- */
- @Test
- public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception {
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
- nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
- mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- mLooper.dispatchAll();
- assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
- assertFalse(callback.mOnStartedCalled);
- assertFalse(callback.mOnStoppedCalled);
- assertEquals(null, callback.mRes);
- mWifiManager.cancelLocalOnlyHotspotRequest();
- verify(mWifiService, never()).stopLocalOnlyHotspot();
- }
-
- @Test
- public void testStartLocalOnlyHotspotForwardsCustomConfig() throws Exception {
- SoftApConfiguration customConfig = new SoftApConfiguration.Builder()
- .setSsid("customSsid")
- .build();
- TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- mWifiManager.startLocalOnlyHotspot(customConfig, mExecutor, callback);
- verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
- anyString(), nullable(String.class), eq(customConfig));
- }
-
- /**
- * Verify the watchLocalOnlyHotspot call goes to WifiServiceImpl.
- */
- @Test
- public void testWatchLocalOnlyHotspot() throws Exception {
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-
- mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
- verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
- }
-
- /**
- * Verify a SecurityException is thrown for callers without proper permissions for
- * startWatchLocalOnlyHotspot.
- */
- @Test(expected = SecurityException.class)
- public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception {
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
- doThrow(new SecurityException()).when(mWifiService)
- .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
- mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
- }
-
- /**
- * Verify an IllegalStateException is thrown for callers that already have a pending request for
- * watchLocalOnlyHotspot.
- */
- @Test(expected = IllegalStateException.class)
- public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
- doThrow(new IllegalStateException()).when(mWifiService)
- .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
- mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
- }
-
- /**
- * Verify an IllegalArgumentException is thrown if callback is not provided.
- */
- @Test
- public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
- try {
- mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), null);
- fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- /**
- * Verify an IllegalArgumentException is thrown if executor is null.
- */
- @Test
- public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForExecutor() {
- try {
- mWifiManager.registerSoftApCallback(null, mSoftApCallback);
- fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- /**
- * Verify an IllegalArgumentException is thrown if callback is not provided.
- */
- @Test
- public void unregisterSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
- try {
- mWifiManager.unregisterSoftApCallback(null);
- fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- /**
- * Verify the call to registerSoftApCallback goes to WifiServiceImpl.
- */
- @Test
- public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
- mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
- verify(mWifiService).registerSoftApCallback(any(IBinder.class),
- any(ISoftApCallback.Stub.class), anyInt());
- }
-
- /**
- * Verify the call to unregisterSoftApCallback goes to WifiServiceImpl.
- */
- @Test
- public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
- ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
- mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
- verify(mWifiService).registerSoftApCallback(any(IBinder.class),
- any(ISoftApCallback.Stub.class), callbackIdentifier.capture());
-
- mWifiManager.unregisterSoftApCallback(mSoftApCallback);
- verify(mWifiService).unregisterSoftApCallback(eq((int) callbackIdentifier.getValue()));
- }
-
- /*
- * Verify client-provided callback is being called through callback proxy
- */
- @Test
- public void softApCallbackProxyCallsOnStateChanged() throws Exception {
- ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
- mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
- verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
- anyInt());
-
- callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
- mLooper.dispatchAll();
- verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
- }
-
- /*
- * Verify client-provided callback is being called through callback proxy
- */
- @Test
- public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception {
- ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
- mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
- verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
- anyInt());
-
- final List<WifiClient> testClients = new ArrayList();
- callbackCaptor.getValue().onConnectedClientsChanged(testClients);
- mLooper.dispatchAll();
- verify(mSoftApCallback).onConnectedClientsChanged(testClients);
- }
-
-
- /*
- * Verify client-provided callback is being called through callback proxy
- */
- @Test
- public void softApCallbackProxyCallsOnSoftApInfoChanged() throws Exception {
- SoftApInfo testSoftApInfo = new SoftApInfo();
- testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
- testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
- ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
- mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
- verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
- anyInt());
-
- callbackCaptor.getValue().onInfoChanged(testSoftApInfo);
- mLooper.dispatchAll();
- verify(mSoftApCallback).onInfoChanged(testSoftApInfo);
- }
-
-
- /*
- * Verify client-provided callback is being called through callback proxy
- */
- @Test
- public void softApCallbackProxyCallsOnCapabilityChanged() throws Exception {
- SoftApCapability testSoftApCapability = new SoftApCapability(0);
- testSoftApCapability.setMaxSupportedClients(10);
- ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
- mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
- verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
- anyInt());
-
- callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability);
- mLooper.dispatchAll();
- verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability);
- }
-
- /*
- * Verify client-provided callback is being called through callback proxy
- */
- @Test
- public void softApCallbackProxyCallsOnBlockedClientConnecting() throws Exception {
- WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77"));
- ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
- mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
- verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
- anyInt());
-
- callbackCaptor.getValue().onBlockedClientConnecting(testWifiClient,
- WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS);
- mLooper.dispatchAll();
- verify(mSoftApCallback).onBlockedClientConnecting(testWifiClient,
- WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS);
- }
-
- /*
- * Verify client-provided callback is being called through callback proxy on multiple events
- */
- @Test
- public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception {
- SoftApInfo testSoftApInfo = new SoftApInfo();
- testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
- testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
- SoftApCapability testSoftApCapability = new SoftApCapability(0);
- testSoftApCapability.setMaxSupportedClients(10);
- ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
- mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
- verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
- anyInt());
-
- final List<WifiClient> testClients = new ArrayList();
- callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0);
- callbackCaptor.getValue().onConnectedClientsChanged(testClients);
- callbackCaptor.getValue().onInfoChanged(testSoftApInfo);
- callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
- callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability);
-
-
- mLooper.dispatchAll();
- verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0);
- verify(mSoftApCallback).onConnectedClientsChanged(testClients);
- verify(mSoftApCallback).onInfoChanged(testSoftApInfo);
- verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
- verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability);
- }
-
- /*
- * Verify client-provided callback is being called on the correct thread
- */
- @Test
- public void softApCallbackIsCalledOnCorrectThread() throws Exception {
- ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
- TestLooper altLooper = new TestLooper();
- Handler altHandler = new Handler(altLooper.getLooper());
- mWifiManager.registerSoftApCallback(new HandlerExecutor(altHandler), mSoftApCallback);
- verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
- anyInt());
-
- callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
- altLooper.dispatchAll();
- verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
- }
-
- /**
- * Verify that the handler provided by the caller is used for registering soft AP callback.
- */
- @Test
- public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception {
- mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
- mLooper.dispatchAll();
- verify(mWifiService).registerSoftApCallback(any(IBinder.class),
- any(ISoftApCallback.Stub.class), anyInt());
- verify(mContext, never()).getMainLooper();
- verify(mContext, never()).getMainExecutor();
- }
-
- /**
- * Verify that the handler provided by the caller is used for the observer.
- */
- @Test
- public void testCorrectLooperIsUsedForObserverHandler() throws Exception {
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
- mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
- mLooper.dispatchAll();
- assertTrue(observer.mOnRegistered);
- verify(mContext, never()).getMainLooper();
- verify(mContext, never()).getMainExecutor();
- }
-
- /**
- * Verify that the main looper's thread is used if a handler is not provided by the requesting
- * application.
- */
- @Test
- public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception {
- // record thread from looper.getThread and check ids.
- TestLooper altLooper = new TestLooper();
- when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor());
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
- mWifiManager.watchLocalOnlyHotspot(observer, null);
- altLooper.dispatchAll();
- assertTrue(observer.mOnRegistered);
- assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
- verify(mContext).getMainExecutor();
- }
-
- /**
- * Verify the LOHS onRegistered observer callback is triggered when WifiManager receives a
- * HOTSPOT_OBSERVER_REGISTERED message from WifiServiceImpl.
- */
- @Test
- public void testOnRegisteredIsCalledWithSubscription() throws Exception {
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
- TestLooper observerLooper = new TestLooper();
- Handler observerHandler = new Handler(observerLooper.getLooper());
- assertFalse(observer.mOnRegistered);
- assertEquals(null, observer.mSub);
- mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
- verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
- // now trigger the callback
- observerLooper.dispatchAll();
- mLooper.dispatchAll();
- assertTrue(observer.mOnRegistered);
- assertNotNull(observer.mSub);
- }
-
- /**
- * Verify the LOHS onStarted observer callback is triggered when WifiManager receives a
- * HOTSPOT_STARTED message from WifiServiceImpl.
- */
- @Test
- public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception {
- SoftApConfiguration softApConfig = generatorTestSoftApConfig();
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
- TestLooper observerLooper = new TestLooper();
- Handler observerHandler = new Handler(observerLooper.getLooper());
- mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
- ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
- ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
- verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
- observerLooper.dispatchAll();
- mLooper.dispatchAll();
- assertFalse(observer.mOnStartedCalled);
- // now trigger the callback
- internalCallback.getValue().onHotspotStarted(softApConfig);
- mLooper.dispatchAll();
- observerLooper.dispatchAll();
- assertTrue(observer.mOnStartedCalled);
- assertEquals(softApConfig, observer.mConfig);
- }
-
- /**
- * Verify the LOHS onStarted observer callback is triggered not when WifiManager receives a
- * HOTSPOT_STARTED message from WifiServiceImpl with a null config.
- */
- @Test
- public void testObserverOnStartedNotCalledWithNullConfig() throws Exception {
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
- TestLooper observerLooper = new TestLooper();
- Handler observerHandler = new Handler(observerLooper.getLooper());
- mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
- ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
- ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
- verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
- observerLooper.dispatchAll();
- mLooper.dispatchAll();
- assertFalse(observer.mOnStartedCalled);
- // now trigger the callback
- internalCallback.getValue().onHotspotStarted(null);
- mLooper.dispatchAll();
- observerLooper.dispatchAll();
- assertFalse(observer.mOnStartedCalled);
- assertEquals(null, observer.mConfig);
- }
-
-
- /**
- * Verify the LOHS onStopped observer callback is triggered when WifiManager receives a
- * HOTSPOT_STOPPED message from WifiServiceImpl.
- */
- @Test
- public void testObserverOnStoppedIsCalled() throws Exception {
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
- TestLooper observerLooper = new TestLooper();
- Handler observerHandler = new Handler(observerLooper.getLooper());
- mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
- ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
- ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
- verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
- observerLooper.dispatchAll();
- mLooper.dispatchAll();
- assertFalse(observer.mOnStoppedCalled);
- // now trigger the callback
- internalCallback.getValue().onHotspotStopped();
- mLooper.dispatchAll();
- observerLooper.dispatchAll();
- assertTrue(observer.mOnStoppedCalled);
- }
-
- /**
- * Verify WifiServiceImpl is not called if there is not a registered LOHS observer callback.
- */
- @Test
- public void testUnregisterWifiServiceImplNotCalledWithoutRegisteredObserver() throws Exception {
- mWifiManager.unregisterLocalOnlyHotspotObserver();
- verifyZeroInteractions(mWifiService);
- }
-
- /**
- * Verify WifiServiceImpl is called when there is a registered LOHS observer callback.
- */
- @Test
- public void testUnregisterWifiServiceImplCalledWithRegisteredObserver() throws Exception {
- TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
- TestLooper observerLooper = new TestLooper();
- Handler observerHandler = new Handler(observerLooper.getLooper());
- mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
- mWifiManager.unregisterLocalOnlyHotspotObserver();
- verify(mWifiService).stopWatchLocalOnlyHotspot();
- }
-
- /**
- * Test that calls to get the current WPS config token return null and do not have any
- * interactions with WifiServiceImpl.
- */
- @Test
- public void testGetCurrentNetworkWpsNfcConfigurationTokenReturnsNull() {
- assertNull(mWifiManager.getCurrentNetworkWpsNfcConfigurationToken());
- verifyNoMoreInteractions(mWifiService);
- }
-
-
- class WpsCallbackTester extends WpsCallback {
- public boolean mStarted = false;
- public boolean mSucceeded = false;
- public boolean mFailed = false;
- public int mFailureCode = -1;
-
- @Override
- public void onStarted(String pin) {
- mStarted = true;
- }
-
- @Override
- public void onSucceeded() {
- mSucceeded = true;
- }
-
- @Override
- public void onFailed(int reason) {
- mFailed = true;
- mFailureCode = reason;
- }
-
- }
-
- /**
- * Verify that a call to start WPS immediately returns a failure.
- */
- @Test
- public void testStartWpsImmediatelyFailsWithCallback() {
- WpsCallbackTester wpsCallback = new WpsCallbackTester();
- mWifiManager.startWps(null, wpsCallback);
- assertTrue(wpsCallback.mFailed);
- assertEquals(ERROR, wpsCallback.mFailureCode);
- assertFalse(wpsCallback.mStarted);
- assertFalse(wpsCallback.mSucceeded);
- verifyNoMoreInteractions(mWifiService);
- }
-
- /**
- * Verify that a call to start WPS does not go to WifiServiceImpl if we do not have a callback.
- */
- @Test
- public void testStartWpsDoesNotCallWifiServiceImpl() {
- mWifiManager.startWps(null, null);
- verifyNoMoreInteractions(mWifiService);
- }
-
- /**
- * Verify that a call to cancel WPS immediately returns a failure.
- */
- @Test
- public void testCancelWpsImmediatelyFailsWithCallback() {
- WpsCallbackTester wpsCallback = new WpsCallbackTester();
- mWifiManager.cancelWps(wpsCallback);
- assertTrue(wpsCallback.mFailed);
- assertEquals(ERROR, wpsCallback.mFailureCode);
- assertFalse(wpsCallback.mStarted);
- assertFalse(wpsCallback.mSucceeded);
- verifyNoMoreInteractions(mWifiService);
- }
-
- /**
- * Verify that a call to cancel WPS does not go to WifiServiceImpl if we do not have a callback.
- */
- @Test
- public void testCancelWpsDoesNotCallWifiServiceImpl() {
- mWifiManager.cancelWps(null);
- verifyNoMoreInteractions(mWifiService);
- }
-
- /**
- * Verify that a successful call properly returns true.
- */
- @Test
- public void testSetWifiApConfigurationSuccessReturnsTrue() throws Exception {
- WifiConfiguration apConfig = new WifiConfiguration();
-
- when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
- .thenReturn(true);
- assertTrue(mWifiManager.setWifiApConfiguration(apConfig));
- }
-
- /**
- * Verify that a failed call properly returns false.
- */
- @Test
- public void testSetWifiApConfigurationFailureReturnsFalse() throws Exception {
- WifiConfiguration apConfig = new WifiConfiguration();
-
- when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
- .thenReturn(false);
- assertFalse(mWifiManager.setWifiApConfiguration(apConfig));
- }
-
- /**
- * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions.
- */
- @Test
- public void testSetWifiApConfigurationRethrowsException() throws Exception {
- doThrow(new SecurityException()).when(mWifiService).setWifiApConfiguration(any(), any());
-
- try {
- mWifiManager.setWifiApConfiguration(new WifiConfiguration());
- fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
- } catch (SecurityException e) { }
- }
-
- /**
- * Verify that a successful call properly returns true.
- */
- @Test
- public void testSetSoftApConfigurationSuccessReturnsTrue() throws Exception {
- SoftApConfiguration apConfig = generatorTestSoftApConfig();
-
- when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
- .thenReturn(true);
- assertTrue(mWifiManager.setSoftApConfiguration(apConfig));
- }
-
- /**
- * Verify that a failed call properly returns false.
- */
- @Test
- public void testSetSoftApConfigurationFailureReturnsFalse() throws Exception {
- SoftApConfiguration apConfig = generatorTestSoftApConfig();
-
- when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
- .thenReturn(false);
- assertFalse(mWifiManager.setSoftApConfiguration(apConfig));
- }
-
- /**
- * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions.
- */
- @Test
- public void testSetSoftApConfigurationRethrowsException() throws Exception {
- doThrow(new SecurityException()).when(mWifiService).setSoftApConfiguration(any(), any());
-
- try {
- mWifiManager.setSoftApConfiguration(generatorTestSoftApConfig());
- fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
- } catch (SecurityException e) { }
- }
-
- /**
- * Check the call to startScan calls WifiService.
- */
- @Test
- public void testStartScan() throws Exception {
- when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn(
- true);
- assertTrue(mWifiManager.startScan());
-
- when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn(
- false);
- assertFalse(mWifiManager.startScan());
- }
-
- /**
- * Verify main looper is used when handler is not provided.
- */
- @Test
- public void registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler()
- throws Exception {
- ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
- mWifiManager.registerTrafficStateCallback(
- new HandlerExecutor(new Handler(mLooper.getLooper())), mTrafficStateCallback);
- verify(mWifiService).registerTrafficStateCallback(
- any(IBinder.class), callbackCaptor.capture(), anyInt());
-
- assertEquals(0, mLooper.dispatchAll());
- callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
- assertEquals(1, mLooper.dispatchAll());
- verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
- }
-
- /**
- * Verify the call to unregisterTrafficStateCallback goes to WifiServiceImpl.
- */
- @Test
- public void unregisterTrafficStateCallbackCallGoesToWifiServiceImpl() throws Exception {
- ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
- mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler),
- mTrafficStateCallback);
- verify(mWifiService).registerTrafficStateCallback(any(IBinder.class),
- any(ITrafficStateCallback.Stub.class), callbackIdentifier.capture());
-
- mWifiManager.unregisterTrafficStateCallback(mTrafficStateCallback);
- verify(mWifiService).unregisterTrafficStateCallback(
- eq((int) callbackIdentifier.getValue()));
- }
-
- /*
- * Verify client-provided callback is being called through callback proxy on multiple events
- */
- @Test
- public void trafficStateCallbackProxyCallsOnMultipleUpdates() throws Exception {
- ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
- mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler),
- mTrafficStateCallback);
- verify(mWifiService).registerTrafficStateCallback(
- any(IBinder.class), callbackCaptor.capture(), anyInt());
-
- InOrder inOrder = inOrder(mTrafficStateCallback);
-
- callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_IN);
- callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
- callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_OUT);
-
- mLooper.dispatchAll();
- inOrder.verify(mTrafficStateCallback).onStateChanged(
- TrafficStateCallback.DATA_ACTIVITY_IN);
- inOrder.verify(mTrafficStateCallback).onStateChanged(
- TrafficStateCallback.DATA_ACTIVITY_INOUT);
- inOrder.verify(mTrafficStateCallback).onStateChanged(
- TrafficStateCallback.DATA_ACTIVITY_OUT);
- }
-
- /**
- * Verify client-provided callback is being called on the correct thread
- */
- @Test
- public void trafficStateCallbackIsCalledOnCorrectThread() throws Exception {
- ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
- TestLooper altLooper = new TestLooper();
- Handler altHandler = new Handler(altLooper.getLooper());
- mWifiManager.registerTrafficStateCallback(new HandlerExecutor(altHandler),
- mTrafficStateCallback);
- verify(mContext, never()).getMainLooper();
- verify(mContext, never()).getMainExecutor();
- verify(mWifiService).registerTrafficStateCallback(
- any(IBinder.class), callbackCaptor.capture(), anyInt());
-
- assertEquals(0, altLooper.dispatchAll());
- callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
- assertEquals(1, altLooper.dispatchAll());
- verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
- }
-
- /**
- * Verify the call to registerNetworkRequestMatchCallback goes to WifiServiceImpl.
- */
- @Test
- public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()
- throws Exception {
- ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
- mWifiManager.registerNetworkRequestMatchCallback(
- new HandlerExecutor(new Handler(mLooper.getLooper())),
- mNetworkRequestMatchCallback);
- verify(mWifiService).registerNetworkRequestMatchCallback(
- any(IBinder.class), callbackCaptor.capture(), anyInt());
-
- INetworkRequestUserSelectionCallback iUserSelectionCallback =
- mock(INetworkRequestUserSelectionCallback.class);
-
- assertEquals(0, mLooper.dispatchAll());
-
- callbackCaptor.getValue().onAbort();
- assertEquals(1, mLooper.dispatchAll());
- verify(mNetworkRequestMatchCallback).onAbort();
-
- callbackCaptor.getValue().onMatch(new ArrayList<ScanResult>());
- assertEquals(1, mLooper.dispatchAll());
- verify(mNetworkRequestMatchCallback).onMatch(anyList());
-
- callbackCaptor.getValue().onUserSelectionConnectSuccess(new WifiConfiguration());
- assertEquals(1, mLooper.dispatchAll());
- verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
- any(WifiConfiguration.class));
-
- callbackCaptor.getValue().onUserSelectionConnectFailure(new WifiConfiguration());
- assertEquals(1, mLooper.dispatchAll());
- verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
- any(WifiConfiguration.class));
- }
-
- /**
- * Verify the call to unregisterNetworkRequestMatchCallback goes to WifiServiceImpl.
- */
- @Test
- public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception {
- ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
- mWifiManager.registerNetworkRequestMatchCallback(new HandlerExecutor(mHandler),
- mNetworkRequestMatchCallback);
- verify(mWifiService).registerNetworkRequestMatchCallback(
- any(IBinder.class), any(INetworkRequestMatchCallback.class),
- callbackIdentifier.capture());
-
- mWifiManager.unregisterNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
- verify(mWifiService).unregisterNetworkRequestMatchCallback(
- eq((int) callbackIdentifier.getValue()));
- }
-
- /**
- * Verify the call to NetworkRequestUserSelectionCallback goes to
- * WifiServiceImpl.
- */
- @Test
- public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl()
- throws Exception {
- ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
- mWifiManager.registerNetworkRequestMatchCallback(
- new HandlerExecutor(new Handler(mLooper.getLooper())),
- mNetworkRequestMatchCallback);
- verify(mWifiService).registerNetworkRequestMatchCallback(
- any(IBinder.class), callbackCaptor.capture(), anyInt());
-
- INetworkRequestUserSelectionCallback iUserSelectionCallback =
- mock(INetworkRequestUserSelectionCallback.class);
- ArgumentCaptor<NetworkRequestUserSelectionCallback> userSelectionCallbackCaptor =
- ArgumentCaptor.forClass(NetworkRequestUserSelectionCallback.class);
- callbackCaptor.getValue().onUserSelectionCallbackRegistration(
- iUserSelectionCallback);
- assertEquals(1, mLooper.dispatchAll());
- verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
- userSelectionCallbackCaptor.capture());
-
- WifiConfiguration selected = new WifiConfiguration();
- userSelectionCallbackCaptor.getValue().select(selected);
- verify(iUserSelectionCallback).select(selected);
-
- userSelectionCallbackCaptor.getValue().reject();
- verify(iUserSelectionCallback).reject();
- }
-
- /**
- * Check the call to getAllMatchingWifiConfigs calls getAllMatchingFqdnsForScanResults and
- * getWifiConfigsForPasspointProfiles of WifiService in order.
- */
- @Test
- public void testGetAllMatchingWifiConfigs() throws Exception {
- Map<String, List<ScanResult>> passpointProfiles = new HashMap<>();
- passpointProfiles.put("www.test.com_987a69bca26", new ArrayList<>());
- when(mWifiService.getAllMatchingPasspointProfilesForScanResults(
- any(List.class))).thenReturn(passpointProfiles);
- InOrder inOrder = inOrder(mWifiService);
-
- mWifiManager.getAllMatchingWifiConfigs(new ArrayList<>());
-
- inOrder.verify(mWifiService).getAllMatchingPasspointProfilesForScanResults(any(List.class));
- inOrder.verify(mWifiService).getWifiConfigsForPasspointProfiles(any(List.class));
- }
-
- /**
- * Check the call to getMatchingOsuProviders calls getMatchingOsuProviders of WifiService
- * with the provided a list of ScanResult.
- */
- @Test
- public void testGetMatchingOsuProviders() throws Exception {
- mWifiManager.getMatchingOsuProviders(new ArrayList<>());
-
- verify(mWifiService).getMatchingOsuProviders(any(List.class));
- }
-
- /**
- * Verify calls to {@link WifiManager#addNetworkSuggestions(List)},
- * {@link WifiManager#getNetworkSuggestions()} and
- * {@link WifiManager#removeNetworkSuggestions(List)}.
- */
- @Test
- public void addGetRemoveNetworkSuggestions() throws Exception {
- List<WifiNetworkSuggestion> testList = new ArrayList<>();
- when(mWifiService.addNetworkSuggestions(any(List.class), anyString(),
- nullable(String.class))).thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS);
- when(mWifiService.removeNetworkSuggestions(any(List.class), anyString())).thenReturn(
- STATUS_NETWORK_SUGGESTIONS_SUCCESS);
- when(mWifiService.getNetworkSuggestions(anyString()))
- .thenReturn(testList);
-
- assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- mWifiManager.addNetworkSuggestions(testList));
- verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME),
- nullable(String.class));
-
- assertEquals(testList, mWifiManager.getNetworkSuggestions());
- verify(mWifiService).getNetworkSuggestions(eq(TEST_PACKAGE_NAME));
-
- assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- mWifiManager.removeNetworkSuggestions(new ArrayList<>()));
- verify(mWifiService).removeNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME));
- }
-
- /**
- * Verify call to {@link WifiManager#getMaxNumberOfNetworkSuggestionsPerApp()}.
- */
- @Test
- public void getMaxNumberOfNetworkSuggestionsPerApp() {
- when(mContext.getSystemServiceName(ActivityManager.class))
- .thenReturn(Context.ACTIVITY_SERVICE);
- when(mContext.getSystemService(Context.ACTIVITY_SERVICE))
- .thenReturn(mActivityManager);
- when(mActivityManager.isLowRamDevice()).thenReturn(true);
- assertEquals(256, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp());
-
- when(mActivityManager.isLowRamDevice()).thenReturn(false);
- assertEquals(1024, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp());
- }
-
- /**
- * Verify getting the factory MAC address.
- */
- @Test
- public void testGetFactoryMacAddress() throws Exception {
- when(mWifiService.getFactoryMacAddresses()).thenReturn(TEST_MAC_ADDRESSES);
- assertArrayEquals(TEST_MAC_ADDRESSES, mWifiManager.getFactoryMacAddresses());
- verify(mWifiService).getFactoryMacAddresses();
- }
-
- /**
- * Verify the call to addOnWifiUsabilityStatsListener goes to WifiServiceImpl.
- */
- @Test
- public void addOnWifiUsabilityStatsListeneroesToWifiServiceImpl() throws Exception {
- mExecutor = new SynchronousExecutor();
- mWifiManager.addOnWifiUsabilityStatsListener(mExecutor, mOnWifiUsabilityStatsListener);
- verify(mWifiService).addOnWifiUsabilityStatsListener(any(IBinder.class),
- any(IOnWifiUsabilityStatsListener.Stub.class), anyInt());
- }
-
- /**
- * Verify the call to removeOnWifiUsabilityStatsListener goes to WifiServiceImpl.
- */
- @Test
- public void removeOnWifiUsabilityListenerGoesToWifiServiceImpl() throws Exception {
- ArgumentCaptor<Integer> listenerIdentifier = ArgumentCaptor.forClass(Integer.class);
- mExecutor = new SynchronousExecutor();
- mWifiManager.addOnWifiUsabilityStatsListener(mExecutor, mOnWifiUsabilityStatsListener);
- verify(mWifiService).addOnWifiUsabilityStatsListener(any(IBinder.class),
- any(IOnWifiUsabilityStatsListener.Stub.class), listenerIdentifier.capture());
-
- mWifiManager.removeOnWifiUsabilityStatsListener(mOnWifiUsabilityStatsListener);
- verify(mWifiService).removeOnWifiUsabilityStatsListener(
- eq((int) listenerIdentifier.getValue()));
- }
-
- /**
- * Test behavior of isEnhancedOpenSupported
- */
- @Test
- public void testIsEnhancedOpenSupported() throws Exception {
- when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(WIFI_FEATURE_OWE));
- assertTrue(mWifiManager.isEnhancedOpenSupported());
- when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(~WIFI_FEATURE_OWE));
- assertFalse(mWifiManager.isEnhancedOpenSupported());
- }
-
- /**
- * Test behavior of isWpa3SaeSupported
- */
- @Test
- public void testIsWpa3SaeSupported() throws Exception {
- when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(WIFI_FEATURE_WPA3_SAE));
- assertTrue(mWifiManager.isWpa3SaeSupported());
- when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(~WIFI_FEATURE_WPA3_SAE));
- assertFalse(mWifiManager.isWpa3SaeSupported());
- }
-
- /**
- * Test behavior of isWpa3SuiteBSupported
- */
- @Test
- public void testIsWpa3SuiteBSupported() throws Exception {
- when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(WIFI_FEATURE_WPA3_SUITE_B));
- assertTrue(mWifiManager.isWpa3SuiteBSupported());
- when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(~WIFI_FEATURE_WPA3_SUITE_B));
- assertFalse(mWifiManager.isWpa3SuiteBSupported());
- }
-
- /**
- * Test behavior of isEasyConnectSupported
- */
- @Test
- public void testIsEasyConnectSupported() throws Exception {
- when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(WIFI_FEATURE_DPP));
- assertTrue(mWifiManager.isEasyConnectSupported());
- when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(~WIFI_FEATURE_DPP));
- assertFalse(mWifiManager.isEasyConnectSupported());
- }
-
- /**
- * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)}
- */
- @Test
- public void testAddNetwork() throws Exception {
- WifiConfiguration configuration = new WifiConfiguration();
- when(mWifiService.addOrUpdateNetwork(any(), anyString()))
- .thenReturn(TEST_NETWORK_ID);
-
- assertEquals(mWifiManager.addNetwork(configuration), TEST_NETWORK_ID);
- verify(mWifiService).addOrUpdateNetwork(configuration, mContext.getOpPackageName());
-
- // send a null config
- assertEquals(mWifiManager.addNetwork(null), -1);
- }
-
- /**
- * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)}
- */
- @Test
- public void testUpdateNetwork() throws Exception {
- WifiConfiguration configuration = new WifiConfiguration();
- when(mWifiService.addOrUpdateNetwork(any(), anyString()))
- .thenReturn(TEST_NETWORK_ID);
-
- configuration.networkId = TEST_NETWORK_ID;
- assertEquals(mWifiManager.updateNetwork(configuration), TEST_NETWORK_ID);
- verify(mWifiService).addOrUpdateNetwork(configuration, mContext.getOpPackageName());
-
- // config with invalid network ID
- configuration.networkId = -1;
- assertEquals(mWifiManager.updateNetwork(configuration), -1);
-
- // send a null config
- assertEquals(mWifiManager.updateNetwork(null), -1);
- }
-
- /**
- * Test behavior of {@link WifiManager#enableNetwork(int, boolean)}
- */
- @Test
- public void testEnableNetwork() throws Exception {
- when(mWifiService.enableNetwork(anyInt(), anyBoolean(), anyString()))
- .thenReturn(true);
- assertTrue(mWifiManager.enableNetwork(TEST_NETWORK_ID, true));
- verify(mWifiService).enableNetwork(TEST_NETWORK_ID, true, mContext.getOpPackageName());
- }
-
- /**
- * Test behavior of {@link WifiManager#disableNetwork(int)}
- */
- @Test
- public void testDisableNetwork() throws Exception {
- when(mWifiService.disableNetwork(anyInt(), anyString()))
- .thenReturn(true);
- assertTrue(mWifiManager.disableNetwork(TEST_NETWORK_ID));
- verify(mWifiService).disableNetwork(TEST_NETWORK_ID, mContext.getOpPackageName());
- }
-
- /**
- * Test behavior of {@link WifiManager#allowAutojoin(int, boolean)}
- * @throws Exception
- */
- @Test
- public void testAllowAutojoin() throws Exception {
- mWifiManager.allowAutojoin(1, true);
- verify(mWifiService).allowAutojoin(1, true);
- }
-
- /**
- * Test behavior of {@link WifiManager#allowAutojoinPasspoint(String, boolean)}
- * @throws Exception
- */
- @Test
- public void testAllowAutojoinPasspoint() throws Exception {
- final String fqdn = "FullyQualifiedDomainName";
- mWifiManager.allowAutojoinPasspoint(fqdn, true);
- verify(mWifiService).allowAutojoinPasspoint(fqdn, true);
- }
-
- /**
- * Test behavior of
- * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)}
- */
- @Test
- public void testSetMacRandomizationSettingPasspointEnabled() throws Exception {
- final String fqdn = "FullyQualifiedDomainName";
- mWifiManager.setMacRandomizationSettingPasspointEnabled(fqdn, true);
- verify(mWifiService).setMacRandomizationSettingPasspointEnabled(fqdn, true);
- }
-
- /**
- * Test behavior of
- * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)}
- */
- @Test
- public void testSetPasspointMeteredOverride() throws Exception {
- final String fqdn = "FullyQualifiedDomainName";
- mWifiManager.setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED);
- verify(mWifiService).setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED);
- }
-
- /**
- * Test behavior of {@link WifiManager#disconnect()}
- */
- @Test
- public void testDisconnect() throws Exception {
- when(mWifiService.disconnect(anyString())).thenReturn(true);
- assertTrue(mWifiManager.disconnect());
- verify(mWifiService).disconnect(mContext.getOpPackageName());
- }
-
- /**
- * Test behavior of {@link WifiManager#reconnect()}
- */
- @Test
- public void testReconnect() throws Exception {
- when(mWifiService.reconnect(anyString())).thenReturn(true);
- assertTrue(mWifiManager.reconnect());
- verify(mWifiService).reconnect(mContext.getOpPackageName());
- }
-
- /**
- * Test behavior of {@link WifiManager#reassociate()}
- */
- @Test
- public void testReassociate() throws Exception {
- when(mWifiService.reassociate(anyString())).thenReturn(true);
- assertTrue(mWifiManager.reassociate());
- verify(mWifiService).reassociate(mContext.getOpPackageName());
- }
-
- /**
- * Test behavior of {@link WifiManager#getSupportedFeatures()}
- */
- @Test
- public void testGetSupportedFeatures() throws Exception {
- long supportedFeatures =
- WIFI_FEATURE_SCANNER
- | WIFI_FEATURE_PASSPOINT
- | WIFI_FEATURE_P2P;
- when(mWifiService.getSupportedFeatures())
- .thenReturn(Long.valueOf(supportedFeatures));
-
- assertTrue(mWifiManager.isWifiScannerSupported());
- assertTrue(mWifiManager.isPasspointSupported());
- assertTrue(mWifiManager.isP2pSupported());
- assertFalse(mWifiManager.isPortableHotspotSupported());
- assertFalse(mWifiManager.isDeviceToDeviceRttSupported());
- assertFalse(mWifiManager.isDeviceToApRttSupported());
- assertFalse(mWifiManager.isPreferredNetworkOffloadSupported());
- assertFalse(mWifiManager.isAdditionalStaSupported());
- assertFalse(mWifiManager.isTdlsSupported());
- assertFalse(mWifiManager.isOffChannelTdlsSupported());
- assertFalse(mWifiManager.isEnhancedPowerReportingSupported());
- }
-
- /**
- * Tests that passing a null Executor to {@link WifiManager#getWifiActivityEnergyInfoAsync}
- * throws an exception.
- */
- @Test(expected = NullPointerException.class)
- public void testGetWifiActivityInfoNullExecutor() throws Exception {
- mWifiManager.getWifiActivityEnergyInfoAsync(null, mOnWifiActivityEnergyInfoListener);
- }
-
- /**
- * Tests that passing a null listener to {@link WifiManager#getWifiActivityEnergyInfoAsync}
- * throws an exception.
- */
- @Test(expected = NullPointerException.class)
- public void testGetWifiActivityInfoNullListener() throws Exception {
- mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, null);
- }
-
- /** Tests that the listener runs on the correct Executor. */
- @Test
- public void testGetWifiActivityInfoRunsOnCorrectExecutor() throws Exception {
- mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, mOnWifiActivityEnergyInfoListener);
- ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor =
- ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class);
- verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture());
- IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue();
- listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
- verify(mExecutor).execute(any());
-
- // ensure that the executor is only triggered once
- listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
- verify(mExecutor).execute(any());
- }
-
- /** Tests that the correct listener runs. */
- @Test
- public void testGetWifiActivityInfoRunsCorrectListener() throws Exception {
- int[] flag = {0};
- mWifiManager.getWifiActivityEnergyInfoAsync(
- new SynchronousExecutor(), info -> flag[0]++);
- ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor =
- ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class);
- verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture());
- IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue();
- listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
- assertEquals(1, flag[0]);
-
- // ensure that the listener is only triggered once
- listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
- assertEquals(1, flag[0]);
- }
-
- /**
- * Test behavior of {@link WifiManager#getConnectionInfo()}
- */
- @Test
- public void testGetConnectionInfo() throws Exception {
- WifiInfo wifiInfo = new WifiInfo();
- when(mWifiService.getConnectionInfo(anyString(), nullable(String.class))).thenReturn(
- wifiInfo);
-
- assertEquals(wifiInfo, mWifiManager.getConnectionInfo());
- }
-
- /**
- * Test behavior of {@link WifiManager#is5GHzBandSupported()}
- */
- @Test
- public void testIs5GHzBandSupported() throws Exception {
- when(mWifiService.is5GHzBandSupported()).thenReturn(true);
- assertTrue(mWifiManager.is5GHzBandSupported());
- verify(mWifiService).is5GHzBandSupported();
- }
-
- /**
- * Test behavior of {@link WifiManager#is6GHzBandSupported()}
- */
- @Test
- public void testIs6GHzBandSupported() throws Exception {
- when(mWifiService.is6GHzBandSupported()).thenReturn(true);
- assertTrue(mWifiManager.is6GHzBandSupported());
- verify(mWifiService).is6GHzBandSupported();
- }
-
- /**
- * Test behavior of {@link WifiManager#isWifiStandardSupported()}
- */
- @Test
- public void testIsWifiStandardSupported() throws Exception {
- int standard = ScanResult.WIFI_STANDARD_11AX;
- when(mWifiService.isWifiStandardSupported(standard)).thenReturn(true);
- assertTrue(mWifiManager.isWifiStandardSupported(standard));
- verify(mWifiService).isWifiStandardSupported(standard);
- }
-
- /**
- * Test behavior of {@link WifiManager#getDhcpInfo()}
- */
- @Test
- public void testGetDhcpInfo() throws Exception {
- DhcpInfo dhcpInfo = new DhcpInfo();
-
- when(mWifiService.getDhcpInfo()).thenReturn(dhcpInfo);
- assertEquals(dhcpInfo, mWifiManager.getDhcpInfo());
- verify(mWifiService).getDhcpInfo();
- }
-
- /**
- * Test behavior of {@link WifiManager#setWifiEnabled(boolean)}
- */
- @Test
- public void testSetWifiEnabled() throws Exception {
- when(mWifiService.setWifiEnabled(anyString(), anyBoolean())).thenReturn(true);
- assertTrue(mWifiManager.setWifiEnabled(true));
- verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), true);
- assertTrue(mWifiManager.setWifiEnabled(false));
- verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), false);
- }
-
- /**
- * Test behavior of {@link WifiManager#connect(int, ActionListener)}
- */
- @Test
- public void testConnectWithListener() throws Exception {
- ActionListener externalListener = mock(ActionListener.class);
- mWifiManager.connect(TEST_NETWORK_ID, externalListener);
-
- ArgumentCaptor<IActionListener> binderListenerCaptor =
- ArgumentCaptor.forClass(IActionListener.class);
- verify(mWifiService).connect(eq(null), eq(TEST_NETWORK_ID), any(Binder.class),
- binderListenerCaptor.capture(), anyInt());
- assertNotNull(binderListenerCaptor.getValue());
-
- // Trigger on success.
- binderListenerCaptor.getValue().onSuccess();
- mLooper.dispatchAll();
- verify(externalListener).onSuccess();
-
- // Trigger on failure.
- binderListenerCaptor.getValue().onFailure(BUSY);
- mLooper.dispatchAll();
- verify(externalListener).onFailure(BUSY);
- }
-
- /**
- * Test behavior of {@link WifiManager#connect(int, ActionListener)}
- */
- @Test
- public void testConnectWithListenerHandleSecurityException() throws Exception {
- doThrow(new SecurityException()).when(mWifiService)
- .connect(eq(null), anyInt(), any(IBinder.class),
- any(IActionListener.class), anyInt());
- ActionListener externalListener = mock(ActionListener.class);
- mWifiManager.connect(TEST_NETWORK_ID, externalListener);
-
- mLooper.dispatchAll();
- verify(externalListener).onFailure(NOT_AUTHORIZED);
- }
-
- /**
- * Test behavior of {@link WifiManager#connect(int, ActionListener)}
- */
- @Test
- public void testConnectWithListenerHandleRemoteException() throws Exception {
- doThrow(new RemoteException()).when(mWifiService)
- .connect(eq(null), anyInt(), any(IBinder.class),
- any(IActionListener.class), anyInt());
- ActionListener externalListener = mock(ActionListener.class);
- mWifiManager.connect(TEST_NETWORK_ID, externalListener);
-
- mLooper.dispatchAll();
- verify(externalListener).onFailure(ERROR);
- }
-
- /**
- * Test behavior of {@link WifiManager#connect(int, ActionListener)}
- */
- @Test
- public void testConnectWithoutListener() throws Exception {
- WifiConfiguration configuration = new WifiConfiguration();
- mWifiManager.connect(configuration, null);
-
- verify(mWifiService).connect(configuration, WifiConfiguration.INVALID_NETWORK_ID, null,
- null, 0);
- }
-
- /**
- * Verify an IllegalArgumentException is thrown if callback is not provided.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testRegisterScanResultsCallbackWithNullCallback() throws Exception {
- mWifiManager.registerScanResultsCallback(mExecutor, null);
- }
-
- /**
- * Verify an IllegalArgumentException is thrown if executor is not provided.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testRegisterCallbackWithNullExecutor() throws Exception {
- mWifiManager.registerScanResultsCallback(null, mScanResultsCallback);
- }
-
- /**
- * Verify client provided callback is being called to the right callback.
- */
- @Test
- public void testAddScanResultsCallbackAndReceiveEvent() throws Exception {
- ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(IScanResultsCallback.Stub.class);
- mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback);
- verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture());
- callbackCaptor.getValue().onScanResultsAvailable();
- verify(mRunnable).run();
- }
-
- /**
- * Verify client provided callback is being called to the right executor.
- */
- @Test
- public void testRegisterScanResultsCallbackWithTheTargetExecutor() throws Exception {
- ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(IScanResultsCallback.Stub.class);
- mWifiManager.registerScanResultsCallback(mExecutor, mScanResultsCallback);
- verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture());
- mWifiManager.registerScanResultsCallback(mAnotherExecutor, mScanResultsCallback);
- callbackCaptor.getValue().onScanResultsAvailable();
- verify(mExecutor, never()).execute(any(Runnable.class));
- verify(mAnotherExecutor).execute(any(Runnable.class));
- }
-
- /**
- * Verify client register unregister then register again, to ensure callback still works.
- */
- @Test
- public void testRegisterUnregisterThenRegisterAgainWithScanResultCallback() throws Exception {
- ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor =
- ArgumentCaptor.forClass(IScanResultsCallback.Stub.class);
- mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback);
- verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture());
- mWifiManager.unregisterScanResultsCallback(mScanResultsCallback);
- callbackCaptor.getValue().onScanResultsAvailable();
- verify(mRunnable, never()).run();
- mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback);
- callbackCaptor.getValue().onScanResultsAvailable();
- verify(mRunnable).run();
- }
-
- /**
- * Verify client unregisterScanResultsCallback.
- */
- @Test
- public void testUnregisterScanResultsCallback() throws Exception {
- mWifiManager.unregisterScanResultsCallback(mScanResultsCallback);
- verify(mWifiService).unregisterScanResultsCallback(any());
- }
-
- /**
- * Verify client unregisterScanResultsCallback with null callback will cause an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testUnregisterScanResultsCallbackWithNullCallback() throws Exception {
- mWifiManager.unregisterScanResultsCallback(null);
- }
-
- /**
- * Verify an IllegalArgumentException is thrown if executor not provided.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testAddSuggestionConnectionStatusListenerWithNullExecutor() {
- mWifiManager.addSuggestionConnectionStatusListener(null, mListener);
- }
-
- /**
- * Verify an IllegalArgumentException is thrown if listener is not provided.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testAddSuggestionConnectionStatusListenerWithNullListener() {
- mWifiManager.addSuggestionConnectionStatusListener(mExecutor, null);
- }
-
- /**
- * Verify client provided listener is being called to the right listener.
- */
- @Test
- public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception {
- int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
- ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
- Executor executor = new SynchronousExecutor();
- mWifiManager.addSuggestionConnectionStatusListener(executor, mListener);
- verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
- callbackCaptor.capture(), anyInt(), anyString(), nullable(String.class));
- callbackCaptor.getValue().onConnectionStatus(mWifiNetworkSuggestion, errorCode);
- verify(mListener).onConnectionStatus(any(WifiNetworkSuggestion.class), eq(errorCode));
- }
-
- /**
- * Verify client provided listener is being called to the right executor.
- */
- @Test
- public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception {
- int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
- ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
- ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
- mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener);
- verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
- callbackCaptor.capture(), anyInt(), anyString(), nullable(String.class));
- callbackCaptor.getValue().onConnectionStatus(any(WifiNetworkSuggestion.class), errorCode);
- verify(mExecutor).execute(any(Runnable.class));
- }
-
- /**
- * Verify an IllegalArgumentException is thrown if listener is not provided.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testRemoveSuggestionConnectionListenerWithNullListener() {
- mWifiManager.removeSuggestionConnectionStatusListener(null);
- }
-
- /**
- * Verify removeSuggestionConnectionListener.
- */
- @Test
- public void testRemoveSuggestionConnectionListener() throws Exception {
- mWifiManager.removeSuggestionConnectionStatusListener(mListener);
- verify(mWifiService).unregisterSuggestionConnectionStatusListener(anyInt(), anyString());
- }
-
- /** Test {@link WifiManager#calculateSignalLevel(int)} */
- @Test
- public void testCalculateSignalLevel() throws Exception {
- when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(3);
- int actual = mWifiManager.calculateSignalLevel(-60);
- verify(mWifiService).calculateSignalLevel(-60);
- assertEquals(3, actual);
- }
-
- /** Test {@link WifiManager#getMaxSignalLevel()} */
- @Test
- public void testGetMaxSignalLevel() throws Exception {
- when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(4);
- int actual = mWifiManager.getMaxSignalLevel();
- verify(mWifiService).calculateSignalLevel(Integer.MAX_VALUE);
- assertEquals(4, actual);
- }
-
- /*
- * Test behavior of isWapiSupported
- * @throws Exception
- */
- @Test
- public void testIsWapiSupported() throws Exception {
- when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(WifiManager.WIFI_FEATURE_WAPI));
- assertTrue(mWifiManager.isWapiSupported());
- when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WAPI));
- assertFalse(mWifiManager.isWapiSupported());
- }
-
- /*
- * Test that DPP channel list is parsed correctly
- */
- @Test
- public void testparseDppChannelList() throws Exception {
- String channelList = "81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48";
- SparseArray<int[]> expectedResult = new SparseArray<>();
- expectedResult.append(81, new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
- expectedResult.append(115, new int[]{36, 40, 44, 48});
-
- SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList);
- assertEquals(expectedResult.size(), result.size());
-
- int index = 0;
- int key;
-
- // Compare the two primitive int arrays
- do {
- try {
- key = result.keyAt(index);
- } catch (java.lang.ArrayIndexOutOfBoundsException e) {
- break;
- }
- int[] expected = expectedResult.get(key);
- int[] output = result.get(key);
- assertEquals(expected.length, output.length);
- for (int i = 0; i < output.length; i++) {
- assertEquals(expected[i], output[i]);
- }
- index++;
- } while (true);
- }
-
- /*
- * Test that DPP channel list parser gracefully fails for invalid input
- */
- @Test
- public void testparseDppChannelListWithInvalidFormats() throws Exception {
- String channelList = "1,2,3,4,5,6,7,8,9,10,11,36,40,44,48";
- SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList);
- assertEquals(result.size(), 0);
-
- channelList = "ajgalskgjalskjg3-09683dh";
- result = WifiManager.parseDppChannelList(channelList);
- assertEquals(result.size(), 0);
-
- channelList = "13/abc,46////";
- result = WifiManager.parseDppChannelList(channelList);
- assertEquals(result.size(), 0);
-
- channelList = "11/4,5,13/";
- result = WifiManager.parseDppChannelList(channelList);
- assertEquals(result.size(), 0);
-
- channelList = "/24,6";
- result = WifiManager.parseDppChannelList(channelList);
- assertEquals(result.size(), 0);
- }
-
- /**
- * Test getWifiConfigsForMatchedNetworkSuggestions for given scanResults.
- */
- @Test
- public void testGetWifiConfigsForMatchedNetworkSuggestions() throws Exception {
- List<WifiConfiguration> testResults = new ArrayList<>();
- testResults.add(new WifiConfiguration());
-
- when(mWifiService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any(List.class)))
- .thenReturn(testResults);
- assertEquals(testResults, mWifiManager
- .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>()));
- }
-
- /**
- * Verify the call to setWifiConnectedNetworkScorer goes to WifiServiceImpl.
- */
- @Test
- public void setWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
- mExecutor = new SynchronousExecutor();
- mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
- verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
- any(IWifiConnectedNetworkScorer.Stub.class));
- }
-
- /**
- * Verify the call to clearWifiConnectedNetworkScorer goes to WifiServiceImpl.
- */
- @Test
- public void clearWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
- mExecutor = new SynchronousExecutor();
- mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
- verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
- any(IWifiConnectedNetworkScorer.Stub.class));
-
- mWifiManager.clearWifiConnectedNetworkScorer();
- verify(mWifiService).clearWifiConnectedNetworkScorer();
- }
-
- /**
- * Verify that Wi-Fi connected scorer receives score update observer after registeration.
- */
- @Test
- public void verifyScorerReceiveScoreUpdateObserverAfterRegistration() throws Exception {
- mExecutor = new SynchronousExecutor();
- mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
- ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> scorerCaptor =
- ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
- verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
- scorerCaptor.capture());
- scorerCaptor.getValue().onSetScoreUpdateObserver(any());
- mLooper.dispatchAll();
- verify(mWifiConnectedNetworkScorer).onSetScoreUpdateObserver(any());
- }
-
- /**
- * Verify that Wi-Fi connected scorer receives session ID when onStart/onStop methods
- * are called.
- */
- @Test
- public void verifyScorerReceiveSessionIdWhenStartStopIsCalled() throws Exception {
- mExecutor = new SynchronousExecutor();
- mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
- ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> callbackCaptor =
- ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
- verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
- callbackCaptor.capture());
- callbackCaptor.getValue().onStart(0);
- callbackCaptor.getValue().onStop(10);
- mLooper.dispatchAll();
- verify(mWifiConnectedNetworkScorer).onStart(0);
- verify(mWifiConnectedNetworkScorer).onStop(10);
- }
-
- @Test
- public void testScanThrottle() throws Exception {
- mWifiManager.setScanThrottleEnabled(true);
- verify(mWifiService).setScanThrottleEnabled(true);
-
- when(mWifiService.isScanThrottleEnabled()).thenReturn(false);
- assertFalse(mWifiManager.isScanThrottleEnabled());
- verify(mWifiService).isScanThrottleEnabled();
- }
-
- @Test
- public void testAutoWakeup() throws Exception {
- mWifiManager.setAutoWakeupEnabled(true);
- verify(mWifiService).setAutoWakeupEnabled(true);
-
- when(mWifiService.isAutoWakeupEnabled()).thenReturn(false);
- assertFalse(mWifiManager.isAutoWakeupEnabled());
- verify(mWifiService).isAutoWakeupEnabled();
- }
-
-
- @Test
- public void testScanAvailable() throws Exception {
- mWifiManager.setScanAlwaysAvailable(true);
- verify(mWifiService).setScanAlwaysAvailable(true);
-
- when(mWifiService.isScanAlwaysAvailable()).thenReturn(false);
- assertFalse(mWifiManager.isScanAlwaysAvailable());
- verify(mWifiService).isScanAlwaysAvailable();
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
deleted file mode 100644
index d479aac..0000000
--- a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
+++ /dev/null
@@ -1,395 +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.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-import android.net.MatchAllNetworkSpecifier;
-import android.os.Parcel;
-import android.os.PatternMatcher;
-import android.util.Pair;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiNetworkAgentSpecifier}.
- */
-@SmallTest
-public class WifiNetworkAgentSpecifierTest {
- private static final String TEST_SSID = "Test123";
- private static final String TEST_SSID_PATTERN = "Test";
- private static final String TEST_SSID_1 = "456test";
- private static final String TEST_BSSID = "12:12:12:aa:0b:c0";
- private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
- private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
- private static final String TEST_BSSID_1 = "aa:cc:12:aa:0b:c0";
- private static final String TEST_PRESHARED_KEY = "\"Test123\"";
-
- /**
- * Validate that parcel marshalling/unmarshalling works
- */
- @Test
- public void testWifiNetworkAgentSpecifierParcel() {
- WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
-
- Parcel parcelW = Parcel.obtain();
- specifier.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiNetworkAgentSpecifier parcelSpecifier =
- WifiNetworkAgentSpecifier.CREATOR.createFromParcel(parcelR);
-
- assertEquals(specifier, parcelSpecifier);
- }
-
- /**
- * Validate NetworkAgentSpecifier equals with itself.
- * a) Create network agent specifier 1 for WPA_PSK network
- * b) Create network agent specifier 2 with the same params as specifier 1.
- * c) Ensure that the specifier 2 equals specifier 1.
- */
- @Test
- public void testWifiNetworkAgentSpecifierEqualsSame() {
- WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
- WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
-
- assertTrue(specifier2.equals(specifier1));
- }
-
- /**
- * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
- * a) Create network agent specifier 1 for WPA_PSK network
- * b) Create network agent specifier 2 with different key mgmt params.
- * c) Ensure that the specifier 2 does not equal specifier 1.
- */
- @Test
- public void testWifiNetworkAgentSpecifierDoesNotEqualsWhenKeyMgmtDifferent() {
- WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
- WifiNetworkAgentSpecifier specifier1 =
- new WifiNetworkAgentSpecifier(
- wifiConfiguration1);
-
- WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
- wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- WifiNetworkAgentSpecifier specifier2 =
- new WifiNetworkAgentSpecifier(
- wifiConfiguration2);
-
- assertFalse(specifier2.equals(specifier1));
- }
-
- /**
- * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
- * a) Create network agent specifier 1 for WPA_PSK network
- * b) Create network agent specifier 2 with different SSID.
- * c) Ensure that the specifier 2 does not equal specifier 1.
- */
- @Test
- public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenSsidDifferent() {
- WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
- WifiNetworkAgentSpecifier specifier1 =
- new WifiNetworkAgentSpecifier(
- wifiConfiguration1);
-
- WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
- wifiConfiguration2.SSID = TEST_SSID_1;
- WifiNetworkAgentSpecifier specifier2 =
- new WifiNetworkAgentSpecifier(
- wifiConfiguration2);
-
- assertFalse(specifier2.equals(specifier1));
- }
-
- /**
- * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
- * a) Create network agent specifier 1 for WPA_PSK network
- * b) Create network agent specifier 2 with different BSSID.
- * c) Ensure that the specifier 2 does not equal specifier 1.
- */
- @Test
- public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenBssidDifferent() {
- WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
- WifiNetworkAgentSpecifier specifier1 =
- new WifiNetworkAgentSpecifier(
- wifiConfiguration1);
-
- WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
- wifiConfiguration2.BSSID = TEST_BSSID_1;
- WifiNetworkAgentSpecifier specifier2 =
- new WifiNetworkAgentSpecifier(
- wifiConfiguration2);
-
- assertFalse(specifier2.equals(specifier1));
- }
-
- /**
- * Validate NetworkAgentSpecifier matching.
- * a) Create a network agent specifier for WPA_PSK network
- * b) Ensure that the specifier matches {@code null} and {@link MatchAllNetworkSpecifier}
- * specifiers.
- */
- @Test
- public void testWifiNetworkAgentSpecifierSatisifiesNullAndAllMatch() {
- WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
-
- assertTrue(specifier.canBeSatisfiedBy(null));
- assertTrue(specifier.canBeSatisfiedBy(new MatchAllNetworkSpecifier()));
- }
-
- /**
- * Validate NetworkAgentSpecifier matching with itself.
- * a) Create network agent specifier 1 for WPA_PSK network
- * b) Create network agent specifier 2 with the same params as specifier 1.
- * c) Ensure that the agent specifier is satisfied by itself.
- */
- @Test
- public void testWifiNetworkAgentSpecifierDoesSatisifySame() {
- WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
- WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
-
- assertTrue(specifier2.canBeSatisfiedBy(specifier1));
- }
-
- /**
- * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
- * a) Create network agent specifier for WPA_PSK network
- * b) Create network specifier with matching SSID pattern.
- * c) Ensure that the agent specifier is satisfied by specifier.
- */
- @Test
- public void
- testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidPattern() {
- WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
- PatternMatcher ssidPattern =
- new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
- Pair<MacAddress, MacAddress> bssidPattern =
- Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
- WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
- wificonfigurationNetworkSpecifier.allowedKeyManagement
- .set(WifiConfiguration.KeyMgmt.WPA_PSK);
- WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
- ssidPattern,
- bssidPattern,
- wificonfigurationNetworkSpecifier);
-
- assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
- assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
- }
-
- /**
- * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
- * a) Create network agent specifier for WPA_PSK network
- * b) Create network specifier with matching BSSID pattern.
- * c) Ensure that the agent specifier is satisfied by specifier.
- */
- @Test
- public void
- testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithBssidPattern() {
- WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
- PatternMatcher ssidPattern =
- new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
- Pair<MacAddress, MacAddress> bssidPattern =
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK));
- WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
- wificonfigurationNetworkSpecifier.allowedKeyManagement
- .set(WifiConfiguration.KeyMgmt.WPA_PSK);
- WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
- ssidPattern,
- bssidPattern,
- wificonfigurationNetworkSpecifier);
-
- assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
- assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
- }
-
- /**
- * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
- * a) Create network agent specifier for WPA_PSK network
- * b) Create network specifier with matching SSID & BSSID pattern.
- * c) Ensure that the agent specifier is satisfied by specifier.
- */
- @Test
- public void
- testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidAndBssidPattern() {
- WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
- PatternMatcher ssidPattern =
- new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
- Pair<MacAddress, MacAddress> bssidPattern =
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK));
- WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
- wificonfigurationNetworkSpecifier.allowedKeyManagement
- .set(WifiConfiguration.KeyMgmt.WPA_PSK);
- WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
- ssidPattern,
- bssidPattern,
- wificonfigurationNetworkSpecifier);
-
- assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
- assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
- }
-
- /**
- * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
- * a) Create network agent specifier for WPA_PSK network
- * b) Create network specifier with non-matching SSID pattern.
- * c) Ensure that the agent specifier is not satisfied by specifier.
- */
- @Test
- public void
- testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidPattern() {
- WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
- wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID_1 + "\"";
- WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
- new WifiNetworkAgentSpecifier(
- wifiConfigurationNetworkAgent);
-
- PatternMatcher ssidPattern =
- new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
- Pair<MacAddress, MacAddress> bssidPattern =
- Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
- WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
- wificonfigurationNetworkSpecifier.allowedKeyManagement
- .set(WifiConfiguration.KeyMgmt.WPA_PSK);
- WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
- ssidPattern,
- bssidPattern,
- wificonfigurationNetworkSpecifier);
-
- assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
- assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
- }
-
- /**
- * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
- * a) Create network agent specifier for WPA_PSK network
- * b) Create network specifier with non-matching BSSID pattern.
- * c) Ensure that the agent specifier is not satisfied by specifier.
- */
- @Test
- public void
- testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithBssidPattern() {
- WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
- wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
- WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
- new WifiNetworkAgentSpecifier(
- wifiConfigurationNetworkAgent);
-
- PatternMatcher ssidPattern =
- new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
- Pair<MacAddress, MacAddress> bssidPattern =
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK));
- WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
- wificonfigurationNetworkSpecifier.allowedKeyManagement
- .set(WifiConfiguration.KeyMgmt.WPA_PSK);
- WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
- ssidPattern,
- bssidPattern,
- wificonfigurationNetworkSpecifier);
-
- assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
- assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
- }
-
- /**
- * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
- * a) Create network agent specifier for WPA_PSK network
- * b) Create network specifier with non-matching SSID and BSSID pattern.
- * c) Ensure that the agent specifier is not satisfied by specifier.
- */
- @Test
- public void
- testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidAndBssidPattern() {
- WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
- wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
- WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
- new WifiNetworkAgentSpecifier(
- wifiConfigurationNetworkAgent);
-
- PatternMatcher ssidPattern =
- new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
- Pair<MacAddress, MacAddress> bssidPattern =
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK));
- WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
- wificonfigurationNetworkSpecifier.allowedKeyManagement
- .set(WifiConfiguration.KeyMgmt.WPA_PSK);
- WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
- ssidPattern,
- bssidPattern,
- wificonfigurationNetworkSpecifier);
-
- assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
- assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
- }
-
- /**
- * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
- * a) Create network agent specifier for WPA_PSK network
- * b) Create network specifier with matching SSID and BSSID pattern, but different key mgmt.
- * c) Ensure that the agent specifier is not satisfied by specifier.
- */
- @Test
- public void
- testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentKeyMgmt() {
- WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
- PatternMatcher ssidPattern =
- new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
- Pair<MacAddress, MacAddress> bssidPattern =
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK));
- WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
- wificonfigurationNetworkSpecifier.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
- ssidPattern,
- bssidPattern,
- wificonfigurationNetworkSpecifier);
-
- assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
- assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
- }
-
-
- private WifiConfiguration createDefaultWifiConfiguration() {
- WifiConfiguration wifiConfiguration = new WifiConfiguration();
- wifiConfiguration.SSID = "\"" + TEST_SSID + "\"";
- wifiConfiguration.BSSID = TEST_BSSID;
- wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
- return wifiConfiguration;
- }
-
- private WifiNetworkAgentSpecifier createDefaultNetworkAgentSpecifier() {
- return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration());
- }
-
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
index fdd11a3..c4967eb 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package android.net.wifi;
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
deleted file mode 100644
index fc0ef46..0000000
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
+++ /dev/null
@@ -1,512 +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.net.wifi;
-
-import static android.os.PatternMatcher.PATTERN_LITERAL;
-import static android.os.PatternMatcher.PATTERN_PREFIX;
-import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-import android.net.MatchAllNetworkSpecifier;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.PatternMatcher;
-import android.util.Pair;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiNetworkSpecifier}.
- */
-@SmallTest
-public class WifiNetworkSpecifierTest {
- private static final String TEST_SSID = "Test123";
- private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
- private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
- private static final String TEST_BSSID = "12:12:12:12:12:12";
- private static final String TEST_PRESHARED_KEY = "\"Test123\"";
-
- /**
- * Validate correctness of WifiNetworkSpecifier object created by
- * {@link WifiNetworkSpecifier.Builder#build()} for open network with SSID pattern.
- */
- @Test
- public void testWifiNetworkSpecifierBuilderForOpenNetworkWithSsidPattern() {
- NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
- .build();
-
- assertTrue(specifier instanceof WifiNetworkSpecifier);
- WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
- assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
- assertEquals(PATTERN_PREFIX, wifiNetworkSpecifier.ssidPatternMatcher.getType());
- assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS,
- wifiNetworkSpecifier.bssidPatternMatcher.first);
- assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS,
- wifiNetworkSpecifier.bssidPatternMatcher.second);
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.NONE));
- }
-
- /**
- * Validate correctness of WifiNetworkSpecifier object created by
- * {@link WifiNetworkSpecifier.Builder#build()} for WPA_PSK network with BSSID
- * pattern.
- */
- @Test
- public void testWifiNetworkSpecifierBuilderForWpa2PskNetworkWithBssidPattern() {
- NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
- .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK))
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .build();
-
- assertTrue(specifier instanceof WifiNetworkSpecifier);
- WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
- assertEquals(".*", wifiNetworkSpecifier.ssidPatternMatcher.getPath());
- assertEquals(PATTERN_SIMPLE_GLOB, wifiNetworkSpecifier.ssidPatternMatcher.getType());
- assertEquals(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- wifiNetworkSpecifier.bssidPatternMatcher.first);
- assertEquals(MacAddress.fromString(TEST_BSSID_OUI_MASK),
- wifiNetworkSpecifier.bssidPatternMatcher.second);
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WPA_PSK));
- assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
- wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
- }
-
- /**
- * Validate correctness of WifiNetworkSpecifier object created by
- * {@link WifiNetworkSpecifier.Builder#build()} for WPA_EAP network with
- * SSID and BSSID pattern.
- */
- @Test
- public void testWifiNetworkSpecifierBuilderForWpa2EapHiddenNetworkWithSsidAndBssid() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
- enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-
- NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
- .setSsid(TEST_SSID)
- .setBssid(MacAddress.fromString(TEST_BSSID))
- .setWpa2EnterpriseConfig(enterpriseConfig)
- .setIsHiddenSsid(true)
- .build();
-
- assertTrue(specifier instanceof WifiNetworkSpecifier);
- WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
- assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
- assertEquals(PATTERN_LITERAL, wifiNetworkSpecifier.ssidPatternMatcher.getType());
- assertEquals(MacAddress.fromString(TEST_BSSID),
- wifiNetworkSpecifier.bssidPatternMatcher.first);
- assertEquals(MacAddress.BROADCAST_ADDRESS,
- wifiNetworkSpecifier.bssidPatternMatcher.second);
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WPA_EAP));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.IEEE8021X));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.hiddenSSID);
- assertEquals(enterpriseConfig.getEapMethod(),
- wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getEapMethod());
- assertEquals(enterpriseConfig.getPhase2Method(),
- wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getPhase2Method());
- }
-
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#setSsid(String)} throws an exception
- * when the string is not Unicode.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testWifiNetworkSpecifierBuilderSetSsidWithNonUnicodeString() {
- new WifiNetworkSpecifier.Builder()
- .setSsid("\ud800")
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} throws an exception
- * when the string is not ASCII encodable.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testWifiNetworkSpecifierSetWpa2PasphraseWithNonAsciiString() {
- new WifiNetworkSpecifier.Builder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase("salvē")
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when neither SSID nor BSSID patterns were set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithNoSsidAndBssidPattern() {
- new WifiNetworkSpecifier.Builder().build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when match-all SSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern1() {
- new WifiNetworkSpecifier.Builder()
- .setSsidPattern(new PatternMatcher(".*", PATTERN_SIMPLE_GLOB))
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when match-all SSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern2() {
- new WifiNetworkSpecifier.Builder()
- .setSsidPattern(new PatternMatcher(".*", PatternMatcher.PATTERN_ADVANCED_GLOB))
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when match-all SSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern3() {
- new WifiNetworkSpecifier.Builder()
- .setSsidPattern(new PatternMatcher("", PATTERN_PREFIX))
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when match-all BSSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchAllBssidPattern() {
- new WifiNetworkSpecifier.Builder()
- .setBssidPattern(WifiManager.ALL_ZEROS_MAC_ADDRESS,
- WifiManager.ALL_ZEROS_MAC_ADDRESS)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when match-none SSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern1() {
- new WifiNetworkSpecifier.Builder()
- .setSsidPattern(new PatternMatcher("", PatternMatcher.PATTERN_LITERAL))
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when match-none SSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern2() {
- new WifiNetworkSpecifier.Builder()
- .setSsid("")
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when match-none BSSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern1() {
- new WifiNetworkSpecifier.Builder()
- .setBssidPattern(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when match-none BSSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern2() {
- new WifiNetworkSpecifier.Builder()
- .setBssid(MacAddress.BROADCAST_ADDRESS)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when match-none BSSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern3() {
- new WifiNetworkSpecifier.Builder()
- .setBssid(WifiManager.ALL_ZEROS_MAC_ADDRESS)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when SSID pattern is set for hidden network.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithBssidMatchPatternForHiddenNetwork() {
- new WifiNetworkSpecifier.Builder()
- .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK))
- .setIsHiddenSsid(true)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when both {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} and
- * {@link WifiNetworkSpecifier.Builder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)} are
- * invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndEnterpriseConfig() {
- new WifiNetworkSpecifier.Builder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when SSID pattern is set for hidden network.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithSsidMatchPatternForHiddenNetwork() {
- new WifiNetworkSpecifier.Builder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
- .setIsHiddenSsid(true)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when both {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} and
- * {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndWpa3Passphrase() {
- new WifiNetworkSpecifier.Builder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when both {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} and
- * {@link WifiNetworkSpecifier.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} are
- * invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnterprise() {
- new WifiNetworkSpecifier.Builder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
- * when both {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} and
- * {@link WifiNetworkSpecifier.Builder#setIsEnhancedOpen(boolean)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnhancedOpen() {
- new WifiNetworkSpecifier.Builder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .setIsEnhancedOpen(true)
- .build();
- }
-
- /**
- * Validate that parcel marshalling/unmarshalling works
- */
- @Test
- public void testWifiNetworkSpecifierParcel() {
- WifiConfiguration wifiConfiguration = new WifiConfiguration();
- wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
- WifiNetworkSpecifier specifier =
- new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- wifiConfiguration);
-
- Parcel parcelW = Parcel.obtain();
- specifier.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiNetworkSpecifier parcelSpecifier =
- WifiNetworkSpecifier.CREATOR.createFromParcel(parcelR);
-
- assertEquals(specifier, parcelSpecifier);
- }
-
- /**
- * Validate NetworkSpecifier matching.
- * a) Create a network specifier for WPA_PSK network
- * b) Ensure that the specifier does not match {@code null} and {@link MatchAllNetworkSpecifier}
- * specifiers.
- */
- @Test
- public void testWifiNetworkSpecifierDoesNotSatisfyNullAndAllMatch() {
- WifiConfiguration wifiConfiguration = new WifiConfiguration();
- wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
- WifiNetworkSpecifier specifier =
- new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- wifiConfiguration);
-
- assertFalse(specifier.canBeSatisfiedBy(null));
- assertFalse(specifier.canBeSatisfiedBy(new MatchAllNetworkSpecifier()));
- }
-
- /**
- * Validate NetworkSpecifier matching.
- * a) Create network specifier 1 for WPA_PSK network
- * b) Create network specifier 2 with the same params as specifier 1.
- * c) Ensure that the specifier 2 is satisfied by specifier 1.
- */
- @Test
- public void testWifiNetworkSpecifierSatisfiesSame() {
- WifiConfiguration wifiConfiguration = new WifiConfiguration();
- wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-
- WifiNetworkSpecifier specifier1 =
- new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- wifiConfiguration);
-
- WifiNetworkSpecifier specifier2 =
- new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- wifiConfiguration);
-
- assertTrue(specifier2.canBeSatisfiedBy(specifier1));
- }
-
- /**
- * Validate NetworkSpecifier matching.
- * a) Create network specifier 1 for WPA_PSK network
- * b) Create network specifier 2 with different key mgmt params.
- * c) Ensure that the specifier 2 is not satisfied by specifier 1.
- */
- @Test
- public void testWifiNetworkSpecifierDoesNotSatisfyWhenKeyMgmtDifferent() {
- WifiConfiguration wifiConfiguration1 = new WifiConfiguration();
- wifiConfiguration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- wifiConfiguration1.preSharedKey = TEST_PRESHARED_KEY;
-
- WifiNetworkSpecifier specifier1 =
- new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- wifiConfiguration1);
-
- WifiConfiguration wifiConfiguration2 = new WifiConfiguration();
- wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- WifiNetworkSpecifier specifier2 =
- new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- wifiConfiguration2);
-
- assertFalse(specifier2.canBeSatisfiedBy(specifier1));
- }
-
- /**
- * Validate NetworkSpecifier matching.
- * a) Create network specifier 1 for WPA_PSK network
- * b) Create network specifier 2 with different SSID pattern.
- * c) Ensure that the specifier 2 is not satisfied by specifier 1.
- */
- @Test
- public void testWifiNetworkSpecifierDoesNotSatisfyWhenSsidDifferent() {
- WifiConfiguration wifiConfiguration = new WifiConfiguration();
- wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-
- WifiNetworkSpecifier specifier1 =
- new WifiNetworkSpecifier(new PatternMatcher("", PATTERN_LITERAL),
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- wifiConfiguration);
-
- WifiNetworkSpecifier specifier2 =
- new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- wifiConfiguration);
-
- assertFalse(specifier2.canBeSatisfiedBy(specifier1));
- }
-
- /**
- * Validate NetworkSpecifier matching.
- * a) Create network specifier 1 for WPA_PSK network
- * b) Create network specifier 2 with different BSSID pattern.
- * c) Ensure that the specifier 2 is not satisfied by specifier 1.
- */
- @Test
- public void testWifiNetworkSpecifierDoesNotSatisfyWhenBssidDifferent() {
- WifiConfiguration wifiConfiguration = new WifiConfiguration();
- wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-
- WifiNetworkSpecifier specifier1 =
- new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
- Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- wifiConfiguration);
-
- WifiNetworkSpecifier specifier2 =
- new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
- Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS,
- WifiManager.ALL_ZEROS_MAC_ADDRESS),
- wifiConfiguration);
-
- assertFalse(specifier2.canBeSatisfiedBy(specifier1));
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
deleted file mode 100644
index 16b4ad0..0000000
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ /dev/null
@@ -1,893 +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.net.wifi;
-
-import static org.junit.Assert.*;
-
-import android.net.MacAddress;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.PasspointTestUtils;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiNetworkSuggestion}.
- */
-@SmallTest
-public class WifiNetworkSuggestionTest {
- private static final String TEST_SSID = "\"Test123\"";
- private static final String TEST_BSSID = "12:12:12:12:12:12";
- private static final String TEST_SSID_1 = "\"Test1234\"";
- private static final String TEST_PRESHARED_KEY = "Test123";
- private static final String TEST_FQDN = "fqdn";
- private static final String TEST_WAPI_CERT_SUITE = "suite";
- private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for Open network which requires
- * app interaction.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForOpenNetworkWithReqAppInteraction() {
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setIsAppInteractionRequired(true)
- .build();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.NONE));
- assertTrue(suggestion.isAppInteractionRequired);
- assertFalse(suggestion.isUserInteractionRequired);
- assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
- suggestion.wifiConfiguration.meteredOverride);
- assertEquals(-1, suggestion.wifiConfiguration.priority);
- assertFalse(suggestion.isUserAllowedToManuallyConnect);
- assertTrue(suggestion.isInitialAutoJoinEnabled);
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for WPA_EAP network which requires
- * app interaction, not share credential and has a priority of zero set.
- */
- @Test
- public void
- testWifiNetworkSuggestionBuilderForWpa2EapNetworkWithPriorityAndReqAppInteraction() {
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setIsAppInteractionRequired(true)
- .setCredentialSharedWithUser(false)
- .setPriority(0)
- .build();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WPA_PSK));
- assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
- suggestion.wifiConfiguration.preSharedKey);
- assertTrue(suggestion.isAppInteractionRequired);
- assertFalse(suggestion.isUserInteractionRequired);
- assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
- suggestion.wifiConfiguration.meteredOverride);
- assertEquals(0, suggestion.wifiConfiguration.priority);
- assertFalse(suggestion.isUserAllowedToManuallyConnect);
- assertTrue(suggestion.isInitialAutoJoinEnabled);
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for WPA_PSK network which requires
- * user interaction and is metered.
- */
- @Test
- public void
- testWifiNetworkSuggestionBuilderForWpa2PskNetworkWithMeteredAndReqUserInteraction() {
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setIsUserInteractionRequired(true)
- .setIsInitialAutojoinEnabled(false)
- .setIsMetered(true)
- .build();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WPA_PSK));
- assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
- suggestion.wifiConfiguration.preSharedKey);
- assertFalse(suggestion.isAppInteractionRequired);
- assertTrue(suggestion.isUserInteractionRequired);
- assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED,
- suggestion.wifiConfiguration.meteredOverride);
- assertEquals(-1, suggestion.wifiConfiguration.priority);
- assertTrue(suggestion.isUserAllowedToManuallyConnect);
- assertFalse(suggestion.isInitialAutoJoinEnabled);
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for WPA_PSK network which requires
- * user interaction and is not metered.
- */
- @Test
- public void
- testWifiNetworkSuggestionBuilderForWpa2PskNetworkWithNotMeteredAndReqUserInteraction() {
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setIsUserInteractionRequired(true)
- .setIsInitialAutojoinEnabled(false)
- .setIsMetered(false)
- .build();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WPA_PSK));
- assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
- suggestion.wifiConfiguration.preSharedKey);
- assertFalse(suggestion.isAppInteractionRequired);
- assertTrue(suggestion.isUserInteractionRequired);
- assertEquals(WifiConfiguration.METERED_OVERRIDE_NOT_METERED,
- suggestion.wifiConfiguration.meteredOverride);
- assertEquals(-1, suggestion.wifiConfiguration.priority);
- assertTrue(suggestion.isUserAllowedToManuallyConnect);
- assertFalse(suggestion.isInitialAutoJoinEnabled);
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for OWE network.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForEnhancedOpenNetworkWithBssid() {
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setBssid(MacAddress.fromString(TEST_BSSID))
- .setIsEnhancedOpen(true)
- .build();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertEquals(TEST_BSSID, suggestion.wifiConfiguration.BSSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.OWE));
- assertNull(suggestion.wifiConfiguration.preSharedKey);
- assertTrue(suggestion.wifiConfiguration.requirePmf);
- assertFalse(suggestion.isUserAllowedToManuallyConnect);
- assertTrue(suggestion.isInitialAutoJoinEnabled);
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for SAE network.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForWpa3PskNetwork() {
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .setCredentialSharedWithUser(true)
- .setIsInitialAutojoinEnabled(false)
- .build();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.SAE));
- assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
- suggestion.wifiConfiguration.preSharedKey);
- assertTrue(suggestion.wifiConfiguration.requirePmf);
- assertTrue(suggestion.isUserAllowedToManuallyConnect);
- assertFalse(suggestion.isInitialAutoJoinEnabled);
- }
-
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for SuiteB network.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
- enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
- enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0);
- enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa3EnterpriseConfig(enterpriseConfig)
- .build();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
- assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.GCMP_256));
- assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers
- .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
- assertTrue(suggestion.wifiConfiguration.requirePmf);
- assertNull(suggestion.wifiConfiguration.preSharedKey);
- // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested
- // here.
- assertTrue(suggestion.isUserAllowedToManuallyConnect);
- assertTrue(suggestion.isInitialAutoJoinEnabled);
- }
-
- /**
- * Ensure create enterprise suggestion requires CA, when CA certificate is missing, will throw
- * an exception.
- */
- @Test (expected = IllegalArgumentException.class)
- public void testWifiNetworkSuggestionBuilderForEapNetworkWithoutCa() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
- enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
- enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa2EnterpriseConfig(enterpriseConfig)
- .build();
- }
-
- /**
- * Ensure create enterprise suggestion requires CA, when both domain suffix and alt subject
- * match are missing, will throw an exception.
- */
- @Test (expected = IllegalArgumentException.class)
- public void testWifiNetworkSuggestionBuilderForEapNetworkWithoutMatch() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
- enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
- enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0);
-
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa3EnterpriseConfig(enterpriseConfig)
- .build();
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-PSK network.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForWapiPskNetwork() {
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWapiPassphrase(TEST_PRESHARED_KEY)
- .build();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WAPI_PSK));
- assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers
- .get(WifiConfiguration.PairwiseCipher.SMS4));
- assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.SMS4));
- assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
- suggestion.wifiConfiguration.preSharedKey);
- }
-
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-CERT network.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForWapiCertNetwork() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.WAPI_CERT);
- enterpriseConfig.setWapiCertSuite(TEST_WAPI_CERT_SUITE);
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWapiEnterpriseConfig(enterpriseConfig)
- .build();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WAPI_CERT));
- assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers
- .get(WifiConfiguration.PairwiseCipher.SMS4));
- assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.SMS4));
- assertNull(suggestion.wifiConfiguration.preSharedKey);
- assertNotNull(suggestion.wifiConfiguration.enterpriseConfig);
- assertEquals(WifiEnterpriseConfig.Eap.WAPI_CERT,
- suggestion.wifiConfiguration.enterpriseConfig.getEapMethod());
- assertEquals(TEST_WAPI_CERT_SUITE,
- suggestion.wifiConfiguration.enterpriseConfig.getWapiCertSuite());
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-CERT network
- * which selects the certificate suite automatically.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForWapiCertAutoNetwork() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.WAPI_CERT);
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWapiEnterpriseConfig(enterpriseConfig)
- .build();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WAPI_CERT));
- assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers
- .get(WifiConfiguration.PairwiseCipher.SMS4));
- assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.SMS4));
- assertNull(suggestion.wifiConfiguration.preSharedKey);
- assertNotNull(suggestion.wifiConfiguration.enterpriseConfig);
- assertEquals(WifiEnterpriseConfig.Eap.WAPI_CERT,
- suggestion.wifiConfiguration.enterpriseConfig.getEapMethod());
- assertEquals("",
- suggestion.wifiConfiguration.enterpriseConfig.getWapiCertSuite());
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for Passpoint network which requires
- * app interaction and metered.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForPasspointNetworkWithReqAppInteractionMetered() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setPasspointConfig(passpointConfiguration)
- .setIsAppInteractionRequired(true)
- .setIsMetered(true)
- .build();
- assertEquals(TEST_FQDN, suggestion.wifiConfiguration.FQDN);
- assertTrue(suggestion.isAppInteractionRequired);
- assertEquals(suggestion.wifiConfiguration.meteredOverride,
- WifiConfiguration.METERED_OVERRIDE_METERED);
- assertEquals(suggestion.getPasspointConfig().getMeteredOverride(),
- WifiConfiguration.METERED_OVERRIDE_METERED);
- assertTrue(suggestion.isUserAllowedToManuallyConnect);
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#setSsid(String)} throws an exception
- * when the string is not Unicode.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testWifiNetworkSuggestionBuilderSetSsidWithNonUnicodeString() {
- new WifiNetworkSuggestion.Builder()
- .setSsid("\ud800")
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#setWpa2Passphrase(String)} throws an exception
- * when the string is not ASCII encodable.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testWifiNetworkSuggestionBuilderSetWpa2PasphraseWithNonAsciiString() {
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase("salvē")
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)}}
- * throws an exception when the PasspointConfiguration is not valid.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testWifiNetworkSuggestionBuilderSetPasspointConfigWithNonValid() {
- PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
- new WifiNetworkSuggestion.Builder()
- .setPasspointConfig(passpointConfiguration)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when {@link WifiNetworkSuggestion.Builder#setSsid(String)} is not set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithNoSsid() {
- new WifiNetworkSuggestion.Builder()
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when {@link WifiNetworkSuggestion.Builder#setSsid(String)} is invoked with an invalid value.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithInvalidSsid() {
- new WifiNetworkSuggestion.Builder()
- .setSsid("")
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when {@link WifiNetworkSuggestion.Builder#setBssid(MacAddress)} is invoked with an invalid
- * value.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithInvalidBroadcastBssid() {
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setBssid(MacAddress.BROADCAST_ADDRESS)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when {@link WifiNetworkSuggestion.Builder#setBssid(MacAddress)} is invoked with an invalid
- * value.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithInvalidAllZeroBssid() {
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setBssid(WifiManager.ALL_ZEROS_MAC_ADDRESS)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#setPriority(int)} throws an exception
- * when the value is negative.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testWifiNetworkSuggestionBuilderWithInvalidPriority() {
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setPriority(-2)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when both {@link WifiNetworkSuggestion.Builder#setWpa2Passphrase(String)} and
- * {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithBothWpa2PasphraseAndWpa3Passphrase() {
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and
- * {@link WifiNetworkSuggestion.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} are
- * invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithBothWpa3PasphraseAndEnterprise() {
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and
- * {@link WifiNetworkSuggestion.Builder#setIsEnhancedOpen(boolean)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithBothWpa3PasphraseAndEnhancedOpen() {
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .setIsEnhancedOpen(true)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when both {@link WifiNetworkSuggestion.Builder#setSsid(String)} and
- * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithBothSsidAndPasspointConfig() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setPasspointConfig(passpointConfiguration)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when both {@link WifiNetworkSuggestion.Builder#setWpa2Passphrase(String)} and
- * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithBothWpa2PassphraseAndPasspointConfig() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- new WifiNetworkSuggestion.Builder()
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setPasspointConfig(passpointConfiguration)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and
- * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithBothWpa3PassphraseAndPasspointConfig() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- new WifiNetworkSuggestion.Builder()
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .setPasspointConfig(passpointConfiguration)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when both {@link WifiNetworkSuggestion.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)}
- * and {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are
- * invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithBothEnterpriseAndPasspointConfig() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- new WifiNetworkSuggestion.Builder()
- .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
- .setPasspointConfig(passpointConfiguration)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when both {@link WifiNetworkSuggestion.Builder#setIsEnhancedOpen(boolean)} and
- * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithBothEnhancedOpenAndPasspointConfig() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- new WifiNetworkSuggestion.Builder()
- .setIsEnhancedOpen(true)
- .setPasspointConfig(passpointConfiguration)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when both {@link WifiNetworkSuggestion.Builder#setIsHiddenSsid(boolean)} and
- * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithBothHiddenSsidAndPasspointConfig() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- new WifiNetworkSuggestion.Builder()
- .setIsHiddenSsid(true)
- .setPasspointConfig(passpointConfiguration)
- .build();
- }
-
- /**
- * Check that parcel marshalling/unmarshalling works
- */
- @Test
- public void testWifiNetworkSuggestionParcel() {
- WifiConfiguration configuration = new WifiConfiguration();
- configuration.SSID = TEST_SSID;
- configuration.BSSID = TEST_BSSID;
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion(
- configuration, null, false, true, true, true);
-
- Parcel parcelW = Parcel.obtain();
- suggestion.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiNetworkSuggestion parcelSuggestion =
- WifiNetworkSuggestion.CREATOR.createFromParcel(parcelR);
-
- // Two suggestion objects are considered equal if they point to the same network (i.e same
- // SSID + keyMgmt + same UID). |isAppInteractionRequired| & |isUserInteractionRequired| are
- // not considered for equality and hence needs to be checked for explicitly below.
- assertEquals(suggestion, parcelSuggestion);
- assertEquals(suggestion.hashCode(), parcelSuggestion.hashCode());
- assertEquals(suggestion.isAppInteractionRequired,
- parcelSuggestion.isAppInteractionRequired);
- assertEquals(suggestion.isUserInteractionRequired,
- parcelSuggestion.isUserInteractionRequired);
- assertEquals(suggestion.isInitialAutoJoinEnabled,
- parcelSuggestion.isInitialAutoJoinEnabled);
- }
-
- /**
- * Check that parcel marshalling/unmarshalling works
- */
- @Test
- public void testPasspointNetworkSuggestionParcel() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setPasspointConfig(passpointConfiguration)
- .build();
-
- Parcel parcelW = Parcel.obtain();
- suggestion.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiNetworkSuggestion parcelSuggestion =
- WifiNetworkSuggestion.CREATOR.createFromParcel(parcelR);
-
- // Two suggestion objects are considered equal if they point to the same network (i.e same
- // SSID + keyMgmt + same UID). |isAppInteractionRequired| & |isUserInteractionRequired| are
- // not considered for equality and hence needs to be checked for explicitly below.
- assertEquals(suggestion, parcelSuggestion);
- assertEquals(suggestion.hashCode(), parcelSuggestion.hashCode());
- assertEquals(suggestion.isAppInteractionRequired,
- parcelSuggestion.isAppInteractionRequired);
- assertEquals(suggestion.isUserInteractionRequired,
- parcelSuggestion.isUserInteractionRequired);
- assertEquals(suggestion.isInitialAutoJoinEnabled,
- parcelSuggestion.isInitialAutoJoinEnabled);
- }
-
- /**
- * Check NetworkSuggestion equals returns {@code true} for 2 network suggestions with the same
- * SSID, BSSID, key mgmt and UID.
- */
- @Test
- public void testWifiNetworkSuggestionEqualsSame() {
- WifiConfiguration configuration = new WifiConfiguration();
- configuration.SSID = TEST_SSID;
- configuration.BSSID = TEST_BSSID;
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- WifiNetworkSuggestion suggestion =
- new WifiNetworkSuggestion(configuration, null, true, false, true, true);
-
- WifiConfiguration configuration1 = new WifiConfiguration();
- configuration1.SSID = TEST_SSID;
- configuration1.BSSID = TEST_BSSID;
- configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- WifiNetworkSuggestion suggestion1 =
- new WifiNetworkSuggestion(configuration1, null, false, true, true, true);
-
- assertEquals(suggestion, suggestion1);
- assertEquals(suggestion.hashCode(), suggestion1.hashCode());
- }
-
- /**
- * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same
- * BSSID, key mgmt and UID, but different SSID.
- */
- @Test
- public void testWifiNetworkSuggestionEqualsFailsWhenSsidIsDifferent() {
- WifiConfiguration configuration = new WifiConfiguration();
- configuration.SSID = TEST_SSID;
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- WifiNetworkSuggestion suggestion =
- new WifiNetworkSuggestion(configuration, null, false, false, true, true);
-
- WifiConfiguration configuration1 = new WifiConfiguration();
- configuration1.SSID = TEST_SSID_1;
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- WifiNetworkSuggestion suggestion1 =
- new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
-
- assertNotEquals(suggestion, suggestion1);
- }
-
- /**
- * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same
- * SSID, key mgmt and UID, but different BSSID.
- */
- @Test
- public void testWifiNetworkSuggestionEqualsFailsWhenBssidIsDifferent() {
- WifiConfiguration configuration = new WifiConfiguration();
- configuration.SSID = TEST_SSID;
- configuration.BSSID = TEST_BSSID;
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- WifiNetworkSuggestion suggestion =
- new WifiNetworkSuggestion(configuration, null, false, false, true, true);
-
- WifiConfiguration configuration1 = new WifiConfiguration();
- configuration1.SSID = TEST_SSID;
- configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- WifiNetworkSuggestion suggestion1 =
- new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
-
- assertNotEquals(suggestion, suggestion1);
- }
-
- /**
- * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same
- * SSID, BSSID and UID, but different key mgmt.
- */
- @Test
- public void testWifiNetworkSuggestionEqualsFailsWhenKeyMgmtIsDifferent() {
- WifiConfiguration configuration = new WifiConfiguration();
- configuration.SSID = TEST_SSID;
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- WifiNetworkSuggestion suggestion =
- new WifiNetworkSuggestion(configuration, null, false, false, true, true);
-
- WifiConfiguration configuration1 = new WifiConfiguration();
- configuration1.SSID = TEST_SSID;
- configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- WifiNetworkSuggestion suggestion1 =
- new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
-
- assertNotEquals(suggestion, suggestion1);
- }
-
- /**
- * Check NetworkSuggestion equals returns {@code true} for 2 Passpoint network suggestions with
- * same FQDN.
- */
- @Test
- public void testPasspointNetworkSuggestionEqualsSameWithSameFQDN() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- PasspointConfiguration passpointConfiguration1 = PasspointTestUtils.createConfig();
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setPasspointConfig(passpointConfiguration)
- .build();
- WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder()
- .setPasspointConfig(passpointConfiguration1)
- .build();
- assertEquals(suggestion, suggestion1);
- assertEquals(suggestion.hashCode(), suggestion1.hashCode());
- }
-
- /**
- * Check NetworkSuggestion equals returns {@code false} for 2 Passpoint network suggestions with
- * different FQDN.
- */
- @Test
- public void testPasspointNetworkSuggestionNotEqualsSameWithDifferentFQDN() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- PasspointConfiguration passpointConfiguration1 = PasspointTestUtils.createConfig();
- passpointConfiguration1.getHomeSp().setFqdn(TEST_FQDN + 1);
-
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setPasspointConfig(passpointConfiguration)
- .build();
- WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder()
- .setPasspointConfig(passpointConfiguration1)
- .build();
- assertNotEquals(suggestion, suggestion1);
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to
- * true on a open network suggestion.
- */
- @Test(expected = IllegalStateException.class)
- public void testSetCredentialSharedWithUserWithOpenNetwork() {
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setCredentialSharedWithUser(true)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)} to
- * false on a open network suggestion.
- */
- @Test(expected = IllegalStateException.class)
- public void testSetIsAutoJoinDisabledWithOpenNetwork() {
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setIsInitialAutojoinEnabled(false)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)}
- * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)}
- * to false on a network suggestion.
- */
- @Test(expected = IllegalStateException.class)
- public void testSetIsAutoJoinDisabledWithSecureNetworkNotSharedWithUser() {
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setCredentialSharedWithUser(false)
- .setIsInitialAutojoinEnabled(false)
- .build();
- }
-
- /**
- * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the
- * correct value to the WifiConfiguration.
- */
- @Test
- public void testSetIsNetworkAsUntrusted() {
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setUntrusted(true)
- .build();
- assertTrue(suggestion.isUntrusted());
- assertFalse(suggestion.isUserAllowedToManuallyConnect);
- }
-
- /**
- * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the
- * correct value to the WifiConfiguration.
- * Also the {@link WifiNetworkSuggestion#isUserAllowedToManuallyConnect} should be false;
- */
- @Test
- public void testSetIsNetworkAsUntrustedOnPasspointNetwork() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
- .setPasspointConfig(passpointConfiguration)
- .setUntrusted(true)
- .build();
- assertTrue(suggestion.isUntrusted());
- assertFalse(suggestion.isUserAllowedToManuallyConnect);
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when set {@link WifiNetworkSuggestion.Builder#setUntrusted(boolean)} to true and
- * set {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to true
- * together.
- */
- @Test(expected = IllegalStateException.class)
- public void testSetCredentialSharedWithUserWithSetIsNetworkAsUntrusted() {
- new WifiNetworkSuggestion.Builder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setCredentialSharedWithUser(true)
- .setUntrusted(true)
- .build();
- }
-
- /**
- * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
- * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)}
- * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)}
- * to false on a passpoint suggestion.
- */
- @Test(expected = IllegalStateException.class)
- public void testSetIsAutoJoinDisabledWithSecureNetworkNotSharedWithUserForPasspoint() {
- PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
- new WifiNetworkSuggestion.Builder()
- .setPasspointConfig(passpointConfiguration)
- .setCredentialSharedWithUser(false)
- .setIsInitialAutojoinEnabled(false)
- .build();
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java
deleted file mode 100644
index b68616f..0000000
--- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java
+++ /dev/null
@@ -1,634 +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.net.wifi;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.validateMockitoUsage;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.wifi.WifiScanner.PnoSettings;
-import android.net.wifi.WifiScanner.PnoSettings.PnoNetwork;
-import android.net.wifi.WifiScanner.ScanData;
-import android.net.wifi.WifiScanner.ScanListener;
-import android.net.wifi.WifiScanner.ScanSettings;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.Parcel;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.util.test.BidirectionalAsyncChannelServer;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-
-import java.util.Arrays;
-import java.util.concurrent.Executor;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiScanner}.
- */
-@SmallTest
-public class WifiScannerTest {
- @Mock
- private Context mContext;
- @Mock
- private IWifiScanner mService;
- @Spy
- private Executor mExecutor = new SynchronousExecutor();
- @Mock
- private ScanListener mScanListener;
- @Mock
- private WifiScanner.ParcelableScanData mParcelableScanData;
- private ScanData[] mScanData = {};
-
- private static final boolean TEST_PNOSETTINGS_IS_CONNECTED = false;
- private static final int TEST_PNOSETTINGS_MIN_5GHZ_RSSI = -60;
- private static final int TEST_PNOSETTINGS_MIN_2GHZ_RSSI = -70;
- private static final int TEST_PNOSETTINGS_MIN_6GHZ_RSSI = -55;
- private static final String TEST_SSID_1 = "TEST1";
- private static final String TEST_SSID_2 = "TEST2";
- private static final int[] TEST_FREQUENCIES_1 = {};
- private static final int[] TEST_FREQUENCIES_2 = {2500, 5124, 6245};
- private static final String DESCRIPTION_NOT_AUTHORIZED = "Not authorized";
-
- private WifiScanner mWifiScanner;
- private TestLooper mLooper;
- private Handler mHandler;
- private BidirectionalAsyncChannelServer mBidirectionalAsyncChannelServer;
-
- /**
- * Setup before tests.
- */
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mLooper = new TestLooper();
- mHandler = spy(new Handler(mLooper.getLooper()));
- mBidirectionalAsyncChannelServer = new BidirectionalAsyncChannelServer(
- mContext, mLooper.getLooper(), mHandler);
- when(mService.getMessenger()).thenReturn(mBidirectionalAsyncChannelServer.getMessenger());
- mWifiScanner = new WifiScanner(mContext, mService, mLooper.getLooper());
- mLooper.dispatchAll();
- when(mParcelableScanData.getResults()).thenReturn(mScanData);
- }
-
- /**
- * Clean up after tests.
- */
- @After
- public void cleanup() {
- validateMockitoUsage();
- }
-
- /**
- * Verify parcel read/write for ScanSettings.
- */
- @Test
- public void verifyScanSettingsParcelWithBand() throws Exception {
- ScanSettings writeSettings = new ScanSettings();
- writeSettings.type = WifiScanner.SCAN_TYPE_LOW_POWER;
- writeSettings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
-
- ScanSettings readSettings = parcelWriteRead(writeSettings);
- assertEquals(readSettings.type, writeSettings.type);
- assertEquals(readSettings.band, writeSettings.band);
- assertEquals(0, readSettings.channels.length);
- }
-
- /**
- * Verify parcel read/write for ScanSettings.
- */
- @Test
- public void verifyScanSettingsParcelWithChannels() throws Exception {
- ScanSettings writeSettings = new ScanSettings();
- writeSettings.type = WifiScanner.SCAN_TYPE_HIGH_ACCURACY;
- writeSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED;
- writeSettings.channels = new WifiScanner.ChannelSpec[] {
- new WifiScanner.ChannelSpec(5),
- new WifiScanner.ChannelSpec(7)
- };
-
- ScanSettings readSettings = parcelWriteRead(writeSettings);
- assertEquals(writeSettings.type, readSettings.type);
- assertEquals(writeSettings.band, readSettings.band);
- assertEquals(2, readSettings.channels.length);
- assertEquals(5, readSettings.channels[0].frequency);
- assertEquals(7, readSettings.channels[1].frequency);
- }
-
- /**
- * Write the provided {@link ScanSettings} to a parcel and deserialize it.
- */
- private static ScanSettings parcelWriteRead(ScanSettings writeSettings) throws Exception {
- Parcel parcel = Parcel.obtain();
- writeSettings.writeToParcel(parcel, 0);
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- return ScanSettings.CREATOR.createFromParcel(parcel);
- }
-
- /**
- * PnoSettings object can be serialized and deserialized, while keeping the
- * values unchanged.
- */
- @Test
- public void canSerializeAndDeserializePnoSettings() throws Exception {
-
- PnoSettings pnoSettings = new PnoSettings();
-
- PnoNetwork pnoNetwork1 = new PnoNetwork(TEST_SSID_1);
- PnoNetwork pnoNetwork2 = new PnoNetwork(TEST_SSID_2);
- pnoNetwork1.frequencies = TEST_FREQUENCIES_1;
- pnoNetwork2.frequencies = TEST_FREQUENCIES_2;
-
- pnoSettings.networkList = new PnoNetwork[]{pnoNetwork1, pnoNetwork2};
- pnoSettings.isConnected = TEST_PNOSETTINGS_IS_CONNECTED;
- pnoSettings.min5GHzRssi = TEST_PNOSETTINGS_MIN_5GHZ_RSSI;
- pnoSettings.min24GHzRssi = TEST_PNOSETTINGS_MIN_2GHZ_RSSI;
- pnoSettings.min6GHzRssi = TEST_PNOSETTINGS_MIN_6GHZ_RSSI;
-
- Parcel parcel = Parcel.obtain();
- pnoSettings.writeToParcel(parcel, 0);
- // Rewind the pointer to the head of the parcel.
- parcel.setDataPosition(0);
- PnoSettings pnoSettingsDeserialized =
- pnoSettings.CREATOR.createFromParcel(parcel);
-
- assertNotNull(pnoSettingsDeserialized);
- assertEquals(TEST_PNOSETTINGS_IS_CONNECTED, pnoSettingsDeserialized.isConnected);
- assertEquals(TEST_PNOSETTINGS_MIN_5GHZ_RSSI, pnoSettingsDeserialized.min5GHzRssi);
- assertEquals(TEST_PNOSETTINGS_MIN_2GHZ_RSSI, pnoSettingsDeserialized.min24GHzRssi);
- assertEquals(TEST_PNOSETTINGS_MIN_6GHZ_RSSI, pnoSettingsDeserialized.min6GHzRssi);
-
- // Test parsing of PnoNetwork
- assertEquals(pnoSettings.networkList.length, pnoSettingsDeserialized.networkList.length);
- for (int i = 0; i < pnoSettings.networkList.length; i++) {
- PnoNetwork expected = pnoSettings.networkList[i];
- PnoNetwork actual = pnoSettingsDeserialized.networkList[i];
- assertEquals(expected.ssid, actual.ssid);
- assertEquals(expected.flags, actual.flags);
- assertEquals(expected.authBitField, actual.authBitField);
- assertTrue(Arrays.equals(expected.frequencies, actual.frequencies));
- }
- }
-
- /**
- * Make sure that frequencies is not null by default.
- */
- @Test
- public void pnoNetworkFrequencyIsNotNull() throws Exception {
- PnoNetwork pnoNetwork = new PnoNetwork(TEST_SSID_1);
- assertNotNull(pnoNetwork.frequencies);
- }
-
- /**
- * Verify parcel read/write for ScanData.
- */
- @Test
- public void verifyScanDataParcel() throws Exception {
- ScanData writeScanData = new ScanData(2, 0, 3,
- WifiScanner.WIFI_BAND_BOTH_WITH_DFS, new ScanResult[0]);
-
- ScanData readScanData = parcelWriteRead(writeScanData);
- assertEquals(writeScanData.getId(), readScanData.getId());
- assertEquals(writeScanData.getFlags(), readScanData.getFlags());
- assertEquals(writeScanData.getBucketsScanned(), readScanData.getBucketsScanned());
- assertEquals(writeScanData.getBandScanned(), readScanData.getBandScanned());
- assertArrayEquals(writeScanData.getResults(), readScanData.getResults());
- }
-
- /**
- * Write the provided {@link ScanData} to a parcel and deserialize it.
- */
- private static ScanData parcelWriteRead(ScanData writeScanData) throws Exception {
- Parcel parcel = Parcel.obtain();
- writeScanData.writeToParcel(parcel, 0);
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- return ScanData.CREATOR.createFromParcel(parcel);
- }
-
-
- /**
- * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)}
- * @throws Exception
- */
- @Test
- public void testStartScan() throws Exception {
- ScanSettings scanSettings = new ScanSettings();
- ScanListener scanListener = mock(ScanListener.class);
-
- mWifiScanner.startScan(scanSettings, scanListener);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler).handleMessage(messageArgumentCaptor.capture());
- Message message = messageArgumentCaptor.getValue();
- assertNotNull(message);
-
- assertEquals(WifiScanner.CMD_START_SINGLE_SCAN, message.what);
- assertTrue(message.obj instanceof Bundle);
- Bundle messageBundle = (Bundle) message.obj;
- assertEquals(scanSettings,
- messageBundle.getParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY));
- assertNull(messageBundle.getParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY));
- assertEquals(mContext.getOpPackageName(),
- messageBundle.getParcelable(WifiScanner.REQUEST_PACKAGE_NAME_KEY));
- assertEquals(mContext.getAttributionTag(),
- messageBundle.getParcelable(WifiScanner.REQUEST_FEATURE_ID_KEY));
-
- }
-
- /**
- * Test behavior of {@link WifiScanner#stopScan(ScanListener)}
- * @throws Exception
- */
- @Test
- public void testStopScan() throws Exception {
- ScanSettings scanSettings = new ScanSettings();
- ScanListener scanListener = mock(ScanListener.class);
-
- mWifiScanner.startScan(scanSettings, scanListener);
- mLooper.dispatchAll();
-
- mWifiScanner.stopScan(scanListener);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture());
- Message message = messageArgumentCaptor.getValue();
- assertNotNull(message);
-
- assertEquals(WifiScanner.CMD_STOP_SINGLE_SCAN, message.what);
- assertTrue(message.obj instanceof Bundle);
- Bundle messageBundle = (Bundle) message.obj;
- assertEquals(mContext.getOpPackageName(),
- messageBundle.getParcelable(WifiScanner.REQUEST_PACKAGE_NAME_KEY));
- assertEquals(mContext.getAttributionTag(),
- messageBundle.getParcelable(WifiScanner.REQUEST_FEATURE_ID_KEY));
- }
-
- /**
- * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)}
- * @throws Exception
- */
- @Test
- public void testStartScanListenerOnSuccess() throws Exception {
- ScanSettings scanSettings = new ScanSettings();
- ScanListener scanListener = mock(ScanListener.class);
-
- mWifiScanner.startScan(scanSettings, scanListener);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler).handleMessage(messageArgumentCaptor.capture());
- Message sentMessage = messageArgumentCaptor.getValue();
- assertNotNull(sentMessage);
-
- assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
- Messenger scannerMessenger =
- mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
- Message responseMessage = Message.obtain();
- responseMessage.what = WifiScanner.CMD_OP_SUCCEEDED;
- responseMessage.arg2 = sentMessage.arg2;
- scannerMessenger.send(responseMessage);
- mLooper.dispatchAll();
-
- verify(scanListener).onSuccess();
- }
-
- /**
- * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)}
- * @throws Exception
- */
- @Test
- public void testStartScanListenerOnResults() throws Exception {
- ScanSettings scanSettings = new ScanSettings();
- ScanListener scanListener = mock(ScanListener.class);
-
- mWifiScanner.startScan(scanSettings, scanListener);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler).handleMessage(messageArgumentCaptor.capture());
- Message sentMessage = messageArgumentCaptor.getValue();
- assertNotNull(sentMessage);
-
- assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
- Messenger scannerMessenger =
- mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
- ScanResult scanResult = new ScanResult();
- ScanData scanDatas[] = new ScanData[]{new ScanData(0, 0 , new ScanResult[] {scanResult})};
- Message responseMessage = Message.obtain();
- responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
- responseMessage.arg2 = sentMessage.arg2;
- responseMessage.obj = new WifiScanner.ParcelableScanData(scanDatas);
- scannerMessenger.send(responseMessage);
- mLooper.dispatchAll();
-
- verify(scanListener).onResults(scanDatas);
- }
-
- /**
- * Test behavior of {@link WifiScanner#startDisconnectedPnoScan(ScanSettings, PnoSettings,
- * Executor, WifiScanner.PnoScanListener)}
- * @throws Exception
- */
- @Test
- public void testStartDisconnectedPnoScan() throws Exception {
- ScanSettings scanSettings = new ScanSettings();
- PnoSettings pnoSettings = new PnoSettings();
- WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class);
-
- mWifiScanner.startDisconnectedPnoScan(
- scanSettings, pnoSettings, mock(Executor.class), pnoScanListener);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler).handleMessage(messageArgumentCaptor.capture());
- Message message = messageArgumentCaptor.getValue();
- assertNotNull(message);
-
- assertEquals(WifiScanner.CMD_START_PNO_SCAN, message.what);
- assertTrue(message.obj instanceof Bundle);
- Bundle messageBundle = (Bundle) message.obj;
- assertEquals(scanSettings,
- messageBundle.getParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY));
- assertTrue(scanSettings.isPnoScan);
- assertFalse(pnoSettings.isConnected);
- assertEquals(pnoSettings,
- messageBundle.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY));
- }
-
- /**
- * Test behavior of {@link WifiScanner#startConnectedPnoScan(ScanSettings, PnoSettings,
- * Executor, WifiScanner.PnoScanListener)}
- * @throws Exception
- */
- @Test
- public void testStartConnectedPnoScan() throws Exception {
- ScanSettings scanSettings = new ScanSettings();
- PnoSettings pnoSettings = new PnoSettings();
- WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class);
-
- mWifiScanner.startConnectedPnoScan(
- scanSettings, pnoSettings, mock(Executor.class), pnoScanListener);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler).handleMessage(messageArgumentCaptor.capture());
- Message message = messageArgumentCaptor.getValue();
- assertNotNull(message);
-
- assertEquals(WifiScanner.CMD_START_PNO_SCAN, message.what);
- assertTrue(message.obj instanceof Bundle);
- Bundle messageBundle = (Bundle) message.obj;
- assertEquals(scanSettings,
- messageBundle.getParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY));
- assertTrue(scanSettings.isPnoScan);
- assertTrue(pnoSettings.isConnected);
- assertEquals(pnoSettings,
- messageBundle.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY));
- }
-
- /**
- * Test behavior of {@link WifiScanner#stopPnoScan(ScanListener)}
- * Executor, WifiScanner.PnoScanListener)}
- * @throws Exception
- */
- @Test
- public void testStopPnoScan() throws Exception {
- ScanSettings scanSettings = new ScanSettings();
- PnoSettings pnoSettings = new PnoSettings();
- WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class);
-
- mWifiScanner.startDisconnectedPnoScan(
- scanSettings, pnoSettings, mock(Executor.class), pnoScanListener);
- mLooper.dispatchAll();
- mWifiScanner.stopPnoScan(pnoScanListener);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture());
- Message message = messageArgumentCaptor.getValue();
- assertNotNull(message);
-
- assertEquals(WifiScanner.CMD_STOP_PNO_SCAN, message.what);
- }
-
- @Test
- public void testScanDataAddResults() throws Exception {
- ScanResult scanResult1 = new ScanResult();
- scanResult1.SSID = TEST_SSID_1;
- ScanData scanData = new ScanData(0, 0, new ScanResult[]{scanResult1});
-
- ScanResult scanResult2 = new ScanResult();
- scanResult2.SSID = TEST_SSID_2;
- scanData.addResults(new ScanResult[]{scanResult2});
-
- ScanResult[] consolidatedScanResults = scanData.getResults();
- assertEquals(2, consolidatedScanResults.length);
- assertEquals(TEST_SSID_1, consolidatedScanResults[0].SSID);
- assertEquals(TEST_SSID_2, consolidatedScanResults[1].SSID);
- }
-
- @Test
- public void testScanDataParcel() throws Exception {
- ScanResult scanResult1 = new ScanResult();
- scanResult1.SSID = TEST_SSID_1;
- ScanData scanData = new ScanData(5, 4, new ScanResult[]{scanResult1});
-
- Parcel parcel = Parcel.obtain();
- scanData.writeToParcel(parcel, 0);
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- ScanData readScanData = ScanData.CREATOR.createFromParcel(parcel);
-
- assertEquals(scanData.getId(), readScanData.getId());
- assertEquals(scanData.getFlags(), readScanData.getFlags());
- assertEquals(scanData.getResults().length, readScanData.getResults().length);
- assertEquals(scanData.getResults()[0].SSID, readScanData.getResults()[0].SSID);
- }
-
- /** Tests that upon registration success, {@link ScanListener#onSuccess()} is called. */
- @Test
- public void testRegisterScanListenerSuccess() throws Exception {
- mWifiScanner.registerScanListener(mExecutor, mScanListener);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler).handleMessage(messageArgumentCaptor.capture());
- Message sentMessage = messageArgumentCaptor.getValue();
- assertNotNull(sentMessage);
-
- assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
- Messenger scannerMessenger =
- mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
- Message responseMessage = Message.obtain();
- responseMessage.what = WifiScanner.CMD_OP_SUCCEEDED;
- responseMessage.arg2 = sentMessage.arg2;
- scannerMessenger.send(responseMessage);
- mLooper.dispatchAll();
-
- verify(mExecutor).execute(any());
- verify(mScanListener).onSuccess();
- }
-
- /**
- * Tests that upon registration failed, {@link ScanListener#onFailure(int, String)} is called.
- */
- @Test
- public void testRegisterScanListenerFailed() throws Exception {
- mWifiScanner.registerScanListener(mExecutor, mScanListener);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler).handleMessage(messageArgumentCaptor.capture());
- Message sentMessage = messageArgumentCaptor.getValue();
- assertNotNull(sentMessage);
-
- assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
- Messenger scannerMessenger =
- mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
- {
- Message responseMessage = Message.obtain();
- responseMessage.what = WifiScanner.CMD_OP_FAILED;
- responseMessage.arg2 = sentMessage.arg2;
- responseMessage.obj = new WifiScanner.OperationResult(
- WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED);
- scannerMessenger.send(responseMessage);
- mLooper.dispatchAll();
- }
-
- verify(mExecutor).execute(any());
- verify(mScanListener).onFailure(
- WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED);
-
- // CMD_OP_FAILED should have caused the removal of the listener, verify this
- {
- Message responseMessage = Message.obtain();
- responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
- responseMessage.arg2 = sentMessage.arg2;
- responseMessage.obj = mParcelableScanData;
- scannerMessenger.send(responseMessage);
- mLooper.dispatchAll();
- }
- // execute() called once before, not called again
- verify(mExecutor, times(1)).execute(any());
- // onResults() never triggered
- verify(mScanListener, never()).onResults(any());
- }
-
- /**
- * Tests that when the ScanListener is triggered, {@link ScanListener#onResults(ScanData[])}
- * is called.
- */
- @Test
- public void testRegisterScanListenerReceiveScanResults() throws Exception {
- mWifiScanner.registerScanListener(mExecutor, mScanListener);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler).handleMessage(messageArgumentCaptor.capture());
- Message sentMessage = messageArgumentCaptor.getValue();
- assertNotNull(sentMessage);
-
- assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
- Messenger scannerMessenger =
- mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
- Message responseMessage = Message.obtain();
- responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
- responseMessage.arg2 = sentMessage.arg2;
- responseMessage.obj = mParcelableScanData;
- scannerMessenger.send(responseMessage);
- mLooper.dispatchAll();
-
- verify(mExecutor).execute(any());
- verify(mScanListener).onResults(mScanData);
- }
-
- /**
- * Tests that after unregistering a scan listener, {@link ScanListener#onResults(ScanData[])}
- * is not called.
- */
- @Test
- public void testUnregisterScanListener() throws Exception {
- mWifiScanner.registerScanListener(mExecutor, mScanListener);
- mWifiScanner.unregisterScanListener(mScanListener);
- mLooper.dispatchAll();
-
- assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
- Messenger scannerMessenger =
- mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture());
- Message sentMessage = messageArgumentCaptor.getValue();
- assertNotNull(sentMessage);
-
- Message responseMessage = Message.obtain();
- responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
- responseMessage.obj = mParcelableScanData;
- responseMessage.arg2 = sentMessage.arg2;
- scannerMessenger.send(responseMessage);
- mLooper.dispatchAll();
-
- verify(mExecutor, never()).execute(any());
- verify(mScanListener, never()).onResults(mScanData);
- }
-
- /**
- * Tests isFullBandScan() method with and without DFS check
- */
- @Test
- public void testIsFullBandScan() throws Exception {
- assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_24_GHZ, true));
- assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_5_GHZ, true));
- assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_6_GHZ, true));
- assertFalse(WifiScanner.isFullBandScan(
- WifiScanner.WIFI_BAND_6_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true));
- assertTrue(WifiScanner.isFullBandScan(
- WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true));
- assertFalse(WifiScanner.isFullBandScan(
- WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, false));
- assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, true));
- assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, false));
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiSsidTest.java b/wifi/tests/src/android/net/wifi/WifiSsidTest.java
deleted file mode 100644
index 10a37c0..0000000
--- a/wifi/tests/src/android/net/wifi/WifiSsidTest.java
+++ /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.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiSsid}.
- */
-@SmallTest
-public class WifiSsidTest {
-
- private static final String TEST_SSID = "Test SSID";
- private static final byte[] TEST_SSID_BYTES = TEST_SSID.getBytes(StandardCharsets.US_ASCII);
-
- /**
- * Check that createFromByteArray() works.
- */
- @Test
- public void testCreateFromByteArray() {
- WifiSsid wifiSsid = WifiSsid.createFromByteArray(TEST_SSID_BYTES);
- assertTrue(wifiSsid != null);
- assertEquals(TEST_SSID, wifiSsid.toString());
- }
-
- /**
- * Verify that SSID created from byte array and string with the same content are equal.
- *
- * @throws Exception
- */
- @Test
- public void testEquals() throws Exception {
- WifiSsid fromBytes = WifiSsid.createFromByteArray(TEST_SSID_BYTES);
- WifiSsid fromString = WifiSsid.createFromAsciiEncoded(TEST_SSID);
- assertTrue(fromBytes != null);
- assertTrue(fromString != null);
- assertEquals(fromBytes, fromString);
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java
deleted file mode 100644
index 5184152..0000000
--- a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java
+++ /dev/null
@@ -1,121 +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.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.validateMockitoUsage;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.MockitoAnnotations;
-
-
-/**
- * Unit tests for {@link android.net.wifi.WifiUsabilityStatsEntry}.
- */
-@SmallTest
-public class WifiUsabilityStatsEntryTest {
-
- /**
- * Setup before tests.
- */
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- }
-
- /**
- * Clean up after tests.
- */
- @After
- public void cleanup() {
- validateMockitoUsage();
- }
-
- /**
- * Verify parcel read/write for Wifi usability stats result.
- */
- @Test
- public void verifyStatsResultWriteAndThenRead() throws Exception {
- WifiUsabilityStatsEntry writeResult = createResult();
- WifiUsabilityStatsEntry readResult = parcelWriteRead(writeResult);
- assertWifiUsabilityStatsEntryEquals(writeResult, readResult);
- }
-
- /**
- * Write the provided {@link WifiUsabilityStatsEntry} to a parcel and deserialize it.
- */
- private static WifiUsabilityStatsEntry parcelWriteRead(
- WifiUsabilityStatsEntry writeResult) throws Exception {
- Parcel parcel = Parcel.obtain();
- writeResult.writeToParcel(parcel, 0);
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- return WifiUsabilityStatsEntry.CREATOR.createFromParcel(parcel);
- }
-
- private static WifiUsabilityStatsEntry createResult() {
- return new WifiUsabilityStatsEntry(
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, true
- );
- }
-
- private static void assertWifiUsabilityStatsEntryEquals(
- WifiUsabilityStatsEntry expected,
- WifiUsabilityStatsEntry actual) {
- assertEquals(expected.getTimeStampMillis(), actual.getTimeStampMillis());
- assertEquals(expected.getRssi(), actual.getRssi());
- assertEquals(expected.getLinkSpeedMbps(), actual.getLinkSpeedMbps());
- assertEquals(expected.getTotalTxSuccess(), actual.getTotalTxSuccess());
- assertEquals(expected.getTotalTxRetries(), actual.getTotalTxRetries());
- assertEquals(expected.getTotalTxBad(), actual.getTotalTxBad());
- assertEquals(expected.getTotalRxSuccess(), actual.getTotalRxSuccess());
- assertEquals(expected.getTotalRadioOnTimeMillis(), actual.getTotalRadioOnTimeMillis());
- assertEquals(expected.getTotalRadioTxTimeMillis(), actual.getTotalRadioTxTimeMillis());
- assertEquals(expected.getTotalRadioRxTimeMillis(), actual.getTotalRadioRxTimeMillis());
- assertEquals(expected.getTotalScanTimeMillis(), actual.getTotalScanTimeMillis());
- assertEquals(expected.getTotalNanScanTimeMillis(), actual.getTotalNanScanTimeMillis());
- assertEquals(expected.getTotalBackgroundScanTimeMillis(),
- actual.getTotalBackgroundScanTimeMillis());
- assertEquals(expected.getTotalRoamScanTimeMillis(), actual.getTotalRoamScanTimeMillis());
- assertEquals(expected.getTotalPnoScanTimeMillis(), actual.getTotalPnoScanTimeMillis());
- assertEquals(expected.getTotalHotspot2ScanTimeMillis(),
- actual.getTotalHotspot2ScanTimeMillis());
- assertEquals(expected.getTotalCcaBusyFreqTimeMillis(),
- actual.getTotalCcaBusyFreqTimeMillis());
- assertEquals(expected.getTotalRadioOnFreqTimeMillis(),
- actual.getTotalRadioOnFreqTimeMillis());
- assertEquals(expected.getTotalBeaconRx(), actual.getTotalBeaconRx());
- assertEquals(expected.getProbeStatusSinceLastUpdate(),
- actual.getProbeStatusSinceLastUpdate());
- assertEquals(expected.getProbeElapsedTimeSinceLastUpdateMillis(),
- actual.getProbeElapsedTimeSinceLastUpdateMillis());
- assertEquals(expected.getProbeMcsRateSinceLastUpdate(),
- actual.getProbeMcsRateSinceLastUpdate());
- assertEquals(expected.getRxLinkSpeedMbps(), actual.getRxLinkSpeedMbps());
- assertEquals(expected.getCellularDataNetworkType(), actual.getCellularDataNetworkType());
- assertEquals(expected.getCellularSignalStrengthDbm(),
- actual.getCellularSignalStrengthDbm());
- assertEquals(expected.getCellularSignalStrengthDb(), actual.getCellularSignalStrengthDb());
- assertEquals(expected.isSameRegisteredCell(), actual.isSameRegisteredCell());
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java b/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java
deleted file mode 100644
index 971aa8e..0000000
--- a/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java
+++ /dev/null
@@ -1,324 +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.net.wifi.aware;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ErrorCollector;
-
-import java.nio.BufferOverflowException;
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Unit test harness for TlvBufferUtils class.
- */
-@SmallTest
-public class TlvBufferUtilsTest {
- @Rule
- public ErrorCollector collector = new ErrorCollector();
-
- /*
- * TlvBufferUtils Tests
- */
-
- @Test
- public void testTlvBuild() {
- TlvBufferUtils.TlvConstructor tlv11 = new TlvBufferUtils.TlvConstructor(1, 1);
- tlv11.allocate(15);
- tlv11.putByte(0, (byte) 2);
- tlv11.putByteArray(2, new byte[] {
- 0, 1, 2 });
-
- collector.checkThat("tlv11-correct-construction",
- tlv11.getArray(), equalTo(new byte[]{0, 1, 2, 2, 3, 0, 1, 2}));
-
- TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
- tlv01.allocate(15);
- tlv01.putByte(0, (byte) 2);
- tlv01.putByteArray(2, new byte[] {
- 0, 1, 2 });
-
- collector.checkThat("tlv01-correct-construction",
- tlv01.getArray(), equalTo(new byte[] {1, 2, 3, 0, 1, 2 }));
-
- collector.checkThat("tlv11-valid",
- TlvBufferUtils.isValid(tlv11.getArray(), 1, 1),
- equalTo(true));
- collector.checkThat("tlv01-valid",
- TlvBufferUtils.isValid(tlv01.getArray(), 0, 1),
- equalTo(true));
- }
-
- /**
- * Validate that re-using a TLV by any of the reallocation method resets it completely.
- */
- @Test
- public void testTlvReuse() {
- TlvBufferUtils.TlvConstructor tlv = new TlvBufferUtils.TlvConstructor(1, 1);
-
- tlv.allocate(10);
- tlv.putByte(0, (byte) 2);
- tlv.putByte(1, (byte) 104);
-
- collector.checkThat("initial", tlv.getArray(), equalTo(new byte[]{0, 1, 2, 1, 1, 104}));
-
- tlv.allocate(8);
- tlv.putByte(5, (byte) 7);
- collector.checkThat("re-alloc", tlv.getArray(), equalTo(new byte[]{5, 1, 7}));
- }
-
- /**
- * Verify that can build a valid TLV from a List of byte[].
- */
- @Test
- public void testTlvListOperations() {
- byte[] entry1 = { 1, 2, 3 };
- byte[] entry2 = { 4, 5 };
- byte[] entry3 = new byte[0];
- List<byte[]> data = new ArrayList<>();
- data.add(entry1);
- data.add(entry2);
- data.add(entry3);
- data.add(null); // zero-length should work
-
- TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
- tlv01.allocateAndPut(data);
- byte[] tlvData = tlv01.getArray();
- List<byte[]> parsedList = new TlvBufferUtils.TlvIterable(0, 1, tlvData).toList();
-
- collector.checkThat("tlvData-correct-length", tlvData.length,
- equalTo(entry1.length + 1 + entry2.length + 1 + entry3.length + 1 + 1));
- collector.checkThat("parsedList-correct-length", parsedList.size(), equalTo(4));
- collector.checkThat("parsedList-entry1", parsedList.get(0), equalTo(entry1));
- collector.checkThat("parsedList-entry2", parsedList.get(1), equalTo(entry2));
- collector.checkThat("parsedList-entry3", parsedList.get(2), equalTo(entry3));
- collector.checkThat("parsedList-entry4", parsedList.get(3), equalTo(new byte[0]));
- }
-
- /**
- * Verify that can parse a (correctly formatted) byte array to a list.
- */
- @Test
- public void testTlvParseToList() {
- byte[] validTlv01 = { 0, 1, 55, 2, 33, 66, 0 };
-
- List<byte[]> parsedList = new TlvBufferUtils.TlvIterable(0, 1, validTlv01).toList();
-
- collector.checkThat("parsedList-entry1", parsedList.get(0), equalTo(new byte[0]));
- collector.checkThat("parsedList-entry2", parsedList.get(1), equalTo(new byte[] { 55 }));
- collector.checkThat("parsedList-entry3", parsedList.get(2), equalTo(new byte[] { 33, 66 }));
- collector.checkThat("parsedList-entry4", parsedList.get(3), equalTo(new byte[0]));
- }
-
- /**
- * Verify that an exception is thrown when trying to parse an invalid array.
- */
- @Test(expected = BufferOverflowException.class)
- public void testTlvParseToListError() {
- byte[] invalidTlv01 = { 0, 1, 55, 2, 55, 66, 3 }; // bad data
-
- List<byte[]> data = new TlvBufferUtils.TlvIterable(0, 1, invalidTlv01).toList();
- }
-
- /**
- * Validate the API which places raw bytes into the TLV (without a TL structure).
- */
- @Test
- public void testRawPuts() {
- TlvBufferUtils.TlvConstructor tlv = new TlvBufferUtils.TlvConstructor(1, 1);
-
- tlv.allocate(10);
- tlv.putByte(0, (byte) 2);
- tlv.putRawByte((byte) 55);
- tlv.putByte(1, (byte) 104);
- tlv.putRawByteArray(new byte[]{66, 77});
-
- collector.checkThat("data", tlv.getArray(),
- equalTo(new byte[]{0, 1, 2, 55, 1, 1, 104, 66, 77}));
- }
-
- @Test
- public void testTlvIterate() {
- final String ascii = "ABC";
- final String nonAscii = "何かもっと複雑な";
-
- TlvBufferUtils.TlvConstructor tlv22 = new TlvBufferUtils.TlvConstructor(2, 2);
- tlv22.allocate(18);
- tlv22.putInt(0, 2);
- tlv22.putShort(2, (short) 3);
- tlv22.putZeroLengthElement(55);
-
- TlvBufferUtils.TlvIterable tlv22It = new TlvBufferUtils.TlvIterable(2, 2, tlv22.getArray());
- int count = 0;
- for (TlvBufferUtils.TlvElement tlv : tlv22It) {
- if (count == 0) {
- collector.checkThat("tlv22-correct-iteration-mType", tlv.type, equalTo(0));
- collector.checkThat("tlv22-correct-iteration-mLength", tlv.length, equalTo(4));
- collector.checkThat("tlv22-correct-iteration-DATA", tlv.getInt(), equalTo(2));
- } else if (count == 1) {
- collector.checkThat("tlv22-correct-iteration-mType", tlv.type, equalTo(2));
- collector.checkThat("tlv22-correct-iteration-mLength", tlv.length, equalTo(2));
- collector.checkThat("tlv22-correct-iteration-DATA", (int) tlv.getShort(),
- equalTo(3));
- } else if (count == 2) {
- collector.checkThat("tlv22-correct-iteration-mType", tlv.type, equalTo(55));
- collector.checkThat("tlv22-correct-iteration-mLength", tlv.length, equalTo(0));
- } else {
- collector.checkThat("Invalid number of iterations in loop - tlv22", true,
- equalTo(false));
- }
- ++count;
- }
- if (count != 3) {
- collector.checkThat("Invalid number of iterations outside loop - tlv22", true,
- equalTo(false));
- }
-
- TlvBufferUtils.TlvConstructor tlv02 = new TlvBufferUtils.TlvConstructor(0, 2);
- tlv02.allocate(100);
- tlv02.putByte(0, (byte) 2);
- tlv02.putString(0, ascii);
- tlv02.putString(0, nonAscii);
- tlv02.putByteArray(0, new byte[]{5, 4, 3, 2, 1});
-
- TlvBufferUtils.TlvIterable tlv02It = new TlvBufferUtils.TlvIterable(0, 2, tlv02.getArray());
- count = 0;
- for (TlvBufferUtils.TlvElement tlv : tlv02It) {
- if (count == 0) {
- collector.checkThat("tlv02-correct-iteration-mLength", tlv.length, equalTo(1));
- collector.checkThat("tlv02-correct-iteration-DATA", (int) tlv.getByte(),
- equalTo(2));
- } else if (count == 1) {
- collector.checkThat("tlv02-correct-iteration-mLength", tlv.length,
- equalTo(ascii.length()));
- collector.checkThat("tlv02-correct-iteration-DATA", tlv.getString().equals(ascii),
- equalTo(true));
- } else if (count == 2) {
- collector.checkThat("tlv02-correct-iteration-mLength", tlv.length,
- equalTo(nonAscii.getBytes().length));
- collector.checkThat("tlv02-correct-iteration-DATA",
- tlv.getString().equals(nonAscii), equalTo(true));
- } else if (count == 3) {
- collector.checkThat("tlv02-correct-iteration-mLength", tlv.length,
- equalTo(5));
- collector.checkThat("tlv02-correct-iteration-DATA", tlv.getRawData(),
- equalTo(new byte[]{5, 4, 3, 2, 1}));
- } else {
- collector.checkThat("Invalid number of iterations in loop - tlv02", true,
- equalTo(false));
- }
- ++count;
- }
- collector.checkThat("Invalid number of iterations outside loop - tlv02", count,
- equalTo(4));
-
- collector.checkThat("tlv22-valid",
- TlvBufferUtils.isValid(tlv22.getArray(), 2, 2),
- equalTo(true));
- collector.checkThat("tlv02-valid",
- TlvBufferUtils.isValid(tlv02.getArray(), 0, 2),
- equalTo(true));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testTlvInvalidSizeT1L0() {
- TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, 0);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testTlvInvalidSizeTm3L2() {
- TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(-3, 2);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testTlvInvalidSizeT1Lm2() {
- TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, -2);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testTlvInvalidSizeT1L3() {
- TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, 3);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testTlvInvalidSizeT3L1() {
- TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(3, 1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testTlvItInvalidSizeT1L0() {
- final byte[] dummy = {
- 0, 1, 2 };
- final int dummyLength = 3;
- TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 0, dummy);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testTlvItInvalidSizeTm3L2() {
- final byte[] dummy = {
- 0, 1, 2 };
- final int dummyLength = 3;
- TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(-3, 2, dummy);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testTlvItInvalidSizeT1Lm2() {
- final byte[] dummy = {
- 0, 1, 2 };
- final int dummyLength = 3;
- TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, -2, dummy);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testTlvItInvalidSizeT1L3() {
- final byte[] dummy = {
- 0, 1, 2 };
- final int dummyLength = 3;
- TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 3, dummy);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testTlvItInvalidSizeT3L1() {
- final byte[] dummy = {
- 0, 1, 2 };
- final int dummyLength = 3;
- TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(3, 1, dummy);
- }
-
- /**
- * Validate that a malformed byte array fails the TLV validity test.
- */
- @Test
- public void testTlvInvalidByteArray() {
- TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
- tlv01.allocate(15);
- tlv01.putByte(0, (byte) 2);
- tlv01.putByteArray(2, new byte[]{0, 1, 2});
-
- byte[] array = tlv01.getArray();
- array[0] = 10;
-
- collector.checkThat("tlv01-invalid",
- TlvBufferUtils.isValid(array, 0, 1), equalTo(false));
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java
deleted file mode 100644
index f2961db..0000000
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java
+++ /dev/null
@@ -1,176 +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.net.wifi.aware;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ErrorCollector;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Unit test harness for WifiAwareAgentNetworkSpecifier class.
- */
-@SmallTest
-public class WifiAwareAgentNetworkSpecifierTest {
- @Rule
- public ErrorCollector collector = new ErrorCollector();
-
- @Test
- public void testParcel() {
- final int numNs = 10;
-
- Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
- for (int i = 0; i < numNs; ++i) {
- nsSet.add(getDummyNetworkSpecifier(10 + i));
- }
- WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(
- nsSet.toArray(new WifiAwareNetworkSpecifier[numNs]));
-
- Parcel parcelW = Parcel.obtain();
- dut.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiAwareAgentNetworkSpecifier rereadDut =
- WifiAwareAgentNetworkSpecifier.CREATOR.createFromParcel(parcelR);
-
- assertEquals(dut, rereadDut);
- assertEquals(dut.hashCode(), rereadDut.hashCode());
-
- // Ensure that individual network specifiers are satisfied by both the original & marshaled
- // |WifiAwareNetworkAgentSpecifier instances.
- for (WifiAwareNetworkSpecifier ns : nsSet) {
- assertTrue(dut.satisfiesAwareNetworkSpecifier(ns));
- assertTrue(rereadDut.satisfiesAwareNetworkSpecifier(ns));
- }
- }
-
- /**
- * Validate that an empty agent network specifier doesn't match any base network specifier.
- */
- @Test
- public void testEmptyDoesntMatchAnything() {
- WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier();
- WifiAwareNetworkSpecifier ns = getDummyNetworkSpecifier(6);
- collector.checkThat("No match expected", ns.canBeSatisfiedBy(dut), equalTo(false));
- }
-
- /**
- * Validate that an agent network specifier constructed with a single entry matches that entry,
- * and only that entry.
- */
- @Test
- public void testSingleMatch() {
- WifiAwareNetworkSpecifier nsThis = getDummyNetworkSpecifier(6);
- WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(nsThis);
- WifiAwareNetworkSpecifier nsOther = getDummyNetworkSpecifier(8);
- collector.checkThat("Match expected", nsThis.canBeSatisfiedBy(dut), equalTo(true));
- collector.checkThat("No match expected", nsOther.canBeSatisfiedBy(dut), equalTo(false));
- }
-
- /**
- * Validate that an agent network specifier constructed with multiple entries matches all those
- * entries - but none other.
- */
- @Test
- public void testMultipleMatchesAllMembers() {
- final int numNs = 10;
-
- Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
- for (int i = 0; i < numNs; ++i) {
- nsSet.add(getDummyNetworkSpecifier(10 + i));
- }
-
- WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(
- nsSet.toArray(new WifiAwareNetworkSpecifier[numNs]));
- WifiAwareNetworkSpecifier nsOther = getDummyNetworkSpecifier(10000);
-
- for (WifiAwareNetworkSpecifier nsThis: nsSet) {
- collector.checkThat("Match expected", nsThis.canBeSatisfiedBy(dut), equalTo(true));
- }
- collector.checkThat("No match expected", nsOther.canBeSatisfiedBy(dut), equalTo(false));
- }
-
- /**
- * Validate that agent network specifier matches against a super-set.
- */
- @Test
- public void testMatchSuperset() {
- final int numNs = 10;
-
- Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
- for (int i = 0; i < numNs; ++i) {
- nsSet.add(getDummyNetworkSpecifier(10 + i));
- }
-
- WifiAwareAgentNetworkSpecifier oldNs = new WifiAwareAgentNetworkSpecifier(
- nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
-
- nsSet.add(getDummyNetworkSpecifier(100 + numNs));
- WifiAwareAgentNetworkSpecifier newNs = new WifiAwareAgentNetworkSpecifier(
- nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
-
- collector.checkThat("Match expected", oldNs.canBeSatisfiedBy(newNs), equalTo(true));
- }
-
- /**
- * Validate that agent network specifier does not match against a sub-set.
- */
- @Test
- public void testNoMatchSubset() {
- final int numNs = 10;
-
- Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
- for (int i = 0; i < numNs; ++i) {
- nsSet.add(getDummyNetworkSpecifier(10 + i));
- }
-
- WifiAwareAgentNetworkSpecifier newNs = new WifiAwareAgentNetworkSpecifier(
- nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
-
- nsSet.add(getDummyNetworkSpecifier(100 + numNs));
- WifiAwareAgentNetworkSpecifier oldNs = new WifiAwareAgentNetworkSpecifier(
- nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
-
- collector.checkThat("Match unexpected", oldNs.canBeSatisfiedBy(newNs), equalTo(false));
- }
-
- // utilities
-
- /**
- * Returns a WifiAwareNetworkSpecifier with dummy (but valid) entries. Each can be
- * differentiated (made unique) by specifying a different client ID.
- */
- WifiAwareNetworkSpecifier getDummyNetworkSpecifier(int clientId) {
- return new WifiAwareNetworkSpecifier(WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB,
- WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, clientId, 0, 0, new byte[6],
- null, null, 10, 5);
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
deleted file mode 100644
index c5f9804..0000000
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ /dev/null
@@ -1,1639 +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.net.wifi.aware;
-
-import static android.net.wifi.aware.WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.net.MacAddress;
-import android.net.wifi.RttManager;
-import android.net.wifi.util.HexEncoding;
-import android.os.Build;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ErrorCollector;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.Inet6Address;
-import java.net.UnknownHostException;
-import java.util.List;
-
-/**
- * Unit test harness for WifiAwareManager class.
- */
-@SmallTest
-public class WifiAwareManagerTest {
- private WifiAwareManager mDut;
- private TestLooper mMockLooper;
- private Handler mMockLooperHandler;
-
- @Rule
- public ErrorCollector collector = new ErrorCollector();
-
- @Mock
- public Context mockContext;
-
- @Mock
- public AttachCallback mockCallback;
-
- @Mock
- public DiscoverySessionCallback mockSessionCallback;
-
- @Mock
- public IWifiAwareManager mockAwareService;
-
- @Mock
- public PublishDiscoverySession mockPublishSession;
-
- @Mock
- public SubscribeDiscoverySession mockSubscribeSession;
-
- @Mock
- public RttManager.RttListener mockRttListener;
-
- @Mock
- public PackageManager mockPackageManager;
-
- @Mock
- public ApplicationInfo mockApplicationInfo;
-
- private static final int AWARE_STATUS_ERROR = -1;
-
- private static final byte[] PMK_VALID = "01234567890123456789012345678901".getBytes();
- private static final byte[] PMK_INVALID = "012".getBytes();
-
- private static final String PASSPHRASE_VALID = "SomeLongEnoughPassphrase";
- private static final String PASSPHRASE_TOO_SHORT = "012";
- private static final String PASSPHRASE_TOO_LONG =
- "0123456789012345678901234567890123456789012345678901234567890123456789";
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
- when(mockPackageManager.getApplicationInfo(anyString(), anyInt())).thenReturn(
- mockApplicationInfo);
- when(mockContext.getOpPackageName()).thenReturn("XXX");
- when(mockContext.getPackageManager()).thenReturn(mockPackageManager);
-
- mDut = new WifiAwareManager(mockContext, mockAwareService);
- mMockLooper = new TestLooper();
- mMockLooperHandler = new Handler(mMockLooper.getLooper());
- }
-
- /*
- * Straight pass-through tests
- */
-
- /**
- * Validate pass-through of isUsageEnabled() API.
- */
- @Test
- public void testIsUsageEnable() throws Exception {
- mDut.isAvailable();
-
- verify(mockAwareService).isUsageEnabled();
- }
-
- /**
- * Validate pass-through of getCharacteristics() API.
- */
- @Test
- public void testGetCharacteristics() throws Exception {
- mDut.getCharacteristics();
-
- verify(mockAwareService).getCharacteristics();
- }
-
- /*
- * WifiAwareEventCallbackProxy Tests
- */
-
- /**
- * Validate the successful connect flow: (1) connect + success (2) publish, (3) disconnect
- * (4) try publishing on old session (5) connect again
- */
- @Test
- public void testConnectFlow() throws Exception {
- final int clientId = 4565;
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IBinder> binder = ArgumentCaptor.forClass(IBinder.class);
-
- // (1) connect + success
- mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(),
- clientProxyCallback.capture(), isNull(), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
- WifiAwareSession session = sessionCaptor.getValue();
-
- // (2) publish - should succeed
- PublishConfig publishConfig = new PublishConfig.Builder().build();
- session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
- any());
-
- // (3) disconnect
- session.close();
- inOrder.verify(mockAwareService).disconnect(eq(clientId), eq(binder.getValue()));
-
- // (4) try publishing again - fails silently
- session.publish(new PublishConfig.Builder().build(), mockSessionCallback,
- mMockLooperHandler);
-
- // (5) connect
- mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), any(), isNull(),
- eq(false));
-
- verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
- }
-
- /**
- * Validate the failed connect flow: (1) connect + failure, (2) connect + success (3) subscribe
- */
- @Test
- public void testConnectFailure() throws Exception {
- final int clientId = 4565;
- final int reason = AWARE_STATUS_ERROR;
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService);
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
-
- // (1) connect + failure
- mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- isNull(), eq(false));
- clientProxyCallback.getValue().onConnectFail(reason);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttachFailed();
-
- // (2) connect + success
- mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- isNull(), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
- WifiAwareSession session = sessionCaptor.getValue();
-
- // (4) subscribe: should succeed
- SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
- session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig),
- any());
-
- verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
- }
-
- /**
- * Validate that can call connect to create multiple sessions: (1) connect
- * + success, (2) try connect again
- */
- @Test
- public void testInvalidConnectSequence() throws Exception {
- final int clientId = 4565;
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
-
- // (1) connect + success
- mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- isNull(), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(any());
-
- // (2) connect + success
- mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- isNull(), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId + 1);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(any());
-
- verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
- }
-
- /*
- * WifiAwareDiscoverySessionCallbackProxy Tests
- */
-
- /**
- * Validate the publish flow: (0) connect + success, (1) publish, (2)
- * success creates session, (3) pass through everything, (4) update publish
- * through session, (5) terminate locally, (6) try another command -
- * ignored.
- */
- @Test
- public void testPublishFlow() throws Exception {
- final int clientId = 4565;
- final int sessionId = 123;
- final ConfigRequest configRequest = new ConfigRequest.Builder().build();
- final PublishConfig publishConfig = new PublishConfig.Builder().build();
- final PeerHandle peerHandle = new PeerHandle(873);
- final String string1 = "hey from here...";
- final byte[] matchFilter = { 1, 12, 2, 31, 32 };
- final int messageId = 2123;
- final int reason = AWARE_STATUS_ERROR;
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession);
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
- ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
- .forClass(PublishDiscoverySession.class);
- ArgumentCaptor<PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(PeerHandle.class);
- ArgumentCaptor<List<byte[]>> matchFilterCaptor = ArgumentCaptor.forClass(
- (Class) List.class);
-
- // (0) connect + success
- mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- eq(configRequest), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
- WifiAwareSession session = sessionCaptor.getValue();
-
- // (1) publish
- session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
- sessionProxyCallback.capture());
-
- // (2) publish session created
- sessionProxyCallback.getValue().onSessionStarted(sessionId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
-
- // (3) ...
- publishSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
- sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter);
- sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
- sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
- sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
- mMockLooper.dispatchAll();
-
- inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId),
- eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0));
- inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(),
- eq(string1.getBytes()),
- matchFilterCaptor.capture());
-
- // note: need to capture/compare elements since the Mockito eq() is a shallow comparator
- List<byte[]> parsedMatchFilter = new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList();
- collector.checkThat("match-filter-size", parsedMatchFilter.size(),
- equalTo(matchFilterCaptor.getValue().size()));
- collector.checkThat("match-filter-entry0", parsedMatchFilter.get(0),
- equalTo(matchFilterCaptor.getValue().get(0)));
- collector.checkThat("match-filter-entry1", parsedMatchFilter.get(1),
- equalTo(matchFilterCaptor.getValue().get(1)));
-
- assertEquals(peerIdCaptor.getValue().peerId, peerHandle.peerId);
- inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
- eq(string1.getBytes()));
- assertEquals(peerIdCaptor.getValue().peerId, peerHandle.peerId);
- inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId));
- inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId));
-
- // (4) update publish
- publishSession.getValue().updatePublish(publishConfig);
- sessionProxyCallback.getValue().onSessionConfigFail(reason);
- mMockLooper.dispatchAll();
- inOrder.verify(mockAwareService).updatePublish(eq(clientId), eq(sessionId),
- eq(publishConfig));
- inOrder.verify(mockSessionCallback).onSessionConfigFailed();
-
- // (5) terminate
- publishSession.getValue().close();
- mMockLooper.dispatchAll();
- inOrder.verify(mockAwareService).terminateSession(clientId, sessionId);
-
- // (6) try an update (nothing)
- publishSession.getValue().updatePublish(publishConfig);
- mMockLooper.dispatchAll();
-
- verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession);
- }
-
- /**
- * Validate race condition of session terminate and session action: (1)
- * connect, (2) publish success + terminate, (3) update.
- */
- @Test
- public void testPublishRemoteTerminate() throws Exception {
- final int clientId = 4565;
- final int sessionId = 123;
- final ConfigRequest configRequest = new ConfigRequest.Builder().build();
- final PublishConfig publishConfig = new PublishConfig.Builder().build();
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession);
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
- ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
- .forClass(PublishDiscoverySession.class);
-
- // (1) connect successfully
- mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- eq(configRequest), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
- WifiAwareSession session = sessionCaptor.getValue();
-
- // (2) publish: successfully - then terminated
- session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
- sessionProxyCallback.capture());
- sessionProxyCallback.getValue().onSessionStarted(sessionId);
- sessionProxyCallback.getValue().onSessionTerminated(0);
- mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
- inOrder.verify(mockSessionCallback).onSessionTerminated();
-
- // (3) failure when trying to update: NOP
- publishSession.getValue().updatePublish(publishConfig);
-
- verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession);
- }
-
- /**
- * Validate the subscribe flow: (0) connect + success, (1) subscribe, (2)
- * success creates session, (3) pass through everything, (4) update
- * subscribe through session, (5) terminate locally, (6) try another command
- * - ignored.
- */
- @Test
- public void testSubscribeFlow() throws Exception {
- final int clientId = 4565;
- final int sessionId = 123;
- final ConfigRequest configRequest = new ConfigRequest.Builder().build();
- final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
- final PeerHandle peerHandle = new PeerHandle(873);
- final String string1 = "hey from here...";
- final byte[] matchFilter = { 1, 12, 3, 31, 32 }; // bad data!
- final int messageId = 2123;
- final int reason = AWARE_STATUS_ERROR;
- final int distanceMm = 100;
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
- mockSubscribeSession);
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
- ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<SubscribeDiscoverySession> subscribeSession = ArgumentCaptor
- .forClass(SubscribeDiscoverySession.class);
- ArgumentCaptor<PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(PeerHandle.class);
-
- // (0) connect + success
- mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- eq(configRequest), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
- WifiAwareSession session = sessionCaptor.getValue();
-
- // (1) subscribe
- session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig),
- sessionProxyCallback.capture());
-
- // (2) subscribe session created
- sessionProxyCallback.getValue().onSessionStarted(sessionId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
-
- // (3) ...
- subscribeSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
- sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter);
- sessionProxyCallback.getValue().onMatchWithDistance(peerHandle.peerId, string1.getBytes(),
- matchFilter, distanceMm);
- sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
- sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
- sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
- mMockLooper.dispatchAll();
-
- inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId),
- eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0));
- inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(),
- eq(string1.getBytes()), isNull());
- inOrder.verify(mockSessionCallback).onServiceDiscoveredWithinRange(peerIdCaptor.capture(),
- eq(string1.getBytes()), isNull(), eq(distanceMm));
- assertEquals((peerIdCaptor.getValue()).peerId, peerHandle.peerId);
- inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
- eq(string1.getBytes()));
- assertEquals((peerIdCaptor.getValue()).peerId, peerHandle.peerId);
- inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId));
- inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId));
-
- // (4) update subscribe
- subscribeSession.getValue().updateSubscribe(subscribeConfig);
- sessionProxyCallback.getValue().onSessionConfigFail(reason);
- mMockLooper.dispatchAll();
- inOrder.verify(mockAwareService).updateSubscribe(eq(clientId), eq(sessionId),
- eq(subscribeConfig));
- inOrder.verify(mockSessionCallback).onSessionConfigFailed();
-
- // (5) terminate
- subscribeSession.getValue().close();
- mMockLooper.dispatchAll();
- inOrder.verify(mockAwareService).terminateSession(clientId, sessionId);
-
- // (6) try an update (nothing)
- subscribeSession.getValue().updateSubscribe(subscribeConfig);
- mMockLooper.dispatchAll();
-
- verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
- mockSubscribeSession);
- }
-
- /**
- * Validate race condition of session terminate and session action: (1)
- * connect, (2) subscribe success + terminate, (3) update.
- */
- @Test
- public void testSubscribeRemoteTerminate() throws Exception {
- final int clientId = 4565;
- final int sessionId = 123;
- final ConfigRequest configRequest = new ConfigRequest.Builder().build();
- final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
- mockSubscribeSession);
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
- ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<SubscribeDiscoverySession> subscribeSession = ArgumentCaptor
- .forClass(SubscribeDiscoverySession.class);
-
- // (1) connect successfully
- mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- eq(configRequest), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
- WifiAwareSession session = sessionCaptor.getValue();
-
- // (2) subscribe: successfully - then terminated
- session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig),
- sessionProxyCallback.capture());
- sessionProxyCallback.getValue().onSessionStarted(sessionId);
- sessionProxyCallback.getValue().onSessionTerminated(0);
- mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
- inOrder.verify(mockSessionCallback).onSessionTerminated();
-
- // (3) failure when trying to update: NOP
- subscribeSession.getValue().updateSubscribe(subscribeConfig);
-
- verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
- mockSubscribeSession);
- }
-
- /*
- * ConfigRequest Tests
- */
-
- @Test
- public void testConfigRequestBuilderDefaults() {
- ConfigRequest configRequest = new ConfigRequest.Builder().build();
-
- collector.checkThat("mClusterHigh", ConfigRequest.CLUSTER_ID_MAX,
- equalTo(configRequest.mClusterHigh));
- collector.checkThat("mClusterLow", ConfigRequest.CLUSTER_ID_MIN,
- equalTo(configRequest.mClusterLow));
- collector.checkThat("mMasterPreference", 0,
- equalTo(configRequest.mMasterPreference));
- collector.checkThat("mSupport5gBand", true, equalTo(configRequest.mSupport5gBand));
- collector.checkThat("mSupport6gBand", false, equalTo(configRequest.mSupport6gBand));
- collector.checkThat("mDiscoveryWindowInterval.length", 3,
- equalTo(configRequest.mDiscoveryWindowInterval.length));
- collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
- equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]));
- collector.checkThat("mDiscoveryWindowInterval[5Hz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
- equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]));
- collector.checkThat("mDiscoveryWindowInterval[6Hz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
- equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ]));
- }
-
- @Test
- public void testConfigRequestBuilder() {
- final int clusterHigh = 100;
- final int clusterLow = 5;
- final int masterPreference = 55;
- final boolean supportBand5g = true;
- final boolean supportBand6g = true;
- final int dwWindow5GHz = 3;
- final int dwWindow6GHz = 4;
-
- ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
- .setClusterLow(clusterLow).setMasterPreference(masterPreference)
- .setSupport5gBand(supportBand5g)
- .setSupport6gBand(supportBand6g)
- .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz)
- .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz)
- .build();
-
- collector.checkThat("mClusterHigh", clusterHigh, equalTo(configRequest.mClusterHigh));
- collector.checkThat("mClusterLow", clusterLow, equalTo(configRequest.mClusterLow));
- collector.checkThat("mMasterPreference", masterPreference,
- equalTo(configRequest.mMasterPreference));
- collector.checkThat("mSupport5gBand", supportBand5g, equalTo(configRequest.mSupport5gBand));
- collector.checkThat("mSupport6gBand", supportBand6g, equalTo(configRequest.mSupport6gBand));
- collector.checkThat("mDiscoveryWindowInterval.length", 3,
- equalTo(configRequest.mDiscoveryWindowInterval.length));
- collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
- equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]));
- collector.checkThat("mDiscoveryWindowInterval[5GHz]", dwWindow5GHz,
- equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]));
- collector.checkThat("mDiscoveryWindowInterval[6GHz]", dwWindow6GHz,
- equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ]));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderMasterPrefNegative() {
- ConfigRequest.Builder builder = new ConfigRequest.Builder();
- builder.setMasterPreference(-1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderMasterPrefReserved1() {
- new ConfigRequest.Builder().setMasterPreference(1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderMasterPrefReserved255() {
- new ConfigRequest.Builder().setMasterPreference(255);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderMasterPrefTooLarge() {
- new ConfigRequest.Builder().setMasterPreference(256);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderClusterLowNegative() {
- new ConfigRequest.Builder().setClusterLow(-1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderClusterHighNegative() {
- new ConfigRequest.Builder().setClusterHigh(-1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderClusterLowAboveMax() {
- new ConfigRequest.Builder().setClusterLow(ConfigRequest.CLUSTER_ID_MAX + 1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderClusterHighAboveMax() {
- new ConfigRequest.Builder().setClusterHigh(ConfigRequest.CLUSTER_ID_MAX + 1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderClusterLowLargerThanHigh() {
- new ConfigRequest.Builder().setClusterLow(100).setClusterHigh(5).build();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderDwIntervalInvalidBand() {
- new ConfigRequest.Builder().setDiscoveryWindowInterval(5, 1).build();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderDwIntervalInvalidValueZero() {
- new ConfigRequest.Builder().setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ,
- 0).build();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderDwIntervalInvalidValueLarge() {
- new ConfigRequest.Builder().setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ,
- 6).build();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConfigRequestBuilderDwIntervalInvalidValueLargeValidate() {
- ConfigRequest cr = new ConfigRequest.Builder().build();
- cr.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ] = 6;
- cr.validate();
- }
-
- @Test
- public void testConfigRequestParcel() {
- final int clusterHigh = 189;
- final int clusterLow = 25;
- final int masterPreference = 177;
- final boolean supportBand5g = true;
- final boolean supportBand6g = false;
- final int dwWindow24GHz = 1;
- final int dwWindow5GHz = 5;
- final int dwWindow6GHz = 4;
-
- ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
- .setClusterLow(clusterLow).setMasterPreference(masterPreference)
- .setSupport5gBand(supportBand5g)
- .setSupport6gBand(supportBand6g)
- .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwWindow24GHz)
- .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz)
- .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz)
- .build();
-
- Parcel parcelW = Parcel.obtain();
- configRequest.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- ConfigRequest rereadConfigRequest = ConfigRequest.CREATOR.createFromParcel(parcelR);
-
- assertEquals(configRequest, rereadConfigRequest);
- assertEquals(configRequest.hashCode(), rereadConfigRequest.hashCode());
- }
-
- /*
- * SubscribeConfig Tests
- */
-
- @Test
- public void testSubscribeConfigBuilderDefaults() {
- SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
-
- collector.checkThat("mServiceName", subscribeConfig.mServiceName, equalTo(null));
- collector.checkThat("mServiceSpecificInfo", subscribeConfig.mServiceSpecificInfo,
- equalTo(null));
- collector.checkThat("mMatchFilter", subscribeConfig.mMatchFilter, equalTo(null));
- collector.checkThat("mSubscribeType", subscribeConfig.mSubscribeType,
- equalTo(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE));
- collector.checkThat("mTtlSec", subscribeConfig.mTtlSec, equalTo(0));
- collector.checkThat("mEnableTerminateNotification",
- subscribeConfig.mEnableTerminateNotification, equalTo(true));
- collector.checkThat("mMinDistanceCmSet", subscribeConfig.mMinDistanceMmSet, equalTo(false));
- collector.checkThat("mMinDistanceMm", subscribeConfig.mMinDistanceMm, equalTo(0));
- collector.checkThat("mMaxDistanceMmSet", subscribeConfig.mMaxDistanceMmSet, equalTo(false));
- collector.checkThat("mMaxDistanceMm", subscribeConfig.mMaxDistanceMm, equalTo(0));
- }
-
- @Test
- public void testSubscribeConfigBuilder() {
- final String serviceName = "some_service_or_other";
- final String serviceSpecificInfo = "long arbitrary string with some info";
- final byte[] matchFilter = { 1, 16, 1, 22 };
- final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
- final int subscribeTtl = 15;
- final boolean enableTerminateNotification = false;
- final int minDistance = 10;
- final int maxDistance = 50;
-
- SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
- new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
- .setSubscribeType(subscribeType)
- .setTtlSec(subscribeTtl)
- .setTerminateNotificationEnabled(enableTerminateNotification)
- .setMinDistanceMm(minDistance)
- .setMaxDistanceMm(maxDistance).build();
-
- collector.checkThat("mServiceName", serviceName.getBytes(),
- equalTo(subscribeConfig.mServiceName));
- collector.checkThat("mServiceSpecificInfo",
- serviceSpecificInfo.getBytes(), equalTo(subscribeConfig.mServiceSpecificInfo));
- collector.checkThat("mMatchFilter", matchFilter, equalTo(subscribeConfig.mMatchFilter));
- collector.checkThat("mSubscribeType", subscribeType,
- equalTo(subscribeConfig.mSubscribeType));
- collector.checkThat("mTtlSec", subscribeTtl, equalTo(subscribeConfig.mTtlSec));
- collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
- equalTo(subscribeConfig.mEnableTerminateNotification));
- collector.checkThat("mMinDistanceMmSet", true, equalTo(subscribeConfig.mMinDistanceMmSet));
- collector.checkThat("mMinDistanceMm", minDistance, equalTo(subscribeConfig.mMinDistanceMm));
- collector.checkThat("mMaxDistanceMmSet", true, equalTo(subscribeConfig.mMaxDistanceMmSet));
- collector.checkThat("mMaxDistanceMm", maxDistance, equalTo(subscribeConfig.mMaxDistanceMm));
- }
-
- @Test
- public void testSubscribeConfigParcel() {
- final String serviceName = "some_service_or_other";
- final String serviceSpecificInfo = "long arbitrary string with some info";
- final byte[] matchFilter = { 1, 16, 1, 22 };
- final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
- final int subscribeTtl = 15;
- final boolean enableTerminateNotification = true;
- final int minDistance = 10;
- final int maxDistance = 50;
-
- SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
- new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
- .setSubscribeType(subscribeType)
- .setTtlSec(subscribeTtl)
- .setTerminateNotificationEnabled(enableTerminateNotification)
- .setMinDistanceMm(minDistance)
- .setMaxDistanceMm(maxDistance).build();
-
- Parcel parcelW = Parcel.obtain();
- subscribeConfig.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- SubscribeConfig rereadSubscribeConfig = SubscribeConfig.CREATOR.createFromParcel(parcelR);
-
- assertEquals(subscribeConfig, rereadSubscribeConfig);
- assertEquals(subscribeConfig.hashCode(), rereadSubscribeConfig.hashCode());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSubscribeConfigBuilderBadSubscribeType() {
- new SubscribeConfig.Builder().setSubscribeType(10);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSubscribeConfigBuilderNegativeTtl() {
- new SubscribeConfig.Builder().setTtlSec(-100);
- }
-
- /*
- * PublishConfig Tests
- */
-
- @Test
- public void testPublishConfigBuilderDefaults() {
- PublishConfig publishConfig = new PublishConfig.Builder().build();
-
- collector.checkThat("mServiceName", publishConfig.mServiceName, equalTo(null));
- collector.checkThat("mServiceSpecificInfo", publishConfig.mServiceSpecificInfo,
- equalTo(null));
- collector.checkThat("mMatchFilter", publishConfig.mMatchFilter, equalTo(null));
- collector.checkThat("mPublishType", publishConfig.mPublishType,
- equalTo(PublishConfig.PUBLISH_TYPE_UNSOLICITED));
- collector.checkThat("mTtlSec", publishConfig.mTtlSec, equalTo(0));
- collector.checkThat("mEnableTerminateNotification",
- publishConfig.mEnableTerminateNotification, equalTo(true));
- collector.checkThat("mEnableRanging", publishConfig.mEnableRanging, equalTo(false));
- }
-
- @Test
- public void testPublishConfigBuilder() {
- final String serviceName = "some_service_or_other";
- final String serviceSpecificInfo = "long arbitrary string with some info";
- final byte[] matchFilter = { 1, 16, 1, 22 };
- final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
- final int publishTtl = 15;
- final boolean enableTerminateNotification = false;
- final boolean enableRanging = true;
-
- PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
- new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
- .setPublishType(publishType)
- .setTtlSec(publishTtl)
- .setTerminateNotificationEnabled(enableTerminateNotification)
- .setRangingEnabled(enableRanging).build();
-
- collector.checkThat("mServiceName", serviceName.getBytes(),
- equalTo(publishConfig.mServiceName));
- collector.checkThat("mServiceSpecificInfo",
- serviceSpecificInfo.getBytes(), equalTo(publishConfig.mServiceSpecificInfo));
- collector.checkThat("mMatchFilter", matchFilter, equalTo(publishConfig.mMatchFilter));
- collector.checkThat("mPublishType", publishType, equalTo(publishConfig.mPublishType));
- collector.checkThat("mTtlSec", publishTtl, equalTo(publishConfig.mTtlSec));
- collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
- equalTo(publishConfig.mEnableTerminateNotification));
- collector.checkThat("mEnableRanging", enableRanging, equalTo(publishConfig.mEnableRanging));
- }
-
- @Test
- public void testPublishConfigParcel() {
- final String serviceName = "some_service_or_other";
- final String serviceSpecificInfo = "long arbitrary string with some info";
- final byte[] matchFilter = { 1, 16, 1, 22 };
- final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
- final int publishTtl = 15;
- final boolean enableTerminateNotification = false;
- final boolean enableRanging = true;
-
- PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
- new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
- .setPublishType(publishType)
- .setTtlSec(publishTtl)
- .setTerminateNotificationEnabled(enableTerminateNotification)
- .setRangingEnabled(enableRanging).build();
-
- Parcel parcelW = Parcel.obtain();
- publishConfig.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- PublishConfig rereadPublishConfig = PublishConfig.CREATOR.createFromParcel(parcelR);
-
- assertEquals(publishConfig, rereadPublishConfig);
- assertEquals(publishConfig.hashCode(), rereadPublishConfig.hashCode());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testPublishConfigBuilderBadPublishType() {
- new PublishConfig.Builder().setPublishType(5);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testPublishConfigBuilderNegativeTtl() {
- new PublishConfig.Builder().setTtlSec(-10);
- }
-
- /*
- * Data-path tests
- */
-
- /**
- * Validate that correct network specifier is generated for client-based data-path.
- */
- @Test
- public void testNetworkSpecifierWithClient() throws Exception {
- final int clientId = 4565;
- final int sessionId = 123;
- final PeerHandle peerHandle = new PeerHandle(123412);
- final byte[] pmk = PMK_VALID;
- final String passphrase = PASSPHRASE_VALID;
- final int port = 5;
- final int transportProtocol = 10;
- final ConfigRequest configRequest = new ConfigRequest.Builder().build();
- final PublishConfig publishConfig = new PublishConfig.Builder().build();
-
- mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
-
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
- ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
- .forClass(PublishDiscoverySession.class);
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession, mockRttListener);
-
- // (1) connect successfully
- mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- eq(configRequest), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
- WifiAwareSession session = sessionCaptor.getValue();
-
- // (2) publish successfully
- session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
- sessionProxyCallback.capture());
- sessionProxyCallback.getValue().onSessionStarted(sessionId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
-
- // (3) request an open (unencrypted) network specifier from the session
- WifiAwareNetworkSpecifier ns =
- (WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierOpen(
- peerHandle);
- WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(
- publishSession.getValue(), peerHandle).build();
-
- // validate format
- collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
- equalTo(ns.role));
- collector.checkThat("client_id", clientId, equalTo(ns.clientId));
- collector.checkThat("session_id", sessionId, equalTo(ns.sessionId));
- collector.checkThat("peer_id", peerHandle.peerId, equalTo(ns.peerId));
-
- collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
- equalTo(nsb.role));
- collector.checkThat("client_id", clientId, equalTo(nsb.clientId));
- collector.checkThat("session_id", sessionId, equalTo(nsb.sessionId));
- collector.checkThat("peer_id", peerHandle.peerId, equalTo(nsb.peerId));
- collector.checkThat("port", 0, equalTo(nsb.port));
- collector.checkThat("transportProtocol", -1, equalTo(nsb.transportProtocol));
-
- // (4) request an encrypted (PMK) network specifier from the session
- ns = (WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierPmk(
- peerHandle, pmk);
- nsb = new WifiAwareNetworkSpecifier.Builder(publishSession.getValue(), peerHandle).setPmk(
- pmk).setPort(port).setTransportProtocol(transportProtocol).build();
-
- // validate format
- collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
- equalTo(ns.role));
- collector.checkThat("client_id", clientId, equalTo(ns.clientId));
- collector.checkThat("session_id", sessionId, equalTo(ns.sessionId));
- collector.checkThat("peer_id", peerHandle.peerId, equalTo(ns.peerId));
- collector.checkThat("pmk", pmk , equalTo(ns.pmk));
-
- collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
- equalTo(nsb.role));
- collector.checkThat("client_id", clientId, equalTo(nsb.clientId));
- collector.checkThat("session_id", sessionId, equalTo(nsb.sessionId));
- collector.checkThat("peer_id", peerHandle.peerId, equalTo(nsb.peerId));
- collector.checkThat("pmk", pmk , equalTo(nsb.pmk));
- collector.checkThat("port", port, equalTo(nsb.port));
- collector.checkThat("transportProtocol", transportProtocol, equalTo(nsb.transportProtocol));
-
- // (5) request an encrypted (Passphrase) network specifier from the session
- ns =
- (WifiAwareNetworkSpecifier) publishSession.getValue()
- .createNetworkSpecifierPassphrase(
- peerHandle, passphrase);
- nsb = new WifiAwareNetworkSpecifier.Builder(publishSession.getValue(),
- peerHandle).setPskPassphrase(passphrase).setPort(port).setTransportProtocol(
- transportProtocol).build();
-
- // validate format
- collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
- equalTo(ns.role));
- collector.checkThat("client_id", clientId, equalTo(ns.clientId));
- collector.checkThat("session_id", sessionId, equalTo(ns.sessionId));
- collector.checkThat("peer_id", peerHandle.peerId, equalTo(ns.peerId));
- collector.checkThat("passphrase", passphrase, equalTo(ns.passphrase));
-
- collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
- equalTo(nsb.role));
- collector.checkThat("client_id", clientId, equalTo(nsb.clientId));
- collector.checkThat("session_id", sessionId, equalTo(nsb.sessionId));
- collector.checkThat("peer_id", peerHandle.peerId, equalTo(nsb.peerId));
- collector.checkThat("passphrase", passphrase, equalTo(nsb.passphrase));
- collector.checkThat("port", port, equalTo(nsb.port));
- collector.checkThat("transportProtocol", transportProtocol, equalTo(nsb.transportProtocol));
-
- verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession, mockRttListener);
- }
-
- /**
- * Validate that correct network specifier is generated for a direct data-path (i.e.
- * specifying MAC address as opposed to a client-based oqaque specification).
- */
- @Test
- public void testNetworkSpecifierDirect() throws Exception {
- final int clientId = 134;
- final ConfigRequest configRequest = new ConfigRequest.Builder().build();
- final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
- final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
- final byte[] pmk = PMK_VALID;
- final String passphrase = PASSPHRASE_VALID;
-
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession, mockRttListener);
-
- // (1) connect successfully
- mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- eq(configRequest), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
- WifiAwareSession session = sessionCaptor.getValue();
-
- // (2) request an open (unencrypted) direct network specifier
- WifiAwareNetworkSpecifier ns =
- (WifiAwareNetworkSpecifier) session.createNetworkSpecifierOpen(role, someMac);
-
- // validate format
- collector.checkThat("role", role, equalTo(ns.role));
- collector.checkThat("client_id", clientId, equalTo(ns.clientId));
- collector.checkThat("peer_mac", someMac, equalTo(ns.peerMac));
-
- // (3) request an encrypted (PMK) direct network specifier
- ns = (WifiAwareNetworkSpecifier) session.createNetworkSpecifierPmk(role, someMac, pmk);
-
- // validate format
- collector.checkThat("role", role, equalTo(ns.role));
- collector.checkThat("client_id", clientId, equalTo(ns.clientId));
- collector.checkThat("peer_mac", someMac, equalTo(ns.peerMac));
- collector.checkThat("pmk", pmk, equalTo(ns.pmk));
-
- // (4) request an encrypted (Passphrase) direct network specifier
- ns = (WifiAwareNetworkSpecifier) session.createNetworkSpecifierPassphrase(role, someMac,
- passphrase);
-
- // validate format
- collector.checkThat("role", role, equalTo(ns.role));
- collector.checkThat("client_id", clientId, equalTo(ns.clientId));
- collector.checkThat("peer_mac", someMac, equalTo(ns.peerMac));
- collector.checkThat("passphrase", passphrase, equalTo(ns.passphrase));
-
- verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession, mockRttListener);
- }
-
- /**
- * Validate that a null PMK triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientNullPmk() throws Exception {
- executeNetworkSpecifierWithClient(new PeerHandle(123412), true, null, null, false);
- }
-
- /**
- * Validate that a non-32-bytes PMK triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientIncorrectLengthPmk() throws Exception {
- executeNetworkSpecifierWithClient(new PeerHandle(123412), true, PMK_INVALID, null, false);
- }
-
- /**
- * Validate that a null Passphrase triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientNullPassphrase() throws Exception {
- executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null, null, false);
- }
-
- /**
- * Validate that a too short Passphrase triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientTooShortPassphrase() throws Exception {
- executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null,
- PASSPHRASE_TOO_SHORT, false);
- }
-
- /**
- * Validate that a too long Passphrase triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientTooLongPassphrase() throws Exception {
- executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null, PASSPHRASE_TOO_LONG,
- false);
- }
-
- /**
- * Validate that a null PeerHandle triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientNullPeer() throws Exception {
- mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
- executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID, false);
- }
-
- /**
- * Validate that a null PeerHandle does not trigger an exception for legacy API.
- */
- @Test
- public void testNetworkSpecifierWithClientNullPeerLegacyApi() throws Exception {
- mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
- executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID, false);
- }
-
- /**
- * Validate that a null PMK triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientNullPmkBuilder() throws Exception {
- executeNetworkSpecifierWithClient(new PeerHandle(123412), true, null, null, true);
- }
-
- /**
- * Validate that a non-32-bytes PMK triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientIncorrectLengthPmkBuilder() throws Exception {
- executeNetworkSpecifierWithClient(new PeerHandle(123412), true, PMK_INVALID, null, true);
- }
-
- /**
- * Validate that a null Passphrase triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientNullPassphraseBuilder() throws Exception {
- executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null, null, true);
- }
-
- /**
- * Validate that a too short Passphrase triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientTooShortPassphraseBuilder() throws Exception {
- executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null,
- PASSPHRASE_TOO_SHORT, true);
- }
-
- /**
- * Validate that a too long Passphrase triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientTooLongPassphraseBuilder() throws Exception {
- executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null, PASSPHRASE_TOO_LONG,
- true);
- }
-
- /**
- * Validate that a null PeerHandle triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierWithClientNullPeerBuilder() throws Exception {
- executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID, true);
- }
-
- /**
- * Validate that a null PeerHandle does not trigger an exception for legacy API.
- */
- @Test
- public void testNetworkSpecifierWithClientNullPeerLegacyApiBuilder() throws Exception {
- mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
- executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID, false);
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void testNetworkSpecifierDeprecatedOnNewApi() throws Exception {
- executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID, false);
- }
-
- private void executeNetworkSpecifierWithClient(PeerHandle peerHandle, boolean doPmk, byte[] pmk,
- String passphrase, boolean useBuilder) throws Exception {
- final int clientId = 4565;
- final int sessionId = 123;
- final ConfigRequest configRequest = new ConfigRequest.Builder().build();
- final PublishConfig publishConfig = new PublishConfig.Builder().build();
-
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
- ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
- .forClass(PublishDiscoverySession.class);
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession, mockRttListener);
-
- // (1) connect successfully
- mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- eq(configRequest), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
- WifiAwareSession session = sessionCaptor.getValue();
-
- // (2) publish successfully
- session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
- sessionProxyCallback.capture());
- sessionProxyCallback.getValue().onSessionStarted(sessionId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
-
- // (3) create network specifier
- if (doPmk) {
- if (useBuilder) {
- new WifiAwareNetworkSpecifier.Builder(publishSession.getValue(), peerHandle).setPmk(
- pmk).build();
- } else {
- publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
- }
- } else {
- if (useBuilder) {
- new WifiAwareNetworkSpecifier.Builder(publishSession.getValue(),
- peerHandle).setPskPassphrase(passphrase).build();
- } else {
- publishSession.getValue().createNetworkSpecifierPassphrase(peerHandle, passphrase);
- }
- }
- }
-
- /**
- * Validate that a null PMK triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierDirectNullPmk() throws Exception {
- executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false), true,
- null, null, true);
- }
-
- /**
- * Validate that a non-32-bytes PMK triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierDirectIncorrectLengthPmk() throws Exception {
- executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false), true,
- PMK_INVALID, null, true);
- }
-
- /**
- * Validate that a null Passphrase triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierDirectNullPassphrase() throws Exception {
- executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false),
- false, null, null, true);
- }
-
- /**
- * Validate that a too short Passphrase triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierDirectTooShortPassphrase() throws Exception {
- executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false),
- false, null, PASSPHRASE_TOO_SHORT, true);
- }
-
- /**
- * Validate that a too long Passphrase triggers an exception.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierDirectTooLongPassphrase() throws Exception {
- executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false),
- false, null, PASSPHRASE_TOO_LONG, true);
- }
-
- /**
- * Validate that a null peer MAC triggers an exception for an Initiator.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierDirectNullPeerInitiator() throws Exception {
- executeNetworkSpecifierDirect(null, false, null, PASSPHRASE_VALID, true);
- }
-
- /**
- * Validate that a null peer MAC triggers an exception for a Resonder.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierDirectNullPeerResponder() throws Exception {
- executeNetworkSpecifierDirect(null, false, null, PASSPHRASE_VALID, false);
- }
-
- /**
- * Validate that a null peer MAC does not trigger an exception for a Resonder on legacy API.
- */
- @Test
- public void testNetworkSpecifierDirectNullPeerResponderLegacyApi() throws Exception {
- mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
- executeNetworkSpecifierDirect(null, false, null, PASSPHRASE_VALID, false);
- }
-
- /**
- * Validate that get an exception when creating a network specifier with an invalid port number
- * (<=0).
- */
- @Test(expected = IllegalArgumentException.class)
- public void testNetworkSpecifierBuilderInvalidPortNumber() throws Exception {
- final PeerHandle peerHandle = new PeerHandle(123412);
- final byte[] pmk = PMK_VALID;
- final int port = 0;
-
- DiscoverySession publishSession = executeSessionStartup(true);
-
- WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
- peerHandle).setPmk(pmk).setPort(port).build();
- }
-
- /**
- * Validate that get an exception when creating a network specifier with port information
- * without also requesting a secure link.
- */
- @Test(expected = IllegalStateException.class)
- public void testNetworkSpecifierBuilderInvalidPortOnInsecure() throws Exception {
- final PeerHandle peerHandle = new PeerHandle(123412);
- final int port = 5;
-
- DiscoverySession publishSession = executeSessionStartup(true);
-
- WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
- peerHandle).setPort(port).build();
- }
-
- /**
- * Validate that get an exception when creating a network specifier with port information on
- * a responder.
- */
- @Test(expected = IllegalStateException.class)
- public void testNetworkSpecifierBuilderInvalidPortOnResponder() throws Exception {
- final PeerHandle peerHandle = new PeerHandle(123412);
- final int port = 5;
-
- DiscoverySession subscribeSession = executeSessionStartup(false);
-
- WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(subscribeSession,
- peerHandle).setPort(port).build();
- }
-
- /**
- * Validate that get an exception when creating a network specifier with an invalid transport
- * protocol number (not in [0, 255]).
- */
- @Test
- public void testNetworkSpecifierBuilderInvalidTransportProtocolNumber() throws Exception {
- final PeerHandle peerHandle = new PeerHandle(123412);
- final byte[] pmk = PMK_VALID;
- final int tpNegative = -1;
- final int tpTooLarge = 256;
- final int tpSmallest = 0;
- final int tpLargest = 255;
-
- DiscoverySession publishSession = executeSessionStartup(true);
-
- try {
- WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
- peerHandle).setPmk(pmk).setTransportProtocol(tpNegative).build();
- assertTrue("No exception on negative transport protocol!", false);
- } catch (IllegalArgumentException e) {
- // nop - exception is correct!
- }
- try {
- WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
- peerHandle).setPmk(pmk).setTransportProtocol(tpTooLarge).build();
- assertTrue("No exception on >255 transport protocol!", false);
- } catch (IllegalArgumentException e) {
- // nop - exception is correct!
- }
- WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
- peerHandle).setPmk(pmk).setTransportProtocol(tpSmallest).build();
- nsb = new WifiAwareNetworkSpecifier.Builder(publishSession, peerHandle).setPmk(
- pmk).setTransportProtocol(tpLargest).build();
- }
-
- /**
- * Validate that get an exception when creating a network specifier with transport protocol
- * information without also requesting a secure link.
- */
- @Test(expected = IllegalStateException.class)
- public void testNetworkSpecifierBuilderInvalidTransportProtocolOnInsecure() throws Exception {
- final PeerHandle peerHandle = new PeerHandle(123412);
- final int transportProtocol = 5;
-
- DiscoverySession publishSession = executeSessionStartup(true);
-
- WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
- peerHandle).setTransportProtocol(transportProtocol).build();
- }
-
- /**
- * Validate that get an exception when creating a network specifier with transport protocol
- * information on a responder.
- */
- @Test(expected = IllegalStateException.class)
- public void testNetworkSpecifierBuilderInvalidTransportProtocolOnResponder() throws Exception {
- final PeerHandle peerHandle = new PeerHandle(123412);
- final int transportProtocol = 5;
-
- DiscoverySession subscribeSession = executeSessionStartup(false);
-
- WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(subscribeSession,
- peerHandle).setTransportProtocol(transportProtocol).build();
- }
-
- /*
- * Utilities
- */
-
- private void executeNetworkSpecifierDirect(byte[] someMac, boolean doPmk, byte[] pmk,
- String passphrase, boolean doInitiator) throws Exception {
- final int clientId = 134;
- final int role = doInitiator ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
- : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
- final ConfigRequest configRequest = new ConfigRequest.Builder().build();
-
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession, mockRttListener);
-
- // (1) connect successfully
- mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- eq(configRequest), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-
- // (2) create network specifier
- if (doPmk) {
- sessionCaptor.getValue().createNetworkSpecifierPmk(role, someMac, pmk);
- } else {
- sessionCaptor.getValue().createNetworkSpecifierPassphrase(role, someMac, passphrase);
- }
- }
-
- private DiscoverySession executeSessionStartup(boolean isPublish) throws Exception {
- final int clientId = 4565;
- final int sessionId = 123;
- final PeerHandle peerHandle = new PeerHandle(123412);
- final int port = 5;
- final ConfigRequest configRequest = new ConfigRequest.Builder().build();
- final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
- final PublishConfig publishConfig = new PublishConfig.Builder().build();
-
- ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
- WifiAwareSession.class);
- ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareEventCallback.class);
- ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
- .forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
- .forClass(PublishDiscoverySession.class);
- ArgumentCaptor<SubscribeDiscoverySession> subscribeSession = ArgumentCaptor
- .forClass(SubscribeDiscoverySession.class);
-
-
- InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
- mockPublishSession, mockRttListener);
-
- // (1) connect successfully
- mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
- eq(configRequest), eq(false));
- clientProxyCallback.getValue().onConnectSuccess(clientId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
- WifiAwareSession session = sessionCaptor.getValue();
-
- if (isPublish) {
- // (2) publish successfully
- session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
- sessionProxyCallback.capture());
- sessionProxyCallback.getValue().onSessionStarted(sessionId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
- return publishSession.getValue();
- } else {
- // (2) subscribe successfully
- session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId),
- eq(subscribeConfig), sessionProxyCallback.capture());
- sessionProxyCallback.getValue().onSessionStarted(sessionId);
- mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
- return subscribeSession.getValue();
- }
- }
-
- // WifiAwareNetworkSpecifier && WifiAwareNetworkInfo tests
-
- @Test
- public void testWifiAwareNetworkSpecifierParcel() {
- WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier(NETWORK_SPECIFIER_TYPE_IB,
- WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, 5, 568, 334,
- HexEncoding.decode("000102030405".toCharArray(), false),
- "01234567890123456789012345678901".getBytes(), "blah blah", 666, 4);
-
- Parcel parcelW = Parcel.obtain();
- ns.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiAwareNetworkSpecifier rereadNs =
- WifiAwareNetworkSpecifier.CREATOR.createFromParcel(parcelR);
-
- assertEquals(ns, rereadNs);
- assertEquals(ns.hashCode(), rereadNs.hashCode());
- }
-
- @Test
- public void testWifiAwareNetworkCapabilitiesParcel() throws UnknownHostException {
- final Inet6Address inet6 = MacAddress.fromString(
- "11:22:33:44:55:66").getLinkLocalIpv6FromEui48Mac();
- // note: dummy scope = 5
- final Inet6Address inet6Scoped = Inet6Address.getByAddress(null, inet6.getAddress(), 5);
- final int port = 5;
- final int transportProtocol = 6;
-
- assertEquals(inet6Scoped.toString(), "/fe80::1322:33ff:fe44:5566%5");
- WifiAwareNetworkInfo cap = new WifiAwareNetworkInfo(inet6Scoped, port, transportProtocol);
-
- Parcel parcelW = Parcel.obtain();
- cap.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiAwareNetworkInfo rereadCap =
- WifiAwareNetworkInfo.CREATOR.createFromParcel(parcelR);
-
- assertEquals(cap.getPeerIpv6Addr().toString(), "/fe80::1322:33ff:fe44:5566%5");
- assertEquals(cap, rereadCap);
- assertEquals(cap.hashCode(), rereadCap.hashCode());
- }
-
- // ParcelablePeerHandle tests
-
- /**
- * Verify parceling of ParcelablePeerHandle and interoperability with PeerHandle.
- */
- @Test
- public void testParcelablePeerHandleParcel() {
- final PeerHandle peerHandle = new PeerHandle(5);
- final ParcelablePeerHandle parcelablePeerHandle = new ParcelablePeerHandle(peerHandle);
-
- Parcel parcelW = Parcel.obtain();
- parcelablePeerHandle.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- ParcelablePeerHandle rereadParcelablePeerHandle =
- ParcelablePeerHandle.CREATOR.createFromParcel(parcelR);
-
- assertEquals(peerHandle, rereadParcelablePeerHandle);
- assertEquals(peerHandle.hashCode(), rereadParcelablePeerHandle.hashCode());
- assertEquals(parcelablePeerHandle, rereadParcelablePeerHandle);
- assertEquals(parcelablePeerHandle.hashCode(), rereadParcelablePeerHandle.hashCode());
-
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java
deleted file mode 100644
index 439e672..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java
+++ /dev/null
@@ -1,223 +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.net.wifi.hotspot2;
-
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.FakeKeys;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Arrays;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.ConfigParser}.
- */
-@SmallTest
-public class ConfigParserTest {
- /**
- * Hotspot 2.0 Release 1 installation file that contains a Passpoint profile and a
- * CA (Certificate Authority) X.509 certificate {@link FakeKeys#CA_CERT0}.
- */
- private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT =
- "assets/hsr1/HSR1ProfileWithCACert.base64";
- private static final String PASSPOINT_INSTALLATION_FILE_WITH_UNENCODED_DATA =
- "assets/hsr1/HSR1ProfileWithCACert.conf";
- private static final String PASSPOINT_INSTALLATION_FILE_WITH_INVALID_PART =
- "assets/hsr1/HSR1ProfileWithNonBase64Part.base64";
- private static final String PASSPOINT_INSTALLATION_FILE_WITH_MISSING_BOUNDARY =
- "assets/hsr1/HSR1ProfileWithMissingBoundary.base64";
- private static final String PASSPOINT_INSTALLATION_FILE_WITH_INVALID_CONTENT_TYPE =
- "assets/hsr1/HSR1ProfileWithInvalidContentType.base64";
- private static final String PASSPOINT_INSTALLATION_FILE_WITHOUT_PROFILE =
- "assets/hsr1/HSR1ProfileWithoutProfile.base64";
- private static final String PASSPOINT_INSTALLATION_FILE_WITH_UPDATE_ID =
- "assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64";
-
- /**
- * Read the content of the given resource file into a String.
- *
- * @param filename String name of the file
- * @return String
- * @throws IOException
- */
- private String loadResourceFile(String filename) throws IOException {
- InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
- BufferedReader reader = new BufferedReader(new InputStreamReader(in));
- StringBuilder builder = new StringBuilder();
- String line;
- while ((line = reader.readLine()) != null) {
- builder.append(line).append("\n");
- }
-
- return builder.toString();
- }
-
- /**
- * Generate a {@link PasspointConfiguration} that matches the configuration specified in the
- * XML file {@link #PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT}.
- *
- * @return {@link PasspointConfiguration}
- */
- private PasspointConfiguration generateConfigurationFromProfile() {
- PasspointConfiguration config = new PasspointConfiguration();
-
- // HomeSP configuration.
- HomeSp homeSp = new HomeSp();
- homeSp.setFriendlyName("Example Network");
- homeSp.setFqdn("hotspot.example.net");
- homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
- config.setHomeSp(homeSp);
-
- // Credential configuration.
- Credential credential = new Credential();
- credential.setRealm("example.com");
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setUsername("user");
- userCredential.setPassword("cGFzc3dvcmQ=");
- userCredential.setEapType(21);
- userCredential.setNonEapInnerMethod("MS-CHAP-V2");
- credential.setUserCredential(userCredential);
- Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
- certCredential.setCertType("x509v3");
- byte[] certSha256Fingerprint = new byte[32];
- Arrays.fill(certSha256Fingerprint, (byte)0x1f);
- certCredential.setCertSha256Fingerprint(certSha256Fingerprint);
- credential.setCertCredential(certCredential);
- Credential.SimCredential simCredential = new Credential.SimCredential();
- simCredential.setImsi("123456*");
- simCredential.setEapType(23);
- credential.setSimCredential(simCredential);
- credential.setCaCertificate(FakeKeys.CA_CERT0);
- config.setCredential(credential);
- return config;
- }
-
- /**
- * Verify a valid installation file is parsed successfully with the matching contents.
- *
- * @throws Exception
- */
- @Test
- public void parseConfigFile() throws Exception {
- String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
- PasspointConfiguration expectedConfig = generateConfigurationFromProfile();
- PasspointConfiguration actualConfig =
- ConfigParser.parsePasspointConfig(
- "application/x-wifi-config", configStr.getBytes());
- assertTrue(actualConfig.equals(expectedConfig));
- }
-
- /**
- * Verify that parsing an installation file with invalid MIME type will fail.
- *
- * @throws Exception
- */
- @Test
- public void parseConfigFileWithInvalidMimeType() throws Exception {
- String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
- assertNull(ConfigParser.parsePasspointConfig(
- "application/wifi-config", configStr.getBytes()));
- }
-
- /**
- * Verify that parsing an un-encoded installation file will fail.
- *
- * @throws Exception
- */
- @Test
- public void parseConfigFileWithUnencodedData() throws Exception {
- String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_UNENCODED_DATA);
- assertNull(ConfigParser.parsePasspointConfig(
- "application/x-wifi-config", configStr.getBytes()));
- }
-
- /**
- * Verify that parsing an installation file that contains a non-base64 part will fail.
- *
- * @throws Exception
- */
- @Test
- public void parseConfigFileWithInvalidPart() throws Exception {
- String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_INVALID_PART);
- assertNull(ConfigParser.parsePasspointConfig(
- "application/x-wifi-config", configStr.getBytes()));
- }
-
- /**
- * Verify that parsing an installation file that contains a missing boundary string will fail.
- *
- * @throws Exception
- */
- @Test
- public void parseConfigFileWithMissingBoundary() throws Exception {
- String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_MISSING_BOUNDARY);
- assertNull(ConfigParser.parsePasspointConfig(
- "application/x-wifi-config", configStr.getBytes()));
- }
-
- /**
- * Verify that parsing an installation file that contains a MIME part with an invalid content
- * type will fail.
- *
- * @throws Exception
- */
- @Test
- public void parseConfigFileWithInvalidContentType() throws Exception {
- String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_INVALID_CONTENT_TYPE);
- assertNull(ConfigParser.parsePasspointConfig(
- "application/x-wifi-config", configStr.getBytes()));
- }
-
- /**
- * Verify that parsing an installation file that doesn't contain a Passpoint profile will fail.
- *
- * @throws Exception
- */
- @Test
- public void parseConfigFileWithoutPasspointProfile() throws Exception {
- String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITHOUT_PROFILE);
- assertNull(ConfigParser.parsePasspointConfig(
- "application/x-wifi-config", configStr.getBytes()));
- }
-
- /**
- * Verify a valid installation file is parsed successfully with the matching contents, and that
- * Update identifier is cleared.
- *
- * @throws Exception
- */
- @Test
- public void parseConfigFileWithUpdateIdentifier() throws Exception {
- String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_UPDATE_ID);
- PasspointConfiguration expectedConfig = generateConfigurationFromProfile();
- PasspointConfiguration actualConfig =
- ConfigParser.parsePasspointConfig(
- "application/x-wifi-config", configStr.getBytes());
- // Expected configuration does not contain an update identifier
- assertTrue(actualConfig.equals(expectedConfig));
- }
-}
\ No newline at end of file
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
deleted file mode 100644
index 2ded849..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
+++ /dev/null
@@ -1,137 +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.net.wifi.hotspot2;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.Uri;
-import android.net.wifi.WifiSsid;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.OsuProvider}.
- */
-@SmallTest
-public class OsuProviderTest {
- private static final WifiSsid TEST_SSID =
- WifiSsid.createFromByteArray("TEST SSID".getBytes(StandardCharsets.UTF_8));
- private static final String TEST_FRIENDLY_NAME = "Friendly Name";
- private static final Map<String, String> TEST_FRIENDLY_NAMES =
- new HashMap<String, String>() {
- {
- put("en", TEST_FRIENDLY_NAME);
- put("kr", TEST_FRIENDLY_NAME + 2);
- put("jp", TEST_FRIENDLY_NAME + 3);
- }
- };
-
- private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
- private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
- private static final String TEST_NAI = "test.access.com";
- private static final List<Integer> TEST_METHOD_LIST =
- Arrays.asList(OsuProvider.METHOD_SOAP_XML_SPP);
-
- /**
- * Verify parcel write and read consistency for the given {@link OsuProvider}.
- *
- * @param writeInfo The {@link OsuProvider} to verify
- * @throws Exception
- */
- private static void verifyParcel(OsuProvider writeInfo) throws Exception {
- Parcel parcel = Parcel.obtain();
- writeInfo.writeToParcel(parcel, 0);
-
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- OsuProvider readInfo = OsuProvider.CREATOR.createFromParcel(parcel);
-
- assertEquals(writeInfo, readInfo);
- assertEquals(writeInfo.hashCode(), readInfo.hashCode());
- }
-
- /**
- * Verify parcel read/write for an OSU provider containing no information.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithEmptyProviderInfo() throws Exception {
- verifyParcel(new OsuProvider((WifiSsid) null, null, null, null, null, null));
- }
-
- /**
- * Verify parcel read/write for an OSU provider containing full information.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithFullProviderInfo() throws Exception {
- verifyParcel(new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES,
- TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST));
- }
-
- /**
- * Verify copy constructor with a null source.
- * @throws Exception
- */
- @Test
- public void verifyCopyConstructorWithNullSource() throws Exception {
- OsuProvider expected = new OsuProvider((WifiSsid) null, null, null, null, null, null);
- assertEquals(expected, new OsuProvider(null));
- }
-
- /**
- * Verify copy constructor with a valid source.
- *
- * @throws Exception
- */
- @Test
- public void verifyCopyConstructorWithValidSource() throws Exception {
- OsuProvider source = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES,
- TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST);
- assertEquals(source, new OsuProvider(source));
- }
-
- /**
- * Verify getter methods.
- *
- * @throws Exception
- */
- @Test
- public void verifyGetters() throws Exception {
- OsuProvider provider = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES,
- TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST);
-
- assertTrue(TEST_SSID.equals(provider.getOsuSsid()));
- assertTrue(TEST_FRIENDLY_NAME.equals(provider.getFriendlyName()));
- assertTrue(TEST_FRIENDLY_NAMES.equals(provider.getFriendlyNameList()));
- assertTrue(TEST_SERVICE_DESCRIPTION.equals(provider.getServiceDescription()));
- assertTrue(TEST_SERVER_URI.equals(provider.getServerUri()));
- assertTrue(TEST_NAI.equals(provider.getNetworkAccessIdentifier()));
- assertTrue(TEST_METHOD_LIST.equals(provider.getMethodList()));
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
deleted file mode 100644
index 638efb9..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
+++ /dev/null
@@ -1,448 +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.net.wifi.hotspot2;
-
-import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.PasspointConfiguration}.
- */
-@SmallTest
-public class PasspointConfigurationTest {
- private static final int MAX_URL_BYTES = 1023;
- private static final int CERTIFICATE_FINGERPRINT_BYTES = 32;
-
- /**
- * Verify parcel write and read consistency for the given configuration.
- *
- * @param writeConfig The configuration to verify
- * @throws Exception
- */
- private static void verifyParcel(PasspointConfiguration writeConfig) throws Exception {
- Parcel parcel = Parcel.obtain();
- writeConfig.writeToParcel(parcel, 0);
-
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- PasspointConfiguration readConfig =
- PasspointConfiguration.CREATOR.createFromParcel(parcel);
- assertTrue(readConfig.equals(writeConfig));
- }
-
- /**
- * Verify parcel read/write for a default configuration.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithDefault() throws Exception {
- verifyParcel(new PasspointConfiguration());
- }
-
- /**
- * Verify parcel read/write for a configuration that contained the full configuration.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithFullConfiguration() throws Exception {
- verifyParcel(PasspointTestUtils.createConfig());
- }
-
- /**
- * Verify parcel read/write for a configuration that doesn't contain a list of service names.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutServiceNames() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setServiceFriendlyNames(null);
- verifyParcel(config);
- }
-
- /**
- * Verify parcel read/write for a configuration that doesn't contain HomeSP.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutHomeSP() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setHomeSp(null);
- verifyParcel(config);
- }
-
- /**
- * Verify parcel read/write for a configuration that doesn't contain Credential.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutCredential() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setCredential(null);
- verifyParcel(config);
- }
-
- /**
- * Verify parcel read/write for a configuration that doesn't contain Policy.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutPolicy() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setPolicy(null);
- verifyParcel(config);
- }
-
- /**
- * Verify parcel read/write for a configuration that doesn't contain subscription update.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutSubscriptionUpdate() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setSubscriptionUpdate(null);
- verifyParcel(config);
- }
-
- /**
- * Verify parcel read/write for a configuration that doesn't contain trust root certificate
- * list.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutTrustRootCertList() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setTrustRootCertList(null);
- verifyParcel(config);
- }
-
- /**
- * Verify parcel read/write for a configuration that doesn't contain AAA server trusted names
- * list.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutAaaServerTrustedNames() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setAaaServerTrustedNames(null);
- verifyParcel(config);
- }
-
- /**
- * Verify that a default/empty configuration is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateDefaultConfig() throws Exception {
- PasspointConfiguration config = new PasspointConfiguration();
-
- assertFalse(config.validate());
- assertFalse(config.validateForR2());
- assertTrue(config.isAutojoinEnabled());
- assertTrue(config.isMacRandomizationEnabled());
- assertTrue(config.getMeteredOverride() == METERED_OVERRIDE_NONE);
- }
-
- /**
- * Verify that a configuration containing all fields is valid for R1/R2.
- *
- * @throws Exception
- */
- @Test
- public void validateFullConfig() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
-
- assertTrue(config.validate());
- assertFalse(config.isOsuProvisioned());
- }
-
- /**
- * Verify that a configuration containing all fields except for UpdateIdentifier is valid for
- * R1, but invalid for R2.
- *
- * @throws Exception
- */
- @Test
- public void validateFullConfigWithoutUpdateIdentifier() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setUpdateIdentifier(Integer.MIN_VALUE);
-
- assertTrue(config.validate());
- assertFalse(config.validateForR2());
- }
-
- /**
- * Verify that a configuration without Credential is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateConfigWithoutCredential() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setCredential(null);
-
- assertFalse(config.validate());
- assertFalse(config.validateForR2());
- }
-
- /**
- * Verify that a configuration without HomeSP is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateConfigWithoutHomeSp() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setHomeSp(null);
-
- assertFalse(config.validate());
- assertFalse(config.validateForR2());
- }
-
- /**
- * Verify that a configuration without Policy is valid, since Policy configurations
- * are optional for R1 and R2.
- *
- * @throws Exception
- */
- @Test
- public void validateConfigWithoutPolicy() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setPolicy(null);
-
- assertTrue(config.validate());
- }
-
- /**
- * Verify that a configuration without subscription update is valid for R1 and invalid for R2,
- * since subscription update configuration is only applicable for R2.
- *
- * @throws Exception
- */
- @Test
- public void validateConfigWithoutSubscriptionUpdate() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setSubscriptionUpdate(null);
-
- assertTrue(config.validate());
- assertFalse(config.validateForR2());
- }
-
- /**
- * Verify that a configuration without AAA server trusted names is valid for R1 and R2,
- * since AAA server trusted names are optional for R1 and R2.
- *
- * @throws Exception
- */
- @Test
- public void validateConfigWithoutAaaServerTrustedNames() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setAaaServerTrustedNames(null);
-
- assertTrue(config.validate());
- }
-
- /**
- * Verify that a configuration with a trust root certificate URL exceeding the max size
- * is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateConfigWithInvalidTrustRootCertUrl() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1];
- Map<String, byte[]> trustRootCertList = new HashMap<>();
- Arrays.fill(rawUrlBytes, (byte) 'a');
- trustRootCertList.put(new String(rawUrlBytes, StandardCharsets.UTF_8),
- new byte[CERTIFICATE_FINGERPRINT_BYTES]);
- config.setTrustRootCertList(trustRootCertList);
-
- assertFalse(config.validate());
-
- trustRootCertList = new HashMap<>();
- trustRootCertList.put(null, new byte[CERTIFICATE_FINGERPRINT_BYTES]);
- config.setTrustRootCertList(trustRootCertList);
-
- assertFalse(config.validate());
- assertFalse(config.validateForR2());
- }
-
- /**
- * Verify that a configuration with an invalid trust root certificate fingerprint is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateConfigWithInvalidTrustRootCertFingerprint() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- Map<String, byte[]> trustRootCertList = new HashMap<>();
- trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES + 1]);
- config.setTrustRootCertList(trustRootCertList);
- assertFalse(config.validate());
-
- trustRootCertList = new HashMap<>();
- trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES - 1]);
- config.setTrustRootCertList(trustRootCertList);
- assertFalse(config.validate());
-
- trustRootCertList = new HashMap<>();
- trustRootCertList.put("test.cert.com", null);
- config.setTrustRootCertList(trustRootCertList);
- assertFalse(config.validate());
- assertFalse(config.validateForR2());
- }
-
- /**
- * Verify that copy constructor works when pass in a null source.
- *
- * @throws Exception
- */
- @Test
- public void validateCopyConstructorWithNullSource() throws Exception {
- PasspointConfiguration copyConfig = new PasspointConfiguration(null);
- PasspointConfiguration defaultConfig = new PasspointConfiguration();
- assertTrue(copyConfig.equals(defaultConfig));
- }
-
- /**
- * Verify that copy constructor works when pass in a valid source.
- *
- * @throws Exception
- */
- @Test
- public void validateCopyConstructorWithValidSource() throws Exception {
- PasspointConfiguration sourceConfig = PasspointTestUtils.createConfig();
- PasspointConfiguration copyConfig = new PasspointConfiguration(sourceConfig);
- assertTrue(copyConfig.equals(sourceConfig));
- }
-
- /**
- * Verify that a configuration containing all fields is valid for R2.
- *
- * @throws Exception
- */
- @Test
- public void validateFullR2Config() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createR2Config();
- assertTrue(config.validate());
- assertTrue(config.validateForR2());
- assertTrue(config.isOsuProvisioned());
- }
-
- /**
- * Verify that the unique identifier generated is identical for two instances
- *
- * @throws Exception
- */
- @Test
- public void validateUniqueId() throws Exception {
- PasspointConfiguration config1 = PasspointTestUtils.createConfig();
- PasspointConfiguration config2 = PasspointTestUtils.createConfig();
-
- assertEquals(config1.getUniqueId(), config2.getUniqueId());
- }
-
- /**
- * Verify that the unique identifier generated is different for two instances with different
- * HomeSp node
- *
- * @throws Exception
- */
- @Test
- public void validateUniqueIdDifferentHomeSp() throws Exception {
- PasspointConfiguration config1 = PasspointTestUtils.createConfig();
-
- // Modify config2's RCOIs to a different set of values
- PasspointConfiguration config2 = PasspointTestUtils.createConfig();
- HomeSp homeSp = config2.getHomeSp();
- homeSp.setRoamingConsortiumOis(new long[] {0xaa, 0xbb});
- config2.setHomeSp(homeSp);
-
- assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
- }
-
- /**
- * Verify that the unique identifier generated is different for two instances with different
- * Credential node
- *
- * @throws Exception
- */
- @Test
- public void validateUniqueIdDifferentCredential() throws Exception {
- PasspointConfiguration config1 = PasspointTestUtils.createConfig();
-
- // Modify config2's RCOIs to a different set of values
- PasspointConfiguration config2 = PasspointTestUtils.createConfig();
- Credential credential = config2.getCredential();
- credential.setRealm("realm2.example.com");
- credential.getSimCredential().setImsi("350460*");
- config2.setCredential(credential);
-
- assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
- }
-
- /**
- * Verify that the unique identifier API generates an exception if HomeSP is not initialized.
- *
- * @throws Exception
- */
- @Test (expected = IllegalStateException.class)
- public void validateUniqueIdExceptionWithEmptyHomeSp() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setHomeSp(null);
- String uniqueId = config.getUniqueId();
- }
-
- /**
- * Verify that the unique identifier API generates an exception if Credential is not
- * initialized.
- *
- * @throws Exception
- */
- @Test (expected = IllegalStateException.class)
- public void validateUniqueIdExceptionWithEmptyCredential() throws Exception {
- PasspointConfiguration config = PasspointTestUtils.createConfig();
- config.setCredential(null);
- String uniqueId = config.getUniqueId();
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
deleted file mode 100644
index 8d55acb..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
+++ /dev/null
@@ -1,172 +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.net.wifi.hotspot2;
-
-import android.net.wifi.EAPConstants;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.net.wifi.hotspot2.pps.Policy;
-import android.net.wifi.hotspot2.pps.UpdateParameter;
-import android.util.Base64;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class PasspointTestUtils {
- private static final int CERTIFICATE_FINGERPRINT_BYTES = 32;
-
- /**
- * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}.
- *
- * @return {@link android.net.wifi.hotspot2.pps.HomeSP}
- */
- private static HomeSp createHomeSp() {
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn("fqdn");
- homeSp.setFriendlyName("friendly name");
- homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
- return homeSp;
- }
-
- /**
- * Utility function for creating a {@link android.net.wifi.hotspot2.pps.Credential}.
- *
- * @return {@link android.net.wifi.hotspot2.pps.Credential}
- */
- private static Credential createCredential() {
- Credential cred = new Credential();
- cred.setRealm("realm");
- cred.setUserCredential(null);
- cred.setCertCredential(null);
- cred.setSimCredential(new Credential.SimCredential());
- cred.getSimCredential().setImsi("1234*");
- cred.getSimCredential().setEapType(EAPConstants.EAP_SIM);
- cred.setCaCertificate(null);
- cred.setClientCertificateChain(null);
- cred.setClientPrivateKey(null);
- return cred;
- }
-
- /**
- * Helper function for creating a {@link Policy} for testing.
- *
- * @return {@link Policy}
- */
- private static Policy createPolicy() {
- Policy policy = new Policy();
- policy.setMinHomeDownlinkBandwidth(123);
- policy.setMinHomeUplinkBandwidth(345);
- policy.setMinRoamingDownlinkBandwidth(567);
- policy.setMinRoamingUplinkBandwidth(789);
- policy.setMaximumBssLoadValue(12);
- policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"});
- HashMap<Integer, String> requiredProtoPortMap = new HashMap<>();
- requiredProtoPortMap.put(12, "23,342,123");
- requiredProtoPortMap.put(23, "789,372,1235");
- policy.setRequiredProtoPortMap(requiredProtoPortMap);
-
- List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>();
- Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
- partner1.setFqdn("partner1.com");
- partner1.setFqdnExactMatch(true);
- partner1.setPriority(12);
- partner1.setCountries("us,jp");
- Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
- partner2.setFqdn("partner2.com");
- partner2.setFqdnExactMatch(false);
- partner2.setPriority(42);
- partner2.setCountries("ca,fr");
- preferredRoamingPartnerList.add(partner1);
- preferredRoamingPartnerList.add(partner2);
- policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
-
- UpdateParameter policyUpdate = new UpdateParameter();
- policyUpdate.setUpdateIntervalInMinutes(1712);
- policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
- policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
- policyUpdate.setServerUri("policy.update.com");
- policyUpdate.setUsername("username");
- policyUpdate.setBase64EncodedPassword(
- Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
- policyUpdate.setTrustRootCertUrl("trust.cert.com");
- policyUpdate.setTrustRootCertSha256Fingerprint(
- new byte[CERTIFICATE_FINGERPRINT_BYTES]);
- policy.setPolicyUpdate(policyUpdate);
-
- return policy;
- }
-
- private static UpdateParameter createSubscriptionUpdate() {
- UpdateParameter subUpdate = new UpdateParameter();
- subUpdate.setUpdateIntervalInMinutes(9021);
- subUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
- subUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
- subUpdate.setServerUri("subscription.update.com");
- subUpdate.setUsername("subUsername");
- subUpdate.setBase64EncodedPassword(
- Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT));
- subUpdate.setTrustRootCertUrl("subscription.trust.cert.com");
- subUpdate.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_FINGERPRINT_BYTES]);
- return subUpdate;
- }
- /**
- * Helper function for creating a {@link PasspointConfiguration} for testing.
- *
- * @return {@link PasspointConfiguration}
- */
- public static PasspointConfiguration createConfig() {
- PasspointConfiguration config = new PasspointConfiguration();
- config.setHomeSp(createHomeSp());
- config.setAaaServerTrustedNames(
- new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"});
- config.setCredential(createCredential());
- config.setPolicy(createPolicy());
- config.setSubscriptionUpdate(createSubscriptionUpdate());
- Map<String, byte[]> trustRootCertList = new HashMap<>();
- trustRootCertList.put("trustRoot.cert1.com",
- new byte[CERTIFICATE_FINGERPRINT_BYTES]);
- trustRootCertList.put("trustRoot.cert2.com",
- new byte[CERTIFICATE_FINGERPRINT_BYTES]);
- config.setTrustRootCertList(trustRootCertList);
- config.setCredentialPriority(120);
- config.setSubscriptionCreationTimeInMillis(231200);
- config.setSubscriptionExpirationTimeInMillis(2134232);
- config.setSubscriptionType("Gold");
- config.setUsageLimitUsageTimePeriodInMinutes(3600);
- config.setUsageLimitStartTimeInMillis(124214213);
- config.setUsageLimitDataLimit(14121);
- config.setUsageLimitTimeLimitInMinutes(78912);
- Map<String, String> friendlyNames = new HashMap<>();
- friendlyNames.put("en", "ServiceName1");
- friendlyNames.put("kr", "ServiceName2");
- config.setServiceFriendlyNames(friendlyNames);
- return config;
- }
-
- /**
- * Helper function for creating an R2 {@link PasspointConfiguration} for testing.
- *
- * @return {@link PasspointConfiguration}
- */
- public static PasspointConfiguration createR2Config() {
- PasspointConfiguration config = createConfig();
- config.setUpdateIdentifier(1234);
- return config;
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
deleted file mode 100644
index 1ac9cb8..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
+++ /dev/null
@@ -1,263 +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.net.wifi.hotspot2.omadm;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.net.wifi.hotspot2.pps.Policy;
-import android.net.wifi.hotspot2.pps.UpdateParameter;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.omadm.PpsMoParser}.
- */
-@SmallTest
-public class PpsMoParserTest {
- private static final String VALID_PPS_MO_XML_FILE = "assets/pps/PerProviderSubscription.xml";
- private static final String PPS_MO_XML_FILE_DUPLICATE_HOMESP =
- "assets/pps/PerProviderSubscription_DuplicateHomeSP.xml";
- private static final String PPS_MO_XML_FILE_DUPLICATE_VALUE =
- "assets/pps/PerProviderSubscription_DuplicateValue.xml";
- private static final String PPS_MO_XML_FILE_MISSING_VALUE =
- "assets/pps/PerProviderSubscription_MissingValue.xml";
- private static final String PPS_MO_XML_FILE_MISSING_NAME =
- "assets/pps/PerProviderSubscription_MissingName.xml";
- private static final String PPS_MO_XML_FILE_INVALID_NODE =
- "assets/pps/PerProviderSubscription_InvalidNode.xml";
- private static final String PPS_MO_XML_FILE_INVALID_NAME =
- "assets/pps/PerProviderSubscription_InvalidName.xml";
-
- /**
- * Read the content of the given resource file into a String.
- *
- * @param filename String name of the file
- * @return String
- * @throws IOException
- */
- private String loadResourceFile(String filename) throws IOException {
- InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
- BufferedReader reader = new BufferedReader(new InputStreamReader(in));
- StringBuilder builder = new StringBuilder();
- String line;
- while ((line = reader.readLine()) != null) {
- builder.append(line).append("\n");
- }
-
- return builder.toString();
- }
-
- /**
- * Generate a {@link PasspointConfiguration} that matches the configuration specified in the
- * XML file {@link #VALID_PPS_MO_XML_FILE}.
- *
- * @return {@link PasspointConfiguration}
- */
- private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception {
- DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
- byte[] certFingerprint = new byte[32];
- Arrays.fill(certFingerprint, (byte) 0x1f);
-
- PasspointConfiguration config = new PasspointConfiguration();
- config.setUpdateIdentifier(12);
- config.setCredentialPriority(99);
-
- // AAA Server trust root.
- Map<String, byte[]> trustRootCertList = new HashMap<>();
- trustRootCertList.put("server1.trust.root.com", certFingerprint);
- config.setTrustRootCertList(trustRootCertList);
-
- // Subscription update.
- UpdateParameter subscriptionUpdate = new UpdateParameter();
- subscriptionUpdate.setUpdateIntervalInMinutes(120);
- subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
- subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
- subscriptionUpdate.setServerUri("subscription.update.com");
- subscriptionUpdate.setUsername("subscriptionUser");
- subscriptionUpdate.setBase64EncodedPassword("subscriptionPass");
- subscriptionUpdate.setTrustRootCertUrl("subscription.update.cert.com");
- subscriptionUpdate.setTrustRootCertSha256Fingerprint(certFingerprint);
- config.setSubscriptionUpdate(subscriptionUpdate);
-
- // Subscription parameters.
- config.setSubscriptionCreationTimeInMillis(format.parse("2016-02-01T10:00:00Z").getTime());
- config.setSubscriptionExpirationTimeInMillis(format.parse("2016-03-01T10:00:00Z").getTime());
- config.setSubscriptionType("Gold");
- config.setUsageLimitDataLimit(921890);
- config.setUsageLimitStartTimeInMillis(format.parse("2016-12-01T10:00:00Z").getTime());
- config.setUsageLimitTimeLimitInMinutes(120);
- config.setUsageLimitUsageTimePeriodInMinutes(99910);
-
- // HomeSP configuration.
- HomeSp homeSp = new HomeSp();
- homeSp.setFriendlyName("Century House");
- homeSp.setFqdn("mi6.co.uk");
- homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
- homeSp.setIconUrl("icon.test.com");
- Map<String, Long> homeNetworkIds = new HashMap<>();
- homeNetworkIds.put("TestSSID", 0x12345678L);
- homeNetworkIds.put("NullHESSID", null);
- homeSp.setHomeNetworkIds(homeNetworkIds);
- homeSp.setMatchAllOis(new long[] {0x11223344});
- homeSp.setMatchAnyOis(new long[] {0x55667788});
- homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"});
- config.setHomeSp(homeSp);
-
- config.setAaaServerTrustedNames(
- new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"});
-
- // Credential configuration.
- Credential credential = new Credential();
- credential.setCreationTimeInMillis(format.parse("2016-01-01T10:00:00Z").getTime());
- credential.setExpirationTimeInMillis(format.parse("2016-02-01T10:00:00Z").getTime());
- credential.setRealm("shaken.stirred.com");
- credential.setCheckAaaServerCertStatus(true);
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setUsername("james");
- userCredential.setPassword("Ym9uZDAwNw==");
- userCredential.setMachineManaged(true);
- userCredential.setSoftTokenApp("TestApp");
- userCredential.setAbleToShare(true);
- userCredential.setEapType(21);
- userCredential.setNonEapInnerMethod("MS-CHAP-V2");
- credential.setUserCredential(userCredential);
- Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
- certCredential.setCertType("x509v3");
- certCredential.setCertSha256Fingerprint(certFingerprint);
- credential.setCertCredential(certCredential);
- Credential.SimCredential simCredential = new Credential.SimCredential();
- simCredential.setImsi("imsi");
- simCredential.setEapType(24);
- credential.setSimCredential(simCredential);
- config.setCredential(credential);
-
- // Policy configuration.
- Policy policy = new Policy();
- List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>();
- Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
- partner1.setFqdn("test1.fqdn.com");
- partner1.setFqdnExactMatch(true);
- partner1.setPriority(127);
- partner1.setCountries("us,fr");
- Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
- partner2.setFqdn("test2.fqdn.com");
- partner2.setFqdnExactMatch(false);
- partner2.setPriority(200);
- partner2.setCountries("*");
- preferredRoamingPartnerList.add(partner1);
- preferredRoamingPartnerList.add(partner2);
- policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
- policy.setMinHomeDownlinkBandwidth(23412);
- policy.setMinHomeUplinkBandwidth(9823);
- policy.setMinRoamingDownlinkBandwidth(9271);
- policy.setMinRoamingUplinkBandwidth(2315);
- policy.setExcludedSsidList(new String[] {"excludeSSID"});
- Map<Integer, String> requiredProtoPortMap = new HashMap<>();
- requiredProtoPortMap.put(12, "34,92,234");
- policy.setRequiredProtoPortMap(requiredProtoPortMap);
- policy.setMaximumBssLoadValue(23);
- UpdateParameter policyUpdate = new UpdateParameter();
- policyUpdate.setUpdateIntervalInMinutes(120);
- policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
- policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
- policyUpdate.setServerUri("policy.update.com");
- policyUpdate.setUsername("updateUser");
- policyUpdate.setBase64EncodedPassword("updatePass");
- policyUpdate.setTrustRootCertUrl("update.cert.com");
- policyUpdate.setTrustRootCertSha256Fingerprint(certFingerprint);
- policy.setPolicyUpdate(policyUpdate);
- config.setPolicy(policy);
- return config;
- }
-
- /**
- * Parse and verify all supported fields under PPS MO tree.
- *
- * @throws Exception
- */
- @Test
- public void parseValidPPSMOTree() throws Exception {
- String ppsMoTree = loadResourceFile(VALID_PPS_MO_XML_FILE);
- PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree();
- PasspointConfiguration actualConfig = PpsMoParser.parseMoText(ppsMoTree);
- assertTrue(actualConfig.equals(expectedConfig));
- }
-
- @Test
- public void parseNullPPSMOTree() throws Exception {
- assertEquals(null, PpsMoParser.parseMoText(null));
- }
-
- @Test
- public void parseEmptyPPSMOTree() throws Exception {
- assertEquals(null, PpsMoParser.parseMoText(new String()));
- }
-
- @Test
- public void parsePPSMOTreeWithDuplicateHomeSP() throws Exception {
- assertEquals(null, PpsMoParser.parseMoText(
- loadResourceFile(PPS_MO_XML_FILE_DUPLICATE_HOMESP)));
- }
-
- @Test
- public void parsePPSMOTreeWithDuplicateValue() throws Exception {
- assertEquals(null, PpsMoParser.parseMoText(
- loadResourceFile(PPS_MO_XML_FILE_DUPLICATE_VALUE)));
- }
-
- @Test
- public void parsePPSMOTreeWithMissingValue() throws Exception {
- assertEquals(null, PpsMoParser.parseMoText(
- loadResourceFile(PPS_MO_XML_FILE_MISSING_VALUE)));
- }
-
- @Test
- public void parsePPSMOTreeWithMissingName() throws Exception {
- assertEquals(null, PpsMoParser.parseMoText(
- loadResourceFile(PPS_MO_XML_FILE_MISSING_NAME)));
- }
-
- @Test
- public void parsePPSMOTreeWithInvalidNode() throws Exception {
- assertEquals(null, PpsMoParser.parseMoText(
- loadResourceFile(PPS_MO_XML_FILE_INVALID_NODE)));
- }
-
- @Test
- public void parsePPSMOTreeWithInvalidName() throws Exception {
- assertEquals(null, PpsMoParser.parseMoText(
- loadResourceFile(PPS_MO_XML_FILE_INVALID_NAME)));
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java
deleted file mode 100644
index 85d0a90..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java
+++ /dev/null
@@ -1,84 +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.net.wifi.hotspot2.omadm;
-
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.hotspot2.omadm.XMLNode;
-import android.net.wifi.hotspot2.omadm.XMLParser;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.omadm.XMLParser}.
- */
-@SmallTest
-public class XMLParserTest {
- XMLParser mParser;
-
- private static XMLNode createNode(XMLNode parent, String tag, String text) {
- XMLNode node = new XMLNode(parent, tag);
- node.addText(text);
- if (parent != null)
- parent.addChild(node);
- node.close();
- return node;
- }
-
- /**
- * Setup before tests.
- */
- @Before
- public void setUp() throws Exception {
- mParser = new XMLParser();
- }
-
- @Test(expected = IOException.class)
- public void parseNullXML() throws Exception {
- mParser.parse(null);
- }
-
- @Test(expected = IOException.class)
- public void parseEmptyXML() throws Exception {
- mParser.parse(new String());
- }
-
- @Test(expected = SAXException.class)
- public void parseMalformedXML() throws Exception {
- String malformedXmlTree = "<root><child1>test1</child2></root>";
- mParser.parse(malformedXmlTree);
- }
-
- @Test
- public void parseValidXMLTree() throws Exception {
- String xmlTree = "<root><child1>test1</child1><child2>test2</child2></root>";
-
- // Construct the expected XML tree.
- XMLNode expectedRoot = createNode(null, "root", "");
- createNode(expectedRoot, "child1", "test1");
- createNode(expectedRoot, "child2", "test2");
-
- XMLNode actualRoot = mParser.parse(xmlTree);
- assertTrue(actualRoot.equals(expectedRoot));
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
deleted file mode 100644
index 829d8f0..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
+++ /dev/null
@@ -1,619 +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.net.wifi.hotspot2.pps;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.EAPConstants;
-import android.net.wifi.FakeKeys;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.pps.CredentialTest}.
- */
-@SmallTest
-public class CredentialTest {
- /**
- * Helper function for generating Credential for testing.
- *
- * @param userCred Instance of UserCredential
- * @param certCred Instance of CertificateCredential
- * @param simCred Instance of SimCredential
- * @param clientCertificateChain Chain of client certificates
- * @param clientPrivateKey Client private key
- * @param caCerts CA certificates
- * @return {@link Credential}
- */
- private static Credential createCredential(Credential.UserCredential userCred,
- Credential.CertificateCredential certCred,
- Credential.SimCredential simCred,
- X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey,
- X509Certificate... caCerts) {
- Credential cred = new Credential();
- cred.setCreationTimeInMillis(123455L);
- cred.setExpirationTimeInMillis(2310093L);
- cred.setRealm("realm");
- cred.setCheckAaaServerCertStatus(true);
- cred.setUserCredential(userCred);
- cred.setCertCredential(certCred);
- cred.setSimCredential(simCred);
- if (caCerts != null && caCerts.length == 1) {
- cred.setCaCertificate(caCerts[0]);
- } else {
- cred.setCaCertificates(caCerts);
- }
- cred.setClientCertificateChain(clientCertificateChain);
- cred.setClientPrivateKey(clientPrivateKey);
- return cred;
- }
-
- /**
- * Helper function for generating certificate credential for testing.
- *
- * @return {@link Credential}
- */
- private static Credential createCredentialWithCertificateCredential()
- throws NoSuchAlgorithmException, CertificateEncodingException {
- Credential.CertificateCredential certCred = new Credential.CertificateCredential();
- certCred.setCertType("x509v3");
- certCred.setCertSha256Fingerprint(
- MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
- return createCredential(null, certCred, null, new X509Certificate[] {FakeKeys.CLIENT_CERT},
- FakeKeys.RSA_KEY1, FakeKeys.CA_CERT0, FakeKeys.CA_CERT1);
- }
-
- /**
- * Helper function for generating SIM credential for testing.
- *
- * @return {@link Credential}
- */
- private static Credential createCredentialWithSimCredential() {
- Credential.SimCredential simCred = new Credential.SimCredential();
- simCred.setImsi("1234*");
- simCred.setEapType(EAPConstants.EAP_SIM);
- return createCredential(null, null, simCred, null, null, (X509Certificate[]) null);
- }
-
- /**
- * Helper function for generating user credential for testing.
- *
- * @return {@link Credential}
- */
- private static Credential createCredentialWithUserCredential() {
- Credential.UserCredential userCred = new Credential.UserCredential();
- userCred.setUsername("username");
- userCred.setPassword("password");
- userCred.setMachineManaged(true);
- userCred.setAbleToShare(true);
- userCred.setSoftTokenApp("TestApp");
- userCred.setEapType(EAPConstants.EAP_TTLS);
- userCred.setNonEapInnerMethod("MS-CHAP");
- return createCredential(userCred, null, null, null, null, FakeKeys.CA_CERT0);
- }
-
- private static void verifyParcel(Credential writeCred) {
- Parcel parcel = Parcel.obtain();
- writeCred.writeToParcel(parcel, 0);
-
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- Credential readCred = Credential.CREATOR.createFromParcel(parcel);
- assertTrue(readCred.equals(writeCred));
- assertEquals(writeCred.hashCode(), readCred.hashCode());
- }
-
- /**
- * Verify parcel read/write for a default/empty credential.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithDefault() throws Exception {
- verifyParcel(new Credential());
- }
-
- /**
- * Verify parcel read/write for a certificate credential.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithCertificateCredential() throws Exception {
- verifyParcel(createCredentialWithCertificateCredential());
- }
-
- /**
- * Verify parcel read/write for a SIM credential.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithSimCredential() throws Exception {
- verifyParcel(createCredentialWithSimCredential());
- }
-
- /**
- * Verify parcel read/write for a user credential.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithUserCredential() throws Exception {
- verifyParcel(createCredentialWithUserCredential());
- }
-
- /**
- * Verify a valid user credential.
- * @throws Exception
- */
- @Test
- public void validateUserCredential() throws Exception {
- Credential cred = createCredentialWithUserCredential();
-
- // For R1 validation
- assertTrue(cred.validate());
-
- // For R2 validation
- assertTrue(cred.validate());
- }
-
- /**
- * Verify that a user credential without CA Certificate is valid.
- *
- * @throws Exception
- */
- @Test
- public void validateUserCredentialWithoutCaCert() throws Exception {
- Credential cred = createCredentialWithUserCredential();
- cred.setCaCertificate(null);
-
- // Accept a configuration with no CA certificate, the system will use the default cert store
- assertTrue(cred.validate());
- }
-
- /**
- * Verify that a user credential with EAP type other than EAP-TTLS is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUserCredentialWithEapTls() throws Exception {
- Credential cred = createCredentialWithUserCredential();
- cred.getUserCredential().setEapType(EAPConstants.EAP_TLS);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
-
- /**
- * Verify that a user credential without realm is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUserCredentialWithoutRealm() throws Exception {
- Credential cred = createCredentialWithUserCredential();
- cred.setRealm(null);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify that a user credential without username is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUserCredentialWithoutUsername() throws Exception {
- Credential cred = createCredentialWithUserCredential();
- cred.getUserCredential().setUsername(null);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify that a user credential without password is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUserCredentialWithoutPassword() throws Exception {
- Credential cred = createCredentialWithUserCredential();
- cred.getUserCredential().setPassword(null);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify that a user credential without auth methoh (non-EAP inner method) is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUserCredentialWithoutAuthMethod() throws Exception {
- Credential cred = createCredentialWithUserCredential();
- cred.getUserCredential().setNonEapInnerMethod(null);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify a certificate credential. CA Certificate, client certificate chain,
- * and client private key are all required. Also the digest for client
- * certificate must match the fingerprint specified in the certificate credential.
- *
- * @throws Exception
- */
- @Test
- public void validateCertCredential() throws Exception {
- Credential cred = createCredentialWithCertificateCredential();
-
- // For R1 validation
- assertTrue(cred.validate());
-
- // For R2 validation
- assertTrue(cred.validate());
- }
-
- /**
- * Verify that an certificate credential without CA Certificate is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateCertCredentialWithoutCaCert() throws Exception {
- Credential cred = createCredentialWithCertificateCredential();
- cred.setCaCertificate(null);
-
- // Accept a configuration with no CA certificate, the system will use the default cert store
- assertTrue(cred.validate());
- }
-
- /**
- * Verify that a certificate credential without client certificate chain is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateCertCredentialWithoutClientCertChain() throws Exception {
- Credential cred = createCredentialWithCertificateCredential();
- cred.setClientCertificateChain(null);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify that a certificate credential without client private key is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateCertCredentialWithoutClientPrivateKey() throws Exception {
- Credential cred = createCredentialWithCertificateCredential();
- cred.setClientPrivateKey(null);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify that a certificate credential with mismatch client certificate fingerprint
- * is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateCertCredentialWithMismatchFingerprint() throws Exception {
- Credential cred = createCredentialWithCertificateCredential();
- cred.getCertCredential().setCertSha256Fingerprint(new byte[32]);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify a SIM credential using EAP-SIM.
- *
- * @throws Exception
- */
- @Test
- public void validateSimCredentialWithEapSim() throws Exception {
- Credential cred = createCredentialWithSimCredential();
-
- // For R1 validation
- assertTrue(cred.validate());
-
- // For R2 validation
- assertTrue(cred.validate());
- }
-
- /**
- * Verify a SIM credential using EAP-AKA.
- *
- * @throws Exception
- */
- @Test
- public void validateSimCredentialWithEapAka() throws Exception {
- Credential cred = createCredentialWithSimCredential();
- cred.getSimCredential().setEapType(EAPConstants.EAP_AKA);
-
- // For R1 validation
- assertTrue(cred.validate());
-
- // For R2 validation
- assertTrue(cred.validate());
- }
-
- /**
- * Verify a SIM credential using EAP-AKA-PRIME.
- *
- * @throws Exception
- */
- @Test
- public void validateSimCredentialWithEapAkaPrime() throws Exception {
- Credential cred = createCredentialWithSimCredential();
- cred.getSimCredential().setEapType(EAPConstants.EAP_AKA_PRIME);
-
- // For R1 validation
- assertTrue(cred.validate());
-
- // For R2 validation
- assertTrue(cred.validate());
- }
-
- /**
- * Verify that a SIM credential without IMSI is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateSimCredentialWithoutIMSI() throws Exception {
- Credential cred = createCredentialWithSimCredential();
- cred.getSimCredential().setImsi(null);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify that a SIM credential with an invalid IMSI is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateSimCredentialWithInvalidIMSI() throws Exception {
- Credential cred = createCredentialWithSimCredential();
- cred.getSimCredential().setImsi("dummy");
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify that a SIM credential with invalid EAP type is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateSimCredentialWithEapTls() throws Exception {
- Credential cred = createCredentialWithSimCredential();
- cred.getSimCredential().setEapType(EAPConstants.EAP_TLS);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify that a credential contained both a user and a SIM credential is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateCredentialWithUserAndSimCredential() throws Exception {
- Credential cred = createCredentialWithUserCredential();
- // Setup SIM credential.
- Credential.SimCredential simCredential = new Credential.SimCredential();
- simCredential.setImsi("1234*");
- simCredential.setEapType(EAPConstants.EAP_SIM);
- cred.setSimCredential(simCredential);
-
- // For R1 validation
- assertFalse(cred.validate());
-
- // For R2 validation
- assertFalse(cred.validate());
- }
-
- /**
- * Verify that copy constructor works when pass in a null source.
- *
- * @throws Exception
- */
- @Test
- public void validateCopyConstructorWithNullSource() throws Exception {
- Credential copyCred = new Credential(null);
- Credential defaultCred = new Credential();
- assertTrue(copyCred.equals(defaultCred));
- }
-
- /**
- * Verify that copy constructor works when pass in a source with user credential.
- *
- * @throws Exception
- */
- @Test
- public void validateCopyConstructorWithSourceWithUserCred() throws Exception {
- Credential sourceCred = createCredentialWithUserCredential();
- Credential copyCred = new Credential(sourceCred);
- assertTrue(copyCred.equals(sourceCred));
- }
-
- /**
- * Verify that copy constructor works when pass in a source with certificate credential.
- *
- * @throws Exception
- */
- @Test
- public void validateCopyConstructorWithSourceWithCertCred() throws Exception {
- Credential sourceCred = createCredentialWithCertificateCredential();
- Credential copyCred = new Credential(sourceCred);
- assertTrue(copyCred.equals(sourceCred));
- }
-
- /**
- * Verify that copy constructor works when pass in a source with SIM credential.
- *
- * @throws Exception
- */
- @Test
- public void validateCopyConstructorWithSourceWithSimCred() throws Exception {
- Credential sourceCred = createCredentialWithSimCredential();
- Credential copyCred = new Credential(sourceCred);
- assertTrue(copyCred.equals(sourceCred));
- }
-
- /**
- * Verify that two certificates are identical.
- */
- @Test
- public void validateTwoCertificateIdentical() {
- assertTrue(Credential.isX509CertificateEquals(FakeKeys.CA_CERT1, FakeKeys.CA_CERT1));
- }
-
- /**
- * Verify that two certificates are different.
- */
- @Test
- public void validateTwoCertificateDifferent() {
- assertFalse(Credential.isX509CertificateEquals(FakeKeys.CA_CERT0, FakeKeys.CA_CERT1));
- }
-
- /**
- * Verify that unique identifiers are the same for objects with the same credentials
- */
- @Test
- public void testUniqueIdSameCredentialTypes() throws Exception {
- assertEquals(createCredentialWithSimCredential().getUniqueId(),
- createCredentialWithSimCredential().getUniqueId());
- assertEquals(createCredentialWithCertificateCredential().getUniqueId(),
- createCredentialWithCertificateCredential().getUniqueId());
- assertEquals(createCredentialWithUserCredential().getUniqueId(),
- createCredentialWithUserCredential().getUniqueId());
- }
-
- /**
- * Verify that unique identifiers are different for each credential
- */
- @Test
- public void testUniqueIdDifferentForDifferentCredentialTypes() throws Exception {
- Credential simCred = createCredentialWithSimCredential();
- Credential certCred = createCredentialWithCertificateCredential();
- Credential userCred = createCredentialWithUserCredential();
-
- assertNotEquals(simCred.getUniqueId(), userCred.getUniqueId());
- assertNotEquals(simCred.getUniqueId(), certCred.getUniqueId());
- assertNotEquals(certCred.getUniqueId(), userCred.getUniqueId());
- }
-
- /**
- * Verify that unique identifiers are different for a credential with different values
- */
- @Test
- public void testUniqueIdDifferentForSimCredentialsWithDifferentValues() throws Exception {
- Credential simCred1 = createCredentialWithSimCredential();
- Credential simCred2 = createCredentialWithSimCredential();
- simCred2.getSimCredential().setImsi("567890*");
-
- assertNotEquals(simCred1.getUniqueId(), simCred2.getUniqueId());
- }
-
- /**
- * Verify that unique identifiers are different for a credential with different values
- */
- @Test
- public void testUniqueIdDifferentForUserCredentialsWithDifferentValues() throws Exception {
- Credential userCred1 = createCredentialWithUserCredential();
- Credential userCred2 = createCredentialWithUserCredential();
- userCred2.getUserCredential().setUsername("anotheruser");
-
- assertNotEquals(userCred1.getUniqueId(), userCred2.getUniqueId());
- }
-
- /**
- * Verify that unique identifiers are different for a credential with different values
- */
- @Test
- public void testUniqueIdDifferentForCertCredentialsWithDifferentValues() throws Exception {
- Credential certCred1 = createCredentialWithCertificateCredential();
- Credential certCred2 = createCredentialWithCertificateCredential();
- certCred2.getCertCredential().setCertSha256Fingerprint(
- MessageDigest.getInstance("SHA-256").digest(FakeKeys.CA_CERT0.getEncoded()));
-
- assertNotEquals(certCred1.getUniqueId(), certCred2.getUniqueId());
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
deleted file mode 100644
index 93d471a..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
+++ /dev/null
@@ -1,221 +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.net.wifi.hotspot2.pps;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.pps.HomeSp}.
- */
-@SmallTest
-public class HomeSpTest {
-
- /**
- * Helper function for creating a map of home network IDs for testing.
- *
- * @return Map of home network IDs
- */
- private static Map<String, Long> createHomeNetworkIds() {
- Map<String, Long> homeNetworkIds = new HashMap<>();
- homeNetworkIds.put("ssid", 0x1234L);
- homeNetworkIds.put("nullhessid", null);
- return homeNetworkIds;
- }
-
- /**
- * Helper function for creating a HomeSp for testing.
- *
- * @param homeNetworkIds The map of home network IDs associated with HomeSp
- * @return {@link HomeSp}
- */
- private static HomeSp createHomeSp(Map<String, Long> homeNetworkIds) {
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn("fqdn");
- homeSp.setFriendlyName("friendly name");
- homeSp.setIconUrl("icon.url");
- homeSp.setHomeNetworkIds(homeNetworkIds);
- homeSp.setMatchAllOis(new long[] {0x11L, 0x22L});
- homeSp.setMatchAnyOis(new long[] {0x33L, 0x44L});
- homeSp.setOtherHomePartners(new String[] {"partner1", "partner2"});
- homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
- return homeSp;
- }
-
- /**
- * Helper function for creating a HomeSp with home network IDs for testing.
- *
- * @return {@link HomeSp}
- */
- private static HomeSp createHomeSpWithHomeNetworkIds() {
- return createHomeSp(createHomeNetworkIds());
- }
-
- /**
- * Helper function for creating a HomeSp without home network IDs for testing.
- *
- * @return {@link HomeSp}
- */
- private static HomeSp createHomeSpWithoutHomeNetworkIds() {
- return createHomeSp(null);
- }
-
- /**
- * Helper function for verifying HomeSp after parcel write then read.
- * @param writeHomeSp
- * @throws Exception
- */
- private static void verifyParcel(HomeSp writeHomeSp) throws Exception {
- Parcel parcel = Parcel.obtain();
- writeHomeSp.writeToParcel(parcel, 0);
-
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- HomeSp readHomeSp = HomeSp.CREATOR.createFromParcel(parcel);
- assertTrue(readHomeSp.equals(writeHomeSp));
- }
-
- /**
- * Verify parcel read/write for an empty HomeSp.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithEmptyHomeSp() throws Exception {
- verifyParcel(new HomeSp());
- }
-
- /**
- * Verify parcel read/write for a HomeSp containing Home Network IDs.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithHomeNetworkIds() throws Exception {
- verifyParcel(createHomeSpWithHomeNetworkIds());
- }
-
- /**
- * Verify parcel read/write for a HomeSp without Home Network IDs.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutHomeNetworkIds() throws Exception {
- verifyParcel(createHomeSpWithoutHomeNetworkIds());
- }
-
- /**
- * Verify that a HomeSp is valid when both FQDN and Friendly Name
- * are provided.
- *
- * @throws Exception
- */
- @Test
- public void validateValidHomeSp() throws Exception {
- HomeSp homeSp = createHomeSpWithHomeNetworkIds();
- assertTrue(homeSp.validate());
- }
-
- /**
- * Verify that a HomeSp is not valid when FQDN is not provided
- *
- * @throws Exception
- */
- @Test
- public void validateHomeSpWithoutFqdn() throws Exception {
- HomeSp homeSp = createHomeSpWithHomeNetworkIds();
- homeSp.setFqdn(null);
- assertFalse(homeSp.validate());
- }
-
- /**
- * Verify that a HomeSp is not valid when Friendly Name is not provided
- *
- * @throws Exception
- */
- @Test
- public void validateHomeSpWithoutFriendlyName() throws Exception {
- HomeSp homeSp = createHomeSpWithHomeNetworkIds();
- homeSp.setFriendlyName(null);
- assertFalse(homeSp.validate());
- }
-
- /**
- * Verify that a HomeSp is valid when the optional Home Network IDs are
- * not provided.
- *
- * @throws Exception
- */
- @Test
- public void validateHomeSpWithoutHomeNetworkIds() throws Exception {
- HomeSp homeSp = createHomeSpWithoutHomeNetworkIds();
- assertTrue(homeSp.validate());
- }
-
- /**
- * Verify that a HomeSp is invalid when the optional Home Network IDs
- * contained an invalid SSID (exceeding maximum number of bytes).
- *
- * @throws Exception
- */
- @Test
- public void validateHomeSpWithInvalidHomeNetworkIds() throws Exception {
- HomeSp homeSp = createHomeSpWithoutHomeNetworkIds();
- // HomeNetworkID with SSID exceeding the maximum length.
- Map<String, Long> homeNetworkIds = new HashMap<>();
- byte[] rawSsidBytes = new byte[33];
- Arrays.fill(rawSsidBytes, (byte) 'a');
- homeNetworkIds.put(new String(rawSsidBytes, StandardCharsets.UTF_8), 0x1234L);
- homeSp.setHomeNetworkIds(homeNetworkIds);
- assertFalse(homeSp.validate());
- }
-
- /**
- * Verify that copy constructor works when pass in a null source.
- *
- * @throws Exception
- */
- @Test
- public void validateCopyConstructorFromNullSource() throws Exception {
- HomeSp copySp = new HomeSp(null);
- HomeSp defaultSp = new HomeSp();
- assertTrue(copySp.equals(defaultSp));
- }
-
- /**
- * Verify that copy constructor works when pass in a valid source.
- *
- * @throws Exception
- */
- @Test
- public void validateCopyConstructorFromValidSource() throws Exception {
- HomeSp sourceSp = createHomeSpWithHomeNetworkIds();
- HomeSp copySp = new HomeSp(sourceSp);
- assertTrue(copySp.equals(sourceSp));
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/PolicyTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/PolicyTest.java
deleted file mode 100644
index 980b199..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/PolicyTest.java
+++ /dev/null
@@ -1,312 +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.net.wifi.hotspot2.pps;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-import android.util.Base64;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.pps.Policy}.
- */
-@SmallTest
-public class PolicyTest {
- private static final int MAX_NUMBER_OF_EXCLUDED_SSIDS = 128;
- private static final int MAX_SSID_BYTES = 32;
- private static final int MAX_PORT_STRING_BYTES = 64;
-
- /**
- * Helper function for creating a {@link Policy} for testing.
- *
- * @return {@link Policy}
- */
- private static Policy createPolicy() {
- Policy policy = new Policy();
- policy.setMinHomeDownlinkBandwidth(123);
- policy.setMinHomeUplinkBandwidth(345);
- policy.setMinRoamingDownlinkBandwidth(567);
- policy.setMinRoamingUplinkBandwidth(789);
- policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"});
- Map<Integer, String> requiredProtoPortMap = new HashMap<>();
- requiredProtoPortMap.put(12, "23,342,123");
- requiredProtoPortMap.put(23, "789,372,1235");
- policy.setRequiredProtoPortMap(requiredProtoPortMap);
- policy.setMaximumBssLoadValue(12);
-
- List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>();
- Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
- partner1.setFqdn("partner1.com");
- partner1.setFqdnExactMatch(true);
- partner1.setPriority(12);
- partner1.setCountries("us,jp");
- Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
- partner2.setFqdn("partner2.com");
- partner2.setFqdnExactMatch(false);
- partner2.setPriority(42);
- partner2.setCountries("ca,fr");
- preferredRoamingPartnerList.add(partner1);
- preferredRoamingPartnerList.add(partner2);
- policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
-
- UpdateParameter policyUpdate = new UpdateParameter();
- policyUpdate.setUpdateIntervalInMinutes(1712);
- policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
- policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
- policyUpdate.setServerUri("policy.update.com");
- policyUpdate.setUsername("username");
- policyUpdate.setBase64EncodedPassword(
- Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
- policyUpdate.setTrustRootCertUrl("trust.cert.com");
- policyUpdate.setTrustRootCertSha256Fingerprint(new byte[32]);
- policy.setPolicyUpdate(policyUpdate);
-
- return policy;
- }
-
- /**
- * Helper function for verifying Policy after parcel write then read.
- * @param policyToWrite
- * @throws Exception
- */
- private static void verifyParcel(Policy policyToWrite) throws Exception {
- Parcel parcel = Parcel.obtain();
- policyToWrite.writeToParcel(parcel, 0);
-
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- Policy policyFromRead = Policy.CREATOR.createFromParcel(parcel);
- assertTrue(policyFromRead.equals(policyToWrite));
- }
-
- /**
- * Verify parcel read/write for an empty Policy.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithEmptyPolicy() throws Exception {
- verifyParcel(new Policy());
- }
-
- /**
- * Verify parcel read/write for a Policy with all fields set.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithFullPolicy() throws Exception {
- verifyParcel(createPolicy());
- }
-
- /**
- * Verify parcel read/write for a Policy without protocol port map.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutProtoPortMap() throws Exception {
- Policy policy = createPolicy();
- policy.setRequiredProtoPortMap(null);
- verifyParcel(policy);
- }
-
- /**
- * Verify parcel read/write for a Policy without preferred roaming partner list.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutPreferredRoamingPartnerList() throws Exception {
- Policy policy = createPolicy();
- policy.setPreferredRoamingPartnerList(null);
- verifyParcel(policy);
- }
-
- /**
- * Verify parcel read/write for a Policy without policy update parameters.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithoutPolicyUpdate() throws Exception {
- Policy policy = createPolicy();
- policy.setPolicyUpdate(null);
- verifyParcel(policy);
- }
-
- /**
- * Verify that policy created using copy constructor with null source should be the same
- * as the policy created using default constructor.
- *
- * @throws Exception
- */
- @Test
- public void verifyCopyConstructionWithNullSource() throws Exception {
- Policy copyPolicy = new Policy(null);
- Policy defaultPolicy = new Policy();
- assertTrue(defaultPolicy.equals(copyPolicy));
- }
-
- /**
- * Verify that policy created using copy constructor with a valid source should be the
- * same as the source.
- *
- * @throws Exception
- */
- @Test
- public void verifyCopyConstructionWithFullPolicy() throws Exception {
- Policy policy = createPolicy();
- Policy copyPolicy = new Policy(policy);
- assertTrue(policy.equals(copyPolicy));
- }
-
- /**
- * Verify that a default policy (with no informatio) is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validatePolicyWithDefault() throws Exception {
- Policy policy = new Policy();
- assertFalse(policy.validate());
- }
-
- /**
- * Verify that a policy created using {@link #createPolicy} is valid, since all fields are
- * filled in with valid values.
- *
- * @throws Exception
- */
- @Test
- public void validatePolicyWithFullPolicy() throws Exception {
- assertTrue(createPolicy().validate());
- }
-
- /**
- * Verify that a policy without policy update parameters is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validatePolicyWithoutPolicyUpdate() throws Exception {
- Policy policy = createPolicy();
- policy.setPolicyUpdate(null);
- assertFalse(policy.validate());
- }
-
- /**
- * Verify that a policy with invalid policy update parameters is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validatePolicyWithInvalidPolicyUpdate() throws Exception {
- Policy policy = createPolicy();
- policy.setPolicyUpdate(new UpdateParameter());
- assertFalse(policy.validate());
- }
-
- /**
- * Verify that a policy with a preferred roaming partner with FQDN not specified is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validatePolicyWithRoamingPartnerWithoutFQDN() throws Exception {
- Policy policy = createPolicy();
- Policy.RoamingPartner partner = new Policy.RoamingPartner();
- partner.setFqdnExactMatch(true);
- partner.setPriority(12);
- partner.setCountries("us,jp");
- policy.getPreferredRoamingPartnerList().add(partner);
- assertFalse(policy.validate());
- }
-
- /**
- * Verify that a policy with a preferred roaming partner with countries not specified is
- * invalid.
- *
- * @throws Exception
- */
- @Test
- public void validatePolicyWithRoamingPartnerWithoutCountries() throws Exception {
- Policy policy = createPolicy();
- Policy.RoamingPartner partner = new Policy.RoamingPartner();
- partner.setFqdn("test.com");
- partner.setFqdnExactMatch(true);
- partner.setPriority(12);
- policy.getPreferredRoamingPartnerList().add(partner);
- assertFalse(policy.validate());
- }
-
- /**
- * Verify that a policy with a proto-port tuple that contains an invalid port string is
- * invalid.
- *
- * @throws Exception
- */
- @Test
- public void validatePolicyWithInvalidPortStringInProtoPortMap() throws Exception {
- Policy policy = createPolicy();
- byte[] rawPortBytes = new byte[MAX_PORT_STRING_BYTES + 1];
- policy.getRequiredProtoPortMap().put(
- 324, new String(rawPortBytes, StandardCharsets.UTF_8));
- assertFalse(policy.validate());
- }
-
- /**
- * Verify that a policy with number of excluded SSIDs exceeded the max is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validatePolicyWithSsidExclusionListSizeExceededMax() throws Exception {
- Policy policy = createPolicy();
- String[] excludedSsidList = new String[MAX_NUMBER_OF_EXCLUDED_SSIDS + 1];
- Arrays.fill(excludedSsidList, "ssid");
- policy.setExcludedSsidList(excludedSsidList);
- assertFalse(policy.validate());
- }
-
- /**
- * Verify that a policy with an invalid SSID in the excluded SSID list is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validatePolicyWithInvalidSsid() throws Exception {
- Policy policy = createPolicy();
- byte[] rawSsidBytes = new byte[MAX_SSID_BYTES + 1];
- Arrays.fill(rawSsidBytes, (byte) 'a');
- String[] excludedSsidList = new String[] {
- new String(rawSsidBytes, StandardCharsets.UTF_8)};
- policy.setExcludedSsidList(excludedSsidList);
- assertFalse(policy.validate());
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/UpdateParameterTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/UpdateParameterTest.java
deleted file mode 100644
index 07cb151..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/UpdateParameterTest.java
+++ /dev/null
@@ -1,349 +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.net.wifi.hotspot2.pps;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.FakeKeys;
-import android.os.Parcel;
-import android.util.Base64;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.pps.UpdateParameter}.
- */
-@SmallTest
-public class UpdateParameterTest {
- private static final int MAX_URI_BYTES = 1023;
- private static final int MAX_URL_BYTES = 1023;
- private static final int MAX_USERNAME_BYTES = 63;
- private static final int MAX_PASSWORD_BYTES = 255;
- private static final int CERTIFICATE_SHA256_BYTES = 32;
-
- /**
- * Helper function for creating a {@link UpdateParameter} for testing.
- *
- * @return {@link UpdateParameter}
- */
- private static UpdateParameter createUpdateParameter() {
- UpdateParameter updateParam = new UpdateParameter();
- updateParam.setUpdateIntervalInMinutes(1712);
- updateParam.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
- updateParam.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
- updateParam.setServerUri("server.pdate.com");
- updateParam.setUsername("username");
- updateParam.setBase64EncodedPassword(
- Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
- updateParam.setTrustRootCertUrl("trust.cert.com");
- updateParam.setTrustRootCertSha256Fingerprint(new byte[32]);
- updateParam.setCaCertificate(FakeKeys.CA_CERT0);
- return updateParam;
- }
-
- /**
- * Helper function for verifying UpdateParameter after parcel write then read.
- * @param paramToWrite The UpdateParamter to verify
- * @throws Exception
- */
- private static void verifyParcel(UpdateParameter paramToWrite) throws Exception {
- Parcel parcel = Parcel.obtain();
- paramToWrite.writeToParcel(parcel, 0);
-
- parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- UpdateParameter paramFromRead = UpdateParameter.CREATOR.createFromParcel(parcel);
- assertTrue(paramFromRead.equals(paramToWrite));
- assertEquals(paramToWrite.hashCode(), paramFromRead.hashCode());
- }
-
- /**
- * Verify parcel read/write for an empty UpdateParameter.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithEmptyUpdateParameter() throws Exception {
- verifyParcel(new UpdateParameter());
- }
-
- /**
- * Verify parcel read/write for a UpdateParameter with all fields set.
- *
- * @throws Exception
- */
- @Test
- public void verifyParcelWithFullUpdateParameter() throws Exception {
- verifyParcel(createUpdateParameter());
- }
-
- /**
- * Verify that UpdateParameter created using copy constructor with null source should be the
- * same as the UpdateParameter created using default constructor.
- *
- * @throws Exception
- */
- @Test
- public void verifyCopyConstructionWithNullSource() throws Exception {
- UpdateParameter copyParam = new UpdateParameter(null);
- UpdateParameter defaultParam = new UpdateParameter();
- assertTrue(defaultParam.equals(copyParam));
- }
-
- /**
- * Verify that UpdateParameter created using copy constructor with a valid source should be the
- * same as the source.
- *
- * @throws Exception
- */
- @Test
- public void verifyCopyConstructionWithFullUpdateParameter() throws Exception {
- UpdateParameter origParam = createUpdateParameter();
- UpdateParameter copyParam = new UpdateParameter(origParam);
- assertTrue(origParam.equals(copyParam));
- }
-
- /**
- * Verify that a default UpdateParameter is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithDefault() throws Exception {
- UpdateParameter updateParam = new UpdateParameter();
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter created using {@link #createUpdateParameter} is valid,
- * since all fields are filled in with valid values.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithFullPolicy() throws Exception {
- assertTrue(createUpdateParameter().validate());
- }
-
- /**
- * Verify that an UpdateParameter with an unknown update method is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithUnknowMethod() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- updateParam.setUpdateMethod("adsfasd");
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with an unknown restriction is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithUnknowRestriction() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- updateParam.setRestriction("adsfasd");
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with an username exceeding maximum size is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithUsernameExceedingMaxSize() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- byte[] rawUsernameBytes = new byte[MAX_USERNAME_BYTES + 1];
- Arrays.fill(rawUsernameBytes, (byte) 'a');
- updateParam.setUsername(new String(rawUsernameBytes, StandardCharsets.UTF_8));
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with an empty username is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithEmptyUsername() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- updateParam.setUsername(null);
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with a password exceeding maximum size is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithPasswordExceedingMaxSize() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- byte[] rawPasswordBytes = new byte[MAX_PASSWORD_BYTES + 1];
- Arrays.fill(rawPasswordBytes, (byte) 'a');
- updateParam.setBase64EncodedPassword(new String(rawPasswordBytes, StandardCharsets.UTF_8));
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with an empty password is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithEmptyPassword() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- updateParam.setBase64EncodedPassword(null);
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with a Base64 encoded password that contained invalid padding
- * is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithPasswordContainedInvalidPadding() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- updateParam.setBase64EncodedPassword(updateParam.getBase64EncodedPassword() + "=");
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter without trust root certificate URL is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithoutTrustRootCertUrl() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- updateParam.setTrustRootCertUrl(null);
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with invalid trust root certificate URL is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithInvalidTrustRootCertUrl() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1];
- Arrays.fill(rawUrlBytes, (byte) 'a');
- updateParam.setTrustRootCertUrl(new String(rawUrlBytes, StandardCharsets.UTF_8));
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter without trust root certificate SHA-256 fingerprint is
- * invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithouttrustRootCertSha256Fingerprint() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- updateParam.setTrustRootCertSha256Fingerprint(null);
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with an incorrect size trust root certificate SHA-256
- * fingerprint is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithInvalidtrustRootCertSha256Fingerprint() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- updateParam.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_SHA256_BYTES + 1]);
- assertFalse(updateParam.validate());
-
- updateParam.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_SHA256_BYTES - 1]);
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter without server URI is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithoutServerUri() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- updateParam.setServerUri(null);
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with an invalid server URI is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validatePolicyWithInvalidServerUri() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- byte[] rawUriBytes = new byte[MAX_URI_BYTES + 1];
- Arrays.fill(rawUriBytes, (byte) 'a');
- updateParam.setServerUri(new String(rawUriBytes, StandardCharsets.UTF_8));
- assertFalse(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with update interval set to "never" will not perform
- * validation on other parameters, since update is not applicable in this case.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithNoServerCheck() throws Exception {
- UpdateParameter updateParam = new UpdateParameter();
- updateParam.setUpdateIntervalInMinutes(UpdateParameter.UPDATE_CHECK_INTERVAL_NEVER);
- updateParam.setUsername(null);
- updateParam.setBase64EncodedPassword(null);
- updateParam.setUpdateMethod(null);
- updateParam.setRestriction(null);
- updateParam.setServerUri(null);
- updateParam.setTrustRootCertUrl(null);
- updateParam.setTrustRootCertSha256Fingerprint(null);
- assertTrue(updateParam.validate());
- }
-
- /**
- * Verify that an UpdateParameter with unset update interval is invalid.
- *
- * @throws Exception
- */
- @Test
- public void validateUpdateParameterWithoutUpdateInterval() throws Exception {
- UpdateParameter updateParam = createUpdateParameter();
- updateParam.setUpdateIntervalInMinutes(Long.MIN_VALUE);
- assertFalse(updateParam.validate());
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
deleted file mode 100644
index 6199325..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
+++ /dev/null
@@ -1,173 +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.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pConfig}
- */
-@SmallTest
-public class WifiP2pConfigTest {
-
- private static final String DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff";
- /**
- * Check network name setter
- */
- @Test
- public void testBuilderInvalidNetworkName() throws Exception {
- WifiP2pConfig.Builder b = new WifiP2pConfig.Builder();
-
- // sunny case
- try {
- b.setNetworkName("DIRECT-ab-Hello");
- } catch (IllegalArgumentException e) {
- fail("Unexpected IllegalArgumentException");
- }
-
- // sunny case, no trailing string
- try {
- b.setNetworkName("DIRECT-WR");
- } catch (IllegalArgumentException e) {
- fail("Unexpected IllegalArgumentException");
- }
-
- // sunny case with maximum bytes for the network name
- try {
- b.setNetworkName("DIRECT-abcdefghijklmnopqrstuvwxy");
- } catch (IllegalArgumentException e) {
- fail("Unexpected IllegalArgumentException");
- }
-
- // less than 9 characters.
- try {
- b.setNetworkName("DIRECT-z");
- fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) { }
-
- // not starts with DIRECT-xy.
- try {
- b.setNetworkName("ABCDEFGHIJK");
- fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) { }
-
- // not starts with uppercase DIRECT-xy
- try {
- b.setNetworkName("direct-ab");
- fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) { }
-
- // x and y are not selected from upper case letters, lower case letters or
- // numbers.
- try {
- b.setNetworkName("direct-a?");
- fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) { }
-
- // over maximum bytes
- try {
- b.setNetworkName("DIRECT-abcdefghijklmnopqrstuvwxyz");
- fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) { }
- }
-
- /**
- * Check passphrase setter
- */
- @Test
- public void testBuilderInvalidPassphrase() throws Exception {
- WifiP2pConfig.Builder b = new WifiP2pConfig.Builder();
-
- // sunny case
- try {
- b.setPassphrase("abcd1234");
- } catch (IllegalArgumentException e) {
- fail("Unexpected IllegalArgumentException");
- }
-
- // null string.
- try {
- b.setPassphrase(null);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected exception.
- }
-
- // less than 8 characters.
- try {
- b.setPassphrase("12abcde");
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected exception.
- }
-
- // more than 63 characters.
- try {
- b.setPassphrase(
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+/");
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected exception.
- }
- }
-
- @Test
- /*
- * Verify WifiP2pConfig basic operations
- */
- public void testWifiP2pConfig() throws Exception {
- WifiP2pConfig config = new WifiP2pConfig();
- config.deviceAddress = DEVICE_ADDRESS;
-
- WifiP2pConfig copiedConfig = new WifiP2pConfig(config);
- // no equals operator, use toString for comparison.
- assertEquals(config.toString(), copiedConfig.toString());
-
- Parcel parcelW = Parcel.obtain();
- config.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiP2pConfig configFromParcel = WifiP2pConfig.CREATOR.createFromParcel(parcelR);
-
- // no equals operator, use toString for comparison.
- assertEquals(config.toString(), configFromParcel.toString());
-
- }
-
- @Test
- /*
- * Verify WifiP2pConfig invalidate API
- */
- public void testInvalidate() throws Exception {
- WifiP2pConfig config = new WifiP2pConfig();
- config.deviceAddress = DEVICE_ADDRESS;
- config.invalidate();
- assertEquals("", config.deviceAddress);
- }
-
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java
deleted file mode 100644
index 22936bd..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java
+++ /dev/null
@@ -1,75 +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.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pDeviceList}
- */
-@SmallTest
-public class WifiP2pDeviceListTest {
-
- private static final WifiP2pDevice TEST_DEVICE_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:ff");
- private static final WifiP2pDevice TEST_DEVICE_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:f1");
- private static final WifiP2pDevice TEST_DEVICE_3 = new WifiP2pDevice("11:22:33:44:55:66");
- private static final WifiP2pDevice TEST_DEVICE_4 = new WifiP2pDevice("a0:b0:c0:d0:e0:f0");
-
- /**
- * Verify basic operations.
- */
- @Test
- public void testListOperations() throws Exception {
- WifiP2pDeviceList list = new WifiP2pDeviceList();
- list.update(TEST_DEVICE_1);
- list.update(TEST_DEVICE_2);
- list.update(TEST_DEVICE_3);
- assertEquals(3, list.getDeviceList().size());
-
- assertEquals(TEST_DEVICE_1, list.get(TEST_DEVICE_1.deviceAddress));
- assertEquals(null, list.get(TEST_DEVICE_4.deviceAddress));
-
- list.remove(TEST_DEVICE_2.deviceAddress);
- assertEquals(null, list.get(TEST_DEVICE_2.deviceAddress));
-
- list.remove(TEST_DEVICE_3);
- assertEquals(null, list.get(TEST_DEVICE_3.deviceAddress));
-
- assertEquals(1, list.getDeviceList().size());
-
- list.clear();
- assertEquals(0, list.getDeviceList().size());
-
- Parcel parcelW = Parcel.obtain();
- list.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiP2pDeviceList fromParcel = WifiP2pDeviceList.CREATOR.createFromParcel(parcelR);
-
- assertEquals(list.toString(), fromParcel.toString());
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java
deleted file mode 100644
index 6edc287..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java
+++ /dev/null
@@ -1,118 +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.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pDevice}
- */
-@SmallTest
-public class WifiP2pDeviceTest {
-
- /**
- * Compare two p2p devices.
- *
- * @param devA is the first device to be compared
- * @param devB is the second device to be compared
- */
- private void compareWifiP2pDevices(WifiP2pDevice devA, WifiP2pDevice devB) {
- assertEquals(devA.deviceName, devB.deviceName);
- assertEquals(devA.deviceAddress, devB.deviceAddress);
- assertEquals(devA.primaryDeviceType, devB.primaryDeviceType);
- assertEquals(devA.secondaryDeviceType, devB.secondaryDeviceType);
- assertEquals(devA.wpsConfigMethodsSupported, devB.wpsConfigMethodsSupported);
- assertEquals(devA.deviceCapability, devB.deviceCapability);
- assertEquals(devA.groupCapability, devB.groupCapability);
- assertEquals(devA.status, devB.status);
- if (devA.wfdInfo != null) {
- assertEquals(devA.wfdInfo.isEnabled(), devB.wfdInfo.isEnabled());
- assertEquals(devA.wfdInfo.getDeviceInfoHex(), devB.wfdInfo.getDeviceInfoHex());
- assertEquals(devA.wfdInfo.getControlPort(), devB.wfdInfo.getControlPort());
- assertEquals(devA.wfdInfo.getMaxThroughput(), devB.wfdInfo.getMaxThroughput());
- } else {
- assertEquals(devA.wfdInfo, devB.wfdInfo);
- }
- }
-
- /**
- * Check equals and hashCode consistency
- */
- @Test
- public void testEqualsWithHashCode() throws Exception {
- WifiP2pDevice dev_a = new WifiP2pDevice();
- dev_a.deviceAddress = new String("02:90:4c:a0:92:54");
- WifiP2pDevice dev_b = new WifiP2pDevice();
- dev_b.deviceAddress = new String("02:90:4c:a0:92:54");
-
- assertTrue(dev_a.equals(dev_b));
- assertEquals(dev_a.hashCode(), dev_b.hashCode());
- }
-
- /**
- * Check the copy constructor with default values.
- */
- @Test
- public void testCopyConstructorWithDefaultValues() throws Exception {
- WifiP2pDevice device = new WifiP2pDevice();
- WifiP2pDevice copy = new WifiP2pDevice(device);
- compareWifiP2pDevices(device, copy);
- }
-
- /**
- * Check the copy constructor with updated values.
- */
- @Test
- public void testCopyConstructorWithUpdatedValues() throws Exception {
- WifiP2pDevice device = new WifiP2pDevice();
- device.deviceName = "deviceName";
- device.deviceAddress = "11:22:33:44:55:66";
- device.primaryDeviceType = "primaryDeviceType";
- device.secondaryDeviceType = "secondaryDeviceType";
- device.wpsConfigMethodsSupported = 0x0008;
- device.deviceCapability = 1;
- device.groupCapability = 1;
- device.status = WifiP2pDevice.CONNECTED;
- device.wfdInfo = new WifiP2pWfdInfo();
- WifiP2pDevice copy = new WifiP2pDevice(device);
- compareWifiP2pDevices(device, copy);
- }
-
- /**
- * Check the copy constructor when the wfdInfo of the source object is null.
- */
- @Test
- public void testCopyConstructorWithNullWfdInfo() throws Exception {
- WifiP2pDevice device = new WifiP2pDevice();
- device.deviceName = "deviceName";
- device.deviceAddress = "11:22:33:44:55:66";
- device.primaryDeviceType = "primaryDeviceType";
- device.secondaryDeviceType = "secondaryDeviceType";
- device.wpsConfigMethodsSupported = 0x0008;
- device.deviceCapability = 1;
- device.groupCapability = 1;
- device.status = WifiP2pDevice.CONNECTED;
- device.wfdInfo = null;
- WifiP2pDevice copy = new WifiP2pDevice(device);
- compareWifiP2pDevices(device, copy);
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java
deleted file mode 100644
index 2402f5b..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pGroupList}
- */
-@SmallTest
-public class WifiP2pGroupListTest {
-
- private static final WifiP2pDevice TEST_GROUP_OWNER_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:f0");
- private static final WifiP2pDevice TEST_GROUP_OWNER_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:f1");
- private static final WifiP2pDevice TEST_GROUP_OWNER_3 = new WifiP2pDevice("aa:bb:cc:dd:ee:f2");
- private static final WifiP2pDevice TEST_GROUP_OWNER_OTHER =
- new WifiP2pDevice("aa:bb:cc:dd:ee:f3");
-
- private WifiP2pGroup mTestGroup1;
- private WifiP2pGroup mTestGroup2;
- private WifiP2pGroup mTestGroup3;
- private WifiP2pGroup mTestGroup4;
-
- private WifiP2pGroup createGroup(
- int networkId, String networkName,
- String passphrase, boolean isGo,
- WifiP2pDevice goDev) {
- WifiP2pGroup group = new WifiP2pGroup();
- group.setNetworkId(networkId);
- group.setNetworkName(networkName);
- group.setPassphrase(passphrase);
- group.setIsGroupOwner(isGo);
- group.setOwner(goDev);
- return group;
- }
-
- @Before
- public void setUp() throws Exception {
- mTestGroup1 = createGroup(0, "testGroup1", "12345678", false, TEST_GROUP_OWNER_1);
- mTestGroup2 = createGroup(1, "testGroup2", "12345678", true, TEST_GROUP_OWNER_2);
- mTestGroup3 = createGroup(2, "testGroup3", "12345678", false, TEST_GROUP_OWNER_3);
- mTestGroup4 = createGroup(3, "testGroup4", "12345678", false, TEST_GROUP_OWNER_1);
- }
-
- /**
- * Verify basic operations.
- */
- @Test
- public void testListOperations() throws Exception {
- WifiP2pGroupList list = new WifiP2pGroupList();
- list.add(mTestGroup1);
- list.add(mTestGroup2);
- list.add(mTestGroup3);
- list.add(mTestGroup4);
- assertEquals(4, list.getGroupList().size());
-
- // in list
- assertEquals(mTestGroup2.getNetworkId(),
- list.getNetworkId(TEST_GROUP_OWNER_2.deviceAddress));
- assertEquals(TEST_GROUP_OWNER_2.deviceAddress,
- list.getOwnerAddr(mTestGroup2.getNetworkId()));
- // not in list
- assertEquals(-1, list.getNetworkId(TEST_GROUP_OWNER_OTHER.deviceAddress));
- // if there are groups with the same GO, return the first one found.
- assertEquals(mTestGroup1.getNetworkId(),
- list.getNetworkId(TEST_GROUP_OWNER_1.deviceAddress));
- // identify groups with the same GO, but different network names.
- assertEquals(mTestGroup4.getNetworkId(),
- list.getNetworkId(TEST_GROUP_OWNER_1.deviceAddress, "testGroup4"));
-
- list.remove(mTestGroup3.getNetworkId());
- assertEquals(-1, list.getNetworkId(TEST_GROUP_OWNER_3.deviceAddress));
- assertFalse(list.contains(mTestGroup3.getNetworkId()));
-
- assertEquals(3, list.getGroupList().size());
-
- Parcel parcelW = Parcel.obtain();
- list.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiP2pGroupList fromParcel = WifiP2pGroupList.CREATOR.createFromParcel(parcelR);
-
- assertEquals(list.toString(), fromParcel.toString());
-
- list.clear();
- assertEquals(0, list.getGroupList().size());
-
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java
deleted file mode 100644
index 9473e42..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java
+++ /dev/null
@@ -1,92 +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.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pGroup}
- */
-@SmallTest
-public class WifiP2pGroupTest {
-
- private static final String INTERFACE = "p2p-p2p0-3";
- private static final int NETWORK_ID = 9;
- private static final String NETWORK_NAME = "DIRECT-xy-Hello";
- private static final String PASSPHRASE = "HelloWorld";
- private static final WifiP2pDevice GROUP_OWNER = new WifiP2pDevice("de:ad:be:ef:00:01");
- private static final int FREQUENCY = 5300;
- private static final WifiP2pDevice CLIENT_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:01");
- private static final WifiP2pDevice CLIENT_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:02");
-
- /**
- * Verify setter/getter functions.
- */
- @Test
- public void testSetterGetter() throws Exception {
- WifiP2pGroup group = new WifiP2pGroup();
-
- group.setInterface(INTERFACE);
- group.setNetworkId(NETWORK_ID);
- group.setNetworkName(NETWORK_NAME);
- group.setPassphrase(PASSPHRASE);
- group.setIsGroupOwner(false);
- group.setOwner(GROUP_OWNER);
- group.setFrequency(FREQUENCY);
- group.addClient(CLIENT_1.deviceAddress);
- group.addClient(CLIENT_2);
-
- assertEquals(INTERFACE, group.getInterface());
- assertEquals(NETWORK_ID, group.getNetworkId());
- assertEquals(NETWORK_NAME, group.getNetworkName());
- assertEquals(PASSPHRASE, group.getPassphrase());
- assertFalse(group.isGroupOwner());
- assertEquals(GROUP_OWNER, group.getOwner());
- assertEquals(FREQUENCY, group.getFrequency());
-
- assertFalse(group.isClientListEmpty());
- assertTrue(group.contains(CLIENT_1));
-
- assertEquals(2, group.getClientList().size());
-
- group.removeClient(CLIENT_1);
- group.removeClient(CLIENT_2.deviceAddress);
- assertFalse(group.contains(CLIENT_1));
- assertTrue(group.isClientListEmpty());
-
- Parcel parcelW = Parcel.obtain();
- group.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiP2pGroup fromParcel = WifiP2pGroup.CREATOR.createFromParcel(parcelR);
-
- assertEquals(group.toString(), fromParcel.toString());
-
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java
deleted file mode 100644
index e207ca1..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.net.InetAddress;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pInfo}
- */
-@SmallTest
-public class WifiP2pInfoTest {
-
- private InetAddress mGroupOnwerIpv4Address;
-
- @Before
- public void setUp() throws Exception {
- byte[] ipv4 = {(byte) 192, (byte) 168, (byte) 49, (byte) 1};
- mGroupOnwerIpv4Address = InetAddress.getByAddress(ipv4);
- }
-
- /**
- * Verifies copy constructor.
- */
- @Test
- public void testCopyOperator() throws Exception {
- WifiP2pInfo info = new WifiP2pInfo();
- info.groupFormed = true;
- info.isGroupOwner = true;
- info.groupOwnerAddress = mGroupOnwerIpv4Address;
-
- WifiP2pInfo copiedInfo = new WifiP2pInfo(info);
-
- // no equals operator, use toString for data comparison.
- assertEquals(info.toString(), copiedInfo.toString());
- }
-
- /**
- * Verifies parcel serialization/deserialization.
- */
- @Test
- public void testParcelOperation() throws Exception {
- WifiP2pInfo info = new WifiP2pInfo();
- info.groupFormed = true;
- info.isGroupOwner = true;
- info.groupOwnerAddress = mGroupOnwerIpv4Address;
-
- Parcel parcelW = Parcel.obtain();
- info.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiP2pInfo fromParcel = WifiP2pInfo.CREATOR.createFromParcel(parcelR);
-
- // no equals operator, use toString for data comparison.
- assertEquals(info.toString(), fromParcel.toString());
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java
deleted file mode 100644
index 9e8dca4..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java
+++ /dev/null
@@ -1,85 +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.net.wifi.p2p;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import libcore.junit.util.ResourceLeakageDetector;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Unit test harness for WifiP2pManager.
- */
-@SmallTest
-public class WifiP2pManagerTest {
- private WifiP2pManager mDut;
- private TestLooper mTestLooper;
-
- @Mock
- public Context mContextMock;
- @Mock
- IWifiP2pManager mP2pServiceMock;
-
- @Rule
- public ResourceLeakageDetector.LeakageDetectorRule leakageDetectorRule =
- ResourceLeakageDetector.getRule();
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- mDut = new WifiP2pManager(mP2pServiceMock);
- mTestLooper = new TestLooper();
- }
-
- /**
- * Validate that on finalize we close the channel and flag a resource leakage.
- */
- @Test
- public void testChannelFinalize() throws Exception {
- try (WifiP2pManager.Channel channel = new WifiP2pManager.Channel(mContextMock,
- mTestLooper.getLooper(), null, null, mDut)) {
- leakageDetectorRule.assertUnreleasedResourceCount(channel, 1);
- }
- }
-
- /**
- * Validate that when close is called on a channel it frees up resources (i.e. don't
- * get flagged again on finalize).
- */
- @Test
- public void testChannelClose() throws Exception {
- WifiP2pManager.Channel channel = new WifiP2pManager.Channel(mContextMock,
- mTestLooper.getLooper(), null, null, mDut);
-
- channel.close();
- verify(mP2pServiceMock).close(any());
-
- leakageDetectorRule.assertUnreleasedResourceCount(channel, 0);
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java
deleted file mode 100644
index e3b10a7..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java
+++ /dev/null
@@ -1,111 +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.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pProvDiscEvent}
- */
-@SmallTest
-public class WifiP2pProvDiscEventTest {
-
- private static final String DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff";
- private static final String EVENT_PBC_REQ_STRING = "P2P-PROV-DISC-PBC-REQ";
- private static final String EVENT_PBC_RSP_STRING = "P2P-PROV-DISC-PBC-RESP";
- private static final String EVENT_ENTER_PIN_STRING = "P2P-PROV-DISC-ENTER-PIN";
- private static final String EVENT_SHOW_PIN_STRING = "P2P-PROV-DISC-SHOW-PIN";
- private static final String TEST_PIN = "44490607";
-
- /**
- * Test parsing PBC request event.
- */
- @Test
- public void testPbcReqEvent() throws Exception {
- WifiP2pProvDiscEvent event =
- new WifiP2pProvDiscEvent(EVENT_PBC_REQ_STRING + " " + DEVICE_ADDRESS);
- assertEquals(WifiP2pProvDiscEvent.PBC_REQ, event.event);
- assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
- }
-
-
- /**
- * Test parsing PBC response event.
- */
- @Test
- public void testPbcRespEvent() throws Exception {
- WifiP2pProvDiscEvent event =
- new WifiP2pProvDiscEvent(EVENT_PBC_RSP_STRING + " " + DEVICE_ADDRESS);
- assertEquals(WifiP2pProvDiscEvent.PBC_RSP, event.event);
- assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
- }
-
- /**
- * Test parsing ENTER-PIN event.
- */
- @Test
- public void testEnterPinEvent() throws Exception {
- WifiP2pProvDiscEvent event =
- new WifiP2pProvDiscEvent(EVENT_ENTER_PIN_STRING + " " + DEVICE_ADDRESS);
- assertEquals(WifiP2pProvDiscEvent.ENTER_PIN, event.event);
- assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
- }
-
- /**
- * Test parsing SHOW-PIN event.
- */
- @Test
- public void testShowPinEvent() throws Exception {
- WifiP2pProvDiscEvent event =
- new WifiP2pProvDiscEvent(
- EVENT_SHOW_PIN_STRING + " " + DEVICE_ADDRESS + " " + TEST_PIN);
- assertEquals(WifiP2pProvDiscEvent.SHOW_PIN, event.event);
- assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
- assertEquals(TEST_PIN, event.pin);
- }
-
- /**
- * Test parsing malformed input.
- */
- @Test
- public void testMalformedInput() throws Exception {
- try {
- WifiP2pProvDiscEvent event = new WifiP2pProvDiscEvent("OneToken");
- fail("Should throw IllegalArgumentException exception.");
- } catch (IllegalArgumentException ex) {
- // expected exception.
- }
- }
-
- /**
- * Test parsing malformed event.
- */
- @Test
- public void testMalformedEvent() throws Exception {
- try {
- WifiP2pProvDiscEvent event = new WifiP2pProvDiscEvent("XXX " + DEVICE_ADDRESS);
- fail("Should throw IllegalArgumentException exception.");
- } catch (IllegalArgumentException ex) {
- // expected exception.
- }
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
deleted file mode 100644
index 2a9b36b..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
+++ /dev/null
@@ -1,108 +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.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pWfdInfo}
- */
-@SmallTest
-public class WifiP2pWfdInfoTest {
-
- private static final int TEST_CTRL_PORT = 9999;
- private static final int TEST_MAX_TPUT = 1024;
-
- private WifiP2pWfdInfo mSourceInfo = new WifiP2pWfdInfo(
- 0,
- TEST_CTRL_PORT,
- TEST_MAX_TPUT);
-
- @Before
- public void setUp() {
- // initialize device info flags.
- mSourceInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
- mSourceInfo.setSessionAvailable(true);
- mSourceInfo.setContentProtectionSupported(true);
- }
-
- /**
- * Verifies setters/getters.
- */
- @Test
- public void testSettersGetters() throws Exception {
- WifiP2pWfdInfo info = new WifiP2pWfdInfo();
-
- info.setEnabled(true);
- assertTrue(info.isEnabled());
-
- info.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
- assertEquals(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE, info.getDeviceType());
-
- info.setSessionAvailable(true);
- assertTrue(info.isSessionAvailable());
-
- info.setContentProtectionSupported(true);
- assertTrue(info.isContentProtectionSupported());
-
- info.setControlPort(TEST_CTRL_PORT);
- assertEquals(TEST_CTRL_PORT, info.getControlPort());
-
- info.setMaxThroughput(TEST_MAX_TPUT);
- assertEquals(TEST_MAX_TPUT, info.getMaxThroughput());
-
- assertEquals("0110270f0400", info.getDeviceInfoHex());
- }
-
- /**
- * Verifies copy constructor.
- */
- @Test
- public void testCopyOperator() throws Exception {
- WifiP2pWfdInfo copiedInfo = new WifiP2pWfdInfo(mSourceInfo);
-
- // no equals operator, use toString for data comparison.
- assertEquals(mSourceInfo.toString(), copiedInfo.toString());
- }
-
- /**
- * Verifies parcel serialization/deserialization.
- */
- @Test
- public void testParcelOperation() throws Exception {
- Parcel parcelW = Parcel.obtain();
- mSourceInfo.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- WifiP2pWfdInfo fromParcel = WifiP2pWfdInfo.CREATOR.createFromParcel(parcelR);
-
- // no equals operator, use toString for data comparison.
- assertEquals(mSourceInfo.toString(), fromParcel.toString());
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java
deleted file mode 100644
index e1cffee..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java
+++ /dev/null
@@ -1,88 +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.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo}
- */
-@SmallTest
-public class WifiP2pDnsSdServiceInfoTest {
-
- private static final String INSTANCE_NAME = "MyPrinter";
- private static final String SERVICE_TYPE = "_ipp._tcp";
- private static final String TXTRECORD_PROP_AVAILABLE = "available";
- private static final String TXTRECORD_PROP_AVAILABLE_VISABLE = "visable";
-
- private Map<String, String> mTxtMap = new HashMap<>();
-
- @Before
- public void setUp() throws Exception {
- mTxtMap.put(TXTRECORD_PROP_AVAILABLE, TXTRECORD_PROP_AVAILABLE_VISABLE);
- }
-
- /**
- * Verify newInstance API
- */
- @Test
- public void testNewInstance() throws Exception {
- WifiP2pDnsSdServiceInfo info = null;
-
- // the least arguments
- info = WifiP2pDnsSdServiceInfo.newInstance(
- INSTANCE_NAME,
- SERVICE_TYPE,
- null);
-
- // all arguments are given.
- info = WifiP2pDnsSdServiceInfo.newInstance(
- INSTANCE_NAME,
- SERVICE_TYPE,
- mTxtMap);
-
- // failure case due to no instance name.
- try {
- info = WifiP2pDnsSdServiceInfo.newInstance(
- null,
- SERVICE_TYPE,
- null);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected exception.
- }
-
- // failure case due to no service type.
- try {
- info = WifiP2pDnsSdServiceInfo.newInstance(
- INSTANCE_NAME,
- null,
- null);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected exception.
- }
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java
deleted file mode 100644
index 7d46a5f..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java
+++ /dev/null
@@ -1,72 +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.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest}
- */
-@SmallTest
-public class WifiP2pDnsSdServiceRequestTest {
-
- private static final String SERVICE_NAME = "MyPrinter";
- private static final String SERVICE_TYPE = "_ipp._tcp";
-
- @Test
- public void testNewInstance() throws Exception {
- WifiP2pDnsSdServiceRequest request = null;
-
- // default new instance
- request = WifiP2pDnsSdServiceRequest.newInstance();
-
- // set service type
- request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_TYPE);
-
- // set service type
- request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_NAME, SERVICE_TYPE);
-
- // failure case due to null service type
- try {
- request = WifiP2pDnsSdServiceRequest.newInstance(null);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected exception.
- }
-
- // failure case due to null service name
- try {
- request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_NAME, null);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected exception.
- }
-
- // failure case due to null service type
- try {
- request = WifiP2pDnsSdServiceRequest.newInstance(null, SERVICE_TYPE);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected exception.
- }
-
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java
deleted file mode 100644
index 49ead11..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo}
- */
-@SmallTest
-public class WifiP2pUpnpServiceInfoTest {
-
- private static final String UUID = "6859dede-8574-59ab-9332-123456789012";
- private static final String DEVICE = "aa:bb:cc:dd:ee:ff";
-
- private List<String> mServiceList = new ArrayList<>();
-
- @Before
- public void setUp() throws Exception {
- mServiceList.add("urn:schemas-upnp-org:service:ContentDirectory:1");
- }
-
- /**
- * Verify newInstance API
- */
- @Test
- public void testNewInstance() throws Exception {
- WifiP2pUpnpServiceInfo info = null;
-
- // the least arguments
- info = WifiP2pUpnpServiceInfo.newInstance(
- UUID, DEVICE, null);
-
- // all arguments are given.
- info = WifiP2pUpnpServiceInfo.newInstance(
- UUID, DEVICE, mServiceList);
-
- // failure case due to no UUID.
- try {
- info = WifiP2pUpnpServiceInfo.newInstance(
- null, DEVICE, null);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected exception.
- }
-
- // failure case due to no device.
- try {
- info = WifiP2pUpnpServiceInfo.newInstance(
- UUID,
- null,
- null);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected exception.
- }
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java
deleted file mode 100644
index 79930dc..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java
+++ /dev/null
@@ -1,49 +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.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest}
- */
-@SmallTest
-public class WifiP2pUpnpServiceRequestTest {
-
- @Test
- public void testNewInstance() throws Exception {
- WifiP2pUpnpServiceRequest request = null;
-
- // Create a service discovery request to search all UPnP services.
- request = WifiP2pUpnpServiceRequest.newInstance();
-
- // Create a service discovery request to search specified UPnP services.
- request = WifiP2pUpnpServiceRequest.newInstance("ssdp:all");
-
- // failure case due to null target string
- try {
- request = WifiP2pUpnpServiceRequest.newInstance(null);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected exception.
- }
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/rtt/CivicLocationTest.java b/wifi/tests/src/android/net/wifi/rtt/CivicLocationTest.java
deleted file mode 100644
index f746fb7..0000000
--- a/wifi/tests/src/android/net/wifi/rtt/CivicLocationTest.java
+++ /dev/null
@@ -1,243 +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.net.wifi.rtt;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import android.location.Address;
-import android.os.Parcel;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for {@link CivicLocation}.
- */
-@RunWith(JUnit4.class)
-public class CivicLocationTest {
- private static final String sUsCountryCode = "US";
-
- private static final byte[] sEmptyBuffer = {};
-
- private static final byte[] sTestCivicLocationBuffer = {
- (byte) 17,
- (byte) 3,
- (byte) 'a',
- (byte) 'b',
- (byte) 'c',
- (byte) 4,
- (byte) 4,
- (byte) 'd',
- (byte) 'e',
- (byte) 'f',
- (byte) 'g',
- (byte) 12,
- (byte) 1,
- (byte) 'h'
- };
-
- private static final byte[] sTestCivicLocationBufferWithAddress = {
- (byte) CivicLocationKeys.HNO,
- (byte) 2,
- (byte) '1',
- (byte) '5',
- (byte) CivicLocationKeys.PRIMARY_ROAD_NAME,
- (byte) 4,
- (byte) 'A',
- (byte) 'l',
- (byte) 't',
- (byte) 'o',
- (byte) CivicLocationKeys.STREET_NAME_POST_MODIFIER,
- (byte) 4,
- (byte) 'R',
- (byte) 'o',
- (byte) 'a',
- (byte) 'd',
- (byte) CivicLocationKeys.CITY,
- (byte) 8,
- (byte) 'M',
- (byte) 't',
- (byte) 'n',
- (byte) ' ',
- (byte) 'V',
- (byte) 'i',
- (byte) 'e',
- (byte) 'w',
- (byte) CivicLocationKeys.STATE,
- (byte) 2,
- (byte) 'C',
- (byte) 'A',
- (byte) CivicLocationKeys.POSTAL_CODE,
- (byte) 5,
- (byte) '9',
- (byte) '4',
- (byte) '0',
- (byte) '4',
- (byte) '3'
- };
-
- /**
- * Test inValid for null CountryCode.
- */
- @Test
- public void testCivicLocationNullCountryCode() {
- CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, null);
-
- boolean valid = civicLocation.isValid();
-
- assertFalse(valid);
- }
-
- /**
- * Test inValid for CountryCode too short.
- */
- @Test
- public void testCivicLocationCountryCodeTooShort() {
- CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, "X");
-
- boolean valid = civicLocation.isValid();
-
- assertFalse(valid);
- }
-
- /**
- * Test inValid for CountryCode too long.
- */
- @Test
- public void testCivicLocationCountryCodeTooLong() {
- CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, "XYZ");
-
- boolean valid = civicLocation.isValid();
-
- assertFalse(valid);
- }
-
- /**
- * Test inValid for null CivicLocation Buffer
- */
- @Test
- public void testCivicLocationNullBuffer() {
- CivicLocation civicLocation = new CivicLocation(null, sUsCountryCode);
-
- boolean valid = civicLocation.isValid();
-
- assertFalse(valid);
- }
-
- /**
- * Test inValid for Empty CivicLocation Buffer.
- */
- @Test
- public void testCivicLocationEmptyBuffer() {
- CivicLocation civicLocation = new CivicLocation(sEmptyBuffer, sUsCountryCode);
-
- boolean valid = civicLocation.isValid();
-
- assertFalse(valid);
- }
-
- /**
- * Test for valid CivicLocationBuffer and Country Code.
- */
- @Test
- public void testCivicLocationValid() {
- CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, sUsCountryCode);
-
- boolean valid = civicLocation.isValid();
-
- assertTrue(valid);
- }
-
- /**
- * Test toString Representation
- */
- @Test
- public void testCivicLocationToString() {
- CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, sUsCountryCode);
-
- String str = civicLocation.toString();
-
- assertEquals("{4=defg, 12=h, 17=abc}", str);
- }
-
- /**
- * Test the toString
- */
- @Test
- public void testCivicLocationgetElementValue() {
- CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, sUsCountryCode);
-
- String value1 = civicLocation.getCivicElementValue(4);
- String value2 = civicLocation.getCivicElementValue(17);
- String value3 = civicLocation.getCivicElementValue(12);
- String value4 = civicLocation.getCivicElementValue(156); // not in test data
- String value5 = civicLocation.getCivicElementValue(276); // greater than key index
-
- assertEquals("defg", value1);
- assertEquals("abc", value2);
- assertEquals("h", value3);
- assertNull(value4);
- assertNull(value5);
- }
-
- /* Test toAddress representation */
- @Test
- public void testCivicLocationToAddress() {
- CivicLocation civicLocation =
- new CivicLocation(sTestCivicLocationBufferWithAddress, sUsCountryCode);
-
- Address address = civicLocation.toAddress();
-
- assertEquals("", address.getAddressLine(0));
- assertEquals("15 Alto", address.getAddressLine(1));
- assertEquals("Mtn View", address.getAddressLine(2));
- assertEquals("CA 94043", address.getAddressLine(3));
- assertEquals("US", address.getAddressLine(4));
- }
-
- /**
- * Test toString Representation
- */
- @Test
- public void testCivicLocationToString2() {
- CivicLocation civicLocation =
- new CivicLocation(sTestCivicLocationBufferWithAddress, sUsCountryCode);
-
- String str = civicLocation.toString();
-
- assertEquals("{1=CA, 3=Mtn View, 19=15, 24=94043, 34=Alto, 39=Road}", str);
- }
-
- /** Test object is Parcellable */
- @Test
- public void testCivicLocationParcelable() {
- CivicLocation civicLocation =
- new CivicLocation(sTestCivicLocationBufferWithAddress, sUsCountryCode);
-
- Parcel parcel = Parcel.obtain();
- civicLocation.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- CivicLocation civicLocationFromParcel =
- CivicLocation.CREATOR.createFromParcel(parcel);
-
- assertEquals(civicLocationFromParcel, civicLocation);
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
deleted file mode 100644
index 271339c..0000000
--- a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
+++ /dev/null
@@ -1,589 +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.net.wifi.rtt;
-
-import android.location.Address;
-import android.location.Location;
-import android.net.MacAddress;
-import android.os.Parcel;
-import android.util.SparseArray;
-import android.webkit.MimeTypeMap;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.List;
-
-/**
- * Tests for {@link ResponderLocation}.
- */
-@RunWith(JUnit4.class)
-public class ResponderLocationTest {
- private static final double LATLNG_TOLERANCE_DEGREES = 0.000_000_05D; // 5E-8 = 6mm of meridian
- private static final double ALT_TOLERANCE_METERS = 0.01;
- private static final double HEIGHT_TOLERANCE_METERS = 0.01;
- private static final int INDEX_ELEMENT_TYPE = 2;
- private static final int INDEX_SUBELEMENT_TYPE = 0;
- private static final int INDEX_SUBELEMENT_LENGTH = 1;
-
- /* Test Buffers */
-
- private static final byte[] sTestLciIeHeader = {
- (byte) 0x01, (byte) 0x00, (byte) 0x08 // LCI Information Element (IE)
- };
-
- private static final byte[] sTestLciShortBuffer = {
- (byte) 0x00
- };
-
- private static final byte[] sTestLciSE = {
- (byte) 0x00, // Subelement LCI
- (byte) 16, // Subelement LCI length always = 16
- (byte) 0x52,
- (byte) 0x83,
- (byte) 0x4d,
- (byte) 0x12,
- (byte) 0xef,
- (byte) 0xd2,
- (byte) 0xb0,
- (byte) 0x8b,
- (byte) 0x9b,
- (byte) 0x4b,
- (byte) 0xf1,
- (byte) 0xcc,
- (byte) 0x2c,
- (byte) 0x00,
- (byte) 0x00,
- (byte) 0x41
- };
-
- private static final byte[] sTestZHeightSE = {
- (byte) 0x04, // Subelement Z
- (byte) 6, // Length always 6
- (byte) 0x00, // LSB STA Floor Info (2 bytes)
- (byte) 0x01, // MSB
- (byte) 0xcd, // LSB Height(m) (3 bytes)
- (byte) 0x2c,
- (byte) 0x00, // MSB Height(m)
- (byte) 0x0e, // STA Height Uncertainty
- };
-
- private static final byte[] sTestUsageSE1 = {
- (byte) 0x06, // Subelement Usage Rights
- (byte) 1, // Length 1 (with no retention limit)
- (byte) 0x01, // Retransmit ok, No expiration, no extra info available
- };
-
- private static final byte[] sTestUsageSE2 = {
- (byte) 0x06, // Subelement Usage Rights
- (byte) 3, // Length 3 (including retention limit)
- (byte) 0x06, // Retransmit not ok, Expiration, extra info available
- (byte) 0x00, // LSB expiration time (0x8000 = 32768 hrs)
- (byte) 0x80 // MSB expiration time
- };
-
- private static final byte[] sTestBssidListSE = {
- (byte) 0x07, // Subelement BSSID list
- (byte) 13, // length dependent on number of BSSIDs in list
- (byte) 0x00, // List is explicit; no expansion of list required
- (byte) 0x01, // BSSID #1 (MSB)
- (byte) 0x02,
- (byte) 0x03,
- (byte) 0x04,
- (byte) 0x05,
- (byte) 0x06, // (LSB)
- (byte) 0xf1, // BSSID #2 (MSB)
- (byte) 0xf2,
- (byte) 0xf3,
- (byte) 0xf4,
- (byte) 0xf5,
- (byte) 0xf6 // (LSB)
- };
-
- private static final byte[] sTestLcrBufferHeader = {
- (byte) 0x01, (byte) 0x00, (byte) 0x0b,
- };
-
- private static final byte[] sEmptyBuffer = {};
-
- private static final byte[] sTestCivicLocationSEWithAddress = {
- (byte) 0, // Civic Location Subelement
- (byte) 39, // Length of subelement value
- (byte) 'U', // CountryCodeChar1
- (byte) 'S', // CountryCodeChar2
- (byte) CivicLocationKeys.HNO,
- (byte) 2,
- (byte) '1',
- (byte) '5',
- (byte) CivicLocationKeys.PRIMARY_ROAD_NAME,
- (byte) 4,
- (byte) 'A',
- (byte) 'l',
- (byte) 't',
- (byte) 'o',
- (byte) CivicLocationKeys.STREET_NAME_POST_MODIFIER,
- (byte) 4,
- (byte) 'R',
- (byte) 'o',
- (byte) 'a',
- (byte) 'd',
- (byte) CivicLocationKeys.CITY,
- (byte) 8,
- (byte) 'M',
- (byte) 't',
- (byte) 'n',
- (byte) ' ',
- (byte) 'V',
- (byte) 'i',
- (byte) 'e',
- (byte) 'w',
- (byte) CivicLocationKeys.STATE,
- (byte) 2,
- (byte) 'C',
- (byte) 'A',
- (byte) CivicLocationKeys.POSTAL_CODE,
- (byte) 5,
- (byte) '9',
- (byte) '4',
- (byte) '0',
- (byte) '4',
- (byte) '3'
- };
-
- // Buffer representing: "https://map.com/mall.jpg"
- private static final byte[] sTestMapUrlSE = {
- (byte) 5, // Map URL Subelement
- (byte) 25,
- (byte) 0, // MAP_TYPE_URL_DEFINED
- (byte) 'h',
- (byte) 't',
- (byte) 't',
- (byte) 'p',
- (byte) 's',
- (byte) ':',
- (byte) '/',
- (byte) '/',
- (byte) 'm',
- (byte) 'a',
- (byte) 'p',
- (byte) '.',
- (byte) 'c',
- (byte) 'o',
- (byte) 'm',
- (byte) '/',
- (byte) 'm',
- (byte) 'a',
- (byte) 'l',
- (byte) 'l',
- (byte) '.',
- (byte) 'j',
- (byte) 'p',
- (byte) 'g'
- };
-
- /**
- * Test if the lci and lcr buffers are null.
- */
- @Test
- public void testIfLciOrLcrIsNull() {
- ResponderLocation responderLocation = new ResponderLocation(null, null);
-
- boolean valid = responderLocation.isValid();
- boolean lciValid = responderLocation.isLciSubelementValid();
- boolean zValid = responderLocation.isZaxisSubelementValid();
-
- assertFalse(valid);
- assertFalse(lciValid);
- assertFalse(zValid);
- }
-
- /**
- * Test if the lci and lcr buffers are empty.
- */
- @Test
- public void testIfLciOrLcrIsEmpty() {
- ResponderLocation responderLocation = new ResponderLocation(sEmptyBuffer, sEmptyBuffer);
-
- boolean valid = responderLocation.isValid();
- boolean lciValid = responderLocation.isLciSubelementValid();
- boolean zValid = responderLocation.isZaxisSubelementValid();
-
- assertFalse(valid);
- assertFalse(lciValid);
- assertFalse(zValid);
- }
-
- /**
- * Test if the lci subelement only has one byte
- */
- @Test
- public void testIfLciShortBuffer() {
- byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciShortBuffer);
- ResponderLocation responderLocation =
- new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
- boolean valid = responderLocation.isValid();
- boolean lciValid = responderLocation.isLciSubelementValid();
- boolean zValid = responderLocation.isZaxisSubelementValid();
-
- assertFalse(valid);
- assertFalse(lciValid);
- assertFalse(zValid);
- }
-
- /**
- * Test that the example buffer contains a valid LCI Subelement.
- */
- @Test
- public void testLciValidSubelement() {
- byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- ResponderLocation responderLocation =
- new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
- boolean valid = responderLocation.isValid();
- boolean lciValid = responderLocation.isLciSubelementValid();
- boolean zValid = responderLocation.isZaxisSubelementValid();
- Location location = responderLocation.toLocation();
-
- assertTrue(valid);
- assertTrue(lciValid);
- assertFalse(zValid);
- assertEquals(0.0009765625D, responderLocation.getLatitudeUncertainty());
- assertEquals(-33.8570095D, responderLocation.getLatitude(),
- LATLNG_TOLERANCE_DEGREES);
- assertEquals(0.0009765625D, responderLocation.getLongitudeUncertainty());
- assertEquals(151.2152005D, responderLocation.getLongitude(),
- LATLNG_TOLERANCE_DEGREES);
- assertEquals(1, responderLocation.getAltitudeType());
- assertEquals(64.0, responderLocation.getAltitudeUncertainty());
- assertEquals(11.2, responderLocation.getAltitude(), ALT_TOLERANCE_METERS);
- assertEquals(1, responderLocation.getDatum()); // WGS84
- assertEquals(false, responderLocation.getRegisteredLocationAgreementIndication());
- assertEquals(false, responderLocation.getRegisteredLocationDseIndication());
- assertEquals(false, responderLocation.getDependentStationIndication());
- assertEquals(1, responderLocation.getLciVersion());
-
- // Testing Location Object
- assertEquals(-33.8570095D, location.getLatitude(),
- LATLNG_TOLERANCE_DEGREES);
- assertEquals(151.2152005D, location.getLongitude(),
- LATLNG_TOLERANCE_DEGREES);
- assertEquals((0.0009765625D + 0.0009765625D) / 2, location.getAccuracy(),
- LATLNG_TOLERANCE_DEGREES);
- assertEquals(11.2, location.getAltitude(), ALT_TOLERANCE_METERS);
- assertEquals(64.0, location.getVerticalAccuracyMeters(), ALT_TOLERANCE_METERS);
- }
-
- /**
- * Test for an invalid LCI element.
- */
- @Test
- public void testLciInvalidElement() {
- byte[] testBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- testBuffer[INDEX_ELEMENT_TYPE] = (byte) 0xFF;
- ResponderLocation responderLocation =
- new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
- boolean valid = responderLocation.isValid();
- boolean lciValid = responderLocation.isLciSubelementValid();
- boolean zValid = responderLocation.isZaxisSubelementValid();
-
- assertFalse(valid);
- assertFalse(lciValid);
- assertFalse(zValid);
- }
-
- /**
- * Test for an invalid subelement type.
- */
- @Test
- public void testSkipLciSubElementUnusedOrUnknown() {
- byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- // Corrupt the subelement type to an unknown type.
- testLciBuffer[sTestLciIeHeader.length + INDEX_SUBELEMENT_TYPE] = (byte) 0x77;
- ResponderLocation responderLocation =
- new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
- boolean valid = responderLocation.isValid();
- boolean lciValid = responderLocation.isLciSubelementValid();
- boolean zValid = responderLocation.isZaxisSubelementValid();
-
- assertFalse(valid);
- assertFalse(lciValid);
- assertFalse(zValid);
- }
-
- /**
- * Test for a subelement LCI length too small.
- */
- @Test
- public void testInvalidLciSubElementLengthTooSmall() {
- byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- // Corrupt the length making it too small.
- testLciBuffer[sTestLciIeHeader.length + INDEX_SUBELEMENT_LENGTH] = (byte) 0x01;
- ResponderLocation responderLocation =
- new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
- boolean valid = responderLocation.isValid();
- boolean lciValid = responderLocation.isLciSubelementValid();
- boolean zValid = responderLocation.isZaxisSubelementValid();
-
- assertFalse(valid);
- assertFalse(lciValid);
- assertFalse(zValid);
- }
-
- /**
- * Test for a subelement LCI length too big.
- */
- @Test
- public void testInvalidLciSubElementLengthTooBig() {
- byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- // Corrupt the length making it too big.
- testLciBuffer[sTestLciIeHeader.length + INDEX_SUBELEMENT_TYPE] = (byte) 0x11;
- ResponderLocation responderLocation =
- new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
- boolean valid = responderLocation.isValid();
- boolean lciValid = responderLocation.isLciSubelementValid();
- boolean zValid = responderLocation.isZaxisSubelementValid();
-
- assertFalse(valid);
- assertFalse(lciValid);
- assertFalse(zValid);
- }
-
- /**
- * Test for a valid Z (Height) subelement following an LCI subelement.
- */
- @Test
- public void testLciValidZBufferSEAfterLci() {
- byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- byte[] testBuffer = concatenateArrays(testBufferTmp, sTestZHeightSE);
- ResponderLocation responderLocation =
- new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
- boolean isValid = responderLocation.isValid();
- boolean isZValid = responderLocation.isZaxisSubelementValid();
- boolean isLciValid = responderLocation.isLciSubelementValid();
- double staFloorNumber = responderLocation.getFloorNumber();
- double staHeightAboveFloorMeters = responderLocation.getHeightAboveFloorMeters();
- double staHeightAboveFloorUncertaintyMeters =
- responderLocation.getHeightAboveFloorUncertaintyMeters();
-
- assertTrue(isValid);
- assertTrue(isZValid);
- assertTrue(isLciValid);
- assertEquals(4.0, staFloorNumber);
- assertEquals(2.8, staHeightAboveFloorMeters, HEIGHT_TOLERANCE_METERS);
- assertEquals(0.125, staHeightAboveFloorUncertaintyMeters);
- }
-
- /**
- * Test for a valid Usage Policy that is unrestrictive
- */
- @Test
- public void testLciOpenUsagePolicy() {
- byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- byte[] testBuffer = concatenateArrays(testBufferTmp, sTestUsageSE1);
- ResponderLocation responderLocation =
- new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
- boolean valid = responderLocation.isValid();
- boolean retransmit = responderLocation.getRetransmitPolicyIndication();
- boolean expiration = responderLocation.getRetentionExpiresIndication();
- boolean extraInfo = responderLocation.getExtraInfoOnAssociationIndication();
-
- assertTrue(valid);
- assertTrue(retransmit);
- assertFalse(expiration);
- assertFalse(extraInfo);
- }
-
- /**
- * Test for a valid Usage Policy that is restrictive
- */
- @Test
- public void testLciRestrictiveUsagePolicy() {
- byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- byte[] testBuffer = concatenateArrays(testBufferTmp, sTestUsageSE2);
- ResponderLocation responderLocation =
- new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
- boolean valid = responderLocation.isValid();
- boolean retransmit = responderLocation.getRetransmitPolicyIndication();
- boolean expiration = responderLocation.getRetentionExpiresIndication();
- boolean extraInfo = responderLocation.getExtraInfoOnAssociationIndication();
-
- assertFalse(valid);
- assertFalse(retransmit);
- assertTrue(expiration);
- assertTrue(extraInfo);
- }
-
- /**
- * Test for a valid BSSID element following an LCI subelement.
- */
- @Test
- public void testLciBssidListSEAfterLci() {
- byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- byte[] testBuffer = concatenateArrays(testBufferTmp, sTestBssidListSE);
- ResponderLocation responderLocation =
- new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
- boolean valid = responderLocation.isValid();
- List<MacAddress> bssidList = responderLocation.getColocatedBssids();
-
- assertTrue(valid);
- assertEquals(2, bssidList.size());
- MacAddress macAddress1 = bssidList.get(0);
- assertEquals("01:02:03:04:05:06", macAddress1.toString());
- MacAddress macAddress2 = bssidList.get(1);
- assertEquals("f1:f2:f3:f4:f5:f6", macAddress2.toString());
- }
-
- /**
- * Test for a valid BSSID element before and LCI element
- */
- @Test
- public void testLciBssidListSEBeforeLci() {
- byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestBssidListSE);
- byte[] testBuffer = concatenateArrays(testBufferTmp, sTestLciSE);
- ResponderLocation responderLocation =
- new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
- boolean valid = responderLocation.isValid();
- List<MacAddress> bssidList = responderLocation.getColocatedBssids();
-
- assertTrue(valid);
- assertEquals(2, bssidList.size());
- MacAddress macAddress1 = bssidList.get(0);
- assertEquals("01:02:03:04:05:06", macAddress1.toString());
- MacAddress macAddress2 = bssidList.get(1);
- assertEquals("f1:f2:f3:f4:f5:f6", macAddress2.toString());
- }
-
- /**
- * Test that a valid address can be extracted from a valid lcr buffer with Civic Location.
- */
- @Test
- public void testLcrTestCivicLocationAddress() {
- byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- byte[] testLcrBuffer =
- concatenateArrays(sTestLcrBufferHeader, sTestCivicLocationSEWithAddress);
- ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer);
-
- boolean valid = responderLocation.isValid();
- String countryCode = responderLocation.getCivicLocationCountryCode();
- Address address = responderLocation.toCivicLocationAddress();
-
- assertTrue(valid);
- assertEquals("US", countryCode);
- assertEquals("", address.getAddressLine(0));
- assertEquals("15 Alto", address.getAddressLine(1));
- assertEquals("Mtn View", address.getAddressLine(2));
- assertEquals("CA 94043", address.getAddressLine(3));
- assertEquals("US", address.getAddressLine(4));
- }
-
- /**
- * Test that a Civic Location sparseArray can be extracted from a valid lcr buffer.
- */
- @Test
- public void testLcrTestCivicLocationSparseArray() {
- byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- byte[] testLcrBuffer =
- concatenateArrays(sTestLcrBufferHeader, sTestCivicLocationSEWithAddress);
- ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer);
-
- boolean valid = responderLocation.isValid();
- SparseArray<String> civicLocationSparseArray = responderLocation
- .toCivicLocationSparseArray();
-
- assertTrue(valid);
- assertEquals("15", civicLocationSparseArray.get(CivicLocationKeys.HNO));
- assertEquals("Alto",
- civicLocationSparseArray.get(CivicLocationKeys.PRIMARY_ROAD_NAME));
- assertEquals("Road",
- civicLocationSparseArray.get(CivicLocationKeys.STREET_NAME_POST_MODIFIER));
- assertEquals("Mtn View", civicLocationSparseArray.get(CivicLocationKeys.CITY));
- assertEquals("94043", civicLocationSparseArray.get(CivicLocationKeys.POSTAL_CODE));
- }
-
- /**
- * Test that a URL can be extracted from a valid lcr buffer with a map image subelement.
- */
- @Test
- public void testLcrCheckMapUriIsValid() {
- byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- byte[] testLcrBuffer = concatenateArrays(sTestLcrBufferHeader, sTestMapUrlSE);
- ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer);
-
- boolean valid = responderLocation.isValid();
- String mapImageMimeType = responderLocation.getMapImageMimeType();
- String urlString = "";
- if (responderLocation.getMapImageUri() != null) {
- urlString = responderLocation.getMapImageUri().toString();
- }
-
- assertTrue(valid);
- MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
- assertEquals(mimeTypeMap.getMimeTypeFromExtension("jpg"), mapImageMimeType);
- assertEquals("https://map.com/mall.jpg", urlString);
- }
-
- /**
- * Test the object is parcelable
- */
- @Test
- public void testResponderLocationParcelable() {
- byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
- ResponderLocation responderLocation =
- new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
- Parcel parcel = Parcel.obtain();
- responderLocation.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- ResponderLocation responderLocationFromParcel =
- ResponderLocation.CREATOR.createFromParcel(parcel);
-
- assertEquals(responderLocationFromParcel, responderLocation);
- }
-
- /* Helper Method */
-
- /**
- * Concatenate two arrays.
- *
- * @param a first array
- * @param b second array
- * @return a third array which is the concatenation of the two array params
- */
- private byte[] concatenateArrays(byte[] a, byte[] b) {
- int aLen = a.length;
- int bLen = b.length;
- byte[] c = new byte[aLen + bLen];
- System.arraycopy(a, 0, c, 0, aLen);
- System.arraycopy(b, 0, c, aLen, bLen);
- return c;
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
deleted file mode 100644
index e6eae416..0000000
--- a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
+++ /dev/null
@@ -1,395 +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.net.wifi.rtt;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.MacAddress;
-import android.net.wifi.ScanResult;
-import android.net.wifi.aware.PeerHandle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Unit test harness for WifiRttManager class.
- */
-@SmallTest
-public class WifiRttManagerTest {
- private WifiRttManager mDut;
- private TestLooper mMockLooper;
- private Executor mMockLooperExecutor;
-
- private final String packageName = "some.package.name.for.rtt.app";
- private final String featureId = "some.feature.id.in.rtt.app";
-
- @Mock
- public Context mockContext;
-
- @Mock
- public IWifiRttManager mockRttService;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- mDut = new WifiRttManager(mockContext, mockRttService);
- mMockLooper = new TestLooper();
- mMockLooperExecutor = mMockLooper.getNewExecutor();
-
- when(mockContext.getOpPackageName()).thenReturn(packageName);
- when(mockContext.getAttributionTag()).thenReturn(featureId);
- }
-
- /**
- * Validate ranging call flow with successful results.
- */
- @Test
- public void testRangeSuccess() throws Exception {
- RangingRequest request = new RangingRequest.Builder().build();
- List<RangingResult> results = new ArrayList<>();
- results.add(
- new RangingResult(RangingResult.STATUS_SUCCESS, MacAddress.BROADCAST_ADDRESS, 15, 5,
- 10, 8, 5, null, null, null, 666));
- RangingResultCallback callbackMock = mock(RangingResultCallback.class);
- ArgumentCaptor<IRttCallback> callbackCaptor = ArgumentCaptor.forClass(IRttCallback.class);
-
- // verify ranging request passed to service
- mDut.startRanging(request, mMockLooperExecutor, callbackMock);
- verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId),
- eq(null), eq(request), callbackCaptor.capture());
-
- // service calls back with success
- callbackCaptor.getValue().onRangingResults(results);
- mMockLooper.dispatchAll();
- verify(callbackMock).onRangingResults(results);
-
- verifyNoMoreInteractions(mockRttService, callbackMock);
- }
-
- /**
- * Validate ranging call flow which failed.
- */
- @Test
- public void testRangeFail() throws Exception {
- int failureCode = RangingResultCallback.STATUS_CODE_FAIL;
-
- RangingRequest request = new RangingRequest.Builder().build();
- RangingResultCallback callbackMock = mock(RangingResultCallback.class);
- ArgumentCaptor<IRttCallback> callbackCaptor = ArgumentCaptor.forClass(IRttCallback.class);
-
- // verify ranging request passed to service
- mDut.startRanging(request, mMockLooperExecutor, callbackMock);
- verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId),
- eq(null), eq(request), callbackCaptor.capture());
-
- // service calls back with failure code
- callbackCaptor.getValue().onRangingFailure(failureCode);
- mMockLooper.dispatchAll();
- verify(callbackMock).onRangingFailure(failureCode);
-
- verifyNoMoreInteractions(mockRttService, callbackMock);
- }
-
- /**
- * Validate that RangingRequest parcel works (produces same object on write/read).
- */
- @Test
- public void testRangingRequestParcel() {
- // Note: not validating parcel code of ScanResult (assumed to work)
- ScanResult scanResult1 = new ScanResult();
- scanResult1.BSSID = "00:01:02:03:04:05";
- ScanResult scanResult2 = new ScanResult();
- scanResult2.BSSID = "06:07:08:09:0A:0B";
- ScanResult scanResult3 = new ScanResult();
- scanResult3.BSSID = "AA:BB:CC:DD:EE:FF";
- List<ScanResult> scanResults2and3 = new ArrayList<>(2);
- scanResults2and3.add(scanResult2);
- scanResults2and3.add(scanResult3);
- MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
- PeerHandle peerHandle1 = new PeerHandle(12);
-
- RangingRequest.Builder builder = new RangingRequest.Builder();
- builder.addAccessPoint(scanResult1);
- builder.addAccessPoints(scanResults2and3);
- builder.addWifiAwarePeer(mac1);
- builder.addWifiAwarePeer(peerHandle1);
- RangingRequest request = builder.build();
-
- Parcel parcelW = Parcel.obtain();
- request.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- RangingRequest rereadRequest = RangingRequest.CREATOR.createFromParcel(parcelR);
-
- assertEquals(request, rereadRequest);
- }
-
- /**
- * Validate that can request as many range operation as the upper limit on number of requests.
- */
- @Test
- public void testRangingRequestAtLimit() {
- ScanResult scanResult = new ScanResult();
- scanResult.BSSID = "AA:BB:CC:DD:EE:FF";
- List<ScanResult> scanResultList = new ArrayList<>();
- for (int i = 0; i < RangingRequest.getMaxPeers() - 3; ++i) {
- scanResultList.add(scanResult);
- }
- MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
-
- // create request
- RangingRequest.Builder builder = new RangingRequest.Builder();
- builder.addAccessPoint(scanResult);
- builder.addAccessPoints(scanResultList);
- builder.addAccessPoint(scanResult);
- builder.addWifiAwarePeer(mac1);
- RangingRequest request = builder.build();
-
- // verify request
- request.enforceValidity(true);
- }
-
- /**
- * Validate that limit on number of requests is applied.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testRangingRequestPastLimit() {
- ScanResult scanResult = new ScanResult();
- scanResult.BSSID = "00:01:02:03:04:05";
- List<ScanResult> scanResultList = new ArrayList<>();
- for (int i = 0; i < RangingRequest.getMaxPeers() - 2; ++i) {
- scanResultList.add(scanResult);
- }
- MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
-
- // create request
- RangingRequest.Builder builder = new RangingRequest.Builder();
- builder.addAccessPoint(scanResult);
- builder.addAccessPoints(scanResultList);
- builder.addAccessPoint(scanResult);
- builder.addWifiAwarePeer(mac1);
- RangingRequest request = builder.build();
-
- // verify request
- request.enforceValidity(true);
- }
-
- /**
- * Validate that Aware requests are invalid on devices which do not support Aware
- */
- @Test(expected = IllegalArgumentException.class)
- public void testRangingRequestWithAwareWithNoAwareSupport() {
- // create request
- RangingRequest.Builder builder = new RangingRequest.Builder();
- builder.addWifiAwarePeer(new PeerHandle(10));
- RangingRequest request = builder.build();
-
- // verify request
- request.enforceValidity(false);
- }
-
- /**
- * Validate that RangingResults parcel works (produces same object on write/read).
- */
- @Test
- public void testRangingResultsParcel() {
- int status = RangingResult.STATUS_SUCCESS;
- final MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
- PeerHandle peerHandle = new PeerHandle(10);
- int distanceCm = 105;
- int distanceStdDevCm = 10;
- int rssi = 5;
- int numAttemptedMeasurements = 8;
- int numSuccessfulMeasurements = 3;
- long timestamp = System.currentTimeMillis();
- byte[] lci = { 0x5, 0x6, 0x7 };
- byte[] lcr = { 0x1, 0x2, 0x3, 0xA, 0xB, 0xC };
-
- // RangingResults constructed with a MAC address
- RangingResult result = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
- numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr, null, timestamp);
-
- Parcel parcelW = Parcel.obtain();
- result.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- RangingResult rereadResult = RangingResult.CREATOR.createFromParcel(parcelR);
-
- assertEquals(result, rereadResult);
-
- // RangingResults constructed with a PeerHandle
- result = new RangingResult(status, peerHandle, distanceCm, distanceStdDevCm, rssi,
- numAttemptedMeasurements, numSuccessfulMeasurements, null, null, null, timestamp);
-
- parcelW = Parcel.obtain();
- result.writeToParcel(parcelW, 0);
- bytes = parcelW.marshall();
- parcelW.recycle();
-
- parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- rereadResult = RangingResult.CREATOR.createFromParcel(parcelR);
-
- assertEquals(result, rereadResult);
- }
-
- /**
- * Validate that RangingResults tests equal even if LCI/LCR is empty (length == 0) and null.
- */
- @Test
- public void testRangingResultsEqualityLciLcr() {
- int status = RangingResult.STATUS_SUCCESS;
- final MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
- PeerHandle peerHandle = new PeerHandle(10);
- int distanceCm = 105;
- int distanceStdDevCm = 10;
- int rssi = 5;
- int numAttemptedMeasurements = 10;
- int numSuccessfulMeasurements = 3;
- long timestamp = System.currentTimeMillis();
- byte[] lci = { };
- byte[] lcr = { };
-
- RangingResult rr1 = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
- numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr, null, timestamp);
- RangingResult rr2 = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
- numAttemptedMeasurements, numSuccessfulMeasurements, null, null, null, timestamp);
-
- assertEquals(rr1, rr2);
- }
-
- /**
- * Validate that ResponderConfig parcel works (produces same object on write/read).
- */
- @Test
- public void testResponderConfigParcel() {
- // ResponderConfig constructed with a MAC address
- ResponderConfig config = new ResponderConfig(MacAddress.fromString("00:01:02:03:04:05"),
- ResponderConfig.RESPONDER_AP, true, ResponderConfig.CHANNEL_WIDTH_80MHZ, 2134, 2345,
- 2555, ResponderConfig.PREAMBLE_LEGACY);
-
- Parcel parcelW = Parcel.obtain();
- config.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- ResponderConfig rereadConfig = ResponderConfig.CREATOR.createFromParcel(parcelR);
-
- assertEquals(config, rereadConfig);
-
- // ResponderConfig constructed with a PeerHandle
- config = new ResponderConfig(new PeerHandle(10), ResponderConfig.RESPONDER_AWARE, false,
- ResponderConfig.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, 5555, 6666, 7777,
- ResponderConfig.PREAMBLE_VHT);
-
- parcelW = Parcel.obtain();
- config.writeToParcel(parcelW, 0);
- bytes = parcelW.marshall();
- parcelW.recycle();
-
- parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
- rereadConfig = ResponderConfig.CREATOR.createFromParcel(parcelR);
-
- assertEquals(config, rereadConfig);
- }
-
- /**
- * Validate preamble selection from ScanResults.
- */
- @Test
- public void testResponderPreambleSelection() {
- ScanResult.InformationElement htCap = new ScanResult.InformationElement();
- htCap.id = ScanResult.InformationElement.EID_HT_CAPABILITIES;
-
- ScanResult.InformationElement vhtCap = new ScanResult.InformationElement();
- vhtCap.id = ScanResult.InformationElement.EID_VHT_CAPABILITIES;
-
- ScanResult.InformationElement vsa = new ScanResult.InformationElement();
- vsa.id = ScanResult.InformationElement.EID_VSA;
-
- // no IE
- ScanResult scan = new ScanResult();
- scan.BSSID = "00:01:02:03:04:05";
- scan.informationElements = null;
- scan.channelWidth = ResponderConfig.CHANNEL_WIDTH_80MHZ;
-
- ResponderConfig config = ResponderConfig.fromScanResult(scan);
-
- assertEquals(ResponderConfig.PREAMBLE_VHT, config.preamble);
-
- // IE with HT & VHT
- scan.channelWidth = ResponderConfig.CHANNEL_WIDTH_40MHZ;
-
- scan.informationElements = new ScanResult.InformationElement[2];
- scan.informationElements[0] = htCap;
- scan.informationElements[1] = vhtCap;
-
- config = ResponderConfig.fromScanResult(scan);
-
- assertEquals(ResponderConfig.PREAMBLE_VHT, config.preamble);
-
- // IE with some entries but no HT or VHT
- scan.informationElements[0] = vsa;
- scan.informationElements[1] = vsa;
-
- config = ResponderConfig.fromScanResult(scan);
-
- assertEquals(ResponderConfig.PREAMBLE_LEGACY, config.preamble);
-
- // IE with HT
- scan.informationElements[0] = vsa;
- scan.informationElements[1] = htCap;
-
- config = ResponderConfig.fromScanResult(scan);
-
- assertEquals(ResponderConfig.PREAMBLE_HT, config.preamble);
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java b/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java
deleted file mode 100644
index 0d75138..0000000
--- a/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java
+++ /dev/null
@@ -1,130 +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.net.wifi.util;
-
-import static android.net.wifi.util.HexEncoding.decode;
-import static android.net.wifi.util.HexEncoding.encode;
-import static android.net.wifi.util.HexEncoding.encodeToString;
-
-import junit.framework.TestCase;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Locale;
-
-/** Copied from {@link libcore.libcore.util.HexEncodingTest}. */
-public class HexEncodingTest extends TestCase {
-
- public void testEncodeByte() {
- Object[][] testCases = new Object[][]{
- {0x01, "01"},
- {0x09, "09"},
- {0x0A, "0A"},
- {0x0F, "0F"},
- {0x10, "10"},
- {0x1F, "1F"},
- {0x20, "20"},
- {0x7F, "7F"},
- {0x80, "80"},
- {0xFF, "FF"},
- };
- for (Object[] testCase : testCases) {
- Number toEncode = (Number) testCase[0];
- String expected = (String) testCase[1];
-
- String actualUpper = encodeToString(toEncode.byteValue(), true /* upperCase */);
- assertEquals(upper(expected), actualUpper);
-
- String actualLower = encodeToString(toEncode.byteValue(), false /* upperCase */);
- assertEquals(lower(expected), actualLower);
- }
- }
-
- public void testEncodeBytes() {
- Object[][] testCases = new Object[][]{
- {"avocados".getBytes(StandardCharsets.UTF_8), "61766F6361646F73"},
- };
-
- for (Object[] testCase : testCases) {
- byte[] bytes = (byte[]) testCase[0];
- String encodedLower = lower((String) testCase[1]);
- String encodedUpper = upper((String) testCase[1]);
-
- assertArraysEqual(encodedUpper.toCharArray(), encode(bytes));
- assertArraysEqual(encodedUpper.toCharArray(), encode(bytes, true /* upperCase */));
- assertArraysEqual(encodedLower.toCharArray(), encode(bytes, false /* upperCase */));
-
- assertArraysEqual(bytes, decode(encode(bytes), false /* allowSingleChar */));
-
- // Make sure we can handle lower case hex encodings as well.
- assertArraysEqual(bytes,
- decode(encodedLower.toCharArray(), false /* allowSingleChar */));
- }
- }
-
- public void testDecode_allow4Bit() {
- assertArraysEqual(new byte[]{6}, decode("6".toCharArray(), true));
- assertArraysEqual(new byte[]{6, 0x76}, decode("676".toCharArray(), true));
- }
-
- public void testDecode_disallow4Bit() {
- try {
- decode("676".toCharArray(), false /* allowSingleChar */);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testDecode_invalid() {
- try {
- decode("DEADBARD".toCharArray(), false /* allowSingleChar */);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- // This demonstrates a difference in behaviour from apache commons : apache
- // commons uses Character.isDigit and would successfully decode a string with
- // arabic and devanagari characters.
- try {
- decode("६१٧٥٥F6361646F73".toCharArray(), false /* allowSingleChar */);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- decode("#%6361646F73".toCharArray(), false /* allowSingleChar */);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- private static void assertArraysEqual(char[] lhs, char[] rhs) {
- assertEquals(new String(lhs), new String(rhs));
- }
-
- private static void assertArraysEqual(byte[] lhs, byte[] rhs) {
- assertEquals(Arrays.toString(lhs), Arrays.toString(rhs));
- }
-
- private static String lower(String string) {
- return string.toLowerCase(Locale.ROOT);
- }
-
- private static String upper(String string) {
- return string.toUpperCase(Locale.ROOT);
- }
-}